[Pkg-wmaker-commits] [wmcube] 07/67: Imported Upstream version 0.99-pre1
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Tue Aug 25 03:22:11 UTC 2015
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch master
in repository wmcube.
commit 925287ee5f00726853410f387b9bb4566cbd5595
Author: Doug Torrance <dtorrance at monmouthcollege.edu>
Date: Sat Jan 10 23:09:27 2015 -0600
Imported Upstream version 0.99-pre1
---
3dObjects/2planes-solid.wmc | 23 -
3dObjects/4d.wmc | 59 -
3dObjects/8star-small.wmc | 40 -
3dObjects/8star.wmc | 40 -
3dObjects/CONTRIBUTE | 51 -
3dObjects/README | 54 -
3dObjects/ball.wmc | 83 --
3dObjects/celtic.wmc | 71 --
3dObjects/cross.wmc | 63 -
3dObjects/cross2.wmc | 51 -
3dObjects/cross3.wmc | 95 --
3dObjects/crystal.wmc | 108 --
3dObjects/cube.wmc | 24 -
3dObjects/diamond.wmc | 66 --
3dObjects/e.wmc | 69 --
3dObjects/e2.wmc | 160 ---
3dObjects/foo.wmc | 149 ---
3dObjects/gnustep.wmc | 110 --
3dObjects/hyperpyramid.wmc | 54 -
3dObjects/jeep.wmc | 157 ---
3dObjects/multicube.wmc | 83 --
3dObjects/pyramid.wmc | 16 -
3dObjects/shield.wmc | 197 ----
3dObjects/spaceshuttle.wmc | 382 ------
3dObjects/spiral.wmc | 49 -
3dObjects/star.wmc | 95 --
3dObjects/starcube.wmc | 69 --
CHANGES | 22 +-
INSTALL | 37 -
Makefile | 58 +
README | 124 +-
TODO | 8 -
WmcObject.cc | 619 ++++++++++
WmcObject.h | 96 ++
cpumoncc/README | 70 ++
cpumoncc/base/BaseCpuMonitor.h | 112 ++
cpumoncc/darwin/CpuMonitor.cc | 41 +
cpumoncc/darwin/CpuMonitor.h | 39 +
cpumoncc/darwin/Makefile | 41 +
cpumoncc/freebsd/CpuMonitor.cc | 80 ++
cpumoncc/freebsd/CpuMonitor.h | 52 +
cpumoncc/freebsd/Makefile | 41 +
cpumoncc/linux/CpuMonitor.cc | 100 ++
cpumoncc/linux/CpuMonitor.h | 45 +
cpumoncc/linux/Makefile | 40 +
cpumoncc/netbsd/CpuMonitor.cc | 113 ++
cpumoncc/netbsd/CpuMonitor.h | 43 +
cpumoncc/netbsd/Makefile | 40 +
cpumoncc/openbsd/CpuMonitor.cc | 42 +
cpumoncc/openbsd/CpuMonitor.h | 38 +
cpumoncc/openbsd/Makefile | 40 +
cpumoncc/programs/Makefile | 14 +
cpumoncc/programs/README | 17 +
cpumoncc/programs/cpu.cc | 56 +
cpumoncc/programs/cpuload.cc | 60 +
cpumoncc/solaris/CpuMonitor.cc | 141 +++
cpumoncc/solaris/CpuMonitor.h | 53 +
cpumoncc/solaris/Makefile | 40 +
COPYING => wmapp/COPYING | 11 +-
wmapp/Changelog | 82 ++
wmapp/Changelog.Jason | 154 +++
wmapp/FAQ.txt | 278 +++++
wmapp/Makefile | 35 +
wmapp/README | 66 ++
wmapp/Widgets.txt | 49 +
wmapp/colors.h | 54 +
wmapp/example1/Makefile | 13 +
wmapp/example1/debian-tiny.xpm | 50 +
wmapp/example1/window0.cc | 204 ++++
wmapp/example1/window1.cc | 86 ++
wmapp/example1/wmexample.cc | 39 +
wmapp/example2/Makefile | 13 +
wmapp/example2/wmairtrafficcontrol.cc | 80 ++
wmapp/example2/wmradar.cc | 220 ++++
wmapp/example2/wmradar.h | 44 +
wmapp/wmapp.cc | 378 ++++++
wmapp/wmapp.h | 170 +++
wmapp/wmbutton.cc | 59 +
wmapp/wmbutton.h | 18 +
wmapp/wmcallback.cc | 34 +
wmapp/wmcallback.h | 113 ++
wmapp/wmcanvas.cc | 160 +++
wmapp/wmcanvas.h | 68 ++
wmapp/wmclickable.h | 21 +
wmapp/wmellipse.cc | 58 +
wmapp/wmellipse.h | 21 +
wmapp/wmframe.cc | 303 +++++
wmapp/wmframe.h | 109 ++
wmapp/wmhistory.cc | 67 ++
wmapp/wmhistory.h | 71 ++
wmapp/wmimage.cc | 91 ++
wmapp/wmimage.h | 52 +
wmapp/wmled.cc | 12 +
wmapp/wmled.h | 34 +
wmapp/wmmeter.h | 57 +
wmapp/wmmeterbar.cc | 80 ++
wmapp/wmmeterbar.h | 47 +
wmapp/wmslider.cc | 42 +
wmapp/wmslider.h | 32 +
wmapp/wmtextbar.cc | 63 +
wmapp/wmtextbar.h | 57 +
wmapp/wmwidget.cc | 99 ++
wmapp/wmwidget.h | 367 ++++++
wmapp/wmwindow.cc | 114 ++
wmapp/wmwindow.h | 130 +++
wmapp/xpm/charmap-large.xpm | 74 ++
wmapp/xpm/charmap-medium.xpm | 62 +
wmapp/xpm/charmap-small.xpm | 62 +
wmapp/xpm/checkbox.xpm | 14 +
wmapp/xpm/emptybar.xpm | 62 +
wmapp/xpm/fullbar.xpm | 62 +
wmapp/xpm/leds.xpm | 14 +
wmapp/xpm/tile.xpm | 121 ++
wmapp/xpm/xbutton.xpm | 14 +
wmapp/xwrapper.cc | 329 ++++++
wmapp/xwrapper.h | 140 +++
3dObjects/ball-solid.wmc => wmc/ball.wmc | 53 +
wmc/cossin.wmc | 362 ++++++
wmc/coussin.bande.diag.wmc | 124 ++
{3dObjects => wmc}/cross2-solid.wmc | 0
{3dObjects => wmc}/cross3-solid.wmc | 0
3dObjects/cube-solid.wmc => wmc/cube.wmc | 16 +
wmc/diamond.wmc | 107 ++
3dObjects/dice-solid.wmc => wmc/dice.wmc | 45 +
wmc/hyp_par.wmc | 70 ++
wmc/judaspriest.wmc | 239 ++++
{3dObjects => wmc}/peace.wmc | 2 +
{3dObjects => wmc}/radioactive.wmc | 2 +
3dObjects/cross4-solid.wmc => wmc/star-solid.wmc | 48 +-
{3dObjects => wmc}/wmlogo.wmc | 2 +
wmcube.cc | 695 +++++++++++
wmcube.h | 118 ++
wmcube/Makefile | 39 -
wmcube/Makefile.FREEBSD | 38 -
wmcube/Makefile.LINUX | 39 -
wmcube/Makefile.NETBSD | 36 -
wmcube/Makefile.OPENBSD | 37 -
wmcube/Makefile.SOLARIS | 38 -
wmcube/wmcube.c | 1351 ----------------------
wmcube/wmcube.xpm | 142 ---
wmgeneral/list.c | 169 ---
wmgeneral/list.h | 59 -
wmgeneral/misc.c | 164 ---
wmgeneral/misc.h | 9 -
wmgeneral/wmgeneral.c | 481 --------
wmgeneral/wmgeneral.h | 59 -
146 files changed, 9448 insertions(+), 5195 deletions(-)
diff --git a/3dObjects/2planes-solid.wmc b/3dObjects/2planes-solid.wmc
deleted file mode 100644
index b884b35..0000000
--- a/3dObjects/2planes-solid.wmc
+++ /dev/null
@@ -1,23 +0,0 @@
-WMCUBE_COORDINATES
-1 -180 -180 180
-2 180 -180 180
-3 180 180 80
-4 -180 180 80
-5 -180 -180 -180
-6 180 -180 -180
-7 180 180 -80
-8 -180 180 -80
-
-WMCUBE_PLANES
-1 2 3
-1 3 4
-2 1 4
-2 4 3
-
-5 6 7
-5 7 8
-6 5 7
-7 5 8
-
-
-
diff --git a/3dObjects/4d.wmc b/3dObjects/4d.wmc
deleted file mode 100644
index 21716d1..0000000
--- a/3dObjects/4d.wmc
+++ /dev/null
@@ -1,59 +0,0 @@
-WMCUBE_COORDINATES
- 1 -51 50 0
- 2 0 50 51
- 3 51 50 0
- 4 0 50 -51
-
- 5 74 0 0
- 6 37 0 64
- 7 -37 0 64
- 8 -74 0 0
- 9 -37 0 -64
- 10 37 0 -64
-
- 11 -51 -50 0
- 12 0 -50 51
- 13 51 -50 0
- 14 0 -50 -51
-
-
- 15 0 100 0
- 16 0 -100 0
-
- WMCUBE_LINES
-
- 15 1
- 15 2
- 15 3
- 15 4
-
- 1 5
- 1 6
- 1 7
- 2 5
- 2 8
- 2 9
- 3 6
- 3 8
- 3 10
- 4 7
- 4 9
- 4 10
-
- 5 11
- 5 12
- 6 11
- 6 13
- 7 12
- 7 13
- 8 11
- 8 14
- 9 12
- 9 14
- 10 13
- 10 14
-
- 11 16
- 12 16
- 13 16
- 14 16
diff --git a/3dObjects/8star-small.wmc b/3dObjects/8star-small.wmc
deleted file mode 100644
index 35dddf5..0000000
--- a/3dObjects/8star-small.wmc
+++ /dev/null
@@ -1,40 +0,0 @@
-WMCUBE_COORDINATES
- 1 -50 -50 0
- 2 50 -50 0
- 3 50 50 0
- 4 -50 50 0
- 5 0 0 71
- 6 0 0 -71
- 7 0 82 58
- 8 82 0 58
- 9 0 -82 58
- 10 -82 0 58
- 11 0 82 -58
- 12 82 0 -58
- 13 0 -82 -58
- 14 -82 0 -58
- WMCUBE_LINES
- 2 8
- 2 9
- 2 12
- 2 13
- 4 7
- 4 10
- 4 11
- 4 14
- 1 9
- 1 10
- 1 13
- 1 14
- 3 7
- 3 8
- 3 11
- 3 12
- 5 7
- 5 8
- 5 9
- 5 10
- 6 11
- 6 12
- 6 13
- 6 14
diff --git a/3dObjects/8star.wmc b/3dObjects/8star.wmc
deleted file mode 100644
index c04e721..0000000
--- a/3dObjects/8star.wmc
+++ /dev/null
@@ -1,40 +0,0 @@
-WMCUBE_COORDINATES
- 1 -10 -10 0
- 2 10 -10 0
- 3 10 10 0
- 4 -10 10 0
- 5 0 0 21
- 6 0 0 -21
- 7 0 82 58
- 8 82 0 58
- 9 0 -82 58
- 10 -82 0 58
- 11 0 82 -58
- 12 82 0 -58
- 13 0 -82 -58
- 14 -82 0 -58
- WMCUBE_LINES
- 2 8
- 2 9
- 2 12
- 2 13
- 4 7
- 4 10
- 4 11
- 4 14
- 1 9
- 1 10
- 1 13
- 1 14
- 3 7
- 3 8
- 3 11
- 3 12
- 5 7
- 5 8
- 5 9
- 5 10
- 6 11
- 6 12
- 6 13
- 6 14
diff --git a/3dObjects/CONTRIBUTE b/3dObjects/CONTRIBUTE
deleted file mode 100644
index 3743655..0000000
--- a/3dObjects/CONTRIBUTE
+++ /dev/null
@@ -1,51 +0,0 @@
-These are the people who have contributed by making objects for wmCube:
-
-FuzzyBear <flung at andrew.cmu.edu>
-
- - 4d.wmc
- - crystal.wmc
- - starcube.wmc
-
-Peter Kokles <kokles at bb.telecom.sk>
-
- - celtic.wmc
- - multicube.wmc
- - peace.wmc
- - radioactive.wmc
- - shield.wmc
-
-Jeff Frasca <phaedrus at thereactor.cleptoscastle.com>
-
- - spiral.wmc
-
-Axel Ahrens <ahrens at ewerk.de>
-
- - hyperpyramid.wmc
-
-Aaron Benner <benner at mcn.net>
-
- - 8star.wmc
- - 8star-small.wmc
-
-Per �kergren <akeper-8 at student.luth.se>
-
- - e.wmc
- - e2.wmc
-
-Adam Hapworth <adamh at mint.net>
-
- - foo.wmc
- - jeep.wmc
-
-tarzeau <tarzeau at space.ch>
-
- - spaceshuttle.wmc
-
-Rafael Garcia-Suarez <garcia-suarez at kazibao.net>
-
- - wmlogo.wmc
-
-Nicolas Mieville <nm at altern.org>
-
- - diamond.wmc
- - gnustep.wmc
diff --git a/3dObjects/README b/3dObjects/README
deleted file mode 100644
index a5cad75..0000000
--- a/3dObjects/README
+++ /dev/null
@@ -1,54 +0,0 @@
-The object-files to be used with wmCube has the
-following format:
-
-WMCUBE_COORDINATES
-
-1 50 -40 30
-2 -50 50 -30
-3 -20 70 -20
-^ ^ ^ ^
-| | | \__ Z-coordinate relative the center
-| | \______ Y-coordinate relative the center
-| \___________ X-coordinate relative the center
- \_______________ Coordinate index
-
-
-The indexes must be 1,2,3...n on a object with n coordinates.
-The center of the object is the coordinate the object will
-revolve around (0,0,0);
-
-The next section is either (case sensitive):
-
-* WMCUBE_LINES
-
-1 2
-2 3
-3 1
-
-These are the coordinates wmCube will draw lines
-between.
-
-or
-
-* WMCUBE_PLANES
-
-1 2 3
-2 3 1
-1 3 2
-2 1 3
-
-These are the coordinates wmCube will use as corner-
-coordinates for a plane. The tricky part is that the
-plane will be drawn only if you list the coordinates
-making up the plane in clockwise order. In the example
-above, the first two rows making up planes with coordinates
-1 2 3 and 2 3 1 will NOT be drawn until the object
-has rotated some X degrees but the other two will be
-drawn at once. Its kinda hard to explain, just try and you
-will eventually understand how it works.
-
-
-Done! Save the file with a .wmc suffix (preferably) and try
-running wmCube with the -o option and it will tell you if
-something is wrong with the object. Otherwise enjoy and
-remember to send me all the cool objects you create :-)
diff --git a/3dObjects/ball.wmc b/3dObjects/ball.wmc
deleted file mode 100644
index 5a0d8be..0000000
--- a/3dObjects/ball.wmc
+++ /dev/null
@@ -1,83 +0,0 @@
-WMCUBE_COORDINATES
-1 -100 -100 100
-2 100 -100 100
-3 100 100 100
-4 -100 100 100
-5 -100 -100 -100
-6 100 -100 -100
-7 100 100 -100
-8 -100 100 -100
-9 -50 -150 -50
-10 50 -150 -50
-11 150 -50 -50
-12 150 50 -50
-13 50 150 -50
-14 -50 150 -50
-15 -150 50 -50
-16 -150 -50 -50
-17 -150 -50 50
-18 -50 -150 50
-19 50 -150 50
-20 150 -50 50
-21 150 50 50
-22 50 150 50
-23 -50 150 50
-24 -150 50 50
-25 -50 -50 150
-26 50 -50 150
-27 50 50 150
-28 -50 50 150
-29 -50 -50 -150
-30 50 -50 -150
-31 50 50 -150
-32 -50 50 -150
-
-WMCUBE_LINES
-9 10
-10 6
-6 11
-11 12
-12 7
-7 13
-13 14
-14 8
-8 15
-15 16
-16 5
-5 9
-17 1
-1 18
-18 19
-19 2
-2 20
-20 21
-21 3
-3 22
-22 23
-23 4
-4 24
-24 17
-9 18
-10 19
-11 20
-12 21
-13 22
-14 23
-15 24
-16 17
-25 26
-26 27
-27 28
-28 25
-25 1
-26 2
-27 3
-28 4
-29 30
-30 31
-31 32
-32 29
-5 29
-6 30
-7 31
-8 32
diff --git a/3dObjects/celtic.wmc b/3dObjects/celtic.wmc
deleted file mode 100644
index 5f45232..0000000
--- a/3dObjects/celtic.wmc
+++ /dev/null
@@ -1,71 +0,0 @@
-WMCUBE_COORDINATES
-1 -40 40 40
-2 -40 -40 40
-3 40 -40 40
-4 40 40 40
-5 -60 20 20
-6 -60 -20 20
-7 60 -20 20
-8 60 20 20
-9 -20 60 20
-10 -20 -60 20
-11 20 -60 20
-12 20 60 20
-13 -40 40 -40
-14 -40 -40 -40
-15 40 -40 -40
-16 40 40 -40
-17 -60 20 -20
-18 -60 -20 -20
-19 60 -20 -20
-20 60 20 -20
-21 -20 60 -20
-22 -20 -60 -20
-23 20 -60 -20
-24 20 60 -20
-25 20 20 60
-26 -20 20 60
-27 20 -20 60
-28 -20 -20 60
-29 20 20 -60
-30 -20 20 -60
-31 20 -20 -60
-32 -20 -20 -60
-
-WMCUBE_LINES
-8 18
-20 6
-5 19
-7 17
-8 20
-7 19
-5 17
-6 18
-8 7
-20 19
-5 6
-17 18
-25 26
-26 28
-28 27
-27 25
-29 30
-30 32
-32 31
-31 29
-25 32
-28 29
-26 31
-27 30
-9 23
-11 21
-10 24
-12 22
-24 12
-23 11
-9 21
-10 22
-11 10
-9 12
-23 22
-24 21
diff --git a/3dObjects/cross.wmc b/3dObjects/cross.wmc
deleted file mode 100644
index 72e9cf6..0000000
--- a/3dObjects/cross.wmc
+++ /dev/null
@@ -1,63 +0,0 @@
-WMCUBE_COORDINATES
-1 -50 -50 50
-2 50 -50 50
-3 50 50 50
-4 -50 50 50
-5 -50 -50 -50
-6 50 -50 -50
-7 50 50 -50
-8 -50 50 -50
-9 -50 -150 -50
-10 50 -150 -50
-11 150 -50 -50
-12 150 50 -50
-13 50 150 -50
-14 -50 150 -50
-15 -150 50 -50
-16 -150 -50 -50
-17 -150 -50 50
-18 -50 -150 50
-19 50 -150 50
-20 150 -50 50
-21 150 50 50
-22 50 150 50
-23 -50 150 50
-24 -150 50 50
-
-WMCUBE_LINES
-1 5
-2 6
-7 3
-8 4
-9 10
-10 6
-6 11
-11 12
-12 7
-7 13
-13 14
-14 8
-8 15
-15 16
-16 5
-5 9
-17 1
-1 18
-18 19
-19 2
-2 20
-20 21
-21 3
-3 22
-22 23
-23 4
-4 24
-24 17
-9 18
-10 19
-11 20
-12 21
-13 22
-14 23
-15 24
-16 17
diff --git a/3dObjects/cross2.wmc b/3dObjects/cross2.wmc
deleted file mode 100644
index 61b5a39..0000000
--- a/3dObjects/cross2.wmc
+++ /dev/null
@@ -1,51 +0,0 @@
-WMCUBE_COORDINATES
-1 -50 -50 50
-2 50 -50 50
-3 50 50 50
-4 -50 50 50
-5 -50 -50 -50
-6 50 -50 -50
-7 50 50 -50
-8 -50 50 -50
-9 -50 -150 -50
-10 50 -150 -50
-11 150 -50 -50
-12 150 50 -50
-13 50 150 -50
-14 -50 150 -50
-15 -150 50 -50
-16 -150 -50 -50
-17 -150 -50 50
-18 -50 -150 50
-19 50 -150 50
-20 150 -50 50
-21 150 50 50
-22 50 150 50
-23 -50 150 50
-24 -150 50 50
-
-WMCUBE_LINES
-9 10
-10 6
-6 11
-11 12
-12 7
-7 13
-13 14
-14 8
-8 15
-15 16
-16 5
-5 9
-17 1
-1 18
-18 19
-19 2
-2 20
-20 21
-21 3
-3 22
-22 23
-23 4
-4 24
-24 17
diff --git a/3dObjects/cross3.wmc b/3dObjects/cross3.wmc
deleted file mode 100644
index 6916934..0000000
--- a/3dObjects/cross3.wmc
+++ /dev/null
@@ -1,95 +0,0 @@
-WMCUBE_COORDINATES
-1 -50 -50 50
-2 50 -50 50
-3 50 50 50
-4 -50 50 50
-5 -50 -50 -50
-6 50 -50 -50
-7 50 50 -50
-8 -50 50 -50
-9 -50 -150 -50
-10 50 -150 -50
-11 150 -50 -50
-12 150 50 -50
-13 50 150 -50
-14 -50 150 -50
-15 -150 50 -50
-16 -150 -50 -50
-17 -150 -50 50
-18 -50 -150 50
-19 50 -150 50
-20 150 -50 50
-21 150 50 50
-22 50 150 50
-23 -50 150 50
-24 -150 50 50
-25 -50 -50 150
-26 50 -50 150
-27 50 50 150
-28 -50 50 150
-29 -50 -50 -150
-30 50 -50 -150
-31 50 50 -150
-32 -50 50 -150
-
-WMCUBE_LINES
-1 5
-2 6
-7 3
-8 4
-9 10
-10 6
-6 11
-11 12
-12 7
-7 13
-13 14
-14 8
-8 15
-15 16
-16 5
-5 9
-17 1
-1 18
-18 19
-19 2
-2 20
-20 21
-21 3
-3 22
-22 23
-23 4
-4 24
-24 17
-9 18
-10 19
-11 20
-12 21
-13 22
-14 23
-15 24
-16 17
-25 26
-26 27
-27 28
-28 25
-25 1
-26 2
-27 3
-28 4
-5 6
-6 7
-7 8
-8 5
-29 30
-30 31
-31 32
-32 29
-5 29
-6 30
-7 31
-8 32
-1 2
-2 3
-3 4
-4 1
diff --git a/3dObjects/crystal.wmc b/3dObjects/crystal.wmc
deleted file mode 100644
index e2341ce..0000000
--- a/3dObjects/crystal.wmc
+++ /dev/null
@@ -1,108 +0,0 @@
-WMCUBE_COORDINATES
- 1 0 0 0
-
- 2 150 0 0
- 3 0 150 0
- 4 0 0 150
- 5 -150 0 0
- 6 0 -150 0
- 7 0 0 -150
-
- 8 100 -30 -30
- 9 100 -30 30
- 10 100 30 30
- 11 100 30 -30
-
- 12 30 100 -30
- 13 30 100 30
- 14 -30 100 30
- 15 -30 100 -30
-
- 16 -100 -30 -30
- 17 -100 -30 30
- 18 -100 30 30
- 19 -100 30 -30
-
- 20 30 -100 -30
- 21 30 -100 30
- 22 -30 -100 30
- 23 -30 -100 -30
-
- 24 30 -30 100
- 25 30 30 100
- 26 -30 30 100
- 27 -30 -30 100
-
- 28 30 -30 -100
- 29 30 30 -100
- 30 -30 30 -100
- 31 -30 -30 -100
-
- WMCUBE_LINES
-
- 1 11
- 1 8
- 1 9
- 1 10
-
- 1 15
- 1 12
- 1 13
- 1 14
-
- 1 18
- 1 19
- 1 16
- 1 17
-
- 1 20
- 1 21
- 1 22
- 1 23
-
- 1 27
- 1 24
- 1 25
- 1 26
-
- 1 31
- 1 28
- 1 29
- 1 30
-
- 2 8
- 2 9
- 2 10
- 2 11
-
- 3 15
- 3 12
- 3 13
- 3 14
-
- 4 27
- 4 24
- 4 25
- 4 26
-
- 5 16
- 5 17
- 5 18
- 5 19
-
- 6 20
- 6 21
- 6 22
- 6 23
-
- 7 31
- 7 28
- 7 29
- 7 30
-
- 1 2
- 1 3
- 1 4
- 1 5
- 1 6
- 1 7
diff --git a/3dObjects/cube.wmc b/3dObjects/cube.wmc
deleted file mode 100644
index a55e975..0000000
--- a/3dObjects/cube.wmc
+++ /dev/null
@@ -1,24 +0,0 @@
-WMCUBE_COORDINATES
-1 -180 -180 180
-2 180 -180 180
-3 180 180 180
-4 -180 180 180
-5 -180 -180 -180
-6 180 -180 -180
-7 180 180 -180
-8 -180 180 -180
-
-WMCUBE_LINES
-1 2
-2 3
-3 4
-4 1
-5 6
-6 7
-7 8
-8 5
-1 5
-2 6
-3 7
-4 8
-
diff --git a/3dObjects/diamond.wmc b/3dObjects/diamond.wmc
deleted file mode 100644
index 06347f8..0000000
--- a/3dObjects/diamond.wmc
+++ /dev/null
@@ -1,66 +0,0 @@
-WMCUBE_COORDINATES
-
-1 -50 0 0
-2 -35 0 35
-3 0 0 50
-4 35 0 35
-5 50 0 0
-6 35 0 -35
-7 0 0 -50
-8 -35 0 -35
-
-9 -32 10 13
-10 -13 10 32
-11 13 10 32
-12 32 10 13
-13 32 10 -13
-14 13 10 -32
-15 -13 10 -32
-16 -32 10 -13
-
-17 0 -60 0
-WMCUBE_LINES
-
-1 2
-2 3
-3 4
-4 5
-5 6
-6 7
-7 8
-8 1
-
-9 10
-10 11
-11 12
-12 13
-13 14
-14 15
-15 16
-16 9
-
-1 9
-1 8
-2 10
-2 9
-3 11
-3 10
-4 12
-4 11
-5 13
-5 12
-6 14
-6 13
-7 15
-7 14
-8 16
-8 15
-
-17 1
-17 2
-17 3
-17 4
-17 5
-17 6
-17 7
-17 8
diff --git a/3dObjects/e.wmc b/3dObjects/e.wmc
deleted file mode 100644
index 7c78070..0000000
--- a/3dObjects/e.wmc
+++ /dev/null
@@ -1,69 +0,0 @@
-WMCUBE_COORDINATES
-1 -60 -120 30
-2 80 -120 30
-3 80 -60 30
-4 0 -60 30
-5 0 -20 30
-6 40 -20 30
-7 40 20 30
-8 0 20 30
-9 0 60 30
-10 80 60 30
-11 80 120 30
-12 -60 120 30
-13 -60 -120 -30
-14 80 -120 -30
-15 80 -60 -30
-16 0 -60 -30
-17 0 -20 -30
-18 40 -20 -30
-19 40 20 -30
-20 0 20 -30
-21 0 60 -30
-22 80 60 -30
-23 80 120 -30
-24 -60 120 -30
-
-
-WMCUBE_LINES
-1 2
-2 3
-3 4
-4 5
-5 6
-6 7
-7 8
-8 9
-9 10
-10 11
-11 12
- 1 12
-13 14
-14 15
-15 16
-16 17
-17 18
-18 19
-19 20
-20 21
-21 22
-22 23
-23 24
-13 24
-
-1 13
-2 14
-3 15
-4 16
-5 17
-6 18
-7 19
-8 20
-9 21
-10 22
-11 23
-12 24
-
-
-
-
diff --git a/3dObjects/e2.wmc b/3dObjects/e2.wmc
deleted file mode 100644
index cd80bd6..0000000
--- a/3dObjects/e2.wmc
+++ /dev/null
@@ -1,160 +0,0 @@
-WMCUBE_COORDINATES
-1 -60 -120 30
-2 80 -120 30
-3 80 -60 30
-4 0 -60 30
-5 0 -20 30
-6 40 -20 30
-7 40 20 30
-8 0 20 30
-9 0 60 30
-10 80 60 30
-11 80 120 30
-12 -60 120 30
-13 -60 -120 -30
-14 80 -120 -30
-15 80 -60 -30
-16 0 -60 -30
-17 0 -20 -30
-18 40 -20 -30
-19 40 20 -30
-20 0 20 -30
-21 0 60 -30
-22 80 60 -30
-23 80 120 -30
-24 -60 120 -30
-
-25 -60 -10 0
-26 -60 -40 0
-27 -80 -10 0
-28 -80 -40 0
-29 -80 -10 -15
-30 -80 -40 -15
-31 -80 -20 -20
-32 -80 -30 -20
-33 -80 -20 -30
-34 -80 -30 -30
-
-35 -60 -60 0
-36 -60 -90 0
-37 -80 -60 0
-38 -80 -90 0
-39 -80 -60 -15
-40 -80 -90 -15
-41 -80 -70 -20
-42 -80 -80 -20
-43 -80 -70 -30
-44 -80 -80 -30
-
-45 -60 10 0
-46 -60 40 0
-47 -80 10 0
-48 -80 40 0
-49 -80 10 -15
-50 -80 40 -15
-51 -80 20 -20
-52 -80 30 -20
-53 -80 20 -30
-54 -80 30 -30
-
-55 -60 60 0
-56 -60 90 0
-57 -80 60 0
-58 -80 90 0
-59 -80 60 -15
-60 -80 90 -15
-61 -80 70 -20
-62 -80 80 -20
-63 -80 70 -30
-64 -80 80 -30
-WMCUBE_LINES
-1 2
-2 3
-3 4
-4 5
-5 6
-6 7
-7 8
-8 9
-9 10
-10 11
-11 12
- 1 12
-13 14
-14 15
-15 16
-16 17
-17 18
-18 19
-19 20
-20 21
-21 22
-22 23
-23 24
-13 24
-1 13
-2 14
-3 15
-4 16
-5 17
-6 18
-7 19
-8 20
-9 21
-10 22
-11 23
-12 24
-
-25 26
-27 28
-25 27
-26 28
-27 29
-28 30
-29 31
-30 32
-31 33
-32 34
-33 34
-
-
-35 36
-37 38
-35 37
-36 38
-37 39
-38 40
-39 41
-40 42
-41 43
-42 44
-43 44
-
-45 46
-47 48
-45 47
-46 48
-47 49
-48 50
-49 51
-50 52
-51 53
-52 54
-53 54
-
-55 56
-57 58
-55 57
-56 58
-57 59
-58 60
-59 61
-60 62
-61 63
-62 64
-63 64
-
-
-
-
-
diff --git a/3dObjects/foo.wmc b/3dObjects/foo.wmc
deleted file mode 100644
index 04add8f..0000000
--- a/3dObjects/foo.wmc
+++ /dev/null
@@ -1,149 +0,0 @@
-WMCUBE_COORDINATES
- 1 -190 110 50
- 2 -190 -90 50
- 3 -160 -90 50
- 4 -160 20 50
- 5 -90 20 50
- 6 -90 50 50
- 7 -160 50 50
- 8 -160 80 50
- 9 -90 80 50
- 10 -90 110 50
-
- 11 -190 110 0
- 12 -190 -90 0
- 13 -160 -90 0
- 14 -160 20 0
- 15 -90 20 0
- 16 -90 50 0
- 17 -160 50 0
- 18 -160 80 0
- 19 -90 80 0
- 20 -90 110 0
-
-
- 21 -50 110 50
- 22 60 110 50
- 23 60 -90 50
- 24 -50 -90 50
- 25 -20 -50 50
- 26 40 -50 50
- 27 40 70 50
- 28 -20 70 50
-
- 29 -50 110 0
- 30 60 110 0
- 31 60 -90 0
- 32 -50 -90 0
- 33 -20 -50 0
- 34 20 -50 0
- 35 20 70 0
- 36 -20 70 0
-
-
- 37 110 110 50
- 38 210 110 50
- 39 210 -90 50
- 40 110 -90 50
- 41 130 -50 50
- 42 190 -50 50
- 43 190 70 50
- 44 130 70 50
-
- 45 110 110 0
- 46 210 110 0
- 47 210 -90 0
- 48 110 -90 0
- 49 130 -50 0
- 50 190 -50 0
- 51 190 70 0
- 52 130 70 0
-
-
- WMCUBE_LINES
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- 6 7
- 7 8
- 8 9
- 9 10
- 10 1
-
- 11 12
- 12 13
- 13 14
- 14 15
- 15 16
- 16 17
- 17 18
- 18 19
- 19 20
- 20 11
-
- 1 11
- 2 12
- 3 13
- 4 14
- 5 15
- 6 16
- 7 17
- 8 18
- 9 19
- 10 20
-
- 21 22
- 22 23
- 23 24
- 24 21
- 25 26
- 26 27
- 27 28
- 28 25
-
- 29 30
- 30 31
- 31 32
- 32 29
- 33 34
- 34 35
- 35 36
- 36 33
-
- 21 29
- 22 30
- 23 31
- 24 32
- 25 33
- 26 34
- 27 35
- 28 36
-
- 37 38
- 38 39
- 39 40
- 40 37
- 41 42
- 42 43
- 43 44
- 44 41
-
- 45 46
- 46 47
- 47 48
- 48 45
- 49 50
- 50 51
- 51 52
- 52 49
-
- 37 45
- 38 46
- 39 47
- 40 48
- 41 49
- 42 50
- 43 51
- 44 52
diff --git a/3dObjects/gnustep.wmc b/3dObjects/gnustep.wmc
deleted file mode 100644
index 5884a86..0000000
--- a/3dObjects/gnustep.wmc
+++ /dev/null
@@ -1,110 +0,0 @@
-WMCUBE_COORDINATES
-
-1 50 0 -10
-2 46 19 -10
-3 35 35 -10
-4 19 46 -10
-5 0 50 -10
-6 -19 46 -10
-7 -35 35 -10
-8 -46 19 -10
-9 -50 0 -10
-10 -46 -19 -10
-11 -35 -35 -10
-12 -19 -46 -10
-13 0 -50 -10
-14 19 -46 -10
-15 35 -35 -10
-16 46 -19 -10
-17 -25 35 -10
-18 -25 0 -10
-19 25 0 -10
-20 25 -35 -10
-
-21 50 0 10
-22 46 19 10
-23 35 35 10
-24 19 46 10
-25 0 50 10
-26 -19 46 10
-27 -35 35 10
-28 -46 19 10
-29 -50 0 10
-30 -46 -19 10
-31 -35 -35 10
-32 -19 -46 10
-33 0 -50 10
-34 19 -46 10
-35 35 -35 10
-36 46 -19 10
-37 -25 35 10
-38 -25 0 10
-39 25 0 10
-40 25 -35 10
-WMCUBE_LINES
-
-1 2
-2 3
-3 4
-4 5
-5 6
-6 7
-7 8
-8 9
-9 10
-10 11
-11 12
-12 13
-13 14
-14 15
-15 16
-16 1
-7 17
-17 18
-18 19
-19 20
-20 15
-
-21 22
-22 23
-23 24
-24 25
-25 26
-26 27
-27 28
-28 29
-29 30
-30 31
-31 32
-32 33
-33 34
-34 35
-35 36
-36 21
-27 37
-37 38
-38 39
-39 40
-40 35
-
-17 37
-18 38
-19 39
-20 40
-
-1 21
-2 22
-3 23
-4 24
-5 25
-6 26
-7 27
-8 28
-9 29
-10 30
-11 31
-12 32
-13 33
-14 34
-15 35
-16 36
diff --git a/3dObjects/hyperpyramid.wmc b/3dObjects/hyperpyramid.wmc
deleted file mode 100644
index 588d802..0000000
--- a/3dObjects/hyperpyramid.wmc
+++ /dev/null
@@ -1,54 +0,0 @@
-WMCUBE_COORDINATES
-1 300 0 0
-2 -150 260 0
-3 -150 -260 0
-4 50 87 0
-5 -100 0 0
-6 50 -87 0
-7 0 0 90
-8 50 87 -250
-9 -100 0 -250
-10 50 -87 -250
-11 0 0 -90
-12 100 0 -50
-13 -87 100 -50
-14 -87 -100 -50
-
-WMCUBE_LINES
-1 4
-4 2
-2 5
-5 3
-3 6
-6 1
-1 7
-2 7
-3 7
-4 7
-5 7
-6 7
-4 8
-5 9
-6 10
-8 11
-9 11
-10 11
-1 12
-8 12
-10 12
-4 12
-6 12
-11 12
-4 13
-2 13
-5 13
-8 13
-9 13
-11 13
-5 14
-3 14
-6 14
-11 14
-9 14
-10 14
-
diff --git a/3dObjects/jeep.wmc b/3dObjects/jeep.wmc
deleted file mode 100644
index 5fb8f1d..0000000
--- a/3dObjects/jeep.wmc
+++ /dev/null
@@ -1,157 +0,0 @@
-WMCUBE_COORDINATES
- 1 -150 -20 0
- 2 -150 50 0
- 3 -40 50 0
- 4 -40 20 0
- 5 30 20 0
- 6 30 60 0
- 7 20 130 0
- 8 30 50 0
- 9 160 50 0
- 10 160 -20 0
- 11 140 -20 0
- 12 130 0 0
- 13 90 0 0
- 14 80 -20 0
- 15 80 -40 0
- 16 100 -60 0
- 17 110 -60 0
- 18 140 -40 0
- 19 -70 -20 0
- 20 -70 -40 0
- 21 -90 -60 0
- 22 -110 -60 0
- 23 -130 -40 0
- 24 -130 -20 0
- 25 -120 0 0
- 26 -80 0 0
- 27 -150 50 0
- 28 -80 120 0
- 29 -80 50 0
- 30 90 40 0
- 31 170 40 0
- 32 180 30 0
- 33 180 10 0
- 34 160 10 0
- 35 80 -10 0
- 36 -80 -10 0
-
- 37 -150 -20 100
- 38 -150 50 100
- 39 -40 50 100
- 40 -40 20 100
- 41 30 20 100
- 42 30 60 100
- 43 20 130 100
- 44 30 50 100
- 45 160 50 100
- 46 160 -20 100
- 47 140 -20 100
- 48 130 0 100
- 49 90 0 100
- 50 80 -20 100
- 51 80 -40 100
- 52 100 -60 100
- 53 110 -60 100
- 54 140 -40 100
- 55 -70 -20 100
- 56 -70 -40 100
- 57 -90 -60 100
- 58 -110 -60 100
- 59 -130 -40 100
- 60 -130 -20 100
- 61 -120 0 100
- 62 -80 0 100
- 63 -150 50 100
- 64 -80 120 100
- 65 -80 50 100
- 66 90 40 100
- 67 170 40 100
- 68 180 30 100
- 69 180 10 100
- 70 160 10 100
- 71 80 -10 100
- 72 -80 -10 100
-
- WMCUBE_LINES
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- 6 7
- 8 9
- 9 10
- 10 11
- 11 12
- 12 13
- 13 14
- 14 15
- 15 16
- 16 17
- 17 18
- 35 36
- 19 20
- 20 21
- 21 22
- 22 23
- 23 24
- 24 1
- 24 25
- 25 26
- 27 28
- 28 29
- 30 31
- 31 32
- 32 33
- 33 34
- 18 11
-
- 37 38
- 38 39
- 39 40
- 40 41
- 41 42
- 42 43
- 44 45
- 45 46
- 46 47
- 47 48
- 48 49
- 49 50
- 50 51
- 51 52
- 52 53
- 53 54
- 71 72
- 55 56
- 56 57
- 57 58
- 58 59
- 59 60
- 60 37
- 60 61
- 61 62
- 63 64
- 64 65
- 66 67
- 67 68
- 68 69
- 69 70
- 54 47
-
- 1 37
- 2 38
- 3 39
- 4 40
- 5 41
- 6 42
- 7 43
- 8 44
- 9 45
- 10 46
- 11 47
- 35 71
- 36 72
- 24 60
- 28 64
diff --git a/3dObjects/multicube.wmc b/3dObjects/multicube.wmc
deleted file mode 100644
index ba05439..0000000
--- a/3dObjects/multicube.wmc
+++ /dev/null
@@ -1,83 +0,0 @@
-WMCUBE_COORDINATES
-1 -40 40 40
-2 -40 -40 40
-3 40 -40 40
-4 40 40 40
-5 -60 20 20
-6 -60 -20 20
-7 60 -20 20
-8 60 20 20
-9 -20 60 20
-10 -20 -60 20
-11 20 -60 20
-12 20 60 20
-13 -40 40 -40
-14 -40 -40 -40
-15 40 -40 -40
-16 40 40 -40
-17 -60 20 -20
-18 -60 -20 -20
-19 60 -20 -20
-20 60 20 -20
-21 -20 60 -20
-22 -20 -60 -20
-23 20 -60 -20
-24 20 60 -20
-25 20 20 60
-26 -20 20 60
-27 20 -20 60
-28 -20 -20 60
-29 20 20 -60
-30 -20 20 -60
-31 20 -20 -60
-32 -20 -20 -60
-
-WMCUBE_LINES
-1 2
-2 3
-3 4
-4 1
-5 6
-6 7
-7 8
-8 5
-9 10
-10 11
-11 12
-12 9
-13 14
-14 15
-15 16
-16 13
-1 13
-2 14
-3 15
-4 16
-17 18
-18 19
-19 20
-20 17
-8 20
-5 17
-6 18
-7 19
-21 22
-22 23
-23 24
-24 21
-12 24
-23 11
-9 21
-10 22
-25 26
-26 28
-27 28
-27 25
-25 29
-26 30
-28 31
-27 32
-29 30
-30 32
-31 32
-31 29
diff --git a/3dObjects/pyramid.wmc b/3dObjects/pyramid.wmc
deleted file mode 100644
index 99a618c..0000000
--- a/3dObjects/pyramid.wmc
+++ /dev/null
@@ -1,16 +0,0 @@
-WMCUBE_COORDINATES
-1 -150 -150 -150
-2 150 -150 -150
-3 150 150 -150
-4 -150 150 -150
-5 0 0 250
-WMCUBE_LINES
-1 2
-2 3
-3 4
-4 1
-1 5
-2 5
-3 5
-4 5
-
diff --git a/3dObjects/shield.wmc b/3dObjects/shield.wmc
deleted file mode 100644
index 3451f45..0000000
--- a/3dObjects/shield.wmc
+++ /dev/null
@@ -1,197 +0,0 @@
-WMCUBE_COORDINATES
-1 -76 112 -10
-2 76 112 -10
-3 -10 99 -10
-4 10 99 -10
-5 10 75 -10
-6 33 75 -10
-7 33 55 -10
-8 10 55 -10
-9 -10 55 -10
-10 -33 55 -10
-11 -33 75 -10
-12 -10 75 -10
-13 -55 20 -10
-14 -10 20 -10
-15 10 20 -10
-16 55 20 -10
-17 55 0 -10
-18 10 0 -10
-19 -10 0 -10
-20 -55 0 -10
-21 -76 0 -10
-22 -72 -29 -10
-23 -59 -56 -10
-24 -34 -79 -10
-25 0 -89 -10
-26 35 -79 -10
-27 59 -56 -10
-28 72 -27 -10
-29 76 0 -10
-30 -53 -48 -10
-31 -45 -42 -10
-32 -36 -40 -10
-33 -26 -42 -10
-34 -19 -35 -10
-35 -10 -32 -10
-36 0 -30 -10
-37 10 -32 -10
-38 19 -35 -10
-39 26 -42 -10
-40 36 -40 -10
-41 45 -42 -10
-42 53 -48 -10
-43 -76 112 20
-44 76 112 20
-45 -10 99 20
-46 10 99 20
-47 10 75 20
-48 33 75 20
-49 33 55 20
-50 10 55 20
-51 -10 55 20
-52 -33 55 20
-53 -33 75 20
-54 10 75 20
-55 -55 20 20
-56 -10 20 20
-57 10 20 20
-58 55 20 20
-59 55 0 20
-60 10 0 20
-61 -10 0 20
-62 -55 0 20
-63 -76 0 20
-64 -72 -29 20
-65 -59 -56 20
-66 -34 -79 20
-67 0 -89 20
-68 35 -79 20
-69 59 -56 20
-70 72 -27 20
-71 76 0 20
-72 -53 -48 20
-73 -45 -42 20
-74 -36 -40 20
-75 -26 -42 20
-76 -19 -35 20
-77 -10 -32 20
-78 0 -30 20
-79 10 -32 20
-80 19 -35 20
-81 26 -42 20
-82 36 -40 20
-83 45 -42 20
-84 53 -48 20
-
-
-WMCUBE_LINES
-1 2
-2 29
-29 28
-28 27
-27 26
-26 25
-25 24
-24 23
-23 22
-22 21
-21 1
-3 4
-4 5
-5 6
-6 7
-7 8
-8 15
-15 16
-16 17
-17 18
-18 37
-35 19
-19 20
-20 13
-13 14
-14 9
-9 10
-10 11
-11 12
-12 3
-23 30
-30 31
-31 32
-32 33
-33 34
-34 35
-35 36
-36 37
-37 38
-38 39
-39 40
-40 41
-41 42
-42 27
-43 44
-44 71
-71 70
-70 69
-69 68
-68 67
-67 66
-66 65
-45 46
-46 47
-47 48
-48 49
-49 50
-50 57
-57 58
-58 59
-59 60
-60 79
-35 61
-61 62
-62 55
-55 56
-56 51
-51 52
-52 53
-53 54
-54 45
-65 72
-72 73
-73 74
-74 75
-75 76
-76 77
-77 78
-78 79
-79 80
-80 81
-81 82
-82 83
-83 84
-84 69
-43 63
-63 64
-64 65
-1 43
-2 44
-3 45
-4 46
-5 47
-6 48
-7 49
-8 50
-15 57
-16 58
-17 59
-18 60
-19 61
-20 62
-13 55
-14 56
-9 51
-10 52
-11 53
-12 54
-67 25
diff --git a/3dObjects/spaceshuttle.wmc b/3dObjects/spaceshuttle.wmc
deleted file mode 100644
index d7b1d1d..0000000
--- a/3dObjects/spaceshuttle.wmc
+++ /dev/null
@@ -1,382 +0,0 @@
-WMCUBE_COORDINATES
-1 -44 0 14
-2 55 0 15
-3 60 0 10
-4 83 0 0
-5 86 0 -3
-6 85 0 -6
-7 77 0 -10
-8 45 0 -12
-9 -44 0 14
-10 -45 0 19
-11 -45 0 19
-12 -82 0 52
-13 -92 0 52
-14 -94 0 51
-15 -80 0 22
-16 -70 0 18
-17 -68 -16 -13
-18 -61 -58 -9
-19 -54 -58 -9
-20 -42 -56 -10
-21 -13 -26 -12
-22 47 -13 -10
-23 -68 16 -13
-24 -61 58 -9
-25 -54 58 -9
-26 -42 55 -10
-27 -13 27 -12
-28 47 13 -10
-29 45 -13 -14
-30 45 -13 9
-31 45 -9 13
-32 45 -4 15
-33 45 4 15
-34 45 9 13
-35 45 13 9
-36 45 13 -14
-37 -45 -13 -14
-38 -45 -13 9
-39 -45 -9 13
-40 -45 -4 15
-41 -45 4 15
-42 -45 9 13
-43 -45 13 9
-44 -45 13 -14
-45 45 13 -4
-46 48 13 -4
-47 78 7 -4
-48 85 3 -4
-49 86 0 -4
-50 45 -13 -4
-51 48 -13 -4
-52 78 -7 -4
-53 85 -3 -4
-54 86 0 -4
-55 45 13 -12
-56 -42 13 -15
-57 -72 13 -14
-58 45 -13 -12
-59 -42 -13 -15
-60 -72 -13 -14
-61 45 13 -12
-62 45 -13 -12
-63 -72 13 -14
-64 -72 -13 -14
-65 -72 14 -14
-66 -84 14 -13
-67 -72 14 -12
-68 -72 -14 -14
-69 -84 -14 -13
-70 -72 -14 -12
-71 -84 14 -13
-72 -84 -14 -13
-73 -72 16 -12
-74 -70 14 4
-75 -69 2 16
-76 -69 -2 16
-77 -70 -15 4
-78 -72 -16 -12
-79 -56 57 -9
-80 -56 16 -13
-81 -56 -57 -9
-82 -56 -16 -13
-83 -93 0 48
-84 -87 0 48
-85 -70 0 23
-86 -80 0 23
-87 -69 15 4
-88 -69 18 12
-89 -69 10 20
-90 -69 2 16
-91 -69 -15 4
-92 -69 -19 12
-93 -69 -11 20
-94 -69 -2 16
-95 -69 15 4
-96 -44 13 5
-97 -69 2 16
-98 -44 2 14
-99 -69 18 12
-100 -52 18 13
-101 -69 10 20
-102 -52 10 21
-103 -52 18 13
-104 -52 -10 21
-105 -52 18 13
-106 -44 13 5
-107 -52 10 21
-108 -44 2 14
-109 -69 -15 4
-110 -44 -13 5
-111 -69 -2 16
-112 -44 -2 14
-113 -69 -19 12
-114 -52 -19 13
-115 -69 -11 20
-116 -52 -10 21
-117 -52 -19 13
-118 -52 -10 21
-119 -52 -19 13
-120 -44 -13 5
-121 -52 -10 21
-122 -44 -2 14
-123 -80 0 16
-124 -81 3 14
-125 -82 3 8
-126 -83 0 6
-127 -82 -3 8
-128 -81 -3 14
-129 -80 0 16
-130 -80 0 16
-131 -69 0 12
-132 -83 0 6
-133 -70 0 4
-134 -82 3 11
-135 -69 2 8
-136 -82 -3 11
-137 -69 -2 -8
-138 -69 0 12
-139 -69 2 8
-140 -70 0 4
-141 -69 -2 8
-142 -69 0 12
-143 -83 8 2
-144 -84 13 -1
-145 -85 13 -6
-146 -85 8 -9
-147 -85 3 -6
-148 -84 3 -1
-149 -83 8 2
-150 -83 8 2
-151 -72 7 -2
-152 -85 8 -9
-153 -73 7 -9
-154 -84 13 -3
-155 -73 10 -5
-156 -84 3 -3
-157 -73 4 -5
-158 -72 7 -2
-159 -73 10 -5
-160 -73 7 -9
-161 -73 4 -5
-162 -72 7 -2
-163 -83 -8 2
-164 -84 -13 -1
-165 -85 -13 -6
-166 -85 -8 -9
-167 -85 -4 -6
-168 -84 -4 -1
-169 -83 -8 2
-170 -83 -8 2
-171 -72 -7 -2
-172 -85 -8 -9
-173 -73 -7 -9
-174 -84 -13 -3
-175 -73 -10 -5
-176 -84 -4 -3
-177 -73 -4 -5
-178 -72 -7 -2
-179 -73 -10 -5
-180 -73 -7 -9
-181 -73 -4 -5
-182 -72 -7 -2
-183 61 2 10
-184 60 5 10
-185 57 5 13
-186 58 3 13
-187 61 2 10
-188 61 -2 10
-189 60 -5 10
-190 57 -5 13
-191 58 -3 13
-192 61 -2 10
-193 60 5 10
-194 57 9 8
-195 55 7 12
-196 57 5 13
-197 60 -5 10
-198 57 -9 8
-199 55 -7 12
-200 57 -5 13
-201 57 9 8
-202 53 10 9
-203 53 7 12
-204 55 7 12
-205 57 -9 8
-206 53 -10 9
-207 53 -7 12
-208 55 -7 12
-209 45 13 5
-210 -45 13 4
-211 45 -13 5
-212 -45 -13 4
-213 45 13 -12
-214 48 13 -12
-215 78 6 -9
-216 85 3 -5
-217 86 0 -4
-218 45 -13 -12
-219 48 -13 -12
-220 78 -7 -9
-221 85 -3 -5
-222 86 0 -4
-223 0 0 0
-WMCUBE_LINES
-2 1
-3 2
-4 3
-5 4
-6 5
-7 6
-8 7
-10 9
-12 11
-13 12
-14 13
-15 14
-16 15
-18 17
-19 18
-20 19
-21 20
-22 21
-24 23
-25 24
-26 25
-27 26
-28 27
-30 29
-31 30
-32 31
-33 32
-34 33
-35 34
-36 35
-38 37
-39 38
-40 39
-41 40
-42 41
-43 42
-44 43
-46 45
-47 46
-48 47
-49 48
-51 50
-52 51
-53 52
-54 53
-56 55
-57 56
-59 58
-60 59
-62 61
-64 63
-66 65
-67 66
-69 68
-70 69
-72 71
-74 73
-75 74
-76 75
-77 76
-78 77
-80 79
-82 81
-84 83
-85 84
-86 85
-88 87
-89 88
-90 89
-92 91
-93 92
-94 93
-96 95
-98 97
-100 99
-102 101
-104 103
-106 105
-108 107
-110 109
-112 111
-114 113
-116 115
-118 117
-120 119
-122 121
-124 123
-125 124
-126 125
-127 126
-128 127
-129 128
-131 130
-133 132
-135 134
-137 136
-139 138
-140 139
-141 140
-142 141
-144 143
-145 144
-146 145
-147 146
-148 147
-149 148
-151 150
-153 152
-155 154
-157 156
-159 158
-160 159
-161 160
-162 161
-164 163
-165 164
-166 165
-167 166
-168 167
-169 168
-171 170
-173 172
-175 174
-177 176
-179 178
-180 179
-181 180
-182 181
-184 183
-185 184
-186 185
-187 186
-189 188
-190 189
-191 190
-192 191
-194 193
-195 194
-196 195
-198 197
-199 198
-200 199
-202 201
-203 202
-204 203
-206 205
-207 206
-208 207
-210 209
-212 211
-214 213
-215 214
-216 215
-217 216
-219 218
-220 219
-221 220
\ No newline at end of file
diff --git a/3dObjects/spiral.wmc b/3dObjects/spiral.wmc
deleted file mode 100644
index 0af2d4f..0000000
--- a/3dObjects/spiral.wmc
+++ /dev/null
@@ -1,49 +0,0 @@
-WMCUBE_COORDINATES
-
-1 80 0 0
-2 0 -90 25
-3 -100 0 50
-4 0 110 75
-5 120 0 100
-6 0 -130 125
-7 -140 0 150
-8 0 150 175
-9 160 0 200
-10 0 70 -25
-11 -60 0 -50
-12 0 -50 -75
-13 40 0 -100
-14 0 30 -125
-15 -20 0 -150
-16 0 -10 -175
-17 0 0 -200
-18 0 -160 200
-19 -160 0 200
-20 0 160 200
-
-WMCUBE_LINES
-
-1 2
-2 3
-3 4
-4 5
-5 6
-6 7
-7 8
-8 9
-1 10
-10 11
-11 12
-12 13
-13 14
-14 15
-15 16
-16 17
-17 9
-17 18
-17 19
-17 20
-9 18
-18 19
-19 20
-20 9
diff --git a/3dObjects/star.wmc b/3dObjects/star.wmc
deleted file mode 100644
index 1fd0b24..0000000
--- a/3dObjects/star.wmc
+++ /dev/null
@@ -1,95 +0,0 @@
-WMCUBE_COORDINATES
-1 -90 -90 90
-2 90 -90 90
-3 90 90 90
-4 -90 90 90
-5 -90 -90 -90
-6 90 -90 -90
-7 90 90 -90
-8 -90 90 -90
-9 -10 -350 -10
-10 10 -350 -10
-11 350 -10 -10
-12 350 10 -10
-13 10 350 -10
-14 -10 350 -10
-15 -350 10 -10
-16 -350 -10 -10
-17 -350 -10 10
-18 -10 -350 10
-19 10 -350 10
-20 350 -10 10
-21 350 10 10
-22 10 350 10
-23 -10 350 10
-24 -350 10 10
-25 -10 -10 350
-26 10 -10 350
-27 10 10 350
-28 -10 10 350
-29 -10 -10 -350
-30 10 -10 -350
-31 10 10 -350
-32 -10 10 -350
-
-WMCUBE_LINES
-1 5
-2 6
-7 3
-8 4
-9 10
-10 6
-6 11
-11 12
-12 7
-7 13
-13 14
-14 8
-8 15
-15 16
-16 5
-5 9
-17 1
-1 18
-18 19
-19 2
-2 20
-20 21
-21 3
-3 22
-22 23
-23 4
-4 24
-24 17
-9 18
-10 19
-11 20
-12 21
-13 22
-14 23
-15 24
-16 17
-25 26
-26 27
-27 28
-28 25
-25 1
-26 2
-27 3
-28 4
-5 6
-6 7
-7 8
-8 5
-29 30
-30 31
-31 32
-32 29
-5 29
-6 30
-7 31
-8 32
-1 2
-2 3
-3 4
-4 1
diff --git a/3dObjects/starcube.wmc b/3dObjects/starcube.wmc
deleted file mode 100644
index a7bc2df..0000000
--- a/3dObjects/starcube.wmc
+++ /dev/null
@@ -1,69 +0,0 @@
-WMCUBE_COORDINATES
- 1 -100 -100 100
- 2 100 -100 100
- 3 100 100 100
- 4 -100 100 100
- 5 -100 -100 -100
- 6 100 -100 -100
- 7 100 100 -100
- 8 -100 100 -100
-
- 9 75 0 0
- 10 0 75 0
- 11 0 0 75
- 12 -75 0 0
- 13 0 -75 0
- 14 0 0 -75
-
- 15 -75 -75 75
- 16 75 -75 75
- 17 75 75 75
- 18 -75 75 75
- 19 -75 -75 -75
- 20 75 -75 -75
- 21 75 75 -75
- 22 -75 75 -75
-
- WMCUBE_LINES
- 1 2
- 2 3
- 3 4
- 4 1
- 5 6
- 6 7
- 7 8
- 8 5
- 1 5
- 2 6
- 3 7
- 4 8
-
- 9 15
- 9 18
- 9 19
- 9 22
-
- 10 15
- 10 16
- 10 19
- 10 20
-
- 11 19
- 11 20
- 11 21
- 11 22
-
- 12 16
- 12 17
- 12 20
- 12 21
-
- 13 17
- 13 18
- 13 21
- 13 22
-
- 14 15
- 14 16
- 14 17
- 14 18
diff --git a/CHANGES b/CHANGES
index 5b38c4e..730b2fa 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,24 @@
-wmcube 0.98:
+wmCube 0.99-pre1
+ * Rewrite to C++ using the wmApp toolkit.
+ - Full color depth
+ - User definable for/background colors
+ - User definable shading
+ - New window layout added with cpu meter
+ - Switch to classic (simple) layout with a mouseclick
+ * Uses the CpuMonitorCC library (also in pre-stage)
+ * Place lightsource with mouseclick or have it move around by itself
+ * Solid wireframe mode added
+ * "Reflex" effect
+ * 3- and 5-button mouse (mouse wheel support)
+ * wmc file format updates
+ - Both planes and lines in the same file (preferably even)
+ - No specific order of sections is required
+ - Comments allowed (all lines starting with a #)
+ - Should be fully backwards compatible
+ * If no object(s) defined looks in /usr/share/wmcube
+ * Rewritten scandir function to be POSIX compliant
+
+wmCube 0.98:
* Added solid flat-shading to 3d-engine
* New tag in object-files (WMCUBE_PLANES) for solid objects
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 8cae7e6..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,37 +0,0 @@
-Requirements
---------------------------------------------------------------
-
-- Linux (glibc 2.1) (Tested on various distributions)
- or Solaris 8 Sparc/x86 (should work on Solaris 2.x and 7)
- or OpenBSD
- or FreeBSD 3-stable, 4-stable
- or NetBSD
-
-- root access
-
- To be able to install the application system-wide
- you need root access.
-
-Installation
---------------------------------------------------------------
-1) % tar -zxvf wmcube-0.98.tar.gz
-
-2) % cd wmcube/wmcube
-
-3) % make (if you are running Linux) or
- % make -f Makefile.xxx (where xxx is the OS you running)
-
-Optional
-
-4) % su root
-
-5) % make install
-
-6) % wmcube & (or wmcube -h for command line options).
-
-General Notes
---------------------------------------------------------------
-Note 1: If "make install" fails on your system, please edit
- the Makefile to set the paths according to your setup.
- "make install" defaults to /usr/local/bin, $HOME & /etc.
-
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ba39bd9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,58 @@
+#
+# wmCube 0.99-pre1
+#
+# To make wmcube compile on another OS change the following things:
+#
+# CXXFLAGS -D: FREEBSD/NETBSD/SOLARIS/OPENBSD/DARWIN
+# CPUMONCC_OS: freebsd/netbsd/solaris/openbsd/darwin (you will also have
+# to make sure that the makefile in the cpumoncc/$(CPUMONCC_OS) directory
+# is working.
+# LFLAGS: Modify/Add any necessary libraries here.
+#
+#
+CXX= g++
+CXXFLAGS=-O2 -DLINUX
+CPUMONCC_OS=linux
+WMCUBE_LIBS=-Lwmapp -lwmapp -Lcpumoncc/$(CPUMONCC_OS) -lcpumoncc
+LFLAGS=$(WMCUBE_LIBS) -L/usr/X11R6/lib -lXpm -lXext -lX11
+OBJECTS = WmcObject.o
+TARGET = wmcube
+
+$(TARGET): wmcube.cc cpumoncc/$(CPUMONCC_OS)/libcpumoncc.a wmapp/libwmapp.a $(OBJECTS)
+ @@echo "###############################################################"
+ @@echo "#"
+ @@echo "# I am now building the actual wmCube application."
+ @@echo "#"
+ @@echo "###############################################################"
+ $(CXX) $(CXXFLAGS) $(OBJECTS) $< -o $@ $(LFLAGS)
+
+cpumoncc/$(CPUMONCC_OS)/libcpumoncc.a:
+ @@echo "###############################################################"
+ @@echo "# I am now building the cpumoncc library in 'cpumoncc/$(CPUMONCC_OS)'."
+ @@echo "# Please modify/verify the makefile in that directory before"
+ @@echo "# reporting an error as a bug."
+ @@echo "###############################################################"
+ cd cpumoncc/$(CPUMONCC_OS); make; cd ../..
+
+wmapp/libwmapp.a:
+ @@echo "###############################################################"
+ @@echo "# I am now building the wmapp library in 'wmapp'"
+ @@echo "# Please modify/verify the makefile in that directory before"
+ @@echo "# reporting an error as a bug."
+ @@echo "###############################################################"
+ cd wmapp; make; cd ..
+
+install: $(TARGET)
+ cp -Rf wmc /usr/share/wmcube
+ cp wmcube /usr/local/bin
+ chmod 755 /usr/local/bin/wmcube
+ chown root:root /usr/local/bin/wmcube
+
+clean:
+ rm -f *.o *\~ $(TARGET)
+ cd wmapp; make clean; cd ..
+ cd cpumoncc/$(CPUMONCC_OS); make clean; cd ../..
+
+install_clean:
+ rm -fr /usr/share/wmcube
+ rm /usr/local/bin/wmcube
diff --git a/README b/README
index 9275d45..18affb7 100644
--- a/README
+++ b/README
@@ -1,41 +1,83 @@
-wmCube 0.98
---------------------------------------------------------------
-Author: Robert Kling
- robkli-8 at student.luth.se
- http://boombox.campus.luth.se
-
-Contributions by:
- Thorsten Jens (thodi at et-inf.fho-emden.de)
- Jakob Borg (email-adress goes here)
- Dan Price (dp at rampant.org)
- Brian Joseph Czapiga (rys at godsey.net)
- Tai-hwa Liang (avatar at mmlab.cse.yzu.edu.tw)
- Jared Smolens (jsmolens+ at andrew.cmu.edu)
-
-Description
---------------------------------------------------------------
-
-wmCube is a dockapp that displays a realtime rotating 3d-object
-and the current CPU load.
-
-Files
---------------------------------------------------------------
-3dObjects/ In here you will find bundled object-files.
-README This file.
-INSTALL Installation instructions.
-CHANGES Description of changes.
-TODO Things I've already planned for wmCube
-COPYING GNU General Public License Version 2.
-
-Bugs
---------------------------------------------------------------
-If you discover any bugs in this software, please send a
-bugreport to robkli-8 at student.luth.se and describe the
-problem as detailed as you can.
-
-Copyright
---------------------------------------------------------------
-wmCube is Copyright (C) 2000/01 by Robert Kling, Lulea SWEDEN
-
-wmCube is licensed through the GNU General Public License.
-Read the COPYING file for the complete GNU license.
+wmCube 0.99-pre1
+(C) Copyright 2003 Robert Kling
+robkli-8 at student.luth.se
+http://kling.mine.nu/wmcube.htm
+
+DESCRIPTION
+wmCube is a dockapp for monitoring the cpu load. A 3D object spins
+faster/slower relative to the load and you can even design your own
+objects for it. Objects can be traditional wireframe or solid shaded or
+a combination of the two.
+
+REQUIREMENTS
+wmCube uses the CpuMonitorCC (cpumoncc) library (spawned from
+previous versions of wmCube) to read the cpu load which supports a
+range of different operating systems. Further, the wmApp toolkit is
+used to do the drawing to the X server. Both cpumoncc and wmApp
+are included in the distribution, versions 0.0.1-pre1 and 0.0.4.1
+respectively.
+
+INSTALL
+THIS PRE-VERSION ONLY WORKS ON LINUX! Please report
+all bugs. Note though that wmCube _should_ compile on all archs
+supported in earlier versions by simply editing the Makefile for
+the particular OS in the cpumoncc directory as well as copying
+and modifying the main makefile. IF YOU GET WMCUBE
+WORKING IN ANOTHER OS THAN LINUX, PLEASE SEND
+ME THE SUCCESSFUL MAKEFILES OR A PATCH! (sorry
+for the shouting)
+
+To install wmCube:
+
+# make
+
+then as root
+
+# make install
+
+This will install wmc-objects into /usr/share/wmcube
+and the binary into /usr/local/bin.
+
+Alternatively you can run wmcube with '-o <directory>' which will
+load objects from the <directory>. More objects will
+be bundled in the stable release.
+
+USAGE
+
+# wmcube -h
+
+will give you a list of all availible command line options. When
+running you control the program by clicking with your mouse on the
+canvas where the object is displayed.
+
+For a 3-button mouse:
+
+First mouse button (left):
+ Upper left corner: Switches between new and classic window mode.
+ Left hand side: Zoom away from the object.
+ Right hand side: Zoom in on the object.
+ Upper edge: Scroll in the next object from below.
+ Lower edge: Scroll in the previous object from above.
+ In the middle (approx): Change 3d mode on object.
+
+Second mouse button (middle button):
+ Changes 3d mode on object.
+
+Third mouse button (right):
+ Sets the position of the lightsource.
+
+For a 5-button mouse (mouse wheel):
+Exactly the same as 3-button mouse except
+that you can also zoom in/out with the wheel
+(button 4 and 5).
+
+CONTRIBUTIONS
+I only test wmCube thoroughly on Linux so anyone running on a
+different OS/architecture please let me now if there are any bugs.
+Suggestions, patches etc. are also very welcome. If you package
+wmCube for a certain distribution/OS and it is not represented on
+this page feel free to send it to me. You can also send me new
+objects (if they're cool) and I will include them in the next release
+alt. put them up on this page. Make sure to put a comment
+(new in 0.99) with your name etc in the wmc-file if you want credit
+for them.
\ No newline at end of file
diff --git a/TODO b/TODO
deleted file mode 100644
index 01df841..0000000
--- a/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-TODO list for wmCube future versions
---------------------------------------------------------------
-
-* Ports to more OS's.
-* Goroud shading, texture mapping (hmm.. do I smell overkill?)
-
-If you have any suggestions, ideas, comments of how to make
-this app better please send it to robkli-8 at student.luth.se.
diff --git a/WmcObject.cc b/WmcObject.cc
new file mode 100644
index 0000000..e5c5a0f
--- /dev/null
+++ b/WmcObject.cc
@@ -0,0 +1,619 @@
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <iostream>
+#include <stdexcept>
+#include <vector>
+#include "wmapp/wmcanvas.h"
+#include "WmcObject.h"
+
+using namespace std;
+
+#define DEBUG 0
+#define PDEBUG() if (DEBUG)
+
+#define CHECK(a, b, c) (((b) < (a)) || ((b) > (c))) ? true : false
+#define ROUND(a) ((a) - floor((a)) >= 0.5) ? (int)ceil((a)) : (int)floor((a))
+#define PI 3.14159265368979
+#define PI2 6.283185307
+#define invPI 0.318309885
+#define WMC_COMMENT_CHAR '#'
+#define VERTEX_SCALE 200.0
+
+/**********************************
+ Color related stuff
+*/
+
+#define REFLEX 0.04 // Do the reflexy thing if the shading is less than this
+#define REFLEX_COLOR 0xAACEEE
+#define WIRE_COLOR 0x20B2AE
+#define CYAN 0x20B2AE
+#define SHADING 90.0
+
+/*******************************************************************
+
+ WmcObject::WmcObject()
+
+ Creates a new (default)
+
+********************************************************************/
+WmcObject::WmcObject()
+{
+ const char *filename = { "/tmp/default_cube.wmc" };
+ FILE *fp = fopen(filename, "w");
+ fwrite(default_cube, sizeof(unsigned char), strlen(default_cube), fp);
+ fclose(fp);
+
+ load(filename);
+
+ lightsource.x = 0;
+ lightsource.y = -1;
+ lightsource.z = 1;
+
+ xoff = 26;
+ yoff = 20;
+ zoff = 3000;
+
+ color = CYAN;
+ shading = SHADING / 100.0;
+}
+
+/*******************************************************************
+
+ WmcObject::WmcObject(const char *filename)
+
+********************************************************************/
+WmcObject::WmcObject(const char *filename)
+{
+ load(filename);
+
+ lightsource.x = 0;
+ lightsource.y = -1;
+ lightsource.z = 1;
+
+ xoff = 26;
+ yoff = 20;
+ zoff = 3000;
+
+ color = CYAN;
+ shading = SHADING / 100.0;
+}
+
+/*******************************************************************
+
+ WmcObject::~WmcObject()
+
+********************************************************************/
+WmcObject::~WmcObject()
+{
+}
+
+void WmcObject::setColorShading(unsigned icolor, float ishading)
+{
+ color = icolor;
+ shading = ishading / 100.0;;
+}
+
+void WmcObject::setMode(int m)
+{
+ PDEBUG() printf("setting mode %d\n", m);
+ switch (m)
+ {
+ case WIREFRAME:
+ PDEBUG() printf("setting wireframe mode\n", m);
+ if (lines) mode = WIREFRAME;
+ break;
+ case SOLID:
+ PDEBUG() printf("setting solid mode\n", m);
+ if (planes) mode = SOLID;
+ break;
+ case SOLID_WIRE:
+ PDEBUG() printf("setting solid wire mode\n", m);
+ if (planes && lines) mode = SOLID_WIRE;
+ break;
+ default:
+ break;
+ }
+}
+
+void WmcObject::setYOffset(int pixels)
+{
+ yoff = pixels;
+}
+
+void WmcObject::modifyZOffset(int idepth)
+{
+ if (zoff + idepth >= 2 * VERTEX_SCALE)
+ zoff += idepth;
+}
+
+void WmcObject::setLightSource(float xc, float yc, float zc)
+{
+ lightsource.x = xc;
+ lightsource.y = yc;
+ lightsource.z = zc;
+}
+
+
+/*******************************************************************
+
+ int WmcObject::freadline(FILE *fp, int maxlen, char *dest)
+
+ Reads a line of chars of maximum 'maxlen' length from file 'fp'
+ into buffer 'dest'. Discards comments (returns length 0) otherwise
+ return the true length of the row.
+
+********************************************************************/
+int WmcObject::freadline(FILE *fp, int maxlen, char *dest)
+{
+ int cnt = 0;
+ bzero(dest, maxlen);
+ if (feof(fp)) return 0;
+ fread(&dest[cnt++], 1, 1, fp);
+ while ((dest[cnt - 1] != '\n') && (!feof(fp)) && (cnt < maxlen)) fread(&dest[cnt++], 1, 1, fp);
+ dest[cnt - 1] = 0;
+ if (dest[0] == WMC_COMMENT_CHAR) return 0;
+ return cnt - 1;
+}
+
+/*******************************************************************
+
+ bool WmcObject::loadVertices(const char *filename)
+
+********************************************************************/
+bool WmcObject::loadVertices(const char *filename)
+{
+ Vertex vtmp;
+ int n = 0;
+ char tmp[64], tmp2[64];
+ FILE *fp;
+ float max = 0;
+
+ PDEBUG() printf("Loading vertices...\n");
+
+ if ((fp = fopen(filename,"r")) == NULL)
+ throw runtime_error("WmcObject::load: object file not found.");
+
+ do
+ {
+ freadline(fp, 63, tmp);
+ if (feof(fp)) return false;
+ }
+ while (!strstr(tmp,"WMCUBE_COORDINATES"));
+
+ do
+ {
+ int len = freadline(fp, 63, tmp);
+ //printf("\"%s\"\n",tmp);
+
+ if (!strstr(tmp,"WMCUBE_PLANES") && !strstr(tmp,"WMCUBE_LINES") && (len > 5))
+ {
+ if (sizeof(float) == sizeof(double))
+ sscanf(tmp,"%63s %lf %lf %lf", tmp2, &vtmp.x, &vtmp.y, &vtmp.z);
+ else
+ sscanf(tmp,"%63s %f %f %f", tmp2, &vtmp.x, &vtmp.y, &vtmp.z);
+
+ n = atoi(tmp2);
+
+ // Save maximum scalar product for scaling
+ if (sqrt(vtmp.x*vtmp.x + vtmp.y*vtmp.y + vtmp.z*vtmp.z) > max)
+ max = sqrt(vtmp.x * vtmp.x + vtmp.y*vtmp.y + vtmp.z*vtmp.z);
+
+ vertex.push_back(vtmp);
+ //printf("%d: %f %f %f\n", n, vertex.back().x, vertex.back().y, vertex.back().z);
+
+ if (n != vertex.size())
+ {
+ fclose(fp);
+ throw runtime_error("WmcObject::load: Error in objectfile: the"
+ "coordinates must be listed in order 1..n.");
+ }
+ }
+ }
+
+ while (!strstr(tmp,"WMCUBE_LINES") && !strstr(tmp,"WMCUBE_PLANES") && (!feof(fp)));
+
+ // Scale the vertices to 0..200
+ for (int i = 0; i < vertex.size(); i++)
+ {
+ vertex.at(i).x = VERTEX_SCALE / max * vertex.at(i).x;
+ vertex.at(i).y = VERTEX_SCALE / max * vertex.at(i).y;
+ vertex.at(i).z = VERTEX_SCALE / max * vertex.at(i).z;
+ rvertex.push_back(vertex.at(i));
+ }
+
+ fclose(fp);
+
+ return true;
+}
+
+/*******************************************************************
+
+ bool WmcObject::loadLines(const char *filename)
+
+********************************************************************/
+bool WmcObject::loadLines(const char *filename)
+{
+ Line ltmp;
+ char tmp[64];
+ int iltmp[3];
+ FILE *fp;
+
+ if ((fp = fopen(filename,"r")) == NULL)
+ throw runtime_error("WmcObject::load: object file not found.\n");
+
+ do
+ {
+ freadline(fp, 63, tmp);
+ if (feof(fp)) return false;
+ }
+ while (!strstr(tmp,"WMCUBE_LINES"));
+
+ PDEBUG() printf("Loading lines...\n");
+
+ do
+ {
+ int len = freadline(fp, 63, tmp);
+
+ if (!strstr(tmp,"WMCUBE_COORDINATES") && !strstr(tmp,"WMCUBE_PLANES") && (len > 2))
+ {
+ sscanf(tmp, "%d %d", &iltmp[0], &iltmp[1]);
+
+ if (CHECK(0, iltmp[0] - 1, vertex.size()) || CHECK(0, iltmp[1] - 1, vertex.size()))
+ {
+ fclose(fp);
+ throw runtime_error("WmcObject::load: Error in objectfile (WMCUBE_LINES section):"
+ "invalid coordinates.");
+ }
+
+ ltmp.a = &rvertex[iltmp[0] - 1];
+ ltmp.b = &rvertex[iltmp[1] - 1];
+ line.push_back(ltmp);
+ //printf("%d %d\n", iltmp[0], iltmp[1]);
+ }
+ }
+ while (!strstr(tmp,"WMCUBE_COORDINATES") && !strstr(tmp,"WMCUBE_PLANES") && !feof(fp));
+
+ fclose(fp);
+
+ return true;
+}
+
+/*******************************************************************
+
+ bool WmcObject::loadPlanes(const char *filename)
+
+********************************************************************/
+bool WmcObject::loadPlanes(const char *filename)
+{
+ Plane ptmp;
+ char tmp[64];
+ int iptmp[3];
+ FILE *fp;
+
+ if ((fp = fopen(filename,"r")) == NULL)
+ throw runtime_error("WmcObject::load: object file not found.");
+
+ do
+ {
+ freadline(fp, 63, tmp);
+ if (feof(fp)) return false;
+ }
+ while (!strstr(tmp,"WMCUBE_PLANES"));
+
+ PDEBUG() printf("Loading planes...\n");
+
+ do
+ {
+ int len = freadline(fp, 63, tmp);
+
+ if (!strstr(tmp,"WMCUBE_COORDINATES") && !strstr(tmp,"WMCUBE_LINES") && (len > 4))
+ {
+ sscanf(tmp,"%d %d %d", &iptmp[0], &iptmp[1], &iptmp[2]);
+
+ if (CHECK(0, iptmp[0] - 1, rvertex.size())
+ || CHECK(0, iptmp[1] - 1, rvertex.size())
+ || CHECK(0, iptmp[2] - 1, rvertex.size()))
+ {
+ fclose(fp);
+ throw runtime_error("WmcObject::load: Error in objectfile (WMCUBE_PLANES section): "
+ "invalid coordinates.");
+ }
+
+ ptmp.a = &rvertex[iptmp[0] - 1];
+ ptmp.b = &rvertex[iptmp[1] - 1];
+ ptmp.c = &rvertex[iptmp[2] - 1];
+ ptmp.ab = -1;
+ ptmp.bc = -1;
+ ptmp.ac = -1;
+ plane.push_back(ptmp);
+ //printf("%d %d %d\n", iptmp[0], iptmp[1], iptmp[2]); fflush(stdout);
+ }
+ }
+ while (!strstr(tmp,"WMCUBE_LINES") && !strstr(tmp,"WMCUBE_COORDINATES") && !feof(fp));
+
+ fclose(fp);
+
+ if (lines)
+ {
+ // Check which lines to draw for SOLID_WIRE mode
+
+ for (int i = 0; i < plane.size(); i++)
+ for (int j = 0; j < line.size(); j++)
+ {
+ if (verticesBelongToLine(plane[i].a, plane[i].b, line[j])) plane[i].ab = j;
+ if (verticesBelongToLine(plane[i].b, plane[i].c, line[j])) plane[i].bc = j;
+ if (verticesBelongToLine(plane[i].a, plane[i].c, line[j])) plane[i].ac = j;
+ }
+ }
+
+ return true;
+}
+
+bool WmcObject::verticesBelongToLine(Vertex *first, Vertex *second, Line l)
+{
+ if ((first == l.a && second == l.b) || (second == l.a && first == l.b))
+ return true;
+
+ return false;
+}
+
+/*******************************************************************
+
+ bool WmcObject::load(const char *filename)
+
+********************************************************************/
+bool WmcObject::load(const char *filename)
+{
+ try
+ {
+ loadVertices(filename);
+ lines = loadLines(filename);
+ planes = loadPlanes(filename);
+ }
+ catch (exception &e)
+ {
+ cout << e.what() << endl;
+ }
+
+ if (!lines && !planes)
+ throw runtime_error("WmcObject::load: no WMCUBE_PLANES or WMCUBE_LINES section found in file.");
+
+ if (planes && lines)
+ mode = SOLID_WIRE;
+ else if (planes)
+ mode = SOLID;
+ else
+ mode = WIREFRAME;
+
+ return true;
+}
+
+/*******************************************************************
+
+ void WmcObject::rotate(int ixang, int iyang, int izang)
+
+ Rotates the object from it's current configuration by ixang, iyang
+ and izang degrees.
+
+********************************************************************/
+void WmcObject::rotate(float ixang, float iyang, float izang)
+{
+ static float xang = 0;
+ static float yang = 0;
+ static float zang = 0;
+ float tx, ty, tz;
+
+ xang = (xang + ixang > PI2) ? xang + ixang - PI2 : xang + ixang;
+ yang = (yang + iyang > PI2) ? yang + iyang - PI2 : yang + iyang;
+ zang = (zang + izang > PI2) ? zang + izang - PI2 : zang + izang;
+
+ for (int i = 0; i < vertex.size(); i++)
+ {
+ tx = cos(yang) * vertex[i].x - sin(yang) * vertex[i].z;
+ tz = sin(yang) * vertex[i].x + cos(yang) * vertex[i].z;
+ ty = cos(zang) * vertex[i].y - sin(zang) * tx;
+
+ rvertex[i].x = cos(zang) * tx + sin(zang) * vertex[i].y;
+ rvertex[i].y = sin(xang) * tz + cos(xang) * ty;
+ rvertex[i].z = cos(xang) * tz - sin(xang) * ty;
+ }
+
+ // Calculate plane color before distorting it with perspective
+ for (int i = 0; i < plane.size(); i++)
+ plane[i].color = luminate(plane[i]);
+
+ // Add perspective
+ for (int i = 0; i < vertex.size(); i++)
+ {
+ rvertex[i].x = 256 * rvertex[i].x / (2 * rvertex[i].z - zoff) + xoff;
+ rvertex[i].y = 256 * rvertex[i].y / (2 * rvertex[i].z - zoff) + yoff;
+ }
+}
+
+/*******************************************************************
+
+ void WmcObject::draw(WMCanvas *icanvas)
+
+ Draws the WmcObject on the WMCanvas icanvas. Defaults to planes if
+ available, otherwise wireframe is used. Buffered mode is used
+ so canvas->display() must be called at the end.
+
+********************************************************************/
+void WmcObject::draw(WMCanvas *icanvas)
+{
+ canvas = icanvas;
+
+ canvas->setbuffered(true);
+
+ switch (mode)
+ {
+ case WIREFRAME:
+ canvas->setcolor((WMColor::WMColor)WIRE_COLOR);
+ for (int i = 0; i < line.size(); i++)
+ canvas->draw_line((int)(line[i].a->x), (int)(line[i].a->y),(int)(line[i].b->x), (int)(line[i].b->y));
+ break;
+
+ case SOLID:
+ sort(plane);
+ for (int i = 0; i < plane.size(); i++)
+ if (visible(plane[i])) drawTriangle(plane[i]);
+ break;
+
+ case SOLID_WIRE:
+ sort(plane);
+ for (int i = 0; i < plane.size(); i++)
+ if (visible(plane[i])) drawTriangle(plane[i], true);
+ break;
+ }
+
+ canvas->display();
+}
+
+/*******************************************************************
+
+ bool WmcObject::visible(Plane p)
+
+ Returns true if the plane is visible (has positive z-component).
+
+********************************************************************/
+bool WmcObject::visible(Plane p)
+{
+ //return normal(p).z > 0.0; // Also works but no need computing x- and y-components
+ return ((p.a->x - p.c->x) * (p.b->y - p.c->y) - (p.b->x - p.c->x) * (p.a->y - p.c->y)) > 0.0;
+}
+
+/*******************************************************************
+
+ Vertex WmcObject::normal(Plane p)
+
+ Returns plane p's normal.
+
+********************************************************************/
+Vertex WmcObject::normal(Plane p)
+{
+ Vertex ret;
+ float x1 = p.a->x - p.c->x, y1 = p.a->y - p.c->y, z1 = p.a->z - p.c->z;
+ float x2 = p.b->x - p.c->x, y2 = p.b->y - p.c->y, z2 = p.b->z - p.c->z;
+ ret.x = y1 * z2 - y2 * z1;
+ ret.y = x2 * z1 - x1 * z2;
+ ret.z = x1 * y2 - y1 * x2;
+
+ return ret;
+}
+
+/*******************************************************************
+
+ float WmcObject::luminate(Plane p)
+
+ Returns the luminousity _DECREASE_ for plane p in the range 0..1.
+ This is based solely on the angle between the plane's normal and
+ the lightsource vector, i.e the distance between the lightsource
+ and plane is _not_ taken into account (which would be easy to fake).
+
+********************************************************************/
+float WmcObject::luminate(Plane p)
+{
+ Vertex pn = normal(p);
+ float sp_pn = sqrt(pn.x * pn.x + pn.y * pn.y + pn.z * pn.z);
+ float sp_lum = sqrt(lightsource.x * lightsource.x + lightsource.y * lightsource.y
+ + lightsource.z * lightsource.z);
+ float pn_lum = pn.x * lightsource.x + pn.y * lightsource.y + pn.z * lightsource.z;
+
+ return invPI * acos((pn_lum / (sp_pn * sp_lum)));
+}
+
+/*******************************************************************
+
+ void WmcObject::sort(vector<Plane> &plane)
+
+ Insertion-sorts a vector of planes by the sum of their z-components.
+
+********************************************************************/
+void WmcObject::sort(vector<Plane> &plane)
+{
+ int i, j, k;
+ float key;
+ float temparr[plane.size()];
+ Plane ptmp;
+
+ for (i = 0; i < plane.size(); i++)
+ temparr[i] = plane[i].a->z + plane[i].b->z + plane[i].c->z;
+
+ for (j = 1; j < plane.size(); j++)
+ {
+ ptmp = plane[j];
+ key = temparr[j];
+ i = j - 1;
+
+ while ((i > -1) && (temparr[i] > key))
+ {
+ plane[i+1] = plane[i];
+ temparr[i+1] = temparr[i];
+ i--;
+ }
+
+ plane[i+1] = ptmp;
+ temparr[i+1] = key;
+ }
+}
+
+/*******************************************************************
+
+ void WmcObject::drawTriangle(Plane p)
+
+ Draws a filled polygon using the builtin routine from wmapp which
+ in turn uses the builtin routine in X. Sadly enough it is uglier
+ than my own original routine due to some corner pixel that gets
+ plotted sometime. Plane color is computed using the global
+ variables colX and colX_dec and 'p.color'.
+
+********************************************************************/
+void WmcObject::drawTriangle(Plane p, bool wire)
+{
+ X::XPoint xp;
+ vector<X::XPoint> points;
+ unsigned char R = 0, G = 0, B = 0;
+ unsigned composit = 0;
+
+ xp.x = (int)p.a->x;
+ xp.y = (int)p.a->y;
+ points.push_back(xp);
+ xp.x = (int)p.b->x;
+ xp.y = (int)p.b->y;
+ points.push_back(xp);
+ xp.x = (int)p.c->x;
+ xp.y = (int)p.c->y;
+ points.push_back(xp);
+
+ R = (unsigned char)(color >> 16);
+ G = (unsigned char)(color >> 8 );
+ B = (unsigned char)(color );
+
+ R -= (unsigned char)((float)R * p.color * shading);
+ G -= (unsigned char)((float)G * p.color * shading);
+ B -= (unsigned char)((float)B * p.color * shading);
+
+ composit = (R << 16) + (G << 8) + B;
+
+ // If the plane is almost purpendicular to the lightsource fake a 'reflex'
+ if (p.color < REFLEX) composit = REFLEX_COLOR;
+
+ canvas->setcolor((WMColor::WMColor)composit);
+ canvas->fill_polygon(points);
+
+ if (!wire) return;
+
+ canvas->setcolor((WMColor::WMColor)WIRE_COLOR);
+
+ if (p.ab > -1)
+ canvas->draw_line((int)(line[p.ab].a->x), (int)(line[p.ab].a->y),
+ (int)(line[p.ab].b->x), (int)(line[p.ab].b->y));
+ if (p.bc > -1)
+ canvas->draw_line((int)(line[p.bc].a->x), (int)(line[p.bc].a->y),
+ (int)(line[p.bc].b->x), (int)(line[p.bc].b->y));
+ if (p.ac > -1)
+ canvas->draw_line((int)(line[p.ac].a->x), (int)(line[p.ac].a->y),
+ (int)(line[p.ac].b->x), (int)(line[p.ac].b->y));
+
+}
diff --git a/WmcObject.h b/WmcObject.h
new file mode 100644
index 0000000..cfb8b1f
--- /dev/null
+++ b/WmcObject.h
@@ -0,0 +1,96 @@
+#ifndef _WMCOBJECT_H_
+#define _WMCOBJECT_H_
+
+#include <vector>
+#include "wmapp/wmcanvas.h"
+
+typedef struct { float x, y, z; } Vertex;
+typedef struct { Vertex *a, *b, *c; float color; int ab, bc, ac; } Plane;
+typedef struct { Vertex *a, *b; } Line;
+typedef enum { WIREFRAME, SOLID, SOLID_WIRE, NUM_MODES };
+
+class WmcObject
+{
+public:
+ WmcObject();
+ WmcObject(const char *);
+ ~WmcObject();
+
+ void setMode(int m);
+ void setColorShading(unsigned color, float shading);
+ void rotate(float xang, float yang, float zang);
+ void draw(WMCanvas *icanvas);
+
+ void setYOffset(int pixels);
+ void modifyZOffset(int idepth);
+ void setLightSource(float xc, float yc, float zc);
+
+private:
+
+ bool load(const char *);
+ bool loadVertices(const char *);
+ bool loadPlanes(const char *);
+ bool loadLines(const char *);
+ int freadline(FILE *fp, int maxlen, char *dest);
+ void sort(vector<Plane> &plane);
+ bool visible(Plane p);
+ float luminate(Plane p);
+ Vertex normal(Plane p);
+ void drawTriangle(Plane p, bool wire = false);
+ bool verticesBelongToLine(Vertex *first, Vertex *second, Line l);
+
+ vector<Vertex> vertex;
+ vector<Vertex> rvertex;
+ vector<Plane> plane;
+ vector<Line> line;
+
+ WMCanvas *canvas;
+ Vertex lightsource;
+ bool lines, planes;
+ int xoff, yoff, zoff;
+ int mode;
+ unsigned int color;
+ float shading;
+};
+
+const char default_cube[] =
+{ ""
+"# The original cube by Robert Kling\n"
+"WMCUBE_COORDINATES\n"
+"1 -180 -180 180\n"
+"2 180 -180 180\n"
+"3 180 180 180\n"
+"4 -180 180 180\n"
+"5 -180 -180 -180\n"
+"6 180 -180 -180\n"
+"7 180 180 -180\n"
+"8 -180 180 -180\n"
+"WMCUBE_LINES\n"
+"1 2\n"
+"2 3\n"
+"3 4\n"
+"4 1\n"
+"5 6\n"
+"6 7\n"
+"7 8\n"
+"8 5\n"
+"1 5\n"
+"2 6\n"
+"3 7\n"
+"4 8\n"
+"WMCUBE_PLANES\n"
+"1 2 3\n"
+"1 3 4\n"
+"2 6 7\n"
+"2 7 3\n"
+"5 1 4\n"
+"5 4 8\n"
+"5 2 1\n"
+"5 6 2\n"
+"4 3 8\n"
+"3 7 8\n"
+"6 5 8\n"
+"6 8 7"
+};
+
+#endif
diff --git a/cpumoncc/README b/cpumoncc/README
new file mode 100644
index 0000000..3b3da91
--- /dev/null
+++ b/cpumoncc/README
@@ -0,0 +1,70 @@
+CpuMonitorCC (cpumoncc)
+Version: 0.0.1-pre1 (aka "Expect Things To Be Broken")
+
+(C) Copyright 2003 Robert Kling
+
+robkli-8 at student.luth.se
+http://kling.mine.nu
+
+DESCRIPTION
+
+This is a small library for reading the instantaneous cpu load
+in many different operating systems. It started out as a part of
+wmCube but as it [wmCube] got ported to more and more OS's it
+seemed tidier to put the OS-specific code into its
+on package. As the name implies it is written in C++.
+
+REQUIREMENTS/FEATURES
+
+Supported systems and their features so far are:
+
+ * Darwin - Basic functionality.
+ * FreeBSD - Basic functionality, discarding of 'nice' processes.
+ * Linux - Multiprocessor support, discarding of 'nice' processes.
+ * NetBSD - Basic functionality, discarding of 'nice' processes.
+ * OpenBSD - Basic functionality.
+ * Solaris - Multiprocessor support.
+
+INSTALLATION
+
+Change to the directory of the OS your building cpumoncc for.
+Type (as root):
+
+make install
+
+To build the programs that come with cpumoncc, go into the directory
+'programs' and type
+
+make
+
+and optionally, as root
+
+make install
+
+CONTRIBUTIONS
+
+Solaris codebase by Dan Price (dp at rampant.org)
+OpenBSD codebase by Brian Joseph Czapiga (rys at godsey.net)
+FreeBSD codebase by Tai-hwa Liang (avatar at mmlab.cse.yzu.edu.tw)
+NetBSD codebase by Jared Smolens <jsmolens+ at andrew.cmu.edu>
+
+I only test cpumoncc thoroughly on Linux so anyone running on a
+different OS/architecture please let me now if there are any bugs
+or if everything's hunky dory. Suggestions, patches, more ports
+etc. are also very welcome.
+
+LICENSE
+
+cpumoncc 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.
+
+cpumoncc 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 cpumoncc; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
diff --git a/cpumoncc/base/BaseCpuMonitor.h b/cpumoncc/base/BaseCpuMonitor.h
new file mode 100644
index 0000000..3577c7d
--- /dev/null
+++ b/cpumoncc/base/BaseCpuMonitor.h
@@ -0,0 +1,112 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/*
+
+ This is the base class which all cpu monitors should inherit
+ from. Best is to use one of the existing monitors as a
+ template when writing a new one. By inheriting this base
+ class it can be as simple as implementing just one function
+ to support a new operating system. This function is
+ getLoad() which should return the (average (in the case of
+ a smp-system)) intermediate cpu-load in the range [0.0, 1.0]
+ multiplied by the inherited protected variable 'range'.
+
+*/
+
+#ifndef _BASECPUMONITOR_H_
+#define _BASECPUMONITOR_H_
+
+#include <stdio.h>
+#include <stdexcept>
+
+#define CPUMONCC_VERSION "0.0.1-pre1"
+#define CPUMONCC_DATE "2003-02-14"
+
+using namespace std;
+
+class BaseCpuMonitor
+{
+public:
+
+ BaseCpuMonitor();
+ virtual float getLoad() = 0;
+ void setRange(float);
+ bool saveInternals(const char *);
+ bool loadInternals(const char *);
+
+protected:
+
+ int which_cpu;
+ bool use_nice;
+ int previous_total;
+ int previous_used;
+ float range;
+};
+
+inline BaseCpuMonitor::BaseCpuMonitor()
+{
+ which_cpu = -1;
+ use_nice = true;
+ previous_total = 0;
+ previous_used = 0;
+ // Set default range to percent
+ range = 100.0;
+}
+
+inline void BaseCpuMonitor::setRange(float irange)
+{
+ range = irange;
+}
+
+inline bool BaseCpuMonitor::saveInternals(const char *filename)
+{
+ int count;
+ FILE *fp = fopen(filename, "w");
+
+ if (fp == 0) return false;
+
+ count = fprintf(fp, "%d %d", previous_used, previous_total);
+ fclose(fp);
+
+ if (count != 2) return false;
+
+ return true;
+}
+
+inline bool BaseCpuMonitor::loadInternals(const char *filename)
+{
+ int count;
+ FILE *fp = fopen(filename, "r");
+
+ if (fp == 0) return false;
+
+ count = fscanf(fp, "%d %d", &previous_used, &previous_total);
+ fclose(fp);
+
+ if (count != 2) return false;
+
+ return true;
+}
+
+
+#endif
diff --git a/cpumoncc/darwin/CpuMonitor.cc b/cpumoncc/darwin/CpuMonitor.cc
new file mode 100644
index 0000000..b98a800
--- /dev/null
+++ b/cpumoncc/darwin/CpuMonitor.cc
@@ -0,0 +1,41 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Darwin
+
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+}
+
+float CpuMonitor::getLoad()
+{
+ float t;
+ double avenrun[3];
+ getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
+
+ // t = 0..100
+ t = 2 * (((5.0*avenrun[0] + 0.5) > 50) ? 50 : (5.0*avenrun[0] + 0.5));
+
+ return range * t / 100.0;
+}
diff --git a/cpumoncc/darwin/CpuMonitor.h b/cpumoncc/darwin/CpuMonitor.h
new file mode 100644
index 0000000..d317820
--- /dev/null
+++ b/cpumoncc/darwin/CpuMonitor.h
@@ -0,0 +1,39 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Darwin
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include <stdlib.h>
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ float getLoad();
+};
+
+#endif
diff --git a/cpumoncc/darwin/Makefile b/cpumoncc/darwin/Makefile
new file mode 100644
index 0000000..2732a39
--- /dev/null
+++ b/cpumoncc/darwin/Makefile
@@ -0,0 +1,41 @@
+#####################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+ rm -fr $(HINSTALL)/cpumoncc
+ rm -f $(LIBINSTALL)/$(TARGET)
+
diff --git a/cpumoncc/freebsd/CpuMonitor.cc b/cpumoncc/freebsd/CpuMonitor.cc
new file mode 100644
index 0000000..726d33b
--- /dev/null
+++ b/cpumoncc/freebsd/CpuMonitor.cc
@@ -0,0 +1,80 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/FreeBSD
+
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+ initialize();
+}
+
+CpuMonitor::CpuMonitor(bool nice) : BaseCpuMonitor()
+{
+ use_nice = nice;
+ initialize();
+}
+
+CpuMonitor::~CpuMonitor()
+{
+ kvm_close(kd);
+}
+
+void CpuMonitor::initialize()
+{
+ nlst[0].n_name = "_cp_time";
+ nlst[1].n_name = NULL;
+
+ if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
+ throw runtime_error("CpuMonitor: unable to open kvm.");
+
+ kvm_nlist(kd, nlst);
+
+ if (nlst[0].n_type == 0)
+ throw runtime_error("CpuMonitor: unable to get nlist.");
+}
+
+float CpuMonitor::getLoad()
+{
+ int total, used;
+ int cpu,nice,system,idle;
+ unsigned long int cpu_time[CPUSTATES];
+ float t;
+
+ if (kvm_read(kd, nlst[0].n_value, &cpu_time, sizeof(cpu_time)) != sizeof(cpu_time))
+ throw runtime_error("CpuMonitor: error reading kvm.");
+
+ cpu = cpu_time[CP_USER];
+ nice = cpu_time[CP_NICE];
+ system = cpu_time[CP_SYS];
+ idle = cpu_time[CP_IDLE];
+
+ used = cpu + system + use_nice*nice;
+ total = used + idle + (1-use_nice)*nice;
+
+ t = range * (float)(used - previous_used) / (float)(total - previous_total);
+ previous_total = total;
+ previous_used = used;
+
+ return t;
+}
diff --git a/cpumoncc/freebsd/CpuMonitor.h b/cpumoncc/freebsd/CpuMonitor.h
new file mode 100644
index 0000000..a03ca3f
--- /dev/null
+++ b/cpumoncc/freebsd/CpuMonitor.h
@@ -0,0 +1,52 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/FreeBSD
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include <kvm.h>
+#include <nlist.h>
+#include <fcntl.h>
+#include <sys/dkstat.h>
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ CpuMonitor(bool nice);
+ ~CpuMonitor();
+
+ float getLoad();
+
+private:
+
+ void initialize();
+
+ kvm_t *kd;
+ struct nlist nlst[2];
+};
+
+#endif
diff --git a/cpumoncc/freebsd/Makefile b/cpumoncc/freebsd/Makefile
new file mode 100644
index 0000000..9346f23
--- /dev/null
+++ b/cpumoncc/freebsd/Makefile
@@ -0,0 +1,41 @@
+######################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=-lkvm
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+ rm -fr $(HINSTALL)/cpumoncc
+ rm -f $(LIBINSTALL)/$(TARGET)
+
\ No newline at end of file
diff --git a/cpumoncc/linux/CpuMonitor.cc b/cpumoncc/linux/CpuMonitor.cc
new file mode 100644
index 0000000..bd4396b
--- /dev/null
+++ b/cpumoncc/linux/CpuMonitor.cc
@@ -0,0 +1,100 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Linux
+
+#include <stdio.h>
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+ initialize();
+}
+
+CpuMonitor::CpuMonitor(int cpu) : BaseCpuMonitor()
+{
+ which_cpu = cpu;
+ initialize();
+}
+
+CpuMonitor::CpuMonitor(int cpu, bool nice) : BaseCpuMonitor()
+{
+ which_cpu = cpu;
+ use_nice = nice;
+ initialize();
+}
+
+void CpuMonitor::initialize()
+{
+ FILE *fp;
+ int i;
+ char cpuid[6];
+ char check_cpu[6];
+ char tmp[32];
+
+ if ((fp = fopen("/proc/stat","r")) == NULL)
+ throw runtime_error("CpuMonitor: no /proc/stat found.");
+
+ if (which_cpu == -1) return;
+
+ snprintf(check_cpu, 6, "cpu%d", which_cpu);
+ //printf("Monitoring %s (%d)\n", check_cpu, which_cpu);
+
+ for (i = -2; i < which_cpu; i++)
+ {
+ fscanf(fp, "%5s %31s %31s %31s %31s", cpuid, tmp, tmp, tmp, tmp);
+ //fscanf(fp, "%5s" , cpuid); printf("%s ", cpuid);
+ //fscanf(fp, "%31s", tmp ); printf("%s ", tmp);
+ //fscanf(fp, "%31s", tmp ); printf("%s ", tmp);
+ //fscanf(fp, "%31s", tmp ); printf("%s ", tmp);
+ //fscanf(fp, "%31s", tmp ); printf("%s\n", tmp); fflush(stdout);
+ }
+
+ if (strcmp(check_cpu, cpuid) != 0)
+ throw runtime_error("CpuMonitor: could not read cpu-load.");
+}
+
+float CpuMonitor::getLoad()
+{
+ int total, used, i;
+ char cpuid[6];
+ int cpu,nice,system,idle;
+ float t;
+ FILE *fp;
+
+ fp = fopen("/proc/stat","r");
+
+ for (i = -2; i < which_cpu; i++)
+ fscanf(fp,"%5s %d %d %d %d", cpuid, &cpu, &nice, &system, &idle);
+
+ fclose(fp);
+
+ used = cpu + system + use_nice * nice;
+ total = used + idle + (1-use_nice) * nice;
+
+ t = range * (float)(used - previous_used) / (float)(total - previous_total);
+ previous_total = total;
+ previous_used = used;
+
+ return t;
+}
+
diff --git a/cpumoncc/linux/CpuMonitor.h b/cpumoncc/linux/CpuMonitor.h
new file mode 100644
index 0000000..82bd910
--- /dev/null
+++ b/cpumoncc/linux/CpuMonitor.h
@@ -0,0 +1,45 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Linux
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ CpuMonitor(int cpu);
+ CpuMonitor(int cpu, bool nice);
+
+ float getLoad();
+
+private:
+
+ void initialize();
+};
+
+#endif
diff --git a/cpumoncc/linux/Makefile b/cpumoncc/linux/Makefile
new file mode 100644
index 0000000..ebe980a
--- /dev/null
+++ b/cpumoncc/linux/Makefile
@@ -0,0 +1,40 @@
+######################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+# rm -fr $(HINSTALL)/cpumoncc
+# rm -f $(LIBINSTALL)/$(TARGET)
diff --git a/cpumoncc/netbsd/CpuMonitor.cc b/cpumoncc/netbsd/CpuMonitor.cc
new file mode 100644
index 0000000..33d2fb0
--- /dev/null
+++ b/cpumoncc/netbsd/CpuMonitor.cc
@@ -0,0 +1,113 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/NetBSD
+
+#include <stdlib.h>
+#include <sys/sched.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+ for (int i = i < CPUSTATES; i++) last_cp_time[i] = 0;
+}
+
+CpuMonitor::CpuMonitor(bool nice) : BaseCpuMonitor()
+{
+ use_nice = nice;
+ for (int i = i < CPUSTATES; i++) last_cp_time[i] = 0;
+}
+
+float CpuMonitor::getLoad()
+{
+ u_int64_t curr_cp_time[CPUSTATES];
+ u_int64_t total_time = 0, idle_time = 0;
+ int mib[2];
+ int i;
+ size_t ssize;
+ const int IDLE_TIME = 4;
+ const int NICE_TIME = 1;
+
+ ssize = sizeof ( curr_cp_time );
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CP_TIME;
+
+ if ( sysctl ( mib, 2, curr_cp_time, &ssize, NULL, 0 ) )
+ throw runtime_error("CpuMonitor: unable to read CP_TIME from sysctl()\n");
+
+ if ( !use_nice )
+ curr_cp_time[NICE_TIME] = 0;
+
+ /* NetBSD gives 5 CPUSTATES -
+ * User, Nice, System, Interrupt, Idle
+ */
+ idle_time = curr_cp_time[IDLE_TIME] - last_cp_time[IDLE_TIME];
+ for ( i = 0; i < CPUSTATES; i++ )
+ {
+ total_time += ( curr_cp_time[i] - last_cp_time[i] );
+ last_cp_time[i] = curr_cp_time[i];
+ }
+
+ /* Calculate the % CPU usage as the User+Nice+System+Interrupt/Total
+ * for the interval
+ */
+ return range * (int) ( total_time - idle_time ) / total_time;
+}
+
+/*
+ * Overloads base class
+ */
+bool CpuMonitor::saveInternals(const char *filename)
+{
+ int count = 0;
+ FILE *fp = fopen(filename, "w");
+
+ if (fp == 0) return false;
+
+ for ( i = 0; i < CPUSTATES; i++ )
+ count += fprintf(fp, "%d", last_cp_time[i]);
+
+ fclose(fp);
+
+ if (count != CPUSTATES) return false;
+
+ return true;
+}
+
+bool CpuMonitor::loadInternals(const char *filename)
+{
+ int count = 0;
+ FILE *fp = fopen(filename, "r");
+
+ if (fp == 0) return false;
+
+ for ( i = 0; i < CPUSTATES; i++ )
+ count += fscanf(fp, "%d", &last_cp_time[i]);
+
+ fclose(fp);
+
+ if (count != CPUSTATES) return false;
+
+ return true;
+}
diff --git a/cpumoncc/netbsd/CpuMonitor.h b/cpumoncc/netbsd/CpuMonitor.h
new file mode 100644
index 0000000..1be7fd0
--- /dev/null
+++ b/cpumoncc/netbsd/CpuMonitor.h
@@ -0,0 +1,43 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/NetBSD
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ CpuMonitor(bool nice);
+ float getLoad();
+
+private:
+
+ u_int64_t last_cp_time[CPUSTATES];
+};
+
+#endif
diff --git a/cpumoncc/netbsd/Makefile b/cpumoncc/netbsd/Makefile
new file mode 100644
index 0000000..ccc3b93
--- /dev/null
+++ b/cpumoncc/netbsd/Makefile
@@ -0,0 +1,40 @@
+######################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+ rm -fr $(HINSTALL)/cpumoncc
+ rm -f $(LIBINSTALL)/$(TARGET)
\ No newline at end of file
diff --git a/cpumoncc/openbsd/CpuMonitor.cc b/cpumoncc/openbsd/CpuMonitor.cc
new file mode 100644
index 0000000..0287f4c
--- /dev/null
+++ b/cpumoncc/openbsd/CpuMonitor.cc
@@ -0,0 +1,42 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/OpenBSD
+
+#include <stdlib.h>
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+}
+
+float CpuMonitor::getLoad()
+{
+ float t;
+ double avenrun[3];
+ getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
+
+ // t = 0..100
+ t = 2 * (((5.0*avenrun[0] + 0.5) > 50) ? 50 : (5.0*avenrun[0] + 0.5));
+
+ return range * t / 100.0;
+}
diff --git a/cpumoncc/openbsd/CpuMonitor.h b/cpumoncc/openbsd/CpuMonitor.h
new file mode 100644
index 0000000..9117592
--- /dev/null
+++ b/cpumoncc/openbsd/CpuMonitor.h
@@ -0,0 +1,38 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/OpenBSD
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ float getLoad();
+};
+
+#endif
diff --git a/cpumoncc/openbsd/Makefile b/cpumoncc/openbsd/Makefile
new file mode 100644
index 0000000..b6334cb
--- /dev/null
+++ b/cpumoncc/openbsd/Makefile
@@ -0,0 +1,40 @@
+######################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+ rm -fr $(HINSTALL)/cpumoncc
+ rm -f $(LIBINSTALL)/$(TARGET)
diff --git a/cpumoncc/programs/Makefile b/cpumoncc/programs/Makefile
new file mode 100644
index 0000000..3bff6a4
--- /dev/null
+++ b/cpumoncc/programs/Makefile
@@ -0,0 +1,14 @@
+CXX=g++
+CXXFLAGS=
+TARGET=cpu
+
+all: cpu.cc cpuload.cc
+ $(CXX) $(CXXFLAGS) -o cpu cpu.cc -lcpumoncc
+ $(CXX) $(CXXFLAGS) -o cpuload cpuload.cc -lcpumoncc
+
+install: all
+ cp cpu /usr/bin
+ cp cpuload /usr/bin
+
+clean:
+ rm -f *~ core *.o cpu cpuload /usr/bin/cpu /usr/bin/cpuload
diff --git a/cpumoncc/programs/README b/cpumoncc/programs/README
new file mode 100644
index 0000000..7809f2a
--- /dev/null
+++ b/cpumoncc/programs/README
@@ -0,0 +1,17 @@
+These are two small programs that show how to use the cpumoncc library.
+
+The first one, cpu, is a 'state-ful' cpu monitor that returns the average
+cpu load for the elapsed time between now and the last time you
+ran the program. Useful (in a geeky way) in promts for example:
+
+geoff at rama [CPU: 1%] ~/workspace/cpumoncc > ls
+README base darwin freebsd linux netbsd openbsd programs solaris
+geoff at rama [CPU: 4%] ~/workspace/cpumoncc >
+
+This particular prompt is (in bash):
+PS1='\u@\h [CPU: `cpu`%] \w > '
+
+
+The second program, cpuload, is a simple text mode cpu monitor.
+
+To build these programs type 'make'. To install, type, as root, 'make install'.
\ No newline at end of file
diff --git a/cpumoncc/programs/cpu.cc b/cpumoncc/programs/cpu.cc
new file mode 100644
index 0000000..993d3d8
--- /dev/null
+++ b/cpumoncc/programs/cpu.cc
@@ -0,0 +1,56 @@
+/*
+
+ cpu.cc v0.0.1
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/*
+ * Note that this program will compile for all on os's supported
+ * by cpumoncc altough it will only function properly on the
+ * os's with a valid implementation of load/saveInternals. With
+ * version 0.0.1-pre1 of cpumoncc they are lacking for OpenBSD
+ * and Darwin. cpumoncc must be installed for this program to
+ * compile.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <cpumoncc/CpuMonitor.h>
+
+char filename[256];
+
+FILE *fp;
+CpuMonitor *cpu = new CpuMonitor();
+
+int main()
+{
+ // Necessary monitor internals will be saved in /home/username/.cpu
+ strncpy(filename, getenv("HOME"), 245);
+ strncat(filename, "/.cpu", 6);
+
+ cpu->loadInternals(filename);
+ printf("%.0f", cpu->getLoad());
+ cpu->saveInternals(filename);
+
+ delete cpu;
+
+ return 0;
+}
diff --git a/cpumoncc/programs/cpuload.cc b/cpumoncc/programs/cpuload.cc
new file mode 100644
index 0000000..65f4d21
--- /dev/null
+++ b/cpumoncc/programs/cpuload.cc
@@ -0,0 +1,60 @@
+/*
+
+ cpuload.cc v0.0.1
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <iostream>
+#include <cpumoncc/CpuMonitor.h>
+
+#define U_POLL_INTERVAL 500000
+
+char filename[256];
+
+FILE *fp;
+CpuMonitor *cpumon = new CpuMonitor();
+
+int prev_used, prev_total;
+
+int main()
+{
+ while (1)
+ {
+ try
+ {
+ printf("\rLoad: %.2f%% ", cpumon->getLoad()); fflush(stdout);
+ }
+ catch (exception e)
+ {
+ cout << e.what();
+ return -1;
+ }
+
+ usleep(U_POLL_INTERVAL);
+ }
+
+ delete cpumon;
+
+ return 0;
+}
diff --git a/cpumoncc/solaris/CpuMonitor.cc b/cpumoncc/solaris/CpuMonitor.cc
new file mode 100644
index 0000000..b26cef6
--- /dev/null
+++ b/cpumoncc/solaris/CpuMonitor.cc
@@ -0,0 +1,141 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Solaris
+
+#include "CpuMonitor.h"
+
+CpuMonitor::CpuMonitor() : BaseCpuMonitor()
+{
+ initialize();
+}
+
+CpuMonitor::CpuMonitor(int cpu) : BaseCpuMonitor()
+{
+ which_cpu = cpu;
+ initialize();
+}
+
+void CpuMonitor::initialize()
+{
+ kstat_t *ksp;
+ int i = 0;
+
+ if (kc == NULL)
+ if ((kc = kstat_open()) == NULL)
+ throw runtime_error("CpuMonitor: can't open /dev/kstat.");
+
+ if (which_cpu != -1)
+ {
+ /*
+ * User selected to monitor a particlur CPU. Find it...
+ */
+ for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
+ if ((strcmp(ksp->ks_module, "cpu_stat") == 0) && (ksp->ks_instance == which_cpu))
+ {
+ the_cpu = ksp;
+ break;
+ }
+ if (the_cpu == NULL) throw runtime_error("CpuMonitor: Cpu not found.");
+ }
+ else
+ {
+ /*
+ * User selected to monitor all CPUs. First, count them.
+ */
+ for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
+ if (strcmp(ksp->ks_module, "cpu_stat") == 0) i++;
+
+ if (cpu_ksp_list) free(cpu_ksp_list);
+
+ cpu_ksp_list = (kstat_t **) calloc(i * sizeof (kstat_t *), 1);
+ ncpus = i;
+
+ /*
+ * stash the ksp for each CPU.
+ */
+ i = 0;
+ for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
+ if (strcmp(ksp->ks_module, "cpu_stat") == 0)
+ {
+ cpu_ksp_list[i] = ksp;
+ i++;
+ }
+ }
+}
+
+float CpuMonitor::getLoad()
+{
+ int i;
+ cpu_stat_t stat;
+ int used, total, user = 0, wait = 0, kern = 0, idle = 0;
+ float t;
+
+ /*
+ * Read each cpu's data. If the kstat chain has changed (a state change
+ * has happened, maybe a new cpu was added to the system or one went
+ * away), then reinitialize everything with initialize(). Finally,
+ * recursively call getLoad().
+ *
+ * We'll need to do a little better than this in the future, since we
+ * could recurse too much in the pathological case here.
+ */
+ if (which_cpu == -1)
+ {
+ for (i = 0; i < ncpus; i++)
+ {
+ if (kstat_read(kc, cpu_ksp_list[i], (void *)&stat) == -1)
+ {
+ // Dont try-catch, let the caller of first getLoad() do that
+ initialize();
+
+ return getLoad();
+ }
+ user += stat.cpu_sysinfo.cpu[CPU_USER]; /* user */
+ wait += stat.cpu_sysinfo.cpu[CPU_WAIT]; /* io wait */
+ kern += stat.cpu_sysinfo.cpu[CPU_KERNEL]; /* sys */
+ idle += stat.cpu_sysinfo.cpu[CPU_IDLE]; /*idle("free")*/
+ }
+ }
+ else
+ {
+ if (kstat_read(kc, the_cpu, (void *)&stat) == -1)
+ {
+ // Dont try-catch, let the caller of first getLoad() do that
+ initialize();
+
+ return getLoad();
+ }
+ user += stat.cpu_sysinfo.cpu[CPU_USER]; /* user */
+ wait += stat.cpu_sysinfo.cpu[CPU_WAIT]; /* io wait */
+ kern += stat.cpu_sysinfo.cpu[CPU_KERNEL]; /* sys */
+ idle += stat.cpu_sysinfo.cpu[CPU_IDLE]; /* idle("free") */
+ }
+
+ used = user + wait + kern;
+ total = used + idle;
+ t = range * (float)(used - previous_used) / (float)(total - previous_total);
+ previous_total = total;
+ previous_used = used;
+
+ return t;
+}
diff --git a/cpumoncc/solaris/CpuMonitor.h b/cpumoncc/solaris/CpuMonitor.h
new file mode 100644
index 0000000..5a1f00c
--- /dev/null
+++ b/cpumoncc/solaris/CpuMonitor.h
@@ -0,0 +1,53 @@
+/*
+
+ Copyright (C) 2003 Robert Kling, robkli-8 at student.luth.se
+
+ This file is part of CpuMonitorCC (cpumoncc)
+
+ cpumoncc 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.
+
+ cpumoncc 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 cpumoncc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// CpuMonitorCC/Solaris
+
+#ifndef _CPUMONITOR_H_
+#define _CPUMONITOR_H_
+
+#include <sys/types.h>
+#include <sys/sysinfo.h>
+#include <kstat.h>
+#include "BaseCpuMonitor.h"
+
+class CpuMonitor : public BaseCpuMonitor
+{
+public:
+
+ CpuMonitor();
+ CpuMonitor(int cpu);
+ ~CpuMonitor();
+
+ float getLoad();
+
+private:
+
+ void initialize();
+
+ kstat_ctl_t *kc;
+ kstat_t **cpu_ksp_list;
+ kstat_t *the_cpu;
+ int ncpus;
+};
+
+#endif
diff --git a/cpumoncc/solaris/Makefile b/cpumoncc/solaris/Makefile
new file mode 100644
index 0000000..84d09e3
--- /dev/null
+++ b/cpumoncc/solaris/Makefile
@@ -0,0 +1,40 @@
+######################################################
+#
+# To compile cpumoncc for a different OS/architecture you
+# will need to modify the variablese below to match your system.
+#
+# For system wide installation type (as root):
+#
+# make install
+#
+# This will install the static library in $(LIBINSTALL) and
+# the header files in $(HINSTALL)/cpumoncc.
+#
+#####################################################
+
+CXX=g++
+CXXFLAGS=-L/opt/sfw/lib -L/usr/local/lib -R/opt/sfw/lib -R/usr/local/lib -lkstat
+HINSTALL=/usr/include
+LIBINSTALL=/usr/lib
+
+#####################################################
+
+TARGET=libcpumoncc.a
+
+$(TARGET): CpuMonitor.o
+ ar rcs $(TARGET) $^
+
+CpuMonitor.o: copy_base
+
+copy_base:
+ cp ../base/BaseCpuMonitor.h .
+
+install: $(TARGET)
+ mkdir -p $(HINSTALL)/cpumoncc
+ cp *.h $(HINSTALL)/cpumoncc
+ install -m 644 $(TARGET) $(LIBINSTALL)
+
+clean:
+ rm -f *~ core *.o cpu $(TARGET) BaseCpuMonitor.h
+ rm -fr $(HINSTALL)/cpumoncc
+ rm -f $(LIBINSTALL)/$(TARGET)
\ No newline at end of file
diff --git a/COPYING b/wmapp/COPYING
similarity index 98%
rename from COPYING
rename to wmapp/COPYING
index a43ea21..5197aee 100644
--- a/COPYING
+++ b/wmapp/COPYING
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 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.
@@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
- Appendix: How to Apply These Terms to Your New Programs
+ 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
@@ -291,7 +291,7 @@ 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>
+ Copyright (C) yyyy <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
@@ -305,14 +305,15 @@ the "copyright" line and a pointer to where the full notice is found.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 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 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.
diff --git a/wmapp/Changelog b/wmapp/Changelog
new file mode 100644
index 0000000..fe9961f
--- /dev/null
+++ b/wmapp/Changelog
@@ -0,0 +1,82 @@
+Changelog for WMApp
+
+Version Changes
+------- -------
+0.0.4.1 * Bug fixes for 0.0.4:
+ * remove stray inline keyword from wmwidget.cc
+ * fix masking of shaped widgets in a non-transparent frame
+ * fix interpolation in WMEllipse::draw_border()
+ * remove WMCanvas::copy_buffer(); use WMCanvas::display()
+ instead
+ * make planes in example2/wmradar.cc still light up when
+ speed == 0; other cosmetic changes
+ * fix indentation in xwrapper.cc
+
+0.0.4 * this version of WMApp brought to you by Jason (see
+ Changelog.Jason for greater detail)
+ * Improve consistency by changing header #include statements
+ and class inheritance tree in places
+ * Add draw_arc() and fill_arc() functions to XWrapper and
+ WMCanvas classes
+ * Add WMWidget::contains() function and give each pixmap its
+ own GC to make creation of shaped widgets easier
+ * Add WMClickable base class
+ * Add WMEllipse base class: places its contents in an ellipse
+ when inherited from
+ * Replace Color typedef with Color class, adding useful
+ Color::alpha_blend() static function
+ * New example game, wmatc (WM Air Traffic Control), to
+ illustrate integration of several widgets
+ * Fix bug that forced a need for setaspectratios() to always
+ be called, even in case with only one child widget
+
+0.0.3 * Makefile simplification by Jason
+ * Tidy up the internals of WMCallback class, by Jason
+ * Each widget now has its own .h and .cc files for better
+ source code modularity (delete the ones you don't need)
+ * Additions of WMCanvas draw_lines(), fill_polygon() methods
+ by Jason
+ * Addition of buffered drawing mode for WMCanvas
+ * Optimization of WMImage real_display() function
+ * Clean up code for WMCanvas now that WMImage::icon() is
+ the same size as the widget sans border
+
+0.0.2 * Addition of WMMouseClick::relative_to(WMWidget), allowing
+ to more easily find the location of a mouseclick within
+ a widget.
+ * Added b_* functions, giving coordinates of that part of a
+ widget contained inside its border.
+ * Break up the example program into different files for
+ clarity.
+ * Fix problem with WMImage not displaying background color
+ in some circumstances.
+ * Renamed some member functions for greater consistency
+ (setcallback() -> addcallback(), for instance)
+ * Changed API for timed interval functions in WMWindow.
+ * The order in which the two prototypes of callback functions
+ are executed may now be interleaved.
+ * Add a WMCanvas widget for drawing purposes; the wmexample
+ program (file example/window1.cc) shows how it may be used.
+ * Update FAQ.
+
+0.0.1 * New widget: WMSlider
+ * Buttons now depress when clicked upon.
+ * Any widget can now have a border, not just a WMFrame.
+ * Now easy to determine which mouse button was clicked.
+ * Widgets other than WMButton and WMWindow can have
+ callbacks attached; see new FAQ.txt for details.
+ * Changes by Jason: (see Changelog.Jason for details)
+ * Fixed X resource leak
+ * Changed all instances of "NULL" to "0"
+ * Removed redundant constructors
+ * Cleaned up some code formatting
+
+0.0.0.20020502 * Added Changelog, small edits to README
+ * Sample program now called wmexample
+
+0.0.0.20020501 * Merged Jason's additions of WMHistory and WMMeterBar
+
+0.0.0.20011212 * First version of library in a usable form
+
+-Kevin B. McCarty <kmccarty at princeton.edu>
+
diff --git a/wmapp/Changelog.Jason b/wmapp/Changelog.Jason
new file mode 100644
index 0000000..dca2522
--- /dev/null
+++ b/wmapp/Changelog.Jason
@@ -0,0 +1,154 @@
+2003-01-05
+
+ * example2/wmradar.cc: Make planes still light up when speed == 0 (oops).
+ Other cosmetic changes.
+
+ * wmellipse.cc (draw_border(...)): Fix interpolation.
+
+ * wmwllipse.h: Remove obsolete comment.
+
+ * wmframe.cc: Fix masking when frame isn't transparent.
+
+ * wmframe.h: Add clipping mask data member. Move clip() to wmframe.cc.
+
+ * xwrapper.cc (draw_horizontal_gradient,draw_vertical_gradient):
+ Reformat indentation (it was so ugly!).
+
+ * FAQ.txt: Remove notes about ellipse/frame clipping bugs.
+
+ * wmcanvas.cc: Note that copy_buffer() is just a partial reimplementation
+ of WMImage::real_display(). So wBuffered is really just a class-wide
+ dodisplay setting. As such, replace calls to copy_buffer() with
+ display(). Might want to rename some things in light of this, as well as
+ remove copy_buffer().
+
+Some other days:
+
+ * example2/{wmradar.cc,wmradar.h,wmairtrafficcontrol.cc}: New example game
+ demonstrating the integration of several widgets.
+
+2002-12-28
+
+ * wmclickable.h: New class for clickable widgets.
+
+ * wmwindow.h wmframe.h, wmframe.cc, wmcallback.h: Use WMClickable.
+
+2002-12-21
+
+ * wmapp.cc: WMFrameBorderBright is too dim. Other dockapps look like
+ they use 0xC8C[38]C8.
+
+ * xwrapper.h, xwrapper.cc: Give each pixmap its own GC, and set clipping
+ mask to dest.mask if it's there. Enables me to remove kludgy use_mask().
+
+ * wmimage.cc, wmapp.cc, wmapp.h, wmcanvas.cc: Remove use_mask().
+
+ * wmimage.h, wmimage.cc: New function seticon(bool) to set a blank
+ b_width() by b_height() icon.
+
+ * wmcanvas.h, wmcanvas.cc: New functions draw_arc() and fill_arc().
+
+2002-12-20
+
+ * wmellipse.h, wmellipse.cc: New class WMEllipse, places its contents in
+ an ellipse.
+
+ * wmwidget.h: Add contains() function to WMWidget. This enables the
+ creation of arbitrarily shaped viewports, in the style of WMEllipse.
+
+ * wmapp.h, wmapp.cc: Add use_mask() function, to muck with GC masking.
+ Needed so that WMEllipse is humanly possible.
+ Whenever drawing to the window, call app()->use_mask(true). When
+ drawing on any other pixmap, call use_mask(false). Default setting is
+ true. A better solution would be to have one GC for each window, and a
+ single GC for everything else.
+
+ * wmimage.cc, wmcanvas.cc: Modify to use use_mask.
+
+ * xwrapper.h, xwrapper.cc: New functions draw_arc() and fill_arc().
+
+ * wmwidget.h, various: Put back WMFrame for parent().
+
+ * Widgets.txt: Update.
+
+2002-12-19
+
+ * xwapper.h: Fix header inclusion order problems. Now you can
+ #include "xwrapper.h" anywhere you like.
+
+ * wmframe.h, wmframe.cc: Simplify and improve consistency by inheriting
+ from WMCallback.
+
+ * wmwindow.h: Only inherit from WMFrame.
+
+ * various: Reorder #include statements to include only necessary files.
+ Use WMWidget* instead of WMFrame* for parent().
+
+ * Makefile, example/Makefile: Tweak.
+
+2002-05-08
+
+ * xwrapper.cc:
+ "Fixed" X memory leak caused by repetitive calls to XAllocColor. <rant>
+ Bizarrly, there doesn't appear to be a way to get the colormap index of an
+ RGB color without allocating it. Ideally, you would only allocate each color
+ once, but the only apparent way to do this is to keep your own custom
+ colormap with reference counts, since X won't tell you the index of a color
+ without allocating it. And without reference counts, the only way to keep
+ from allocating repeatedly is to deallocate after each allocation. But this
+ means that you're using colors which haven't been allocated. Realistically,
+ this doesn't matter except in 8 bit mode, where there aren't enough colors
+ for the spectrum-style WMMeterBar. In order to display well in 8 bit mode,
+ it seems that major color management is necessary, as X is far too stupid to
+ do it for us. Maybe I should look at Berlin again. </rant>
+
+2002-05-07
+
+ * wmwidgets.cc, wmwidgets.h, wmapp.h, wmextras.h xwrapper.cc,
+ example/wmexample.cc, FAQ.txt:
+ Removed all pointer comparisons/assignments to NULL. NULL isn't type-safe,
+ and in C++, "if (ptr != NULL)" is the same as "if (ptr)" because "No object
+ is allocated with the address 0" (Stroustrup 88).
+
+ * wmapp.cc, wmwidgets.cc:
+ Removed more redundant constructor calls.
+
+ * wmwidgets.cc, wmwidgets.h:
+ - Slight formatting fix again.
+ - Wrote a destructor for WMWindow to deallocate its pixmaps.
+ - Made initpixmaps() be called only once for each window. This fixes a
+ memory leak in X that occurred when switching windows.
+
+ * wmapp.cc, wmapp.h:
+ - Wrote a short destructor to deallocate windows (probably unnecessary).
+ - delete[]'d character arrays after XSetClassHint().
+
+ * xwrapper.cc, xwrapper.h:
+ Wrote a free_pixmap() function to complement create_pixmap (don't call
+ create_pixmap() on an existing pixmap without freeing it first!).
+
+2002-05-06
+
+ * xwrapper.cc:
+ - Cleaned up get_point() a little.
+ - Added simple deallocation in Xwrapper::~Xwrapper ().
+
+ * wmapp.cc:69
+ Removed redundant assignment to static Xwrapper object after it was
+ already constructed (which caused my previous modification to crash due to
+ the destructor being called twice).
+
+ * wmwidgets.txt:
+ Added WMSlider to the class hierarchy and removed tabs.
+
+ * wmextras.h:
+ Removed redundant calls to base class constructors and members.
+
+2002-05-05
+
+ * wmextras.cc:
+ Merged slider_click() and slider_scroll() into one, simpler/more readable
+ function.
+
+ * wmwidgets.cc:
+ Cleaned up my formatting a little.
diff --git a/wmapp/FAQ.txt b/wmapp/FAQ.txt
new file mode 100644
index 0000000..dd87cf8
--- /dev/null
+++ b/wmapp/FAQ.txt
@@ -0,0 +1,278 @@
+WMApp DockApp Library -- FAQ
+
+Starred items below are new or significantly updated for the latest release
+of WMApp, 0.0.4, or bug-fix release 0.0.4.1.
+
+1. Widget Layout
+ 1.1. Can I specify widget positions in absolute coordinates?
+ *1.2. Help! My layout is all messed up!
+ 1.3. Widgets that are all supposed to be the same size aren't.
+ 1.4. How do I keep a frame from having transparent padding?
+
+2. Callbacks and timed-execution functions
+ 2.1. How do I write a callback function?
+ 2.2. Can I attach a callback to widgets other than the WMButton?
+ 2.3. Which mouse button was pressed?
+ 2.4. At what location was the widget clicked?
+ 2.5. What is the story with callbacks on a WMWindow? (a.k.a.
+ executing functions at regular intervals)
+
+3. Specific widget questions
+ *3.1. How to use a WMCanvas?
+ *3.2. How to use a WMEllipse?
+ *3.3. How to create other shapes of widget?
+
+4. Memory issues
+ 4.1. Why do I get a (segmentation fault | runtime error saying "pure
+ virtual function called") in my program?
+
+1.1. Can I specify widget positions in absolute coordinates?
+
+Yes, if you really must.
+
+Make sure the widget fits inside its parent widget, or there will probably be
+a mess. The easiest way to do this is probably to set its position relative
+to its parent's:
+
+ widget.setposition(WMRectangle(parent.left()+wleft, parent.top()+wtop,
+ wwidth, wheight));
+
+where wleft, wtop are the desired coordinates of the widget relative to the
+top left corner of its parent. Remember that the 56x56 pixel WMWindow will
+have a different offset in Afterstep vs. WindowMaker mode, so at least
+operate relative to a previously declared WMWindow in all of your coordinates.
+
+If you are using both absolute positioning and automatic layout with
+setaspectratios(), you may get unexpected results. See 1.3 for a better way.
+
+1.2. Help! My layout is all messed up!
+
+Always lay out widgets in the order from parent to child:
+
+ window.addchild(frame1);
+ window.addchild(frame2);
+ window.setaspectratios(2, 3);
+
+ frame1.addchild(textbar);
+ frame1.addchild(led);
+ frame1.addchild(meterbar);
+ textbar.setwidth(24);
+ frame1.setaspectratios(0, 4, 1);
+ // etc.
+
+Always set the border and padding for a frame before calling setaspectratios()
+on it. [As of WMApp 0.0.4, you no longer have to call setaspectratios()
+explicitly when a frame has only one child, or when you want all children of a
+frame to be of equal size.] And don't forget that borders around any widgets
+are included in their dimensions.
+
+1.3. Widgets that are all supposed to be the same size aren't.
+
+This is due to rounding in the process of setting widget aspect ratios.
+All accumulated rounding error ends up on the last widget in the frame.
+(TODO: spread out the rounding error more evenly)
+
+If you are a stickler for accuracy, you can draw your widget layout on
+a 56x56 grid. Use the grid to determine the exact sizes, then in all calls
+to setaspectratios(), use these sizes.
+
+1.4. How do I keep a frame from having transparent padding?
+
+ frame.settransparency(false);
+
+Note: In order for a frame to _have_ transparent padding, its border thickness
+must also be zero.
+
+2.1. How do I write a callback function?
+
+There are two types of callback, with the prototypes
+
+ void callback1(const WMApp *a, void *data)
+ void callback2(const WMApp *a, WMWidget *w, void *data)
+
+First you write a function with one of these prototypes. For instance,
+to exit the application, the callback function is simply
+
+ void halt(const WMApp *a, void *) { a->stop(); }
+
+Any additional data needed by the callback function may be passed as a pointer
+to void. For convenience, you may pass in the address of one WMWidget to the
+second callback prototype without dealing with pointers to void. Dynamic
+casting in the body of the callback function may be necessary; see the example
+program code in example/window0.cc for details.
+
+Given this, you may attach callbacks to a WMButton or other WMCallback object
+as follows:
+
+ button.addcallback(stop, 0 /* no additional data needed */);
+ button.addcallback(another_callback, &other_widget, &some_data);
+
+(Notice that the name changed from setcallback to addcallback!)
+When a WMButton is pressed, all the callbacks will be executed in the order
+in which they were attached.
+
+2.2. Can I attach a callback to widgets other than the WMButton or WMWindow?
+
+Yes! Define a new class that inherits from both the desired widget and from
+WMCallback. For example, the following code lets you clear a WMHistory
+widget by clicking on it.
+
+Note: if you are using a pointer to the inherited class as the "void *"
+argument of a callback function, be sure to first statically cast it to a
+"WMWidget *". Dynamic casts from "void *" aren't guaranteed to work in C++.
+
+ // Define the new class
+ class WMHistoryCallback : public WMCallback, public WMHistory {
+ public: WMHistoryCallback() : WMCallback(), WMHistory() { }
+ };
+
+ // Callback to clear a WMHistory widget when it's clicked on
+ void clearhistory(const WMApp *a, WMWidget *w, void *)
+ {
+ WMHistoryCallback *h = dynamic_cast<WMHistoryCallback *>(w);
+
+ // check that dynamic_cast doesn't return null pointer! maybe you
+ // even want "assert(h)" instead of "if (h)"
+ if (h) h->clear();
+ }
+
+ int main(int argc, char **argv)
+ {
+ WMApp::initialize(argc, argv);
+
+ WMHistoryCallback h;
+ h.addcallback(clearhistory, &h, 0);
+ // ...
+ }
+
+2.3. Which mouse button was pressed?
+
+This can be retrieved from the application class. The following code
+fragment is a callback that will execute only when mouse button 1 is
+released:
+
+ void callback(WMApp *a, void *)
+ {
+ if (a->mouseclick().button != Button1) return;
+ // body of function goes here
+ }
+
+Recall that in most cases (if XFree86 has been set up correctly), the "up" and
+"down" directions of a mouse scroll wheel correspond to Button4 and Button5.
+But don't forget while designing your program interface that not everyone has a
+scroll-wheel mouse!
+
+2.4. At what location was the widget clicked?
+
+Position of the mouse click relative to the _application_ may be retrieved
+within a callback via a->mouseclick().x and a->mouseclick().y . Note that
+these are the coordinates of the cursor when the mouse button is _released_,
+which is when the callbacks are executed. To make these coordinates useful,
+you probably want to use a->mouseclick().relative_to(w).x and .y, where w is a
+pointer to the widget executing the callback. This gives the coordinates
+of the mouseclick relative to the left and top bounds of the widget. You
+can get the coordinates relative only to the part of the widget INSIDE its
+border using the b_relative_to() function.
+
+The most recent mouse button release may also be examined outside any callback
+functions. Keep in mind that this will not necessarily correspond to the
+execution of any callback functions, since the mouse may have been clicked
+over a widget with no callbacks.
+
+2.5. What is the story with callbacks on a WMWindow? (a.k.a. executing
+functions at regular intervals)
+
+In version 0.0.1, there existed a WMWindow::setcallback() method. This
+actually didn't set callbacks, but instead set functions to execute at regular
+intervals (for use in clocks, timing out internet connections, etc.). Since
+the name was confusing, in 0.0.2 I've replaced it by the
+WMWindow::add_timed_function() method.
+
+As with callbacks, there are two types of possible timed-execution functions:
+
+ void timed_function1(WMApp *, WMWidget *);
+ void timed_function2(WMApp *, WMWidget *, void * data);
+
+They should be attached to a window as follows:
+
+ window.add_timed_function(period, timed_function1, &some_data);
+ window.add_timed_function(period, timed_function2, &a_widget, &data);
+
+where "period" is an integer that specifies how often the timed-execution
+function should run, in centiseconds (e.g. to run a function every 5 seconds,
+use a period of 500). You can change this base time interval of 10 millisec
+using the WMWindow::setupdatefreq() member function.
+
+Of course, these regular intervals are not exact, since they do not take into
+account the times needed to redraw widgets, execute callback functions, and
+execute the timed-execution functions themselves. Don't rely on them for
+air traffic control. (Of course, Jason went ahead and did just that --
+see the code in the example2 directory, or just "make wmatc")
+
+For an example use, see the code for the clock in example/window0.cc.
+
+3.1. How to use a WMCanvas?
+
+The canvas widget may be used in two modes: buffered and unbuffered. To
+switch between them: wmcanvas_ptr->setbuffered(true) [or false, whichever].
+In unbuffered mode (the default), any drawings upon the widget will immediately
+be copied to the WMWindow pixmap, and will show up the next time the
+WMApp::repaint() method is called. In buffered mode, changes to the WMCanvas
+will not be copied to the WMWindow's pixmap until the WMCanvas::display()
+method is called. The advantage to buffered mode is that it uses less CPU
+and it lets you make a number of changes that display all at once.
+
+There are a number of drawing functions available. WMCanvas is stateful, so
+you must set the drawing color with WMCanvas::setcolor each time you want to
+draw in a different color. Having set the desired color (if unset, it defaults
+to the traditional WMApp foreground turquoise-ish color), you may use various
+drawing methods. The x and y coordinates in these drawing methods are always
+relative to the INSIDE of the WMCanvas widget (i.e. not including the border).
+
+setcolor(Color c)
+ Set the current drawing color to c.
+draw_point(int x, int y)
+ Draw a [1-pixel wide] point at position (x,y).
+draw_line(int x1, int y1, int x2, int y2)
+ Draw a line from (x1,y1) to (x2,y2).
+draw_lines(const vector<X::XPoint> & points)
+ Draw a set of connected lines (think connect-the-dots) from point to
+ point.
+
+The full list of drawing methods may of course be found in wmcanvas.h.
+For a somewhat trivial example use of a WMCanvas with an attached callback
+function (the world's dumbest paint program), see the code located in
+example1/window1.cc. A more interesting use is prototyped in
+example2/wmradar.h.
+
+3.2. How to use a WMEllipse?
+
+To create an elliptical widget, make a new class that inherits from both the
+desired widget and from the WMEllipse. This will usually work trivially as
+shown in the two example programs.
+
+3.3. How to create other shapes of widget?
+
+Using wmellipse.h and wmellipse.cc as models, you just have to write a
+"contains" method that specifies which points are inside the borders of
+your shape, and a "draw_border" method that tells how to draw a border for
+your shape. Inherit from both your shape and from some WMWidget. Clipping,
+execution of callbacks when the mouse is clicked inside your shape, and so on,
+will be done automagically by the library.
+
+4.1. Why do I get a (segmentation fault | runtime error saying "pure virtual
+function called") in my program?
+
+If you write a function that returns a WMFrame or WMWindow complete with
+all its child widgets set up, the child widgets must have been either declared
+static inside that function, or else allocated on the heap with "new".
+Otherwise they do not exist in memory at the time the WMApp tries to display
+them. This is clearly bad :-)
+
+I presume that the misleading "pure virtual function called" error occurs
+because the run-time type identification of the C++ program sees garbage at a
+memory location which is supposed to be a class inherited from WMWidget. Then,
+having no idea what to make of the garbage, the program casts it to the base
+class WMWidget, resulting in a call to WMWidget::real_display(), a pure virtual
+function. Or something like that.
+
diff --git a/wmapp/Makefile b/wmapp/Makefile
new file mode 100644
index 0000000..2b773fb
--- /dev/null
+++ b/wmapp/Makefile
@@ -0,0 +1,35 @@
+export CXX = g++
+export CFLAGS = -fPIC -g -Wall -pedantic -O2
+export LFLAGS = -L$(CURDIR) -L/usr/X11R6/lib -lXpm -lXext -lX11 -lwmapp
+
+SOURCES = $(wildcard *.cc)
+OBJECTS = $(SOURCES:.cc=.o)
+
+libwmapp.a: $(OBJECTS)
+ ar rcs libwmapp.a $^
+
+%.d: %.cc
+ @set -e; $(CXX) -MM $(CFLAGS) $< | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+ [ -s $@ ] || rm -f $@
+
+-include $(SOURCES:.cc=.d)
+
+%.o:
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+wmexample: libwmapp.a
+ $(MAKE) -C example1
+
+wmatc: libwmapp.a
+ $(MAKE) -C example2
+
+clean:
+ -rm -f tags *.o *.d *\~ libwmapp.a
+ $(MAKE) -C example1 clean
+ $(MAKE) -C example2 clean
+
+dist-clean: clean
+ -rm -f libwmapp.a wmexample wmatc
+
+.PHONY: all clean dist-clean wmexample wmatc
+
diff --git a/wmapp/README b/wmapp/README
new file mode 100644
index 0000000..71f8a0c
--- /dev/null
+++ b/wmapp/README
@@ -0,0 +1,66 @@
+WMApp: version 0.0.4.1
+Copyright (C) 2001-2003 Kevin and Jason McCarty <kmccarty at princeton.edu>
+ and others (see code for details)
+Licensed under the GNU GPL (see COPYING file).
+
+This is WMApp, a C++ graphics library written exclusively for developing
+WindowMaker dockapps. If you like dockapps, but you also like C++ and you
+are tired of trying to work with the code in wmgeneral.c, this library is
+for you!
+
+For an example program based on this library, check out the source code
+in the example directory. This program is long on eyecandy and short
+on usefulness, but it gives an idea of what is possible. "make wmexample"
+to build it.
+
+Features
+--------
+- Dockapp windows are set up automatically for you.
+- State model: a dockapp may be in one of several states ("windows"), which
+ can each look different and have different functionality
+- On-the-fly clipping; no more masking xpms needed!
+- Simple callback model: attach as many callback functions to each button
+ as desired. Callbacks can take arbitrary data as an argument, change
+ the properties of other widgets, and even switch between dockapp states.
+- You may automatically execute a list of functions (different for each window)
+ at set intervals of time. Useful for clocks, CPU load displays, etc.
+- Numerous widgets, all with the familiar dockapp look. The color scheme
+ of many may be changed. Many common WindowMaker dockapps could already
+ be rewritten to use this library.
+
+Widgets
+-------
+- Text box for conveying information; comes with three font sizes.
+- Progress meter to show changes in a quantity, e.g. percent download.
+- History display to show how a quantity changes over time, e.g. CPU load.
+- Buttons (optionally with an image) that can have callback functions set
+ and can be activated and deactivated.
+- Images that may display an XPM icon.
+- Glowing LED-type things that may be in one of four states:
+ off, green, yellow, and red.
+- Frames in which widgets (including other frames) may be nested. Frames
+ may have a border and / or padding between their contents.
+- Sliders that may be moved up and down with the mouse wheel
+ (or by clicking) to set a value.
+- Canvas that may be drawn upon with various drawing functions.
+
+Most of the above widgets may also inherit from one or more of the following
+for additional features:
+
+- Elliptical widget that clips contents to an ellipse
+- Callback widget that can execute actions when clicked upon
+
+Limitations
+-----------
+- Still not guaranteed not to leak memory or X resources
+- API is not guaranteed to be backwards compatible when it changes
+ (note the version number)
+- The executables produced with this library are several times larger
+ than those created using wmgeneral.c.
+- WMApp does not support dynamic widget resizing.
+- Text box fonts do not have lowercase letters. (They can easily be
+ implemented -- just edit the character maps in the xpm directory --
+ but I think they would look quite bad due to the small fonts.)
+- Changing the color of the fonts is not supported at runtime. (You can
+ of course do this at compile time by editing the font XPMs.)
+
diff --git a/wmapp/Widgets.txt b/wmapp/Widgets.txt
new file mode 100644
index 0000000..e5722e3
--- /dev/null
+++ b/wmapp/Widgets.txt
@@ -0,0 +1,49 @@
+WMWidgets Class Hierarchy
+
+Note: * represents widgets which cannot be instantiated, only inherited from
+Only public inheritances are shown in this diagram.
+
+WMWidget* - Base class for all widgets
+ |
+ +--WMEllipse* - Inherited widgets are displayed inside an ellipse
+ |
+ +--WMTextBar - Draw a string of text
+ |
+ +--WMMeter* - Base class for meter widgets
+ | |
+ | +--WMMeterBar - A bar that displays a quantity by ranging from
+ | | empty to full
+ | +--WMSlider - A bar that can be slid up or down to set a value
+ | (also inherits from WMCallback)
+ |
+ +--WMHistory - Show a graph of how a quantity has been varying with time
+ |
+ +--WMImage - Display an XPM on a region of the window
+ | |
+ | +--WMCanvas - Display a region which may be changed by drawing functions
+ | |
+ | +--WMLED - Display an image of an LED in one of four states
+ | |
+ | +--WMButton - A button which, when pressed, executes one or more
+ | ^ callback functions
+ | | - may also have an image on it
+ | |
+ +--WMCallback* - A widget that can execute callback functions when clicked
+ | ^
+ | |
+ | WMClickable* - (does not inherit from WMWidget)
+ | | Inherited widgets must specify what happens when
+ | | a mouse button is pressed or released, by defining
+ | | press() and release() methods.
+ | v
+ +--WMFrame - A widget which contains other widgets and may have an optional
+ | border
+ +--WMWindow - The topmost level widget. All other widgets must be
+ contained (recursively) by this widget in order to be
+ displayed
+
+
+WMApp - Contains one or more WMWindows. Only one WMWindow may be displayed
+ on screen at a time. (WMWindows are still active in the background
+ when not displayed, unless they are set otherwise.)
+
diff --git a/wmapp/colors.h b/wmapp/colors.h
new file mode 100644
index 0000000..b7eedce
--- /dev/null
+++ b/wmapp/colors.h
@@ -0,0 +1,54 @@
+#ifndef WM_COLORS_H
+#define WM_COLORS_H
+
+#define SLICE(_int, _bit) (((_int) >> (_bit)) & 0xff)
+
+class Color {
+ unsigned char _R, _G, _B;
+
+ public:
+ Color(unsigned long int li = 0)
+ : _R(SLICE(li, 16)), _G(SLICE(li, 8)), _B(SLICE(li, 0)) { }
+ Color(int R, int G, int B) : _R(R), _G(G), _B(B) { }
+
+ bool operator == (const Color & c) const
+ { return _R == c._R && _G == c._G && _B == c._B; }
+ bool operator != (const Color & c) const
+ { return ! operator==(c); }
+
+ unsigned char r() const { return _R; }
+ unsigned char g() const { return _G; }
+ unsigned char b() const { return _B; }
+
+ static Color alpha_blend(const Color & c1, const Color & c2, double weight1)
+ {
+ double weight2 = 1.0 - weight1;
+ int r = static_cast<int>(c1.r() * weight1 + c2.r() * weight2 + 0.5);
+ int g = static_cast<int>(c1.g() * weight1 + c2.g() * weight2 + 0.5);
+ int b = static_cast<int>(c1.b() * weight1 + c2.b() * weight2 + 0.5);
+ return Color(r, g, b);
+ }
+};
+
+#undef SLICE
+
+#define WMColor(x) (WMApp::colormap[static_cast<int>(WMColor:: x)])
+
+namespace WMColor {
+ enum WMColor {
+ Background, // Background of WMFrames and WMImages
+ Dim, // Dark drawing color
+ Medium, // Medium drawing color
+ Bright, // Light drawing color
+ ButtonFace, // Color of face of buttons
+ ButtonBorderDim, // Colors of borders of WMButtons
+ ButtonBorderMedium,
+ ButtonBorderBright,
+ FrameBorderDim, // Colors of borders of WMFrames
+ FrameBorderMedium,
+ FrameBorderBright
+ };
+ const int numcolors = 11;
+}
+
+#endif
diff --git a/wmapp/example1/Makefile b/wmapp/example1/Makefile
new file mode 100644
index 0000000..d6a5575
--- /dev/null
+++ b/wmapp/example1/Makefile
@@ -0,0 +1,13 @@
+OBJECTS = wmexample.o window0.o window1.o
+
+../wmexample: $(OBJECTS) ../libwmapp.a
+ $(CXX) $(CFLAGS) $(OBJECTS) $(LFLAGS) -o $@
+
+$(OBJECTS): %.o: %.cc ../*.h
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f *.o *\~
+
+.PHONY: clean
+
diff --git a/wmapp/example1/debian-tiny.xpm b/wmapp/example1/debian-tiny.xpm
new file mode 100644
index 0000000..065ed64
--- /dev/null
+++ b/wmapp/example1/debian-tiny.xpm
@@ -0,0 +1,50 @@
+/* XPM */
+static char * debian_tiny_xpm[] = {
+"9 9 38 1",
+" c None",
+". c #AEAAAE",
+"+ c #AB9194",
+"@ c #A87173",
+"# c #AA8487",
+"$ c #AEA5A9",
+"% c #A76568",
+"& c #A23B3D",
+"* c #A9787B",
+"= c #A76C6F",
+"- c #A03132",
+"; c #AC999C",
+"> c #AC9396",
+", c #A65E60",
+"' c #AEA9AD",
+") c #AD9598",
+"! c #AE9DA1",
+"~ c #A97C7F",
+"{ c #A96E70",
+"] c #A76A6C",
+"^ c #ADA0A4",
+"/ c #AD9B9F",
+"( c #AD989C",
+"_ c #AD9B9E",
+": c #A86E70",
+"< c #A86D70",
+"[ c #AEA6AA",
+"} c #AE9DA0",
+"| c #AC8689",
+"1 c #AA797C",
+"2 c #AD9DA1",
+"3 c #AA8689",
+"4 c #A97679",
+"5 c #AD8C8F",
+"6 c #AB8184",
+"7 c #A6585A",
+"8 c #A97476",
+"9 c #AE9EA2",
+"...+@#$..",
+"..%&*=-;.",
+".>,')!~{.",
+".]^/(._:.",
+".<[}|[12.",
+".34.56/..",
+".'7[.....",
+"..^89....",
+"....$...."};
diff --git a/wmapp/example1/window0.cc b/wmapp/example1/window0.cc
new file mode 100644
index 0000000..032a74e
--- /dev/null
+++ b/wmapp/example1/window0.cc
@@ -0,0 +1,204 @@
+#include "../wmapp.h"
+#include "../wmframe.h"
+#include "../wmwindow.h"
+#include "../wmtextbar.h"
+#include "../wmslider.h"
+#include "../wmled.h"
+#include "../wmmeterbar.h"
+#include "../wmhistory.h"
+#include "../wmbutton.h"
+#include "../wmellipse.h"
+
+#include "../xpm/checkbox.xpm"
+#include "../xpm/xbutton.xpm"
+#include "debian-tiny.xpm"
+
+// for the clock:
+#include <time.h>
+#include <sys/timeb.h>
+
+// This file defines a window that contains various widgets to demonstrate
+// the WMApp library. Also it is shown how to make a clock widget.
+
+// Callbacks for the buttons -----------------------------------------------
+
+// This one ends the program (always useful) and will be attached to the
+// button with the "X".
+void
+halt(const WMApp *a, void *) { a->stop(); }
+
+// The following three callbacks will be attached to the checkbox button:
+
+// This one changes the state of the middle LED if mousebutton 1 is clicked.
+void
+ledset(const WMApp *a, WMWidget *w, void *)
+{
+ if (a->mouseclick().button != Button1) return;
+
+ WMLed *l = dynamic_cast<WMLed *>(w);
+ if (l) {
+ l->setled(static_cast<WMLed::LedState>((1 + l->led()) % 4));
+ a->repaint();
+ }
+}
+
+// This one toggles the style of the vertical meter if button 2 is clicked.
+void
+togglegraphstyle (const WMApp *a, WMWidget *w, void *)
+{
+ if (a->mouseclick().button != Button2) return;
+
+ WMMeterBar *m = dynamic_cast<WMMeterBar *>(w);
+ if (m) {
+ m->setstyle(static_cast<WMMeterBar::Style>((1 + m->style()) % 3));
+ m->setorientation((m->orientation() == Orientation::Horizontal) ?
+ Orientation::Vertical : Orientation::Horizontal);
+ a->repaint();
+ }
+}
+
+// This one toggles whether the "close" button can be pressed if mouse
+// button 3 is clicked.
+void
+toggleclose(const WMApp *a, WMWidget *w, void *)
+{
+ if (a->mouseclick().button != Button3) return;
+
+ WMButton *b = dynamic_cast<WMButton *>(w);
+ if (b && b->is_active()) b->deactivate();
+ else if (b && !b->is_active()) b->activate();
+}
+
+// This callback will be attached to the Debian button. It switches
+// between windows.
+// Note: if the last statement in a callback function requests
+// a switch to a new window, you don't need a "repaint()".
+void
+switch_to_1(const WMApp *a, void *)
+{ a->switch_to(1); }
+
+// Define a class that will be a WMHistory widget with callbacks
+class WMHistCallback : public WMCallback, public WMHistory, public WMEllipse {
+ public: WMHistCallback() : WMCallback(), WMHistory(), WMEllipse() { }
+};
+
+// Callback to clear this widget when it's clicked on
+void
+clearhistory(const WMApp *a, WMWidget *w, void *)
+{
+ WMHistCallback *h = dynamic_cast<WMHistCallback *>(w);
+ if (h) h->clear();
+}
+
+// Callbacks for the windows -----------------------------------------------
+// Window callbacks are executed every 50 milliseconds (by default; you
+// can set this value) for the currently displayed window.
+
+// This function will update the time on the clock display every 5 seconds.
+void
+displaytime(const WMApp *a, WMWidget *w, void *)
+{
+ struct timeb currenttime;
+ string timestr;
+ WMTextBar *b = dynamic_cast<WMTextBar *>(w);
+
+ if (!b) return;
+ ftime(¤ttime);
+ // extract current time from date-and-time string
+ timestr = string(ctime(¤ttime.time) + 11);
+ b->settext(timestr);
+ a->repaint();
+}
+
+// make random increments to the meterbar and history every 150 ms
+void
+updatehist (const WMApp *a, WMWidget *w1, void *w2)
+{
+ WMMeterBar *b = dynamic_cast<WMMeterBar *>(w1);
+ if (b) {
+ int increment = static_cast<int>(b->value() - 13
+ + 31 * static_cast<float>(rand()) / RAND_MAX) + 307;
+ //I added 307 becuase gcc does bad things to a signed dividend in a modulus,
+ //which makes for *interesting* results
+
+ b->setvalue(increment % 307, 306);
+ }
+
+ WMHistory *h = dynamic_cast<WMHistory *>(static_cast<WMWidget *>(w2));
+ if (b && h) h->setvalue(b->value());
+ a->repaint();
+}
+
+// The function where we lay out all the widgets ---------------------------
+
+void
+makewindow0(WMWindow *w0)
+{
+ // Everything following is GUI boilerplate code.
+ static WMFrame top, mid, bottom, topright, botright;
+ static WMTextBar time("00:00", 0);
+ static WMSlider slider(30, 50);
+ static WMLed l, m, r;
+ static WMMeterBar meterbar;
+ static WMHistCallback history;
+ static WMButton debian, go, stop;
+
+ w0->add_timed_function(500, displaytime, &time, 0);
+ w0->add_timed_function(15, updatehist, &meterbar,
+ dynamic_cast<WMWidget *>(&history));
+ w0->addchild(top);
+ w0->addchild(mid);
+ w0->addchild(bottom);
+ w0->setorientation(Orientation::Vertical);
+ w0->setaspectratios(1, 2, 1);
+
+ top.addchild(time);
+ top.addchild(topright);
+ top.setaspectratios(6, 5);
+
+ mid.addchild(history);
+ mid.addchild(slider);
+ slider.setorientation(Orientation::Vertical);
+ mid.setaspectratios(3, 1);
+
+ bottom.addchild(meterbar);
+ bottom.addchild(botright);
+ bottom.setaspectratios(1, 2);
+
+ topright.addchild(l);
+ topright.addchild(m);
+ topright.addchild(r);
+ topright.setpadding(0);
+ topright.setborder(1);
+
+ botright.addchild(debian);
+ botright.addchild(go);
+ botright.addchild(stop);
+ botright.setpadding(0);
+ botright.setborder(1);
+
+ l.setled(WMLed::Good);
+ r.setled(WMLed::Error);
+
+ // should set initial total of seconds
+ srand(std::time(0));
+ meterbar.setstyle(WMMeterBar::Spectrum);
+ meterbar.setvalue(150, false);
+ meterbar.settotal(306, false);
+ history.settotal(306, false);
+ history.addcallback(clearhistory, &history, 0);
+
+ debian.seticon(debian_tiny_xpm);
+ debian.addcallback(switch_to_1, 0);
+
+ go.seticon(checkbox_xpm);
+ go.addcallback(ledset, &m, 0);
+ go.addcallback(toggleclose, &stop, 0);
+ go.addcallback(togglegraphstyle, &meterbar, 0);
+
+ // Let's start this button out in an inactive state, just for fun.
+ stop.deactivate();
+ stop.seticon(xbutton_xpm);
+ stop.addcallback(halt, 0);
+}
+
diff --git a/wmapp/example1/window1.cc b/wmapp/example1/window1.cc
new file mode 100644
index 0000000..644cad5
--- /dev/null
+++ b/wmapp/example1/window1.cc
@@ -0,0 +1,86 @@
+#include "../wmapp.h"
+#include "../wmwindow.h"
+#include "../wmframe.h"
+#include "../wmcanvas.h"
+#include "../wmbutton.h"
+#include "../wmellipse.h"
+#include "debian-tiny.xpm"
+
+// This file creates a window with a small, very simple paint program.
+
+// Define a class that will be a WMCanvas widget with callbacks
+class WMPainter : public WMCallback, public WMCanvas, public WMEllipse {
+ public: WMPainter() : WMCallback(), WMCanvas() { }
+};
+
+// Make one of the buttons elliptical.
+class WMEllipticalButton : public WMEllipse, public WMButton {
+ public: WMEllipticalButton() : WMEllipse(), WMButton() { }
+};
+
+// Callback to paint onto this widget when it's clicked on
+void
+paint(const WMApp *a, WMWidget *w, void *)
+{
+ WMMouseClick click = a->mouseclick().b_relative_to(w);
+ WMPainter *p = dynamic_cast<WMPainter *>(w);
+ // draw a 3x3 square at the mouse location clicked upon
+ if (p) p->fill_rectangle(click.x - 2, click.y - 2, 3, 3);
+ a->repaint();
+}
+
+// Callbacks for the buttons -----------------------------------------------
+
+// This callback changes the current paint color of the WMCanvas, depending
+// upon which button was pressed.
+void
+changecolor(const WMApp *a, WMWidget *w, void *color)
+{
+ WMColor::WMColor c = *static_cast<WMColor::WMColor *>(color);
+ WMPainter *wp = dynamic_cast<WMPainter *>(w);
+ if (wp) wp->setcolor(c);
+}
+
+// This callback will be attached to the big button
+// on the second window. It switches between windows.
+// Note: if the last statement in a callback function requests
+// a switch to a new window, you don't need a "repaint()".
+void
+switch_to_0(const WMApp *a, void *)
+{ a->switch_to(0); }
+
+void makewindow1(WMWindow *w1)
+{
+ static WMEllipticalButton debianwin;
+ static WMEllipticalButton colorbutton[4];
+ static WMFrame top, topleft, bottom;
+ static WMPainter drawing;
+ static int colors[4] = { 0x000000, 0xFF0000, 0x00FF00, 0x0000FF };
+
+ w1->addchild(top);
+ w1->addchild(bottom);
+ w1->setorientation(Orientation::Vertical);
+ w1->setaspectratios(1, 3);
+
+ top.addchild(topleft);
+ top.addchild(debianwin);
+ top.setaspectratios(4, 1);
+
+ topleft.setpadding(0);
+ topleft.setborder(1);
+ topleft.settransparency(false);
+
+ for (unsigned int i = 0; i < 4; i++) {
+ colorbutton[i].setbgcolor(colors[i]);
+ colorbutton[i].addcallback(changecolor, &drawing, colors + i);
+ topleft.addchild(colorbutton[i]);
+ }
+
+ debianwin.seticon(debian_tiny_xpm);
+ debianwin.addcallback(switch_to_0, 0);
+
+ drawing.addcallback(paint, &drawing);
+ bottom.addchild(drawing);
+ drawing.setborder(4);
+}
+
diff --git a/wmapp/example1/wmexample.cc b/wmapp/example1/wmexample.cc
new file mode 100644
index 0000000..b83b72c
--- /dev/null
+++ b/wmapp/example1/wmexample.cc
@@ -0,0 +1,39 @@
+#include "../wmapp.h"
+#include "../wmwindow.h"
+
+// This is an example WindowMaker dockapp program written using the
+// WMApp dockapp library. The first window shows off various widgets
+// and demonstrates how to make a clock. The second window illustrates
+// a miniature paint program.
+
+extern void makewindow0(WMWindow *w0_ptr); // see window0.cc
+extern void makewindow1(WMWindow *w1_ptr); // see window1.cc
+
+// The main() function, where we lay out all the widgets -------------------
+// The files window0.cc and window1.cc are much more interesting.
+
+int main(int argc, char *argv[])
+{
+ // This should always be the very first line in the main() function of
+ // a WMApplication:
+ WMApp::initialize(argc, argv);
+
+ WMApp a;
+ WMWindow w0, w1;
+ makewindow0(&w0);
+ makewindow1(&w1);
+
+ // Attach windows to the application
+ a.addwindow(w0);
+ a.addwindow(w1);
+
+ // This makes everything go.
+ a.run();
+
+ // Any cleanup code after the window closes should go here.
+ // (In this case, none is needed.)
+
+ return 0;
+}
+
+
diff --git a/wmapp/example2/Makefile b/wmapp/example2/Makefile
new file mode 100644
index 0000000..b8ed170
--- /dev/null
+++ b/wmapp/example2/Makefile
@@ -0,0 +1,13 @@
+OBJECTS = wmairtrafficcontrol.o wmradar.o
+
+../wmatc: $(OBJECTS) ../libwmapp.a
+ $(CXX) $(CFLAGS) $(OBJECTS) $(LFLAGS) -o $@
+
+$(OBJECTS): %.o: %.cc ../*.h wmradar.h
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f *.o *\~
+
+.PHONY: clean
+
diff --git a/wmapp/example2/wmairtrafficcontrol.cc b/wmapp/example2/wmairtrafficcontrol.cc
new file mode 100644
index 0000000..89df1ce
--- /dev/null
+++ b/wmapp/example2/wmairtrafficcontrol.cc
@@ -0,0 +1,80 @@
+#include <ctime>
+#include <cstdlib>
+#include "wmradar.h"
+#include "../wmslider.h"
+#include "../wmcallback.h"
+#include "../wmapp.h"
+#include "../wmwindow.h"
+#include "../wmframe.h"
+#include "../wmbutton.h"
+#include "../xpm/xbutton.xpm"
+
+//WM Air Traffic Control: The FAQ said don't rely on callback timings for
+//air traffic control, so I did.
+//
+//Click on the radar to change the nearest plane's heading towards that point.
+//Move the slider to change the planes' speed.
+//If two planes collide, they will disappear, a red point will appear, and
+//the score will be incremented.
+
+void
+halt(const WMApp *a, void *) { a->stop(); }
+
+void add_plane(const WMApp* a, WMWidget* w, void*)
+{
+ if (!(std::rand() % 3))
+ {
+ WMRadar* r = dynamic_cast<WMRadar*>(w);
+ if (r)
+ r->add_plane();
+ }
+}
+
+void increment_time(const WMApp* a, WMWidget* w, void*)
+{
+ WMRadar* r = dynamic_cast<WMRadar*>(w);
+ if (r)
+ r->increment_time();
+ a->repaint();
+}
+
+int main(int argc, char *argv[])
+{
+ WMApp::initialize(argc, argv);
+
+ WMApp a;
+ WMWindow win;
+
+ WMTextBar score;
+ WMSlider speed;
+ WMRadar radar(&score, &speed);
+ WMFrame left, right;
+ WMButton quit;
+
+ win.add_timed_function(1, increment_time, &radar, 0);
+ win.add_timed_function(80, add_plane, &radar, 0);
+ win.addchild(left);
+ win.addchild(right);
+ win.setaspectratios(50, 15);
+
+ left.addchild(radar);
+ left.addchild(score);
+ left.setorientation(Orientation::Vertical);
+ left.setaspectratios(50, 15);
+
+ right.addchild(speed);
+ right.addchild(quit);
+ right.setorientation(Orientation::Vertical);
+ right.setaspectratios(50, 15);
+
+ quit.seticon(xbutton_xpm);
+ quit.addcallback(halt, 0);
+
+ speed.setorientation(Orientation::Vertical);
+
+ std::srand(std::time(0));
+
+ a.addwindow(win);
+ a.run();
+ return 0;
+}
diff --git a/wmapp/example2/wmradar.cc b/wmapp/example2/wmradar.cc
new file mode 100644
index 0000000..8344c1e
--- /dev/null
+++ b/wmapp/example2/wmradar.cc
@@ -0,0 +1,220 @@
+#include <cstdlib>
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+#include "wmradar.h"
+#include "../wmapp.h"
+
+using std::sin;
+using std::cos;
+using std::atan2;
+
+WMRadar::WMRadar(WMTextBar* t, WMSlider* s)
+: angle(0), text_score(t), speed(s)
+{
+ setbuffered(true);
+ text_score->settext(" 0", false);
+ speed->settotal(50, false);
+ speed->setvalue(8, false);
+}
+
+void
+WMRadar::real_display()
+{
+ if (!p_icon())
+ seticon(false);
+ setcolor(WMColor(Background));
+ fill_rectangle(0, 0, b_width(), b_height()); //clear background
+
+ setcolor(WMColor(Dim));
+ for (double i = 0; i < 2 * M_PI; i += M_PI_4)
+ draw_line(b_width() / 2, b_height() / 2, (1 + cos(i)) * b_width() / 2,
+ (1 - sin(i)) * b_height() / 2); //draw radial lines
+
+ draw_arc(b_width() / 3, b_height() / 3, b_width() / 3 - 1, b_height() / 3 - 1,
+ 0, 360 * 64);
+ draw_arc(b_width() / 6, b_height() / 6, 2 * b_width() / 3,
+ 2 * b_height() / 3, 0, 360 * 64); //draw circles
+
+ setcolor(Color(255, 0, 0));
+ for (clist::const_iterator i = collisions.begin(); i != collisions.end(); ++i)
+ fill_arc(i->x - 1, i->y - 1, 3, 3, 0, 360 * 64); //draw collision points
+
+ std::vector<X::XPoint> points(3);
+ for (plist::const_iterator i = planes.begin(); i != planes.end(); ++i)
+ {
+ setcolor(Color(0, 255 * i->brightness, 0)); // achieve a fading effect
+ points[0].x = i->x;
+ points[0].y = i->y;
+ points[1].x = int(i->x) + 7 * cos(i->direction + 5.5 * M_PI / 6);
+ points[1].y = int(i->y) - 7 * sin(i->direction + 5.5 * M_PI / 6);
+ points[2].x = int(i->x) + 7 * cos(i->direction + 6.5 * M_PI / 6);
+ points[2].y = int(i->y) - 7 * sin(i->direction + 6.5 * M_PI / 6);
+ // construct an isoceles triangle pointing in plane's direction of motion
+ fill_polygon(points); // and draw it
+ }
+
+ setcolor(Color(0, 255, 0));
+ draw_line(b_width() / 2, b_height() / 2, (1 + cos(angle)) * b_width() / 2,
+ (1 - sin(angle)) * b_height() / 2); //draw radar line
+
+ WMImage::real_display(); //update window
+}
+
+double rand(double low, double high)
+{
+ return low + std::rand() * (high - low) / RAND_MAX;
+}
+
+void
+WMRadar::add_plane()
+{
+ if (planes.size() > 4)
+ return;
+
+ double theta = rand(0, 2 * M_PI); //put plane somewhere along edge
+ plane p = { (1 + cos(theta)) * b_width() / 2,
+ (1 - sin(theta)) * b_height() / 2,
+ rand(theta + 3 * M_PI_4, theta + 5 * M_PI_4), //direction pointing inwards
+ 0.5 }; //brightness
+
+ planes.push_back(p);
+}
+
+inline double dist2 (double x1, double y1, double x2, double y2)
+{ //return distance squared between points
+ return std::pow(x1 - x2, 2) + std::pow(y1 - y2, 2);
+}
+
+inline double norm_angle(double angle)
+{ //return angle shifted into the range [0, 2pi)
+ return angle - 2 * M_PI * std::floor(angle / (2 * M_PI));
+}
+
+bool
+WMRadar::release(int, int x, int y)
+{
+ if (wPressed)
+ {
+ wPressed = false;
+ if (contains(x, y) && planes.size())
+ {
+ int newx = x - b_left(),
+ newy = y - b_top();
+ plist::iterator closest;
+ double mindist2 = 10000;
+ for (plist::iterator i = planes.begin(); i != planes.end(); ++i)
+ {
+ double d2 = dist2(i->x, i->y, newx, newy);
+ if (d2 < mindist2)
+ {
+ mindist2 = d2;
+ closest = i;
+ }
+ }
+ closest->direction = norm_angle(atan2(double(int(closest->y) - newy),
+ double(newx - int(closest->x))));
+ //change nearest plane's direction towards (x, y)
+ }
+ return true;
+ }
+ else return false;
+}
+
+void
+WMRadar::increment_time()
+{
+ for (plist::iterator i = planes.begin(); i != planes.end();)
+ { //Collision test planes
+ if (!contains(i->x + left(), i->y + top()))
+ ++i;
+ else
+ {
+ plist::iterator j = i;
+ bool collided = false;
+ for (++j; j != planes.end();)
+ if (dist2(i->x, i->y, j->x, j->y) <= 0.75)
+ { //remove each collided plane and increment score
+ j = planes.erase(j);
+ collided = true;
+ increment_score();
+ }
+ else
+ ++j;
+ if (collided)
+ {
+ increment_score();
+ collision c = { i->x, i->y };
+ collisions.push_back(c); //make record of collision location
+ i = planes.erase(i);
+ }
+ else
+ ++i;
+ }
+ }
+
+ const double angleinc = M_PI / 125;
+
+ for (plist::iterator i = planes.begin(); i != planes.end();)
+ {
+ double incx = speed->value() * cos(i->direction) / 100;
+ double incy = -speed->value() * sin(i->direction) / 100;
+ double nextx = i->x + incx;
+ double nexty = i->y + incy;
+
+ //to check if a plane crossed the radar line, approximate the plane's path
+ //as an arc:
+ double& l_start_angle = angle; //make an interval of radar line's angles
+ const double l_end_angle = l_start_angle + angleinc;
+
+ //make an interval of the plane's angles
+ double p_start_angle = norm_angle(atan2(b_height() / 2 - i->y,
+ i->x - b_width() / 2));
+ double p_end_angle = norm_angle(atan2(b_height() / 2 - nexty,
+ nextx - b_width() / 2));
+
+ const double crossp = (b_width() / 2 - i->x) * incy
+ - (b_height() / 2 - i->y) * incx; //test whether plane is moving in
+ //a positive or a negative angle
+ if (crossp < 0.0) //make angle increase counterclockwise
+ {
+ const double temp = p_start_angle;
+ p_start_angle = p_end_angle;
+ p_end_angle = temp;
+ }
+ if (p_end_angle < p_start_angle)
+ p_end_angle += 2 * M_PI; //make sure end is > start
+
+ //intersect radar line interval and plane interval. If result is non-empty,
+ //there was an intersection.
+ if (std::min(p_end_angle, l_end_angle)
+ >= std::max(p_start_angle, l_start_angle))
+ i->brightness = 1.0; //if plane crossed radar line, make it bright
+ else
+ i->brightness *= 0.996; //otherwise decay brightness
+
+
+ i->x = nextx; //update plane's position
+ i->y = nexty;
+ if (!WMWidget::contains(i->x + b_left(), i->y + b_top()))
+ i = planes.erase(i); //cull planes outside of radar
+ else
+ ++i;
+ }
+
+ angle = norm_angle(angle + angleinc); //increment radar direction
+
+ display();
+}
+
+void
+WMRadar::increment_score ()
+{
+ using namespace std;
+ istringstream in(text_score->text()); //get string from textbar
+ int score;
+ in >> score; //extract score
+ ostringstream out;
+ out << setw(6) << setfill(' ') << score + 1; //increment and put in a string
+ text_score->settext(out.str()); //put back in textbar
+}
diff --git a/wmapp/example2/wmradar.h b/wmapp/example2/wmradar.h
new file mode 100644
index 0000000..228cdc6
--- /dev/null
+++ b/wmapp/example2/wmradar.h
@@ -0,0 +1,44 @@
+#ifndef _WMRADAR_H
+#define _WMRADAR_H
+
+#include <list>
+#include "../wmellipse.h"
+#include "../wmcanvas.h"
+#include "../wmcallback.h"
+#include "../wmtextbar.h"
+#include "../wmslider.h"
+
+class WMRadar : public WMCanvas, public WMCallback, public WMEllipse {
+private:
+ struct plane
+ {
+ double x, y, direction, brightness;
+ };
+ typedef std::list<plane> plist;
+
+ struct collision
+ { int x, y; };
+ typedef std::list<collision> clist;
+
+ plist planes;
+ clist collisions;
+ double angle;
+
+ WMTextBar* text_score;
+ WMSlider* speed;
+
+protected:
+ void real_display();
+
+public:
+ WMRadar(WMTextBar*, WMSlider*);
+
+ void add_plane();
+ bool release(int button, int x, int y); //change nearest plane's direction
+ void increment_time();
+
+private:
+ void increment_score();
+};
+
+#endif //_WMRADAR_H
diff --git a/wmapp/wmapp.cc b/wmapp/wmapp.cc
new file mode 100644
index 0000000..e335318
--- /dev/null
+++ b/wmapp/wmapp.cc
@@ -0,0 +1,378 @@
+#include <string>
+#include "wmapp.h"
+#include "wmwindow.h"
+
+using std::string;
+
+namespace Unix {
+ extern "C" {
+# include <unistd.h> // for usleep()
+ }
+};
+
+// All the xpms we need:
+namespace Xpms {
+# include "xpm/charmap-small.xpm"
+# include "xpm/charmap-medium.xpm"
+# include "xpm/charmap-large.xpm"
+# include "xpm/checkbox.xpm"
+# include "xpm/xbutton.xpm"
+# include "xpm/leds.xpm"
+# include "xpm/emptybar.xpm"
+# include "xpm/fullbar.xpm"
+# include "xpm/tile.xpm"
+};
+
+// Xlib doesn't seem to work if these are class members.
+// They're declared as extern in xwrapper.h.
+X::Window wActiveWin, wProgramWin;
+X::Atom deleteWin;
+X::Atom _XA_GNUSTEP_WM_FUNC;
+
+// static class members of WMApp declared here:
+
+Xwrapper WMApp::Xw;
+WMPixmap WMApp::char_pixmaps[3];
+WMPixmap WMApp::checkbox_pixmap, WMApp::xbutton_pixmap, WMApp::leds_pixmap[4];
+WMPixmap WMApp::emptybar_pixmap, WMApp::fullbar_pixmap;
+WMPixmap WMApp::tile_pixmap;
+Color WMApp::colormap[WMColor::numcolors];
+
+char ** WMApp::wArgv;
+string WMApp::wName;
+int WMApp::wArgc;
+int WMApp::wWindowSize;
+enum WindowManager::WindowManager WMApp::wManager;
+
+
+// initialize: static function to create pixmaps and set default colors.
+// This should be called as the very first line of a program using this
+// library.
+void
+WMApp::initialize(int argc, char *argv[])
+{
+ static bool inited = false;
+ if (inited) return;
+
+ wArgc = argc;
+ wName = (argc && argv) ? string(argv[0]) : string("WMApplication");
+ wArgv = argv;
+ deleteWin = X::XInternAtom(Xw.xdisplay(), "WM_DELETE_WINDOW", false);
+ _XA_GNUSTEP_WM_FUNC = X::XInternAtom(Xw.xdisplay(),
+ "_GNUSTEP_WM_FUNCTION", false);
+
+ // create all the required pixmaps
+ Xw.create_pixmap(char_pixmaps[0], Xpms::charmap_small_xpm);
+ Xw.create_pixmap(char_pixmaps[1], Xpms::charmap_medium_xpm);
+ Xw.create_pixmap(char_pixmaps[2], Xpms::charmap_large_xpm);
+ Xw.create_pixmap(checkbox_pixmap, Xpms::checkbox_xpm);
+ Xw.create_pixmap(xbutton_pixmap, Xpms::xbutton_xpm);
+ Xw.create_pixmap(fullbar_pixmap, Xpms::fullbar_xpm);
+ Xw.create_pixmap(emptybar_pixmap, Xpms::emptybar_xpm);
+ Xw.create_pixmap(tile_pixmap, Xpms::tile_xpm);
+
+ // create four LED pixmaps
+ WMPixmap all_leds_pixmap;
+ int ledwidth = 4, ledheight = 4;
+
+ Xw.create_pixmap(all_leds_pixmap, Xpms::leds_xpm);
+ for (unsigned int s = 0; s < 4; s++) {
+ leds_pixmap[s].attr.width = ledwidth;
+ leds_pixmap[s].attr.width = ledheight;
+ Xw.create_pixmap(leds_pixmap[s], ledwidth, ledheight);
+ Xw.copy_rectangle(all_leds_pixmap, leds_pixmap[s], ledwidth * s, 0,
+ ledwidth, ledheight, 0, 0);
+ }
+
+# define colormap(x) colormap[static_cast<int>(WMColor:: x)]
+ // create colormap
+ // XXX: eventually, read from RC file
+ colormap(Background) = 0x212121;
+ colormap(Dim) = 0x283C28;
+ colormap(Medium) = 0x188A86;
+ colormap(Bright) = 0x20B2AE;
+ colormap(ButtonFace) = 0xAEAAAE;
+ colormap(ButtonBorderDim) = 0;
+ colormap(ButtonBorderMedium) = 0x86828E;
+ colormap(ButtonBorderBright) = 0xF7F3FF;
+ colormap(FrameBorderDim) = 0;
+ colormap(FrameBorderMedium) = 0;
+ colormap(FrameBorderBright) = 0xC8C8C8; //0xAEAAAE;
+# undef colormap
+
+ inited = true;
+
+ // set the window behavior from command-line options
+ wManager = WindowManager::Other;
+ wWindowSize = 64;
+
+ for (int i = 1; i < wArgc && strcmp(wArgv[i], "--"); i++) {
+ if (strcmp(wArgv[i], "-w") == 0) {
+ wManager = WindowManager::WindowMaker; break;
+ }
+ else if (strcmp(wArgv[i], "-a") == 0) {
+ wManager = WindowManager::Afterstep;
+ wWindowSize = 56;
+ break;
+ }
+ }
+}
+
+// Here begin the magic Xlib incantations required to create a dockapp window.
+// I have no idea how this works, it just does. Code mostly obtained from
+// wmsmixer by Damian Kramer, based in turn upon wmmixer by Sam Hawker.
+
+// simple function to create an XWindow
+void
+WMApp::create_window(X::Window *dest, int left, int top) const
+{
+ X::XClassHint classHint;
+
+ *dest = X::XCreateSimpleWindow(Xw.xdisplay(), Xw.xrootwin(), left, top,
+ wWindowSize, wWindowSize, 0, 0, 0);
+
+ //XXX: May be able to get away without allocating new char arrays, but I don't
+ //trust X not to modify them.
+ classHint.res_name = new char[wName.size() + 1];
+ classHint.res_class = new char[wName.size() + 1];
+ strcpy(classHint.res_name, wName.c_str());
+ strcpy(classHint.res_class, wName.c_str());
+ X::XSetClassHint(Xw.xdisplay(), *dest, &classHint);
+ delete[] classHint.res_name;
+ delete[] classHint.res_class;
+}
+
+// This function sets up the X window.
+// Called from WMApp::run()
+void WMApp::Xsetup()
+{
+ X::Display * display = Xw.xdisplay();
+
+ X::XWMHints wmhints;
+ X::XSizeHints shints;
+ int winsize = wWindowSize;
+ bool pos;
+
+ shints.x = shints.y = shints.flags = 0;
+ pos = (X::XWMGeometry(display, X::XDefaultScreen(display), "" /*geometry*/,
+ 0, 0, &shints, &shints.x, &shints.y, &shints.width, &shints.height,
+ &shints.win_gravity) & X_MACRO(XValue | YValue));
+ shints.min_width = shints.min_height = winsize;
+ shints.max_width = shints.max_height = winsize;
+ shints.base_width = shints.base_height = winsize;
+ shints.flags = X_MACRO(PMinSize | PMaxSize | PBaseSize);
+ create_window(&wProgramWin, shints.x, shints.y);
+
+ if (pos || wManager == WindowManager::WindowMaker
+ || wManager == WindowManager::Afterstep)
+ shints.flags |= X_MACRO(USPosition);
+
+ if (wManager == WindowManager::WindowMaker) {
+ wmhints.initial_state = X_MACRO(WithdrawnState);
+ wmhints.flags = X_MACRO(WindowGroupHint | StateHint | IconWindowHint);
+ create_window(&wActiveWin, shints.x, shints.y);
+ wmhints.icon_window = wActiveWin;
+ }
+ else {
+ wmhints.initial_state = X_MACRO(NormalState);
+ wmhints.flags = X_MACRO(WindowGroupHint | StateHint);
+ wActiveWin = wProgramWin;
+ }
+
+ wmhints.window_group = wProgramWin;
+ X::XSetWMHints(display, wProgramWin, &wmhints);
+ X::XSetWMNormalHints(display, wProgramWin, &shints);
+ if (wArgc > 0)
+ X::XSetCommand(display, wProgramWin, wArgv, wArgc);
+ X::XStoreName(display, wProgramWin, wName.c_str());
+ X::XSetIconName(display, wProgramWin, wName.c_str());
+ X::XSetWMProtocols(display, wActiveWin, &deleteWin, 1);
+}
+
+// This function masks out the "clear" parts of the X window.
+// Called from WMWindow::real_display()
+void
+WMApp::mask() const
+{
+ X::Display * display = Xw.xdisplay();
+ WMPixmap pixmap = current()->pixmap();
+
+ if (wManager == WindowManager::WindowMaker ||
+ wManager == WindowManager::Afterstep)
+ // apply the mask if using a compliant window manager
+ X::XShapeCombineMask(display, wActiveWin, X_MACRO(ShapeBounding),
+ 0, 0, pixmap.mask, X_MACRO(ShapeSet));
+ else
+ // otherwise, create a tile background for the window
+ Xw.copy_rectangle(tile_pixmap, pixmap.pixmap, 0, 0, wWindowSize,
+ wWindowSize);
+
+ Xw.fill_rectangle(pixmap, 0, 0, wWindowSize, wWindowSize,
+ WMColor(Background));
+}
+
+// This function redraws the X window if necessary.
+// Called from WMWindow::real_display()
+void
+WMApp::repaint() const
+{
+ X::XEvent xev;
+
+ Xw.copy_rectangle(current()->pixmap(), wActiveWin,
+ 0, 0, wWindowSize, wWindowSize);
+
+ while (X::XCheckTypedEvent(Xw.xdisplay(), X_MACRO(Expose), &xev))
+ /* loop */;
+ X::XFlush(Xw.xdisplay());
+}
+
+// This function displays the X window.
+// Called from WMWindow::real_activate()
+void
+WMApp::Xshow() const
+{
+ X::Display * display = Xw.xdisplay();
+
+ // request input events and map the window
+ X::XSelectInput(display, wActiveWin,
+ X_MACRO(ExposureMask | ButtonPressMask | ButtonReleaseMask)
+ | X_MACRO(ButtonMotionMask));
+ X::XMapWindow(display, wProgramWin);
+ repaint();
+
+ // loop over X events and callbacks
+ Xwait();
+}
+
+// This function waits for X events, redraws the window when necessary,
+// and calls callbacks of the window.
+void
+WMApp::Xwait() const
+{
+ X::Display * display = Xw.xdisplay();
+ X::XEvent xev;
+
+ while (true) {
+ // sleep for the specified time in milliseconds
+ Unix::usleep(1000 * current()->updatefreq());
+ // execute any timed functions which need it
+ current()->run_timed_functions();
+
+ // execute any pending X events
+ while (XPending(display)) {
+ X::XNextEvent(display, &xev);
+
+ switch (xev.type) {
+ case Expose:
+ repaint();
+ break;
+ case ButtonPress:
+ current()->press(xev.xbutton.button, xev.xbutton.x, xev.xbutton.y);
+ break;
+ case ButtonRelease:
+ wMouseEvent.button = xev.xbutton.button;
+ wMouseEvent.x = xev.xbutton.x;
+ wMouseEvent.y = xev.xbutton.y;
+ current()->release(xev.xbutton.button, xev.xbutton.x, xev.xbutton.y);
+ if (done()) return;
+ break;
+ case ClientMessage:
+ if (static_cast<unsigned int>(xev.xclient.data.l[0]) == deleteWin)
+ { stop(); return; }
+ break;
+ default: break;
+ }
+ }
+ }
+}
+
+// End of magic Xlib incantations.
+
+// The following functions deal with setting the state of the application
+// and running it.
+
+void
+WMApp::switch_to(WMWindow *w) const
+{
+ for (unsigned int i = 0; i < wWindows.size(); i++)
+ if (w == wWindows[i]) {
+ switch_to(i);
+ return;
+ }
+}
+
+void
+WMApp::switch_to(WMWindow &w) const { switch_to(&w); }
+
+// run: This function starts the GUI of the dockapp. Call it as the
+// last line in a program using this library. Calling run() with no
+// argument starts the program on the first window. You can also
+// call run(WMWindow *), run(WMWindow &), or run(unsigned int) in order
+// to start with a different window.
+//
+// So your program in the simplest case should look like this:
+//
+// int main(int argc, char *argv[]) {
+// WMApp::initialize(argc, argv);
+// WMWindow w;
+// WMApp a = WMApp(w);
+// // layout the window and set up callbacks here
+// // ...
+// a.addwindow(w);
+// a.run();
+// return 0;
+// }
+
+void
+WMApp::run(WMWindow *w)
+{
+ for (unsigned int i = 0; i < wWindows.size(); i++)
+ if (w == wWindows[i]) {
+ run(i);
+ return;
+ }
+}
+
+void
+WMApp::run(WMWindow &w) { run(&w); }
+
+void
+WMApp::run(int w) { run(static_cast<unsigned int>(w)); }
+
+void
+WMApp::run(unsigned int w)
+{
+ if (w >= wWindows.size()) return;
+
+ // set up pointers from windows to "this"
+ for (unsigned int i = 0; i < wWindows.size(); i++)
+ wWindows[i]->wApp = this;
+
+ Xsetup();
+ wActiveWindow = wNextWindow = w;
+
+ while (wFinished == false) {
+ // This function does not exit until wNextWindow != wActiveWindow
+ // or wFinished == true. User interaction happens in here.
+ current()->display();
+
+ // To switch to a different window, set a callback on a button within
+ // this window, like this:
+ // void callback1(const WMApp *a, void *) { a->switch_to(5); }
+ // To exit the program, likewise, you need a callback like
+ // void callback2(const WMApp *a, void *) { a->stop(); }
+ // (Alternately you could put the window on a timer by setting one of
+ // these as a callback of the window itself, substituting WMWindow for
+ // WMButton in the function definitions.)
+
+ wActiveWindow = wNextWindow;
+
+ // if we have switched to a different window, continue with that one.
+ }
+
+ // otherwise, exit the WMApp::run() function. (Normally a call like
+ // wm_app->run(); will be the last in a program's main() function,
+ // in which case we also exit the program.)
+ return;
+}
+
diff --git a/wmapp/wmapp.h b/wmapp/wmapp.h
new file mode 100644
index 0000000..66c022f
--- /dev/null
+++ b/wmapp/wmapp.h
@@ -0,0 +1,170 @@
+#include <vector>
+#include <string>
+#include "wmwidget.h"
+#include "xwrapper.h"
+#include "colors.h"
+
+#ifndef _WMAPP_H
+#define _WMAPP_H
+
+class WMWindow;
+
+namespace WindowManager {
+ enum WindowManager { WindowMaker, Afterstep, Other };
+};
+
+struct WMMouseClick {
+ int button;
+ int x;
+ int y;
+
+ WMMouseClick(int Button = Button1, int X = 0, int Y = 0);
+ WMMouseClick relative_to(const WMWidget &w) const;
+ WMMouseClick relative_to(const WMWidget *w) const;
+ WMMouseClick b_relative_to(const WMWidget &w) const;
+ WMMouseClick b_relative_to(const WMWidget *w) const;
+};
+
+inline WMMouseClick::WMMouseClick(int Button, int X, int Y)
+: button(Button), x(X), y(Y) { }
+
+inline WMMouseClick
+WMMouseClick::relative_to(const WMWidget &w) const
+{ return WMMouseClick(button, x - w.left(), y - w.top()); }
+
+inline WMMouseClick
+WMMouseClick::relative_to(const WMWidget *w) const
+{ return relative_to(*w); }
+
+inline WMMouseClick
+WMMouseClick::b_relative_to(const WMWidget &w) const
+{ return WMMouseClick(button, x - w.b_left(), y - w.b_top()); }
+
+inline WMMouseClick
+WMMouseClick::b_relative_to(const WMWidget *w) const
+{ return b_relative_to(*w); }
+
+class WMApp {
+ private:
+ static int wWindowSize;
+ static int wArgc;
+ static char ** wArgv;
+ static std::string wName;
+
+ std::vector<WMWindow *> wWindows;
+ mutable int wActiveWindow;
+ mutable int wNextWindow;
+ mutable bool wFinished;
+ mutable WMMouseClick wMouseEvent;
+
+ void create_window(X::Window *dest, int left, int top) const;
+ void Xsetup();
+ void Xwait() const;
+
+ public:
+ static WindowManager::WindowManager wManager;
+ static Xwrapper Xw;
+ static WMPixmap char_pixmaps[3];
+ static WMPixmap checkbox_pixmap, xbutton_pixmap, leds_pixmap[4];
+ static WMPixmap emptybar_pixmap, fullbar_pixmap;
+ static WMPixmap tile_pixmap;
+ static Color colormap[WMColor::numcolors];
+
+ // Always call this function first in main():
+ static void initialize(int argc = 0, char *argv[] = 0);
+ static unsigned int size();
+
+ WMApp();
+ ~WMApp();
+
+ void addwindow(WMWindow *);
+ void addwindow(WMWindow &);
+
+ // Use this call to start the GUI.
+ void run(unsigned int window = 0);
+ void run(int window);
+ void run(WMWindow &);
+ void run(WMWindow *);
+
+ // Use these within callbacks of windows or buttons in order to switch
+ // to a different window, or to exit the GUI.
+ void switch_to(unsigned int window) const;
+ void switch_to(int window) const;
+ void switch_to(WMWindow &) const;
+ void switch_to(WMWindow *) const;
+ void stop() const;
+
+ // Use this within callbacks of windows or buttons in order to play
+ // with other widgets.
+ WMWindow * window(unsigned int) const;
+ WMWindow * current() const;
+ unsigned int currentnum() const;
+
+ // Use this within callbacks to see which mouse button was pressed
+ // and where.
+ const WMMouseClick & mouseclick() const;
+
+ // Windows use this call to see if it's time for them to exit yet.
+ bool done() const;
+
+ // utility functions for windows
+ void mask() const;
+ void repaint() const;
+ void Xshow() const;
+};
+
+inline
+WMApp::WMApp()
+: wActiveWindow(0), wNextWindow(0), wFinished(false) { }
+
+inline
+WMApp::~WMApp()
+{
+ if (wProgramWin == wActiveWin)
+ X::XDestroyWindow(Xw.xdisplay(), wProgramWin);
+ else {
+ X::XDestroyWindow(Xw.xdisplay(), wProgramWin);
+ X::XDestroyWindow(Xw.xdisplay(), wActiveWin);
+ }
+}
+
+inline void
+WMApp::addwindow(WMWindow *w) { wWindows.push_back(w); }
+
+inline void
+WMApp::addwindow(WMWindow &w) { wWindows.push_back(&w); }
+
+inline unsigned int
+WMApp::size() { return wWindowSize; }
+
+inline WMWindow *
+WMApp::window(unsigned int i) const
+{ return i < wWindows.size() ? wWindows[i] : 0; }
+
+inline WMWindow *
+WMApp::current() const { return wWindows[wActiveWindow]; }
+
+inline unsigned int
+WMApp::currentnum() const { return wActiveWindow; }
+
+inline const WMMouseClick &
+WMApp::mouseclick() const { return wMouseEvent; }
+
+inline void
+WMApp::switch_to(unsigned int window) const
+{ if (window < wWindows.size()) wNextWindow = window; }
+
+inline void
+WMApp::switch_to(int window) const
+{
+ if (window >= 0 && window < static_cast<int>(wWindows.size()))
+ wNextWindow = window;
+}
+
+inline void
+WMApp::stop() const { wFinished = true; }
+
+inline bool
+WMApp::done() const { return wFinished || wActiveWindow != wNextWindow; }
+
+#endif
diff --git a/wmapp/wmbutton.cc b/wmapp/wmbutton.cc
new file mode 100644
index 0000000..2989a03
--- /dev/null
+++ b/wmapp/wmbutton.cc
@@ -0,0 +1,59 @@
+#include "wmbutton.h"
+#include "wmapp.h"
+#include "wmwindow.h"
+
+// functions for WMButton ------------------------------------------------
+
+WMButton::WMButton()
+{
+ setborder(1);
+ setbgcolor(WMColor(ButtonFace), false);
+ set_top_left_c(WMColor(ButtonBorderBright));
+ set_bottom_right_c(WMColor(ButtonBorderDim));
+}
+
+void
+WMButton::real_display()
+{
+ if (is_active())
+ WMImage::real_display();
+ else
+ // If button is not clickable, don't draw an icon.
+ // Note: If the button has no icon, I recommend that you change its
+ // background color from the default; otherwise the button will always
+ // look as if it is disabled.
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(ButtonFace));
+}
+
+bool
+WMButton::press(int button, int x, int y)
+{
+ if (contains(x, y)) {
+ if (is_active()) {
+ wPressed = true;
+ set_top_left_c(WMColor(ButtonBorderDim));
+ set_bottom_right_c(WMColor(ButtonBorderBright));
+ draw_border();
+ app()->repaint();
+ }
+ return true;
+ }
+ else return false;
+}
+
+bool
+WMButton::release(int button, int x, int y)
+{
+ if (wPressed) {
+ wPressed = false;
+ set_top_left_c(WMColor(ButtonBorderBright));
+ set_bottom_right_c(WMColor(ButtonBorderDim));
+ draw_border();
+ app()->repaint();
+ if (contains(x, y))
+ execute();
+ return true;
+ }
+ else return false;
+}
diff --git a/wmapp/wmbutton.h b/wmapp/wmbutton.h
new file mode 100644
index 0000000..83fa1d9
--- /dev/null
+++ b/wmapp/wmbutton.h
@@ -0,0 +1,18 @@
+#include "wmimage.h"
+#include "wmcallback.h"
+
+#ifndef _WMBUTTON_H
+#define _WMBUTTON_H
+
+// WMButton: An image that can execute callback functions when clicked upon
+class WMButton : public WMCallback, public WMImage {
+ private:
+ void real_display();
+
+ public:
+ WMButton();
+ bool press(int button, int x, int y);
+ bool release(int button, int x, int y);
+};
+
+#endif
diff --git a/wmapp/wmcallback.cc b/wmapp/wmcallback.cc
new file mode 100644
index 0000000..9fb2a94
--- /dev/null
+++ b/wmapp/wmcallback.cc
@@ -0,0 +1,34 @@
+#include "wmcallback.h"
+
+// functions for WMCallback ----------------------------------------------
+
+void
+WMCallback::execute()
+{
+ // execute all callbacks for this object, in order
+ for (unsigned int i = 0; i < numcallbacks(); i++)
+ runcallback(i);
+}
+
+bool
+WMCallback::press(int button, int x, int y)
+{
+ if (contains(x, y)) {
+ wPressed = true;
+ return true;
+ }
+ else return false;
+}
+
+bool
+WMCallback::release(int button, int x, int y)
+{
+ if (wPressed) {
+ wPressed = false;
+ if (contains(x,y))
+ execute();
+ return true;
+ }
+ else return false;
+}
+
diff --git a/wmapp/wmcallback.h b/wmapp/wmcallback.h
new file mode 100644
index 0000000..de9aab4
--- /dev/null
+++ b/wmapp/wmcallback.h
@@ -0,0 +1,113 @@
+#include <vector>
+#include "wmwidget.h"
+#include "wmclickable.h"
+
+#ifndef _WMCALLBACK_H
+#define _WMCALLBACK_H
+
+using std::vector;
+
+// WMCallback: A class capable of setting and executing callback functions.
+class WMCallback : public virtual WMWidget, public virtual WMClickable {
+ public:
+ typedef void (* data_func)(const WMApp *, void *);
+ typedef void (* widget_func)(const WMApp *, WMWidget *, void *);
+
+ private:
+ class callback {
+ public: virtual void execute(const WMApp *) = 0;
+ };
+
+ class data_callback : public callback {
+ data_func func;
+ void * data;
+ public:
+ data_callback(data_func, void *);
+ void execute(const WMApp *);
+ };
+
+ class widget_callback : public callback {
+ widget_func func;
+ WMWidget * widget;
+ void * data;
+ public:
+ widget_callback(widget_func, WMWidget *, void *);
+ void execute(const WMApp *);
+ };
+
+ vector<callback*> wCallback;
+
+ public:
+ WMCallback();
+ WMCallback(data_func, void * = 0);
+ WMCallback(widget_func, WMWidget *, void * = 0);
+ virtual ~WMCallback() { clearcallbacks(); }
+
+ unsigned int numcallbacks() const;
+ void addcallback(data_func, void * = 0);
+ void addcallback(widget_func, WMWidget *, void * = 0);
+ void runcallback(unsigned int i);
+ void clearcallbacks();
+
+ // check to see if a mouse click hit the widget; if so, run callbacks
+ virtual bool press(int button, int x, int y);
+ virtual bool release(int button, int x, int y);
+ virtual void execute();
+};
+
+// inline functions for WMCallback ---------------------------------------
+
+inline
+WMCallback::data_callback::data_callback(data_func f, void *datap)
+: func(f), data(datap) { }
+
+inline void
+WMCallback::data_callback::execute(const WMApp *app)
+{ (func)(app, data); }
+
+inline
+WMCallback::widget_callback::widget_callback
+(widget_func f, WMWidget *w, void *datap)
+: func(f), widget(w), data(datap) { }
+
+inline void
+WMCallback::widget_callback::execute(const WMApp *app)
+{ (func)(app, widget, data); }
+
+inline
+WMCallback::WMCallback()
+{ }
+
+inline
+WMCallback::WMCallback(data_func f, void *data)
+{ addcallback(f, data); }
+
+inline
+WMCallback::WMCallback(widget_func f, WMWidget *w, void *data)
+{ addcallback(f, w, data); }
+
+inline void
+WMCallback::addcallback(data_func f, void *data)
+{ wCallback.push_back(new data_callback(f, data)); }
+
+inline void
+WMCallback::addcallback(widget_func f, WMWidget *w, void *data)
+{ wCallback.push_back(new widget_callback(f, w, data)); }
+
+inline void
+WMCallback::runcallback(unsigned int i)
+{ wCallback[i]->execute(app()); }
+
+inline unsigned int
+WMCallback::numcallbacks() const { return wCallback.size(); }
+
+inline void
+WMCallback::clearcallbacks()
+{
+ for (vector<callback *>::iterator i = wCallback.begin();
+ i != wCallback.end(); ++i)
+ delete *i;
+ wCallback.clear();
+}
+
+#endif
diff --git a/wmapp/wmcanvas.cc b/wmapp/wmcanvas.cc
new file mode 100644
index 0000000..e1cf273
--- /dev/null
+++ b/wmapp/wmcanvas.cc
@@ -0,0 +1,160 @@
+#include <vector>
+#include "wmcanvas.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+// functions for WMCanvas ------------------------------------------------
+
+WMCanvas::WMCanvas(const WMPixmap * pm)
+: WMImage(pm), wCurrentColor(WMColor(Bright)), wBuffered(false) { }
+
+WMCanvas::WMCanvas(const WMPixmap & pm)
+: WMImage(pm), wCurrentColor(WMColor(Bright)), wBuffered(false) { }
+
+WMCanvas::WMCanvas(char *xpm[])
+: WMImage(xpm), wCurrentColor(WMColor(Bright)), wBuffered(false) { }
+
+// these are all variants of the drawing functions in xwrapper.h.
+// Unlike there, they are relative to the borders of the widget.
+// Note that icon() should return an XPM which is the dimension of
+// the WMCanvas _minus_ the border thickness.
+
+/*void
+WMCanvas::copy_buffer()
+{
+ WMApp::Xw.copy_rectangle(*icon(), window()->pixmap(), 0, 0,
+ b_width(), b_height(), b_left(), b_top());
+// draw_border();
+}*/
+
+// don't use this macro in your programs, it's just to make my life easier in
+// the WMCanvas method definitions
+#define COPY_BUFFER() if (! buffered()) { display() /*copy_buffer()*/; }
+
+Color
+WMCanvas::get_point(int rel_x, int rel_y) const
+{ return WMApp::Xw.get_point(*icon(), rel_x, rel_y); }
+
+void
+WMCanvas::draw_point(int rel_x, int rel_y)
+{
+ WMApp::Xw.draw_point(*p_icon(), rel_x, rel_y, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::draw_line(int rel_x1, int rel_y1, int rel_x2, int rel_y2)
+{
+ WMApp::Xw.draw_line(*p_icon(), rel_x1, rel_y1, rel_x2, rel_y2, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::draw_arc(int x, int y, int width, int height, int angle1, int angle2)
+{
+ WMApp::Xw.draw_arc(*p_icon(), x, y, width, height, angle1, angle2, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::draw_lines(const vector<X::XPoint>& points)
+{
+ X::XPoint *p = new X::XPoint[points.size()];
+ for (size_t i = 0; i < points.size(); ++i)
+ {
+ p[i].x = points[i].x;
+ p[i].y = points[i].y;
+ }
+ WMApp::Xw.draw_lines(*p_icon(), p, points.size(), color());
+ delete[] p;
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::draw_horizontal_gradient(int rel_x1, int rel_y1, int rel_x2,
+ int rel_y2, Color c1, Color c2, double amt)
+{
+ WMApp::Xw.draw_horizontal_gradient(*p_icon(), rel_x1, rel_y1, rel_x2, rel_y2,
+ c1, c2, amt);
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::draw_vertical_gradient(int rel_x1, int rel_y1, int rel_x2,
+ int rel_y2, Color c1, Color c2, double amt)
+{
+ WMApp::Xw.draw_vertical_gradient(*p_icon(), rel_x1, rel_y1, rel_x2, rel_y2,
+ c1, c2, amt);
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::empty_rectangle(int rel_x, int rel_y, int w, int h, int thickness)
+{
+ WMApp::Xw.draw_border(*p_icon(), rel_x, rel_y, w, h, thickness,
+ color(), color(), color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::empty_rectangle(const WMRectangle & rel_posn, int thickness)
+{
+ WMApp::Xw.draw_border(*p_icon(), rel_posn, thickness,
+ color(), color(), color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::fill_rectangle(int rel_x, int rel_y, int w, int h)
+{
+ WMApp::Xw.fill_rectangle(*p_icon(), rel_x, rel_y, w, h, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::fill_rectangle(const WMRectangle & rel_posn)
+{
+ WMApp::Xw.fill_rectangle(*p_icon(), rel_posn, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::fill_arc(int x, int y, int width, int height, int angle1, int angle2)
+{
+ WMApp::Xw.fill_arc(*p_icon(), x, y, width, height, angle1, angle2, color());
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::fill_polygon(const vector<X::XPoint>& points, Xwrapper::XShape shape)
+{
+ X::XPoint *p = new X::XPoint[points.size()];
+ for (size_t i = 0; i < points.size(); ++i)
+ {
+ p[i].x = points[i].x;
+ p[i].y = points[i].y;
+ }
+ WMApp::Xw.fill_polygon(*p_icon(), p, points.size(), color(), shape);
+ delete[] p;
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::copy_rectangle(const WMPixmap & source, int source_x, int source_y,
+ int source_w, int source_h, int dest_x, int dest_y)
+{
+ WMApp::Xw.copy_rectangle(source, *p_icon(), source_x, source_y,
+ source_w, source_h, dest_x, dest_y);
+ COPY_BUFFER();
+}
+
+void
+WMCanvas::copy_rectangle(const WMPixmap & source, const WMRectangle & posn,
+ int dest_x, int dest_y)
+{
+ WMApp::Xw.copy_rectangle(source, *p_icon(), posn, dest_x, dest_y);
+ COPY_BUFFER();
+}
+
+#undef COPY_BUFFER
+
diff --git a/wmapp/wmcanvas.h b/wmapp/wmcanvas.h
new file mode 100644
index 0000000..aa596fc
--- /dev/null
+++ b/wmapp/wmcanvas.h
@@ -0,0 +1,68 @@
+#include <vector>
+#include "wmimage.h"
+
+#ifndef _WMCANVAS_H
+#define _WMCANVAS_H
+
+using std::vector;
+
+// WMCanvas: a widget inheriting from WMImage that allows you to change the
+// image using drawing functions
+class WMCanvas : public virtual WMImage {
+ Color wCurrentColor;
+ bool wBuffered;
+ public:
+ WMCanvas(const WMPixmap * pm = 0);
+ WMCanvas(const WMPixmap & pm);
+ WMCanvas(char *xpm[]);
+
+ void setcolor(Color);
+ void setbuffered(bool);
+ Color color() const;
+ bool buffered() const;
+
+ // these are all variants of the drawing functions in xwrapper.h.
+ // Unlike there, they are relative to the borders of the widget.
+ Color get_point(int rel_x, int rel_y) const;
+ void draw_point(int rel_x, int rel_y);
+ void draw_line(int rel_x1, int rel_y1, int rel_x2, int rel_y2);
+ void draw_arc(int x, int y, int width, int height, int angle1, int angle2);
+ //angles are in units of degrees * 64
+ void draw_lines(const vector<X::XPoint>& points);
+ //X::XPoint is simply a struct { short x, y };
+ void draw_horizontal_gradient(int rel_x1, int rel_y1, int rel_x2, int rel_y2,
+ Color c1, Color c2, double amount = 1.0);
+ void draw_vertical_gradient(int rel_x1, int rel_y1, int rel_x2, int rel_y2,
+ Color c1, Color c2, double amount = 1.0);
+ void empty_rectangle(int rel_x, int rel_y, int width, int height,
+ int thickness);
+ void empty_rectangle(const WMRectangle & rel_posn, int thickness);
+ void fill_rectangle(int rel_x, int rel_y, int width, int height);
+ void fill_rectangle(const WMRectangle & rel_posn);
+ void fill_arc(int x, int y, int width, int height, int angle1, int angle2);
+ //angles are in units of degrees * 64
+ void fill_polygon(const vector<X::XPoint>& points,
+ Xwrapper::XShape shape = Xwrapper::complex);
+ //see xwrapper.h for the meaning of shape
+ void copy_rectangle(const WMPixmap & source, int source_x, int source_y,
+ int source_w, int source_h,
+ int dest_x = 0, int dest_y = 0);
+ void copy_rectangle(const WMPixmap & source, const WMRectangle & posn,
+ int dest_x = 0, int dest_y = 0);
+};
+
+// inline functions for WMCanvas -----------------------------------------
+
+inline void
+WMCanvas::setcolor(Color c) { wCurrentColor = c; }
+
+inline void
+WMCanvas::setbuffered(bool b) { wBuffered = b; }
+
+inline Color
+WMCanvas::color() const { return wCurrentColor; }
+
+inline bool
+WMCanvas::buffered() const { return wBuffered; }
+
+#endif
diff --git a/wmapp/wmclickable.h b/wmapp/wmclickable.h
new file mode 100644
index 0000000..419386a
--- /dev/null
+++ b/wmapp/wmclickable.h
@@ -0,0 +1,21 @@
+#ifndef _WMCLICKABLE_H
+#define _WMCLICKABLE_H
+
+// WMClickable: Widgets that are clickable should inherit from this class.
+class WMClickable {
+ protected:
+ bool wPressed;
+ public:
+ WMClickable();
+ virtual ~WMClickable() { }
+
+ virtual bool press(int button, int x, int y) = 0;
+ virtual bool release(int button, int x, int y) = 0;
+};
+
+// inline functions for WMClickable --------------------------------------
+
+inline WMClickable::WMClickable()
+: wPressed(false) { }
+
+#endif
diff --git a/wmapp/wmellipse.cc b/wmapp/wmellipse.cc
new file mode 100644
index 0000000..4bbe1c7
--- /dev/null
+++ b/wmapp/wmellipse.cc
@@ -0,0 +1,58 @@
+#include <cmath>
+#include "wmellipse.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+// functions for WMEllipse -----------------------------------------------
+
+void
+WMEllipse::draw_border()
+{ WMEllipse::draw_border(top_left_c(), bottom_right_c(), 5 /* steps */); }
+
+void
+WMEllipse::draw_border(Color c1, Color c2, int steps)
+{
+ if (border()) {
+ X::XGCValues gcv;
+ gcv.line_width = border();
+ X::XChangeGC(WMApp::Xw.xdisplay(), window()->pixmap().gc,
+ X_MACRO(GCLineWidth), &gcv);
+
+ // These dimensions are all experimentally determined :)
+ int l = left() + (border() - 1) / 2,
+ t = top() + (border() - 1) / 2,
+ w = width() - border() + (1 - border() % 2),
+ h = height() - border() + (1 - border() % 2);
+
+ const double weight_inc = 1.0 / (steps + 1);
+ const double angle_inc = 45 / steps;
+ for (double weight = weight_inc, angle = 0; angle < 44;
+ weight += weight_inc, angle += angle_inc)
+ {
+ Color c = Color::alpha_blend(c1, c2, weight);
+ WMApp::Xw.draw_arc(window()->pixmap(), l, t, w, h, (int)(angle * 64),
+ (int)(angle_inc * 64), c);
+ WMApp::Xw.draw_arc(window()->pixmap(), l, t, w, h, (int)((270 - angle) * 64),
+ (int)(-angle_inc * 64), c);
+ }
+
+ WMApp::Xw.draw_arc(window()->pixmap(), l, t, w, h, 45 * 64, 180 * 64, c1);
+ WMApp::Xw.draw_arc(window()->pixmap(), l, t, w, h, 270 * 64, 90 * 64, c2);
+
+ gcv.line_width = 0;
+ X::XChangeGC(WMApp::Xw.xdisplay(), window()->pixmap().gc,
+ X_MACRO(GCLineWidth), &gcv);
+ }
+}
+
+bool
+WMEllipse::contains(int x, int y) const
+{
+ double h_axis = std::ldexp(double(width()), -1);
+ double v_axis = std::ldexp(double(height()), -1);
+ double xc = (h_axis + left() - 0.5 - x) / h_axis;
+ xc *= xc;
+ double yc = (v_axis + top() - 0.5 - y) / v_axis;
+ yc *= yc;
+ return ((xc + yc) <= 1.0);
+}
diff --git a/wmapp/wmellipse.h b/wmapp/wmellipse.h
new file mode 100644
index 0000000..b26000e
--- /dev/null
+++ b/wmapp/wmellipse.h
@@ -0,0 +1,21 @@
+#include "wmwidget.h"
+
+#ifndef _WMELLIPSE_H
+#define _WMELLIPSE_H
+
+// WMEllipse: Widgets inherited from this class will be displayed within an
+// elliptical border. Simply inherit from WMEllipse and the desired widget.
+// Note: In order to get a circle, you must make the widget's width the same
+// as its height, for example by placing it inside a WMFrame with padding.
+class WMEllipse : public virtual WMWidget {
+ protected:
+ virtual void draw_border(Color c1, Color c2, int nsteps);
+ virtual void draw_border();
+
+ public:
+ bool contains(int x, int y) const;
+
+ virtual ~WMEllipse() { }
+};
+
+#endif
diff --git a/wmapp/wmframe.cc b/wmapp/wmframe.cc
new file mode 100644
index 0000000..197e744
--- /dev/null
+++ b/wmapp/wmframe.cc
@@ -0,0 +1,303 @@
+#include <iostream>
+#include <cstdarg>
+#include "wmframe.h"
+#include "wmclickable.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMFrame -------------------------------------------------
+
+WMFrame::~WMFrame()
+{
+ if (wClipMask) {
+ WMApp::Xw.free_pixmap(*wClipMask);
+ delete wClipMask;
+ }
+}
+
+void
+WMFrame::real_display()
+{
+ if (border() || !transparency())
+ // fill frame with background color before adding children
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(Background));
+}
+
+void
+WMFrame::display()
+{
+ if (!(parent() && parent()->is_displayed())) return;
+ real_display();
+ setdisplayed(true);
+
+ X::GC old_gc = 0;
+ if (wClipMask) {
+ // keep children from drawing where they shouldn't
+ old_gc = window()->pixmap().gc;
+ window()->pixmap().gc = wClipMask->gc;
+ }
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->display();
+ if (wClipMask)
+ window()->pixmap().gc = old_gc;
+
+ draw_border();
+}
+
+void
+WMFrame::hide()
+{
+ if (!is_displayed()) return;
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->hide();
+ real_hide();
+ setdisplayed(false);
+}
+
+void
+WMFrame::activate()
+{
+ if (is_active()) return;
+ setactive(true);
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->activate();
+ real_activate();
+ if (app()->done()) return;
+ if (is_displayed()) display();
+}
+
+void
+WMFrame::deactivate()
+{
+ if (!is_active()) return;
+ real_deactivate();
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->deactivate();
+ setactive(false);
+ if (is_displayed()) display();
+}
+
+bool
+WMFrame::addchild(WMWidget *w)
+{
+ if (is_displayed()) return false;
+
+ // child cannot already have a parent
+ if (w->parent()) {
+ cerr << "WMError: Reparenting child widget " << w << " to " << this
+ << " not allowed" << endl;
+ return false;
+ }
+
+ // child cannot recursively contain "this"
+ const WMWidget *test = this;
+ while ((test = test->parent()))
+ if (test == w) {
+ cerr << "WMError: Widget " << w << " cannot be its own ancestor" << endl;
+ return false;
+ }
+
+ w->setparent(this);
+ wChildren.push_back(w);
+ return true;
+}
+
+bool
+WMFrame::removechild(WMWidget *w)
+{
+ if (is_displayed()) return false;
+ for (unsigned int i = 0; i < numchildren(); i++)
+ if (w == child(i)) {
+ child(i)->setparent(0);
+ wChildren.erase(wChildren.begin() + i);
+ return true;
+ }
+ cerr << "WMError: Widget " << w << " is not a child of " << this << endl;
+ return false;
+}
+
+void
+WMFrame::clip(char *xpm_array[65])
+{
+ if (! is_displayed()) setaspectratios();
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->clip(xpm_array);
+
+ if (! transparency() || border()) { // create a mask for drawing children
+ if (!wClipMask) {
+ wClipMask = new WMPixmap;
+ WMApp::Xw.create_pixmap(*wClipMask, xpm_array);
+ X::XFreePixmap(WMApp::Xw.xdisplay(), wClipMask->pixmap);
+ // free unused pixmap
+ wClipMask->pixmap = wClipMask->mask;
+ wClipMask->mask = 0; // muck around so xwrapper::free_pixmap works right
+ X::XSetClipMask(WMApp::Xw.xdisplay(), wClipMask->gc, wClipMask->pixmap);
+ }
+
+ for (int col = left(); col < right(); col++)
+ for (int row = top(); row < bottom(); row++)
+ xpm_array[row + 3][col] = contains(col, row) ? 'X' : ' ';
+ // clip in the whole frame on the window's mask, but don't let widgets
+ // draw outside the frame
+ }
+}
+
+bool
+WMFrame::press(int button, int x, int y)
+{
+ WMClickable *c;
+
+ if (!contains(x, y)) {
+ return false; // button pressed is not within this frame
+ }
+
+ for (unsigned int i = 0; i < numchildren(); i++)
+ if ((c = dynamic_cast<WMClickable *>(child(i))))
+ if (c->press(button, x, y)) return true;
+ return false;
+}
+
+// If the mouse button is released over the WMWidget on which it was
+// initially pressed, that widget's callbacks should be executed.
+bool
+WMFrame::release(int button, int x, int y)
+{
+ WMClickable *c;
+
+ for (unsigned int i = 0; i < numchildren(); i++)
+ if ((c = dynamic_cast<WMClickable *>(child(i))))
+ if (c->release(button, x, y)) return true;
+ return false;
+}
+
+// This function needs to be fixed to take care of leftover space if the
+// integer division wipes out a remainder.
+bool
+WMFrame::setaspectratios(vector<int> r)
+{
+ int totalspace = 0, availablespace;
+ if (wRatiosSet || numchildren() == 0) return true; // nothing to do
+
+ // if insufficient space to display any children, return an error
+ if (width() < 2 * border() || height() < 2 * border())
+ { cerr << "WMError: Frame " << this << " too small" << endl; return false; }
+
+ if (r.size() > 0) {
+ // Widgets that do not already have a size, for whom there is no
+ // corresponding element in the vector of size ratios, will be
+ // made size zero
+ while (r.size() < numchildren())
+ r.push_back(0);
+ }
+
+ // calculate total space consumed by widgets with known sizes
+ for (unsigned int i = 0; i < numchildren(); i++)
+ totalspace += child(i)->par_to_parent();
+ availablespace = b_parallel() - totalspace - (numchildren() - 1) * padding();
+
+ // If widgets of known size take up more space than the frame has,
+ // rescale them in proportion and do not display the other widgets.
+ if (availablespace < 1) {
+ int numgoodchildren = 0;
+ for (unsigned int i = 0; i < numchildren(); i++) {
+ if (child(i)->par_to_parent() > 0)
+ numgoodchildren++;
+ }
+ availablespace = b_parallel() - (numgoodchildren - 1) * padding();
+ if (availablespace < 1 || numgoodchildren == 0) {
+ // not enough space, even for only the known-size widgets
+ cerr << "WMError: Frame " << this << " too small" << endl;
+ return false;
+ }
+
+ for (unsigned int i = 0; i < numchildren(); i++) {
+ if (child(i)->par_to_parent() > 0) {
+ double ratio = child(i)->par_to_parent() / totalspace;
+ child(i)->set_par_to_parent(static_cast<int>
+ (ratio * availablespace));
+ }
+ }
+ }
+
+ else { // Otherwise, scale the unknown-sized widgets appropriately.
+ double ratiosum = 0;
+ for (unsigned int i = 0; i < numchildren(); i++) {
+ if (child(i)->par_to_parent() == 0)
+ ratiosum += ((r.size() > 0) ? r[i] : 1.0);
+ }
+ for (unsigned int i = 0; i < numchildren(); i++)
+ if (child(i)->par_to_parent() == 0) {
+ double ratio = (r.size() ? r[i] : 1.0) / ratiosum;
+ child(i)->set_par_to_parent(static_cast<int>
+ (ratio * availablespace));
+ }
+ }
+
+ // Scale widgets in the perpendicular direction if necessary
+ for (unsigned int i = 0; i < numchildren(); i++)
+ if (child(i)->perp_to_parent() <= 0
+ || child(i)->perp_to_parent() > b_perpend())
+ child(i)->set_perp_to_parent(b_perpend());
+
+ // Finally, set the location of all these child widgets.
+ int posn = 0;
+ for (unsigned int i = 0; i < numchildren(); i++) {
+ if (child(i)->width() && child(i)->height()) {
+ if (orientation() == Orientation::Horizontal) {
+ child(i)->setleft(b_left() + posn);
+ child(i)->settop(b_top());
+ }
+ else {
+ child(i)->setleft(b_left());
+ child(i)->settop(b_top() + posn);
+ }
+ posn += child(i)->par_to_parent() + padding();
+ }
+ }
+
+ // Deal with rounding errors: if the last widget doesn't reach all the
+ // way to the end of the parent, force it to. This isn't the best way
+ // to do this, but it's the easiest :)
+ if (child(numchildren() - 1)->par_to_parent()) {
+ WMWidget *lastchild = child(numchildren() - 1);
+ if (orientation() == Orientation::Horizontal)
+ lastchild->setwidth(right() - border() - lastchild->left());
+ else
+ lastchild->setheight(bottom() - border() - lastchild->top());
+ }
+
+ wRatiosSet = true;
+ return true;
+}
+
+// varargs version for people too lazy to create an std::vector.
+// Use with caution: the number of arguments MUST equal the number
+// of children, since we can't check the number of arguments of a
+// varargs function within the function. I'm not sure what happens
+// if you try to provide this function with fewer arguments than
+// the widget has children, but I imagine it's bad.
+bool
+WMFrame::setaspectratios(int ratio, ...)
+{
+ if (numchildren() < 1)
+ // nothing to do, return OK
+ return true;
+
+ std::va_list args;
+ vector<int> v = vector<int>();
+ v.push_back(ratio);
+
+ va_start(args, ratio);
+ for (unsigned int i = 1; i < numchildren(); i++) {
+ ratio = va_arg(args, int);
+ v.push_back(ratio);
+ }
+ va_end(args);
+
+ return setaspectratios(v);
+}
+
diff --git a/wmapp/wmframe.h b/wmapp/wmframe.h
new file mode 100644
index 0000000..977268b
--- /dev/null
+++ b/wmapp/wmframe.h
@@ -0,0 +1,109 @@
+#include <vector>
+#include "wmwidget.h"
+#include "wmclickable.h"
+#include "xwrapper.h"
+
+#ifndef _WMFRAME_H
+#define _WMFRAME_H
+
+using std::vector;
+
+// WMFrame: A widget that can contain other widgets
+class WMFrame : public virtual WMClickable, public virtual WMWidget {
+ private:
+ int wPadding;
+ bool wRatiosSet;
+ bool wTransparentPadding;
+ WMPixmap *wClipMask;
+
+ protected:
+ vector<WMWidget *> wChildren;
+ virtual void real_display();
+
+ public:
+ WMFrame();
+ virtual ~WMFrame();
+
+ WMWidget * child(int i) const;
+ unsigned int numchildren() const;
+ bool addchild(WMWidget &child);
+ bool addchild(WMWidget *child);
+ bool removechild(WMWidget &child);
+ bool removechild(WMWidget *child);
+
+ void clip(char *xpm_array[65]);
+ virtual void display();
+ virtual void hide();
+ virtual void activate();
+ virtual void deactivate();
+
+ int padding() const;
+ bool transparency() const;
+
+ void setpadding(int);
+ void settransparency(bool);
+
+ // what to do if a mouse button is pressed?
+ bool press(int button, int x, int y);
+ bool release(int button, int x, int y);
+
+ // NOTE: The setaspectratios() function must be called on frames / windows
+ // in order from Parent to Child widgets!
+ //
+ // if passed no argument, this function allots equal space to
+ // all child widgets that do not already have a declared size.
+ // Otherwise, it uses the vector or va_list it's passed as a list of how
+ // the widgets should be sized relative to each other. Note that even though
+ // widgets with non-zero sizes are not resized, the vector of sizes must
+ // contain dummy place-holder arguments for them anyway.
+ //
+ // For example, if the frame contains 4 widgets a,b,c,d, of which b already
+ // has a known (non-zero) size, and you call this function with argument
+ // being the vector (5,4,3), then widget a will be allotted 5/(5+3) = 5/8
+ // and widget c will be allotted 3/(5+3) = 3/8 of the space not already
+ // allotted to widget b. Widget d will not be displayed. On the other hand,
+ // if you call this function with no argument, then a, c, and d will EACH be
+ // allocated 1/3 of the space not already taken by widget b.
+ //
+ // This function, however it is called, will scale widgets to the
+ // perpendicular size of the frame if their perpendicular dimension is not
+ // known. If the perpendicular size of the widget IS known, it will be
+ // rescaled only if the widget is larger than the frame in that dimension.
+ bool setaspectratios(vector<int> ratiolist = vector<int>());
+
+ // a va_list version for people too lazy to create an std::vector:
+ bool setaspectratios(int ratio1, ...);
+};
+
+// inline functions for WMFrame ------------------------------------------
+
+inline WMFrame::WMFrame()
+: wPadding(2), wRatiosSet(false), wTransparentPadding(true), wClipMask(0),
+ wChildren() { setborder(0); }
+
+inline unsigned int
+WMFrame::numchildren() const { return wChildren.size(); }
+
+inline WMWidget *
+WMFrame::child(int i) const { return wChildren[i]; }
+
+inline bool
+WMFrame::addchild(WMWidget &child) { return addchild(&child); }
+
+inline bool
+WMFrame::removechild(WMWidget &child) { return removechild(&child); }
+
+inline int
+WMFrame::padding() const { return wPadding; }
+
+inline bool
+WMFrame::transparency() const { return wTransparentPadding; }
+
+inline void
+WMFrame::setpadding(int p) { if (!is_displayed()) wPadding = p; }
+
+inline void
+WMFrame::settransparency(bool b)
+{ if (!is_displayed()) wTransparentPadding = b; }
+
+#endif
diff --git a/wmapp/wmhistory.cc b/wmapp/wmhistory.cc
new file mode 100644
index 0000000..5900069
--- /dev/null
+++ b/wmapp/wmhistory.cc
@@ -0,0 +1,67 @@
+#include <iostream>
+#include "wmhistory.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMHistory -----------------------------------------------
+// added by Jason
+
+void WMHistory::setvalue (int value, int index, bool dodisplay)
+{
+ if (index == -1)
+ {
+ wValues.pop_back();
+ wValues.push_front(value);
+ }
+ else
+ wValues[index] = value;
+ if (dodisplay)
+ display();
+}
+
+void WMHistory::setvalues (const vector<int>& values, bool dodisplay)
+{
+ vector<int>::const_iterator src = values.begin();
+ deque<int>::iterator dest = wValues.begin();
+ while (src != values.end() && dest != wValues.end())
+ *dest++ = *src++;
+ while (dest != wValues.end())
+ *dest++ = 0;
+ if (dodisplay)
+ display();
+}
+
+void WMHistory::clear(bool dodisplay)
+{ setvalues(vector<int>(0), dodisplay); }
+
+void WMHistory::real_display ()
+// XXX: Currently no vertical style, since it doesn't make a lot of sense
+{
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(Background));
+ if (!wTotal)
+ return;
+ if (width() < 2 * border() || height() < 2 * border())
+ { cerr << "WMError: History " << this << " too small" << endl; return; }
+
+ for (int x = 0; x < b_width(); x++)
+ {
+ int h = static_cast<int> (fraction(x) * b_height());
+ if (h < 1)
+ continue;
+ else if (h == 1)
+ WMApp::Xw.draw_point(window()->pixmap(), b_right() - 1 - x, b_bottom() - 1
+ , WMColor(Bright));
+ else
+ {
+ WMApp::Xw.draw_line(window()->pixmap(), b_right() - 1 - x, b_bottom() - h,
+ b_right() - 1 - x, b_bottom() - h + 1, WMColor(Bright));
+ if (h > 2)
+ WMApp::Xw.draw_line(window()->pixmap(), b_right() - 1 - x, b_bottom() - h + 2, b_right() - 1 - x, b_bottom() - 1, WMColor(Medium));
+ }
+ }
+}
+
diff --git a/wmapp/wmhistory.h b/wmapp/wmhistory.h
new file mode 100644
index 0000000..cd7c4cc
--- /dev/null
+++ b/wmapp/wmhistory.h
@@ -0,0 +1,71 @@
+#include <vector>
+#include <deque>
+#include "wmwidget.h"
+
+#ifndef _WMHISTORY_H
+#define _WMHISTORY_H
+
+using std::vector;
+using std::deque;
+
+// WMHistory: a progress / load meter showing a history
+// added by Jason
+// XXX: Should we have an option to rescale the graph automatically?
+class WMHistory : public virtual WMWidget {
+ private:
+ static const int size = 64; //Number of values that we keep around
+ deque<int> wValues;
+ int wTotal;
+ void real_display();
+
+ public:
+ WMHistory();
+ WMHistory(int total);
+ WMHistory(const vector<int>& values, int total);
+ // XXX: Too lazy to make any other constructors.
+
+ // All indexed functions refer to the element added that many units ago.
+ // An index of -1 therefore appends a new value to the graph.
+ void setvalue(int value, int index = -1, bool dodisplay = true);
+
+ //setvalues zeros the history before copying the given values in.
+ void setvalues(const vector<int>& values, bool dodisplay = true);
+ void setvalues(const vector<int>& values, int total, bool dodisplay = true);
+ void clear(bool dodisplay = true);
+
+ void settotal(int total, bool dodisplay = true);
+
+ int value(int index = 0) const;
+ int total() const;
+ double fraction(int index = 0) const;
+};
+
+// inline functions for WMHistory ----------------------------------------
+
+inline WMHistory::WMHistory ()
+: wValues(WMHistory::size, 0), wTotal(0) { }
+
+inline WMHistory::WMHistory (int total)
+: wValues(WMHistory::size, 0), wTotal(total) { }
+
+inline WMHistory::WMHistory (const vector<int>& values, int total)
+: wValues(size), wTotal(total)
+{ setvalues(values, false); }
+
+inline void WMHistory::setvalues(const vector<int>& values, int total,
+ bool dodisplay)
+{ wTotal = total; setvalues(values, dodisplay); }
+
+inline void WMHistory::settotal (int total, bool dodisplay)
+{ wTotal = total; if (dodisplay) display(); }
+
+inline int WMHistory::value (int index) const
+{ return wValues[index]; }
+
+inline int WMHistory::total () const
+{ return wTotal; }
+
+inline double WMHistory::fraction (int index) const
+{ return static_cast<double>(wValues[index]) / wTotal; }
+
+#endif
diff --git a/wmapp/wmimage.cc b/wmapp/wmimage.cc
new file mode 100644
index 0000000..9d2b115
--- /dev/null
+++ b/wmapp/wmimage.cc
@@ -0,0 +1,91 @@
+#include <iostream>
+#include "wmimage.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMImage -------------------------------------------------
+
+WMImage::WMImage(const WMPixmap *pm)
+: wBGColor(WMColor(Background)) { seticon(pm); }
+
+WMImage::WMImage(const WMPixmap &pm)
+: wBGColor(WMColor(Background)) { seticon(pm); }
+
+WMImage::WMImage(char *xpm[])
+: wBGColor(WMColor(Background)) { seticon(xpm); }
+
+WMImage::~WMImage()
+{ if (icon()) WMApp::Xw.free_pixmap(wIcon); }
+
+void
+WMImage::seticon(bool dodisplay)
+{
+ if (icon()) WMApp::Xw.free_pixmap(wIcon);
+ if(WMApp::Xw.create_pixmap(wIcon, b_width(), b_height()))
+ {
+ WMApp::Xw.fill_rectangle(wIcon, 0, 0, b_width(), b_height(), bgcolor());
+ wIconPtr = &wIcon;
+ if (dodisplay) display();
+ }
+ else wIconPtr = 0;
+}
+
+void
+WMImage::seticon(const WMPixmap &pm, bool dodisplay)
+{
+ if (icon()) WMApp::Xw.free_pixmap(wIcon);
+ if (WMApp::Xw.create_pixmap(wIcon, pm))
+ { wIconPtr = &wIcon; if (dodisplay) display(); }
+ else wIconPtr = 0;
+}
+
+void
+WMImage::seticon(char *xpm[], bool dodisplay)
+{
+ if (icon()) WMApp::Xw.free_pixmap(wIcon);
+ if (WMApp::Xw.create_pixmap(wIcon, xpm))
+ { wIconPtr = &wIcon; if (dodisplay) display(); }
+ else wIconPtr = 0;
+}
+
+void
+WMImage::real_display()
+{
+ const int imgwidth = icon() ? icon()->attr.width : 0;
+ const int imgheight = icon() ? icon()->attr.height : 0;
+
+ // if no icon, create an icon that consists only of the background color
+ if (! icon())
+ seticon(false);
+
+ // if widget is not big enough to hold icon, complain about it
+ else if (imgwidth > b_width() || imgheight > b_height()) {
+ cerr << "WMError: Image " << this << " too small for icon" << endl;
+ return;
+ }
+
+ // if icon is smaller than widget, color in the rest with background color
+ else if (imgwidth < b_width() || imgheight < b_height()) {
+ WMPixmap temp;
+
+ // Blit background color onto rectangle
+ WMApp::Xw.create_pixmap(temp, b_width(), b_height());
+ WMApp::Xw.fill_rectangle(temp, 0, 0, b_width(), b_height(), bgcolor());
+ // center icon onto background
+ WMApp::Xw.copy_rectangle(*icon(), temp, 0, 0, imgwidth, imgheight,
+ (b_width() - imgwidth) / 2, (b_height() - imgheight) / 2);
+ // swap pixmaps
+ WMApp::Xw.free_pixmap(wIcon);
+ WMApp::Xw.create_pixmap(wIcon, temp);
+ WMApp::Xw.free_pixmap(temp);
+ }
+
+ // if we get here, widget (minus border) and icon are the same size -
+ // hallelujah!
+ WMApp::Xw.copy_rectangle(*icon(), window()->pixmap(), 0, 0,
+ b_width(), b_height(), b_left(), b_top());
+}
+
diff --git a/wmapp/wmimage.h b/wmapp/wmimage.h
new file mode 100644
index 0000000..899c31f
--- /dev/null
+++ b/wmapp/wmimage.h
@@ -0,0 +1,52 @@
+#include "wmwidget.h"
+#include "xwrapper.h"
+
+#ifndef _WMIMAGE_H
+#define _WMIMAGE_H
+
+// WMImage: a widget that displays a picture in Xpm format
+class WMImage : public virtual WMWidget {
+ private:
+ WMPixmap wIcon;
+ WMPixmap * wIconPtr;
+
+ protected:
+ Color wBGColor;
+ virtual void real_display();
+ WMPixmap * p_icon();
+
+ public:
+ WMImage(const WMPixmap * pm = 0);
+ WMImage(const WMPixmap & pm);
+ WMImage(char *xpm[]);
+ virtual ~WMImage();
+
+ void seticon(bool dodisplay = true); //make an empty icon
+ void seticon(const WMPixmap *, bool dodisplay = true);
+ void seticon(const WMPixmap &, bool dodisplay = true);
+ void seticon(char *xpm[], bool dodisplay = true);
+ void setbgcolor(Color, bool dodisplay = true);
+ Color bgcolor() const;
+ const WMPixmap * icon() const;
+};
+
+// inline functions for WMImage ------------------------------------------
+
+inline void
+WMImage::seticon(const WMPixmap *pm, bool dodisplay)
+{ if (pm) seticon(*pm, dodisplay); else wIconPtr = 0; }
+
+inline void
+WMImage::setbgcolor(Color c, bool dodisplay)
+{ wBGColor = c; if (dodisplay) display(); }
+
+inline Color
+WMImage::bgcolor() const { return wBGColor; }
+
+inline WMPixmap *
+WMImage::p_icon() { return wIconPtr; }
+
+inline const WMPixmap *
+WMImage::icon() const { return wIconPtr; }
+
+#endif
diff --git a/wmapp/wmled.cc b/wmapp/wmled.cc
new file mode 100644
index 0000000..4c08b2a
--- /dev/null
+++ b/wmapp/wmled.cc
@@ -0,0 +1,12 @@
+#include "wmled.h"
+#include "wmapp.h"
+
+// functions for WMLed ---------------------------------------------------
+
+void
+WMLed::real_display()
+{
+ seticon(WMApp::leds_pixmap[static_cast<int>(led())], false);
+ if (icon()) WMImage::real_display();
+}
+
diff --git a/wmapp/wmled.h b/wmapp/wmled.h
new file mode 100644
index 0000000..5cf71de
--- /dev/null
+++ b/wmapp/wmled.h
@@ -0,0 +1,34 @@
+#include "wmimage.h"
+
+#ifndef _WMLED_H
+#define _WMLED_H
+
+// WMLed: displays a round LED-type thing with a different color depending on
+// its status.
+class WMLed : public virtual WMImage {
+ public:
+ enum LedState { Off, Good, Warning, Error };
+
+ private:
+ enum LedState wState;
+ void real_display();
+
+ public:
+ WMLed(LedState s = Off);
+ void setled(enum LedState s, bool dodisplay = true);
+ enum LedState led() const;
+};
+
+// inline functions for WMLed --------------------------------------------
+
+inline WMLed::WMLed(enum LedState s)
+: wState(s) { setborder(0); }
+
+inline void
+WMLed::setled(enum LedState s, bool dodisplay)
+{ wState = s; if (dodisplay) display(); }
+
+inline enum WMLed::LedState
+WMLed::led() const { return wState; }
+
+#endif
diff --git a/wmapp/wmmeter.h b/wmapp/wmmeter.h
new file mode 100644
index 0000000..0239781
--- /dev/null
+++ b/wmapp/wmmeter.h
@@ -0,0 +1,57 @@
+#include "wmwidget.h"
+
+#ifndef _WMMETER_H
+#define _WMMETER_H
+
+// WMMeter: Base class for widgets that display a state of progress or load.
+// Cannot be instantiated (inherits the pure virtual function real_display).
+class WMMeter : public virtual WMWidget {
+ private:
+ int wValue, wTotal;
+
+ public:
+ WMMeter();
+ WMMeter(int total);
+ WMMeter(int value, int total);
+
+ virtual void setvalue(int value, bool dodisplay = true);
+ virtual void settotal(int total, bool dodisplay = true);
+
+ int value() const;
+ int total() const;
+ double fraction() const;
+};
+
+// inline functions for WMMeter ------------------------------------------
+
+inline WMMeter::WMMeter()
+: wValue(0), wTotal(0) { }
+
+inline WMMeter::WMMeter(int total)
+: wValue(0), wTotal(total) { }
+
+inline WMMeter::WMMeter(int val, int total)
+: wValue(val), wTotal(total) { }
+
+inline void
+WMMeter::setvalue(int val, bool dodisplay)
+{ wValue = val; if (dodisplay) display(); }
+
+inline void
+WMMeter::settotal(int total, bool dodisplay)
+{ wTotal = total; if (dodisplay) display(); }
+
+inline int
+WMMeter::value() const { return wValue; }
+
+inline int
+WMMeter::total() const { return wTotal; }
+
+inline double
+WMMeter::fraction() const
+{
+ if (wTotal == 0) return 0;
+ else return static_cast<double>(wValue) / wTotal;
+}
+
+#endif
diff --git a/wmapp/wmmeterbar.cc b/wmapp/wmmeterbar.cc
new file mode 100644
index 0000000..2ec6dfd
--- /dev/null
+++ b/wmapp/wmmeterbar.cc
@@ -0,0 +1,80 @@
+#include <iostream>
+#include <algorithm> // for max()
+#include "wmmeterbar.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMMeterBar ----------------------------------------------
+// added by Jason
+
+void
+WMMeterBar::real_display()
+{
+ if ((orientation() == Orientation::Horizontal && width() < 2 * border())
+ || (orientation() == Orientation::Vertical && height() < 2 * border()))
+ { cerr << "WMError: Meter Bar " << this << " too small" << endl; return; }
+
+ //first draw desired background
+ switch (style())
+ {
+ case Spectrum:
+ if (orientation() == Orientation::Horizontal)
+ WMApp::Xw.draw_horizontal_gradient(window()->pixmap(),
+ b_left(), b_top(), b_right(), b_bottom(), 0x5C00, 0x5C0000);
+ else
+ WMApp::Xw.draw_vertical_gradient(window()->pixmap(),
+ b_left(), b_top(), b_right(), b_bottom(), 0x5C0000, 0x5C00);
+ break;
+ case Spec_No_BG:
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(Background));
+ break;
+ case Blue:
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(Background));
+ if (orientation() == Orientation::Horizontal)
+ for (int x = 0; x < b_width(); x += 2)
+ WMApp::Xw.draw_line(window()->pixmap(), x + b_left(), b_top(),
+ x + b_left(), b_bottom(), 0x004941);
+ else
+ for (int y = 0; y < b_height(); y += 2)
+ WMApp::Xw.draw_line(window()->pixmap(), b_left(),
+ b_bottom() - y, b_right(), b_bottom() - y, 0x004941);
+ break;
+ }
+
+ //then draw the progress bar
+ if (total() && value())
+ switch (style())
+ {
+ case Spectrum:
+ case Spec_No_BG:
+ if (orientation() == Orientation::Horizontal)
+ WMApp::Xw.draw_horizontal_gradient(window()->pixmap(),
+ b_left(), b_top(), b_right(), b_bottom(),
+ 0xFF00, 0xFF0000, fraction());
+ else
+ WMApp::Xw.draw_vertical_gradient(window()->pixmap(),
+ b_left(), b_bottom(), b_right(), b_top(),
+ 0xFF00, 0xFF0000, fraction());
+ break;
+ case Blue:
+ if (orientation() == Orientation::Horizontal)
+ for (int x = 0;
+ x < static_cast<int>(std::min(1.0, fraction()) * b_width());
+ x += 2)
+ WMApp::Xw.draw_line(window()->pixmap(), x + b_left(), b_top(),
+ x + b_left(), b_bottom(), WMColor(Bright));
+ else
+ for (int y = 0;
+ y < static_cast<int>(std::min(1.0, fraction()) * b_height());
+ y += 2)
+ WMApp::Xw.draw_line(window()->pixmap(), b_left(), b_bottom() - y,
+ b_right(), b_bottom() - y, WMColor(Bright));
+ break;
+ }
+}
+
diff --git a/wmapp/wmmeterbar.h b/wmapp/wmmeterbar.h
new file mode 100644
index 0000000..00a4c0e
--- /dev/null
+++ b/wmapp/wmmeterbar.h
@@ -0,0 +1,47 @@
+#include "wmmeter.h"
+
+#ifndef _WMMETERBAR_H
+#define _WMMETERBAR_H
+
+// WMMeterBar: a progress bar showing the instantaneous progress or load
+// added by Jason
+class WMMeterBar : public virtual WMMeter {
+ public:
+ // The styles correspond to those in wmmon, wmtop, and wmsmixer respectively:
+ // green-to-red bar on dark green-to-red background; likewise on dark
+ // colorless background; and turquoise hashmarks on dark background.
+ enum Style { Spectrum, Spec_No_BG, Blue };
+
+ private:
+ enum Style wStyle;
+
+ protected:
+ void real_display();
+
+ public:
+ WMMeterBar();
+ WMMeterBar(int total);
+ WMMeterBar(int value, int total);
+
+ void setstyle(enum Style, bool dodisplay = true);
+ enum Style style() const;
+};
+
+// inline functions for WMMeterBar ---------------------------------------
+
+inline WMMeterBar::WMMeterBar() : WMMeter() { }
+
+inline WMMeterBar::WMMeterBar(int total) : WMMeter()
+{ settotal(total); }
+
+inline WMMeterBar::WMMeterBar(int val, int total) : WMMeter()
+{ settotal(total); setvalue(val); }
+
+inline void
+WMMeterBar::setstyle(enum Style s, bool dodisplay)
+{ wStyle = s; if (dodisplay) display(); }
+
+inline enum WMMeterBar::Style
+WMMeterBar::style() const { return wStyle; }
+
+#endif
diff --git a/wmapp/wmslider.cc b/wmapp/wmslider.cc
new file mode 100644
index 0000000..e73fd1e
--- /dev/null
+++ b/wmapp/wmslider.cc
@@ -0,0 +1,42 @@
+#include <algorithm> // for max, min
+#include "wmslider.h"
+#include "wmapp.h"
+
+void slider_click(const WMApp *a, WMWidget *w, void *)
+{
+ WMSlider *s;
+ if (!(s = dynamic_cast<WMSlider *>(w))) return;
+
+ const WMMouseClick click = a->mouseclick().b_relative_to(w);
+ int newval;
+
+ if (click.button > Button3) {
+ const int increment = s->total() / 10;
+ newval = s->value() + (click.button == Button4 ? increment : -increment);
+ }
+ else {
+ const int xrel = click.x;
+ // the messy definition of yrel is due to widget layout using a downward-
+ // going y-axis, but WMMeterBars using an upward-going y-axis
+ const int yrel = s->b_height() - click.y;
+ const int rel = (s->orientation() == Orientation::Horizontal) ? xrel : yrel;
+ newval = (rel * s->total()) / s->b_parallel();
+ }
+
+ s->setvalue(std::max(0, std::min(s->total(), newval)));
+ a->repaint();
+}
+
+void
+WMSlider::attach_callbacks()
+{
+ addcallback(slider_click, this, 0);
+}
+
+// clearcallbacks() shouldn't delete the main callback function of this class
+void
+WMSlider::clearcallbacks()
+{
+ WMCallback::clearcallbacks();
+ WMSlider::attach_callbacks();
+}
diff --git a/wmapp/wmslider.h b/wmapp/wmslider.h
new file mode 100644
index 0000000..a706f1c
--- /dev/null
+++ b/wmapp/wmslider.h
@@ -0,0 +1,32 @@
+#include "wmcallback.h"
+#include "wmmeterbar.h"
+
+#ifndef _WMSLIDER_H
+#define _WMSLIDER_H
+
+// WMSlider: a bar that can be slid up or down to set a value.
+// Derived from WMMeterBar and WMCallback.
+class WMSlider : public WMCallback, public WMMeterBar {
+ private:
+ void attach_callbacks();
+
+ public:
+ WMSlider();
+ WMSlider(int total);
+ WMSlider(int value, int total);
+
+ void clearcallbacks();
+};
+
+inline WMSlider::WMSlider()
+{ setstyle(Blue, false); attach_callbacks(); }
+
+inline WMSlider::WMSlider(int total)
+: WMMeterBar(total)
+{ setstyle(Blue, false); attach_callbacks(); }
+
+inline WMSlider::WMSlider(int value, int total)
+: WMMeterBar(value, total)
+{ setstyle(Blue, false); attach_callbacks(); }
+
+#endif
diff --git a/wmapp/wmtextbar.cc b/wmapp/wmtextbar.cc
new file mode 100644
index 0000000..7cb9ec3
--- /dev/null
+++ b/wmapp/wmtextbar.cc
@@ -0,0 +1,63 @@
+#include <iostream>
+#include "wmtextbar.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMTextBar -----------------------------------------------
+
+void
+WMTextBar::real_display()
+{
+ int charwidth, charheight, xbase, ybase;
+
+ // Blit background color onto rectangle
+ WMApp::Xw.fill_rectangle(window()->pixmap(), b_position(),
+ WMColor(Background));
+
+ switch (fontsize()) {
+ case 0: charwidth = 5, charheight = 9; break;
+ case 1: charwidth = 6, charheight = 9; break;
+ case 2: charwidth = 7, charheight = 11; break;
+ default:
+ cerr << "WMError: Text bar " << this << " has bad font size "
+ << fontsize() << endl;
+ return;
+ }
+
+ if (b_width() < charwidth || b_height() < charheight)
+ { cerr << "WMError: Text bar " << this << " too small" << endl; return; }
+
+ xbase = b_left(), ybase = b_top();
+ // center the characters in the direction perpendicular to their orientation
+ if (orientation() == Orientation::Horizontal)
+ ybase += (b_height() - charheight) / 2;
+ else
+ xbase += (b_width() - charwidth) / 2;
+
+ // plot characters onto X display
+ for (unsigned int i = 0; xbase + charwidth < b_right()
+ && ybase + charheight < b_bottom(); i++) {
+ unsigned char c = text(i);
+ if (c > ' ' && c <= 127) // 7-bit printable ASCII
+ // note: for a degree character, use ASCII 127 (DEL)
+ WMApp::Xw.copy_rectangle(app()->char_pixmaps[fontsize()],
+ window()->pixmap(),
+ /* source X-Y coords */ charwidth * (c % 16), charheight * (c / 16 - 2),
+ /* source width/height*/ charwidth, charheight,
+ /* destination coords */ xbase, ybase);
+ else
+ // no pixmap for this character; display a blank.
+ WMApp::Xw.copy_rectangle(app()->char_pixmaps[fontsize()],
+ window()->pixmap(), 0, 0,
+ charwidth, charheight, xbase, ybase);
+
+ if (orientation() == Orientation::Horizontal)
+ xbase += charwidth;
+ else
+ ybase += charheight;
+ }
+}
+
diff --git a/wmapp/wmtextbar.h b/wmapp/wmtextbar.h
new file mode 100644
index 0000000..9e0307b
--- /dev/null
+++ b/wmapp/wmtextbar.h
@@ -0,0 +1,57 @@
+#include "wmwidget.h"
+#include <string>
+
+#ifndef _WMTEXTBAR_H
+#define _WMTEXTBAR_H
+
+using std::string;
+
+// WMTextBar: a place to draw text in.
+class WMTextBar : public virtual WMWidget {
+ private:
+ string wText;
+ int wFontsize;
+ void real_display();
+
+ public:
+ WMTextBar(const string & text = "", int fontsize = 1);
+ ~WMTextBar();
+
+ void settext(const string & text, bool dodisplay = true);
+ void setfont(int fontsize, bool dodisplay = true);
+ const string & text() const;
+ char text(unsigned int) const;
+ int fontsize() const;
+ int size() const;
+};
+
+// inline functions for WMTextBar ----------------------------------------
+
+inline WMTextBar::WMTextBar(const string &text, int fontsize)
+: wText(text), wFontsize(fontsize)
+{ }
+
+inline WMTextBar::~WMTextBar() { }
+
+inline void
+WMTextBar::settext(const string &text, bool dodisplay)
+{ wText = text; if (dodisplay) display(); }
+
+inline void
+WMTextBar::setfont(int fontsize, bool dodisplay)
+{ wFontsize = fontsize; if (dodisplay) display(); }
+
+inline const string &
+WMTextBar::text() const { return wText; }
+
+inline char
+WMTextBar::text(unsigned int posn) const
+{ return (posn >= wText.size()) ? ' ' : wText[posn]; }
+
+inline int
+WMTextBar::fontsize() const { return wFontsize; }
+
+inline int
+WMTextBar::size() const { return wText.size(); }
+
+#endif
diff --git a/wmapp/wmwidget.cc b/wmapp/wmwidget.cc
new file mode 100644
index 0000000..14c8bc3
--- /dev/null
+++ b/wmapp/wmwidget.cc
@@ -0,0 +1,99 @@
+#include "wmwidget.h"
+#include "wmwindow.h"
+#include "wmapp.h"
+
+// functions for WMWidget ------------------------------------------------
+
+WMWidget::WMWidget(const WMRectangle &posn, Orientation::Orientation o)
+: wOrientation(o), wPosition(posn), wBorder(1),
+ wTopLeft(WMColor(FrameBorderDim)), wBottomRight(WMColor(FrameBorderBright)),
+ wParent(0), wDisplayed(false), wActive(true)
+{ }
+
+int
+WMWidget::par_to_parent() const
+{
+ if (!parent()) return -1;
+ return (parent()->orientation() == Orientation::Horizontal) ?
+ position().width() : position().height();
+}
+
+int
+WMWidget::perp_to_parent() const
+{
+ if (!parent()) return -1;
+ return (parent()->orientation() == Orientation::Horizontal) ?
+ position().height() : position().width();
+}
+
+void
+WMWidget::set_par_to_parent(int p)
+{
+ if (wParent && !wDisplayed)
+ ((wParent->wOrientation == Orientation::Horizontal) ?
+ wPosition.setwidth(p) : wPosition.setheight(p));
+}
+
+void
+WMWidget::set_perp_to_parent(int p)
+{
+ if (wParent && !wDisplayed)
+ ((wParent->wOrientation == Orientation::Horizontal) ?
+ wPosition.setheight(p) : wPosition.setwidth(p));
+}
+
+const WMWindow *
+WMWidget::window() const { return wParent ? wParent->window() : 0; }
+
+WMApp *
+WMWidget::app() const { return wParent ? wParent->app() : 0; }
+
+void
+WMWidget::display()
+{
+ if (!(parent() && parent()->is_displayed())) return;
+ real_display();
+ draw_border();
+ setdisplayed(true);
+}
+
+void
+WMWidget::draw_border()
+{
+ if (border() && 2 * border() < width() && 2 * border() < height())
+ WMApp::Xw.draw_border(window()->pixmap(), position(), border(),
+ top_left_c(), bottom_right_c(),
+ Color::alpha_blend(top_left_c(), bottom_right_c(),
+ 0.5));
+}
+
+void
+WMWidget::hide()
+{
+ if (!is_displayed()) return;
+ real_hide();
+ setdisplayed(false);
+}
+
+void
+WMWidget::activate()
+{
+ if (is_active()) return;
+ real_activate();
+ setactive(true);
+ if (is_displayed()) display();
+}
+
+void
+WMWidget::deactivate()
+{
+ if (!is_active()) return;
+ real_deactivate();
+ setactive(false);
+ if (is_displayed()) display();
+}
+
+void
+WMWidget::real_hide()
+{ if (window()) WMApp::Xw.clear_rectangle(window()->pixmap(), position()); }
+
diff --git a/wmapp/wmwidget.h b/wmapp/wmwidget.h
new file mode 100644
index 0000000..38213e0
--- /dev/null
+++ b/wmapp/wmwidget.h
@@ -0,0 +1,367 @@
+#include "colors.h"
+
+#ifndef _WMWIDGET_H
+#define _WMWIDGET_H
+
+// needed forward declarations
+class WMApp;
+class WMWindow;
+class WMFrame;
+
+// Classes for writing complicated WindowMaker Dockapp programs! Yaay!
+// Note: I'm lazy, so ALL LAYOUT has to be done statically before the
+// WMApp starts to run.
+
+namespace Orientation {
+ enum Orientation { Horizontal, Vertical };
+};
+
+class WMRectangle {
+ private:
+ int wLeft, wTop, wWidth, wHeight;
+ public:
+ WMRectangle(int Left = 0, int Top = 0, int Width = 0, int Height = 0);
+ WMRectangle(const WMRectangle &r);
+ WMRectangle & operator = (const WMRectangle &r);
+ ~WMRectangle();
+
+ int left() const;
+ int right() const;
+ int top() const;
+ int bottom() const;
+ int width() const;
+ int height() const;
+ bool contains(int x, int y) const;
+
+ void setleft(int);
+ void settop(int);
+ void setwidth(int);
+ void setheight(int);
+};
+
+// WMWidget: the base class for all Dockapp widgets. Cannot be instantiated.
+class WMWidget {
+ private:
+ enum Orientation::Orientation wOrientation;
+ WMRectangle wPosition;
+ int wBorder;
+ Color wTopLeft, wBottomRight;
+ const WMFrame * wParent;
+ bool wDisplayed;
+ bool wActive;
+
+ protected:
+ // these functions do the actual work of displaying a widget.
+ virtual void real_display() = 0;
+ virtual void draw_border();
+ virtual void real_hide();
+
+ // colors for border of widget
+ Color top_left_c() const;
+ Color bottom_right_c() const;
+ void set_top_left_c(const Color & c);
+ void set_bottom_right_c(const Color & c);
+
+ virtual void real_activate() { } // these will be no-ops except
+ virtual void real_deactivate() { } // for clickable widgets
+
+ void setactive(bool);
+ void setdisplayed(bool);
+
+ public:
+ WMWidget(const WMRectangle &layout = WMRectangle(0, 0, 0, 0),
+ Orientation::Orientation o = Orientation::Horizontal);
+ virtual ~WMWidget();
+
+ virtual WMApp *app() const;
+ virtual const WMWindow *window() const;
+ virtual const WMFrame *parent() const;
+ virtual void setparent(const WMFrame *); // should be protected, but then
+ virtual void setparent(const WMFrame &); // WMFrame can't use on children
+ virtual void clip(char *xpm_array[65]);
+
+ virtual void setposition(const WMRectangle &posn);
+ void setorientation(Orientation::Orientation o);
+
+ // these functions do all the busywork of displaying a widget.
+ virtual void display(); // over-ridden by WMFrame
+ virtual void hide(); // in order to act recursively
+ virtual void activate(); // on all child widgets
+ virtual void deactivate(); //
+
+ const WMRectangle & position() const;
+ enum Orientation::Orientation orientation() const;
+ virtual bool contains(int x, int y) const;
+
+ int top() const;
+ int left() const;
+ int bottom() const;
+ int right() const;
+ int border() const;
+
+ int width() const;
+ int height() const;
+ int parallel() const; // dimension parallel to orientation
+ int perpend() const; // dimension perpendicular to orientation
+ int par_to_parent() const; // dimension parallel to parent's orientation
+ int perp_to_parent() const; // dimension perp. to parent's orientation
+
+ // like above, but only considering the part of the widget INSIDE its border
+ WMRectangle b_position() const;
+ int b_top() const;
+ int b_left() const;
+ int b_bottom() const;
+ int b_right() const;
+ int b_width() const;
+ int b_height() const;
+ int b_parallel() const;
+ int b_perpend() const;
+ int b_par_to_parent() const;
+ int b_perp_to_parent() const;
+
+ // "set" accessor functions
+ void settop(int);
+ void setleft(int);
+ void setborder(int);
+
+ void setwidth(int);
+ void setheight(int);
+ void setparallel(int);
+ void setperpend(int);
+ void set_par_to_parent(int);
+ void set_perp_to_parent(int);
+
+ bool is_displayed() const;
+ bool is_active() const;
+};
+
+
+// inline functions for WMRectangle --------------------------------------
+
+inline WMRectangle::WMRectangle(int Left, int Top, int Width, int Height)
+: wLeft(Left), wTop(Top), wWidth(Width), wHeight(Height)
+{ }
+
+inline WMRectangle::WMRectangle(const WMRectangle &r)
+: wLeft(r.wLeft), wTop(r.wTop), wWidth(r.wWidth), wHeight(r.wHeight)
+{ }
+
+inline WMRectangle::~WMRectangle() { }
+
+inline WMRectangle &
+WMRectangle::operator = (const WMRectangle &r)
+{
+ wLeft = r.wLeft, wTop = r.wTop, wWidth = r.wWidth, wHeight = r.wHeight;
+ return *this;
+}
+
+inline int
+WMRectangle::left() const { return wLeft; }
+
+inline int
+WMRectangle::right() const { return wLeft + wWidth; }
+
+inline int
+WMRectangle::top() const { return wTop; }
+
+inline int
+WMRectangle::bottom() const { return wTop + wHeight; }
+
+inline int
+WMRectangle::width() const { return wWidth; }
+
+inline int
+WMRectangle::height() const { return wHeight; }
+
+inline void
+WMRectangle::setleft(int l) { wLeft = l; }
+
+inline void
+WMRectangle::settop(int t) { wTop = t; }
+
+inline void
+WMRectangle::setwidth(int w) { wWidth = w; }
+
+inline void
+WMRectangle::setheight(int h) { wHeight = h; }
+
+inline bool
+WMRectangle::contains(int x, int y) const
+{ return x >= left() && x < right() && y >= top() && y < bottom(); }
+
+// inline functions for WMWidget -----------------------------------------
+
+inline WMWidget::~WMWidget() { }
+
+inline const WMFrame *
+WMWidget::parent() const { return wParent; }
+
+inline void
+WMWidget::clip(char *xpm_array[65])
+{
+ for (int col = left(); col < right(); col++)
+ for (int row = top(); row < bottom(); row++)
+ if (contains(col, row))
+ xpm_array[row + 3][col] = 'X';
+}
+
+inline void
+WMWidget::setparent(const WMFrame *f) { wParent = f; }
+
+inline void
+WMWidget::setparent(const WMFrame &f) { wParent = &f; }
+
+inline void
+WMWidget::setactive(bool b) { wActive = b; }
+
+inline void
+WMWidget::setdisplayed(bool b) { wDisplayed = b; }
+
+inline Color
+WMWidget::top_left_c() const { return wTopLeft; }
+
+inline Color
+WMWidget::bottom_right_c() const { return wBottomRight; }
+
+inline void
+WMWidget::set_top_left_c(const Color & c) { wTopLeft = c; }
+
+inline void
+WMWidget::set_bottom_right_c(const Color & c) { wBottomRight = c; }
+
+inline void
+WMWidget::setposition(const WMRectangle &posn)
+{ if (!wDisplayed) wPosition = posn; }
+
+inline void
+WMWidget::setorientation(Orientation::Orientation o)
+{ if (!wDisplayed) wOrientation = o; }
+
+inline const WMRectangle &
+WMWidget::position() const { return wPosition; }
+
+inline enum Orientation::Orientation
+WMWidget::orientation() const { return wOrientation; }
+
+inline bool
+WMWidget::contains(int x, int y) const { return position().contains(x, y); }
+
+inline int
+WMWidget::top() const { return position().top(); }
+
+inline int
+WMWidget::left() const { return position().left(); }
+
+inline int
+WMWidget::bottom() const { return position().bottom(); }
+
+inline int
+WMWidget::right() const { return position().right(); }
+
+inline int
+WMWidget::border() const { return wBorder; }
+
+inline int
+WMWidget::width() const { return position().width(); }
+
+inline int
+WMWidget::height() const { return position().height(); }
+
+inline int
+WMWidget::parallel() const
+{
+ return (orientation() == Orientation::Horizontal) ?
+ position().width() : position().height();
+}
+
+inline int
+WMWidget::perpend() const
+{
+ return (orientation() == Orientation::Horizontal) ?
+ position().height() : position().width();
+}
+
+// like above, but only considering the part of the widget INSIDE its border:
+
+inline WMRectangle
+WMWidget::b_position() const
+{
+ return WMRectangle(left() + border(), top() + border(),
+ width() - 2 * border(), height() - 2 * border());
+}
+
+inline int
+WMWidget::b_top() const { return top() + border(); }
+
+inline int
+WMWidget::b_left() const { return left() + border(); }
+
+inline int
+WMWidget::b_bottom() const { return bottom() - border(); }
+
+inline int
+WMWidget::b_right() const { return right() - border(); }
+
+inline int
+WMWidget::b_width() const { return width() - 2 * border(); }
+
+inline int
+WMWidget::b_height() const { return height() - 2 * border(); }
+
+inline int
+WMWidget::b_parallel() const { return parallel() - 2 * border(); }
+
+inline int
+WMWidget::b_perpend() const { return perpend() - 2 * border(); }
+
+inline int
+WMWidget::b_par_to_parent() const { return par_to_parent() - 2 * border(); }
+
+inline int
+WMWidget::b_perp_to_parent() const { return perp_to_parent() - 2 * border(); }
+
+// "set" accessor functions:
+
+inline void
+WMWidget::setwidth(int w)
+{ if (!wDisplayed) wPosition.setwidth(w); }
+
+inline void
+WMWidget::setheight(int h)
+{ if (!wDisplayed) wPosition.setheight(h); }
+
+inline void
+WMWidget::settop(int t)
+{ if (!wDisplayed) wPosition.settop(t); }
+
+inline void
+WMWidget::setleft(int l)
+{ if (!wDisplayed) wPosition.setleft(l); }
+
+inline void
+WMWidget::setborder(int b)
+{ if (!wDisplayed) wBorder = b; }
+
+inline void
+WMWidget::setparallel(int p)
+{
+ if (!wDisplayed)
+ ((wOrientation == Orientation::Horizontal) ?
+ wPosition.setwidth(p) : wPosition.setheight(p));
+}
+
+inline void
+WMWidget::setperpend(int p)
+{
+ if (!wDisplayed)
+ ((wOrientation == Orientation::Horizontal) ?
+ wPosition.setheight(p) : wPosition.setwidth(p));
+}
+
+inline bool
+WMWidget::is_displayed() const { return wDisplayed; }
+
+inline bool
+WMWidget::is_active() const { return wActive; }
+
+#endif
diff --git a/wmapp/wmwindow.cc b/wmapp/wmwindow.cc
new file mode 100644
index 0000000..71a7e98
--- /dev/null
+++ b/wmapp/wmwindow.cc
@@ -0,0 +1,114 @@
+#include <iostream>
+#include "wmwindow.h"
+#include "wmapp.h"
+
+using std::cerr;
+using std::endl;
+
+// functions for WMWindow ------------------------------------------------
+
+// this is here instead of inlined due to dependency on WMApp
+WMWindow::WMWindow()
+: WMFrame(), wApp(0), wUpdateFreq(10 /* milliseconds */),
+ wCounter(0), wFuncPeriod()
+{
+ setpadding(2);
+ setborder(0);
+
+ pixmap().pixmap = 0;
+ //use this as a flag determining whether the pixmaps are initialized
+
+ int offset = WMApp::size() / 2 - 28;
+ setposition(WMRectangle(offset, offset, 56, 56));
+}
+
+WMWindow::~WMWindow ()
+{
+ if (pixmap().pixmap) { //only free if it was actually allocated
+ WMApp::Xw.free_pixmap(pixmap());
+ }
+}
+
+void
+WMWindow::run_timed_functions()
+{
+ for (unsigned int i = 0; i < numcallbacks(); i++)
+ if (! (wCounter % wFuncPeriod[i])) {
+ runcallback(i);
+ }
+ wCounter++;
+}
+
+void
+WMWindow::initpixmaps()
+{
+ // Xlib has no facility to create a mask on the fly from an xpm (at least
+ // not that I know about), so we have to do it the hard way, initializing a
+ // mask from a char* array:
+
+ char *mask_xpm[67];
+ for (unsigned int i = 0; i < 67; i++)
+ mask_xpm[i] = new char[65];
+
+ strcpy(mask_xpm[0], "64 64 2 1"); // width, height, #colors, (?)
+ strcpy(mask_xpm[1], " c None"); // transparent
+ strcpy(mask_xpm[2], "X c #000000"); // black
+ for (unsigned int i = 3; i < 67; i++)
+ strcpy(mask_xpm[i], // string with 64 spaces --v
+ " ");
+ // 0123456789012345678901234567890123456789012345678901234567890123
+ // 1 2 3 4 5 6
+
+ // now mask out where we want to display things
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->clip(mask_xpm);
+
+ // finally, create the pixmap and mask
+ WMApp::Xw.create_pixmap(pixmap(), mask_xpm);
+ WMApp::Xw.fill_rectangle(pixmap(), 0, 0, 64, 64, 0xFFFFFF /*white*/);
+
+ // clean up
+ for (unsigned int i = 0; i < 67; i++)
+ delete [] mask_xpm[i];
+}
+
+void
+WMWindow::display()
+{
+ // obviously, we replace the check for existence of a parent
+ // with check for existence of an app
+ if (!app()) {
+ cerr << "WMError: Window " << this << "has no parent application" << endl;
+ return;
+ }
+
+ real_display();
+ setdisplayed(true);
+ for (unsigned int i = 0; i < numchildren(); i++)
+ child(i)->display();
+
+ // show the window and start running the GUI and callbacks
+ app()->Xshow();
+
+ // don't get here until the GUI has been requested to switch to
+ // a different window (via a callback), or to exit
+ return;
+}
+
+void
+WMWindow::real_display()
+{
+ if (!wPixmap.pixmap)
+ initpixmaps(); //call this function only once
+
+ // apply the mask to the application window so that areas not included
+ // in any widget are clear to the icon tile below
+ app()->mask();
+}
+
+void
+WMWindow::real_activate() { display(); }
+
+void
+WMWindow::real_deactivate() { hide(); }
+
diff --git a/wmapp/wmwindow.h b/wmapp/wmwindow.h
new file mode 100644
index 0000000..20a4ef5
--- /dev/null
+++ b/wmapp/wmwindow.h
@@ -0,0 +1,130 @@
+#include "wmframe.h"
+#include "wmcallback.h"
+#include "xwrapper.h"
+
+#ifndef _WMWINDOW_H
+#define _WMWINDOW_H
+
+class WMApp;
+
+// WMWindow: A 64x64 pixel square containing a number of widgets. You can
+// set it to run callback functions at regular intervals. Only one WMWindow
+// may be displayed at once. This is controlled by the WMApp containing a
+// vector of WMWindows.
+class WMWindow : private WMCallback, public WMFrame {
+ friend class WMApp;
+
+ private:
+ WMApp * wApp;
+ mutable WMPixmap wPixmap;
+
+ // how often to execute callbacks and update display, in milliseconds
+ int wUpdateFreq;
+ int wCounter;
+ // list of periods of individual callbacks (in units of wUpdateFreq)
+ vector<int> wFuncPeriod;
+
+ void initpixmaps();
+ void real_display();
+ void real_activate();
+ void real_deactivate();
+
+ // should be called only by a WMApp.
+ void display();
+ void hide();
+ void activate();
+ void deactivate();
+ void run_timed_functions();
+
+ public:
+ WMWindow();
+ ~WMWindow();
+
+ const WMWindow * window() const; // returns "this"
+
+ // override these to make them no-ops; windows have no parents
+ WMFrame *parent();
+ void setparent(const WMFrame *);
+ void setparent(const WMFrame &);
+
+ WMApp * app() const;
+ int updatefreq() const;
+ WMPixmap & pixmap() const;
+
+ void setapp(WMApp *);
+
+ void setupdatefreq(int milliseconds);
+ void add_timed_function(int period, data_func d, void * = 0);
+ void add_timed_function(int period, widget_func w, WMWidget *, void * = 0);
+ void clear_timed_functions();
+
+ bool press(int button, int x, int y);
+ bool release(int button, int x, int y);
+};
+
+// inline functions for WMWindow -----------------------------------------
+
+inline void
+WMWindow::activate() { WMFrame::activate(); }
+
+inline void
+WMWindow::deactivate() { WMFrame::deactivate(); }
+
+inline void
+WMWindow::hide() { WMFrame::hide(); }
+
+inline const WMWindow *
+WMWindow::window() const { return this; }
+
+inline WMFrame *
+WMWindow::parent() { return 0; }
+
+inline void
+WMWindow::setparent(const WMFrame *) { }
+
+inline void
+WMWindow::setparent(const WMFrame &) { }
+
+inline WMApp *
+WMWindow::app() const { return wApp; }
+
+inline int
+WMWindow::updatefreq() const { return wUpdateFreq; }
+
+inline void
+WMWindow::setupdatefreq(int milliseconds) { wUpdateFreq = milliseconds; }
+
+inline void
+WMWindow::add_timed_function(int period, data_func f, void *datap)
+{
+ WMCallback::addcallback(f, datap);
+ wFuncPeriod.push_back(period);
+}
+
+inline void
+WMWindow::add_timed_function(int period, widget_func f, WMWidget *w,
+ void *datap)
+{
+ WMCallback::addcallback(f, w, datap);
+ wFuncPeriod.push_back(period);
+}
+
+inline void
+WMWindow::clear_timed_functions()
+{
+ WMCallback::clearcallbacks();
+ wFuncPeriod.clear();
+}
+
+inline WMPixmap &
+WMWindow::pixmap() const { return wPixmap; }
+
+inline bool
+WMWindow::press(int button, int x, int y)
+{ return WMFrame::press(button, x, y); }
+
+inline bool
+WMWindow::release(int button, int x, int y)
+{ return WMFrame::release(button, x, y); }
+
+#endif
diff --git a/wmapp/xpm/charmap-large.xpm b/wmapp/xpm/charmap-large.xpm
new file mode 100644
index 0000000..037ca2f
--- /dev/null
+++ b/wmapp/xpm/charmap-large.xpm
@@ -0,0 +1,74 @@
+/* XPM */
+static char * charmap_large_xpm[] = {
+"112 66 5 1",
+" c None",
+". c #282828",
+"+ c #004941",
+"@ c #20B2AE",
+"# c #188A86",
+"................................................................................................................",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+"................................................................................................................",
+"................................................................................................................",
+"..@@@@...++++#.#@@@@#.#@@@@#.#++++#.#@@@@#.#@@@@#.#@@@@#.#@@@@#.#@@@@#.........++++...++++...++++...++++...++++.",
+". at ....@.+.... at .+....@.+.... at .@.... at .@....+. at ....+.+....@. at ....@. at ....@... at ....+....+.+....+.+....+.+....+.+....+",
+". at ....@.+.... at .+....@.+.... at .@.... at .@....+. at ....+.+....@. at ....@. at ....@... at ....+....+.+....+.+....+.+....+.+....+",
+". at ....@.+.... at .+....@.+.... at .@.... at .@....+. at ....+.+....@. at ....@. at ....@........+....+.+....+.+....+.+....+.+....+",
+".#++++#..++++#.#@@@@#.#@@@@#.#@@@@#.#@@@@#.#@@@@#..++++#.#@@@@#.#@@@@#.........++++...++++...++++...++++...++++.",
+". at ....@.+.... at .@....+.+.... at .+....@.+.... at .@.... at .+....@. at ....@.+.... at ........+....+.+....+.+....+.+....+.+....+",
+". at ....@.+.... at .@....+.+.... at .+....@.+.... at .@.... at .+....@. at ....@.+.... at ...@....+....+.+....+.+....+.+....+.+....+",
+". at ....@.+.... at .@....+.+.... at .+....@.+.... at .@.... at .+....@. at ....@.+.... at ...@....+....+.+....+.+....+.+....+.+....+",
+"..@@@@...++++#.#@@@@#.#@@@@#..++++#.#@@@@#.#@@@@#..++++#.#@@@@#.#@@@@#.........++++...++++...++++...++++...++++.",
+"................................................................................................................",
+"................................................................................................................",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+"................................................................................................................",
+"................................................................................................................",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+"................................................................................................................",
+"................................................................................................................",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+"................................................................................................................",
+"................................................................................................................",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+".+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+.+....+",
+"..++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++...++++.",
+"................................................................................................................"};
diff --git a/wmapp/xpm/charmap-medium.xpm b/wmapp/xpm/charmap-medium.xpm
new file mode 100644
index 0000000..99a87a7
--- /dev/null
+++ b/wmapp/xpm/charmap-medium.xpm
@@ -0,0 +1,62 @@
+/* XPM */
+static char * charmap_medium_xpm[] = {
+"96 54 5 1",
+" c None",
+". c #282828",
+"+ c #004941",
+"@ c #20B2AE",
+"# c #188A86",
+"................................................................................................",
+"..+++...+++...+++...+++...+++...+++...+++...+++... at ++...++@...+++...+++.........+++.........++##",
+".+...+.+...+.+...+.+...+.+...+.+...+.+...+.+...+. at ...+.+...@.+...+.+. at .+.......+...+.......+..@+",
+".+...+.+...+.+...+.+...+.+...+.+...+.+...+.+...+. at ...+.+...@.+...+.+. at .+.......+...+.......+.##+",
+"..+++...+++...+++...+++...+++...+++...+++...+++..#+++...+++#..+++..#@@@#........#@@.........+ at +.",
+".+...+.+...+.+...+.+...+.+...+.+...+.+...+.+...+. at ...+.+...@.+...+.+. at .+.......+...+.......+##.+",
+".+...+.+...+.+...+.+...+.+...+.+...+.+...+.+...+. at ...+.+...@.+...+.+. at .+....@..+...+.......+ at ..+",
+"..+++...+++...+++...+++...+++...+++...+++...+++... at ++...++@...+++...+++....##...+++...#@...##++.",
+"................................................................................................",
+"................................................................................................",
+"..@@@...+++#.#@@@#.#@@@#. at +++@.#@@@#.#@@@#.#@@@#.#@@@#.#@@@#..............+++...+++...+++...+++.",
+". at ...@.+... at .+...@.+... at .@... at .@...+. at ...+.+...@. at ...@. at ...@.............+...+.+...+.+...+.+...+",
+". at ...@.+... at .+...@.+... at .@... at .@...+. at ...+.+...@. at ...@. at ...@..#@....#@...+...+.+...+.+...+.+...+",
+".#+++#..+++#.#@@@#..@@@#.#@@@#.@@@@#.#@@@#..+++#.#@@@#.#@@@#..............+++...+++...+++...+++.",
+". at ...@.+... at .@...+.+... at .+...@.+... at .@... at .+...@. at ...@.+... at .............+...+.+...+.+...+.+...+",
+". at ...@.+... at .@...+.+... at .+...@.+... at .@... at .+...@. at ...@.+... at ..#@..... at ...+...+.+...+.+...+.+...+",
+"..@@@...+++ at .#@@@#.#@@@#..+++#.#@@@#.#@@@#..+++ at .#@@@#.#@@@#........##....+++...+++...+++...+++.",
+"................................................................................................",
+"................................................................................................",
+".+@@@+.+@@@+.#@@@...@@@#.#@@@..#@@@#.#@@@#.#@@@#.#+++#..@@@...+++#.#+++#.#+++.. at +++@.#@@@..#@@@#",
+". at ...@. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@...+. at ...@.+. at .+.+...@. at ...@. at ...+.@@.@@. at ...@. at ...@",
+". at ...@. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@...+. at ...@.+. at .+.+...@. at ..@.. at ...+.@. at .@. at ...@. at ...@",
+".#+@@#.#@@@#.#@@@..#+++..#+++#.#@@@..#@@@..#+#@#.#@@@#..+#+...+++#.#@@...#+++..#+++#.#+++#.#+++#",
+". at .@@+. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@... at .@... at .+.@.+.+... at .@.. at ..@...+. at ...@. at ...@. at ...@",
+". at ...+.@... at .@... at .@...+. at ...@. at ...+.@...+. at ...@. at ...@.+. at .+.@... at .@... at .@...+. at ...@. at ...@. at ...@",
+".#@@@#.#+++#.#@@@...@@@#.#@@@..#@@@#.#+++..#@@@#.#+++#..@@@..#@@@#.#+++#.#@@@#.#+++#.#+++#.#@@@#",
+"................................................................................................",
+"................................................................................................",
+".#@@@#.#@@@#.#@@@#.#@@@#.#@@@#.#+++#.#+++#.#+++#.#+++#.#+++#.#@@@#.#@++..##++...++@#..+++...+++.",
+". at ...@. at ...@. at ...@. at ...+.+.@.+. at ...@. at ...@. at ...@. at ...@. at ...@.+... at .@...+.+ at ..+.+...@.+...+.+...+",
+". at ...@. at ...@. at ...@. at ...+.+.@.+. at ...@. at ...@. at ...@.. at .@.. at ...@.+.. at +.@...+.+##.+.+... at .+...+.+...+",
+".#@@@#.#@++#.#@@@..#@@@#..+#+..#+++#.#+++#.#+++#... at ...#@@@#..+ at +..#+++...+ at +...+++#..+++...+++.",
+". at ...+.@. at .@. at ...@.+... at .+.@.+. at ...@. at ...@. at .@. at ..@. at ..+...@.+ at ..+.@...+.+.##+.+... at .+...+.+...+",
+". at ...+.@..@@. at ...@.+... at .+.@.+. at ...@. at ...@.@@.@@. at ...@.+... at .@...+. at ...+.+..@+.+... at .+...+.+...+",
+".#+++..#@@@#.#+++#.#@@@#..+#+..#@@@#..#@#..#+++#.#+++#.#@@@#.#@@@#.#@++...++##..++@#..+++..#@@@#",
+"................................................................................................",
+"................................................................................................",
+"..+++..+@@@+.#@@@...@@@#.#@@@..#@@@#.#@@@#.#@@@#.#+++#..@@@...+++#.#+++#.#+++.. at +++@.#@@@..#@@@#",
+".+...+. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@...+. at ...@.+. at .+.+...@. at ...@. at ...+.@@.@@. at ...@. at ...@",
+".+...+. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@...+. at ...@.+. at .+.+...@. at ..@.. at ...+.@. at .@. at ...@. at ...@",
+"..+++..#@@@#.#@@@..#+++..#+++#.#@@@..#@@@..#+#@#.#@@@#..+#+...+++#.#@@...#+++..#+++#.#+++#.#+++#",
+".+...+. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@... at .@... at .+.@.+.+... at .@.. at ..@...+. at ...@. at ...@. at ...@",
+".+...+. at ...@. at ...@. at ...+.@... at .@...+. at ...+.@... at .@... at .+.@.+. at ...@. at ...@. at ...+.@... at .@... at .@...@",
+"..+++..#+++#.#@@@...@@@#.#@@@..#@@@#.#+++..#@@@#.#+++#..@@@..#@@@#.#+++#.#@@@#.#+++#.#+++#.#@@@#",
+"................................................................................................",
+"................................................................................................",
+".#@@@#.#@@@#.#@@@#.#@@@#.#@@@#.#+++#.#+++#.#+++#.#+++#.#+++#.#@@@#..++ at ...+#+... at ++...+++..+@+..",
+". at ...@. at ...@. at ...@. at ...+.+.@.+. at ...@. at ...@. at ...@. at ...@. at ...@.+... at .+.@.+.+. at .+.+.@.+.+...+. at .@..",
+". at ...@. at ...@. at ...@. at ...+.+.@.+. at ...@. at ...@. at ...@.. at .@.. at ...@.+.. at +.+.@.+.+. at .+.+.@.+.+...+.+ at +..",
+".#@@@#.#@++#.#@@@..#@@@#..+#+..#+++#.#+++#.#+++#... at ...#@@@#..+ at +...@#+...+#+...+#@...+++.......",
+". at ...+.@. at .@. at ...@.+... at .+.@.+. at ...@. at ...@. at .@. at ..@. at ..+...@.+ at ..+.+.@.+.+. at .+.+.@.+.+...+......",
+". at ...+.@..@@. at ...@.+... at .+.@.+. at ...@. at ...@.@@.@@. at ...@.+... at .@...+.+. at .+.+.@.+.+. at .+.+...+......",
+".#+++..#@@@#.#+++#.#@@@#..+#+..#@@@#..#@#..#+++#.#+++#.#@@@#.#@@@#..++ at ...+#+... at ++...+++.......",
+"................................................................................................"};
diff --git a/wmapp/xpm/charmap-small.xpm b/wmapp/xpm/charmap-small.xpm
new file mode 100644
index 0000000..13ff702
--- /dev/null
+++ b/wmapp/xpm/charmap-small.xpm
@@ -0,0 +1,62 @@
+/* XPM */
+static char * charmap_small_xpm[] = {
+"80 54 5 1",
+" c None",
+". c #282828",
+"+ c #004941",
+"@ c #20B2AE",
+"# c #188A86",
+"................................................................................",
+"..++...++...++...++...++...++...++...++... at +...+@...++.............++........++.",
+".+..+.+..+.+..+.+..+.+..+.+..+.+..+.+..+. at ..+.+..@.+..+.. at ........+..+......+.@+",
+".+..+.+..+.+..+.+..+.+..+.+..+.+..+.+..+. at ..+.+..@.+..+.. at ........+..+......+##+",
+"..++...++...++...++...++...++...++...++..#++...++#..++..@@@.......#@@........ at +.",
+".+..+.+..+.+..+.+..+.+..+.+..+.+..+.+..+. at ..+.+..@.+..+.. at ........+..+......##.+",
+".+..+.+..+.+..+.+..+.+..+.+..+.+..+.+..+. at ..+.+..@.+..+.. at .....@..+..+...... at ..+",
+"..++...++...++...++...++...++...++...++... at +...+@...++........##...++...#@...++.",
+"................................................................................",
+"................................................................................",
+"..@@...++#.#@@#.#@@#.#++#.#@@#.#@@#.#@@#.#@@#.#@@#............++...++...++...++.",
+". at ..@.+.. at .+..@.+.. at .@.. at .@..+. at ..+.+..@. at ..@. at ..@...........+..+.+..+.+..+.+..+",
+". at ..@.+.. at .+..@.+.. at .@.. at .@..+. at ..+.+..@. at ..@. at ..@..#@...#@..+..+.+..+.+..+.+..+",
+".#++#..++#.#@@#.#@@#.#@@#.@@@#.#@@#..++#.#@@#.#@@#............++...++...++...++.",
+". at ..@.+.. at .@..+.+.. at .+..@.+.. at .@.. at .+..@. at ..@.+.. at ...........+..+.+..+.+..+.+..+",
+". at ..@.+.. at .@..+.+.. at .+..@.+.. at .@.. at .+..@. at ..@.+.. at ..#@.... at ..+..+.+..+.+..+.+..+",
+"..@@...++ at .#@@#.#@@#..++#.#@@#.#@@#..++#.#@@#.#@@#.......##...++...++...++...++.",
+"................................................................................",
+"................................................................................",
+".+@@+.+@@+.#@@...@@#.#@@..#@@#.#@@#.#@@#.#++#.@@@...++#.#++#.#++.. at ..@.#@@..#@@#",
+". at ..@. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@..+. at ..@.+ at .+.+..@. at ..@. at ..+.@@@@. at ..@. at ..@",
+". at ..@. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@..+. at ..@.+ at .+.+..@. at .@.. at ..+.@##@. at ..@. at ..@",
+".#+@@.#@@#.#@@..#+++.#++#.#@@..#@@..#+@#.#@@#..#+...++#.#@...#++..#++#.#++#.#++#",
+". at .@#. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@.. at .@.. at .+@.+.+.. at .@. at ..@..+. at ..@. at ..@. at ..@",
+". at ..+.@.. at .@.. at .@..+. at ..@. at ..+.@..+. at ..@. at ..@.+ at .+.@.. at .@.. at .@..+. at ..@. at ..@. at ..@",
+".#@@..#++#.#@@...@@#.#@@..#@@#.#++..#@@#.#++#.@@@..#@@#.#++#.#@@#.#++#.#++#.#@@#",
+"................................................................................",
+"................................................................................",
+".#@@#.#@@#.#@@#.#@@#.@@@#.#++#.#++#.#++#.#++#.#++#.#@@#.@@+...++...+@@..++...++.",
+". at ..@. at ..@. at ..@. at ..+.+@.+. at ..@. at ..@. at ..@. at ..@. at ..@.+.. at .@..+. at ..+.+..@.+..+.+..+",
+". at ..@. at ..@. at ..@. at ..+.+@.+. at ..@. at ..@. at ..@. at ..@. at ..@.+. at +.@..+.##.+.+.. at .+..+.+..+",
+".#@@#.#++#.#@@..#@@#..#+..#++#.#++#.#++#..@@...@@#..##..#++... at +...++#..++...++.",
+". at ..+.@##@. at ..@.+.. at .+@.+. at ..@. at ..@.@##@. at ..@.+.. at .+@.+. at ..+.+##+.+.. at .+..+.+..+",
+". at ..+.@.@@. at ..@.+.. at .+@.+. at ..@. at ..@.@@@@. at ..@.+.. at .@..+. at ..+.+.@+.+.. at .+..+.+..+",
+".#++..#@@#.#++#.#@@#..#+..#@@#..#@.. at ..@.#++#.#@@#.#@@#.@@+...++...+@@..++..#@@#",
+"................................................................................",
+"................................................................................",
+"..++..+@@+.#@@...@@#.#@@..#@@#.#@@#.#@@#.#++#.@@@...++#.#++#.#++.. at ..@.#@@..#@@#",
+".+..+. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@..+. at ..@.+ at .+.+..@. at ..@. at ..+.@@@@. at ..@. at ..@",
+".+..+. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@..+. at ..@.+ at .+.+..@. at .@.. at ..+.@##@. at ..@. at ..@",
+"..++..#@@#.#@@..#+++.#++#.#@@..#@@..#+@#.#@@#..#+...++#.#@...#++..#++#.#++#.#++#",
+".+..+. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@.. at .@.. at .+@.+.+.. at .@. at ..@..+. at ..@. at ..@. at ..@",
+".+..+. at ..@. at ..@. at ..+.@.. at .@..+. at ..+.@.. at .@.. at .+@.+. at ..@. at ..@. at ..+.@.. at .@.. at .@..@",
+"..++..#++#.#@@...@@#.#@@..#@@#.#++..#@@#.#++#.@@@..#@@#.#++#.#@@#.#++#.#++#.#@@#",
+"................................................................................",
+"................................................................................",
+".#@@#.#@@#.#@@#.#@@#.@@@#.#++#.#++#.#++#.#++#.#++#.#@@#..#@...#+...@#...++..+ at +.",
+". at ..@. at ..@. at ..@. at ..+.+@.+. at ..@. at ..@. at ..@. at ..@. at ..@.+.. at .+@.+.+ at .+.+.@+.+..+. at .@.",
+". at ..@. at ..@. at ..@. at ..+.+@.+. at ..@. at ..@. at ..@. at ..@. at ..@.+. at +.+@.+.+ at .+.+.@+.+..+.+ at +.",
+".#@@#.#++#.#@@..#@@#..#+..#++#.#++#.#++#..@@...@@#..##..@#+...#+...+#@..++......",
+". at ..+.@##@. at ..@.+.. at .+@.+. at ..@. at ..@.@##@. at ..@.+.. at .+@.+.+ at .+.+@.+.+. at +.+..+.....",
+". at ..+.@.@@. at ..@.+.. at .+@.+. at ..@. at ..@.@@@@. at ..@.+.. at .@..+.+ at .+.+@.+.+. at +.+..+.....",
+".#++..#@@#.#++#.#@@#..#+..#@@#..#@.. at ..@.#++#.#@@#.#@@#..#@...#+...@#...++......",
+"................................................................................"};
diff --git a/wmapp/xpm/checkbox.xpm b/wmapp/xpm/checkbox.xpm
new file mode 100644
index 0000000..7b4b0e9
--- /dev/null
+++ b/wmapp/xpm/checkbox.xpm
@@ -0,0 +1,14 @@
+/* XPM */
+static char * checkbox_xpm[] = {
+"9 9 2 1",
+". c #AEAAAE",
+"+ c #000000",
+".........",
+"......++.",
+".....+++.",
+".++.+++..",
+".+++++...",
+".++++....",
+".+++.....",
+".++......",
+"........."};
diff --git a/wmapp/xpm/emptybar.xpm b/wmapp/xpm/emptybar.xpm
new file mode 100644
index 0000000..e369631
--- /dev/null
+++ b/wmapp/xpm/emptybar.xpm
@@ -0,0 +1,62 @@
+/* XPM for empty bar - taken from wmtop's progress bar, dimmed with GIMP */
+static char * emptybar_xpm[] = {
+"58 1 58 1",
+" c None",
+". c #007007",
+"+ c #026D07",
+"@ c #046C07",
+"# c #066A07",
+"$ c #086706",
+"% c #0A6506",
+"& c #0C6406",
+"* c #0E6206",
+"= c #105F06",
+"- c #115E06",
+"; c #145C06",
+"> c #165905",
+", c #185705",
+"' c #1A5605",
+") c #1C5405",
+"! c #1E5105",
+"~ c #1F5005",
+"{ c #224E05",
+"] c #244C04",
+"^ c #264904",
+"/ c #284804",
+"( c #2A4604",
+"_ c #2C4304",
+": c #2D4204",
+"< c #304004",
+"[ c #323E03",
+"} c #343B03",
+"| c #353A03",
+"1 c #383803",
+"2 c #3A3503",
+"3 c #3B3403",
+"4 c #3E3203",
+"5 c #403003",
+"6 c #422D03",
+"7 c #432C03",
+"8 c #462A03",
+"9 c #482803",
+"0 c #492603",
+"a c #4C2403",
+"b c #4E2202",
+"c c #501F02",
+"d c #511E02",
+"e c #541C02",
+"f c #561A02",
+"g c #571802",
+"h c #591602",
+"i c #5C1401",
+"j c #5E1101",
+"k c #5F1001",
+"l c #620E01",
+"m c #640C01",
+"n c #650A01",
+"o c #670801",
+"p c #6A0600",
+"q c #6C0400",
+"r c #6D0200",
+"s c #700000",
+"..+@#$%&*=-;>,')!~{]^/(_:<[}|1234567890abcdefghijklmnopqrs"};
diff --git a/wmapp/xpm/fullbar.xpm b/wmapp/xpm/fullbar.xpm
new file mode 100644
index 0000000..f5c3986
--- /dev/null
+++ b/wmapp/xpm/fullbar.xpm
@@ -0,0 +1,62 @@
+/* XPM for full progress bar - taken from wmtop */
+static char * fullbar_xpm[] = {
+"58 1 58 1",
+" c None",
+". c #00FF0F",
+"+ c #04FA0F",
+"@ c #09F50F",
+"# c #0DF10F",
+"$ c #12EC0E",
+"% c #16E80E",
+"& c #1BE30E",
+"* c #1FDF0D",
+"= c #24DA0D",
+"- c #28D60D",
+"; c #2DD10D",
+"> c #32CC0C",
+", c #36C80C",
+"' c #3BC30C",
+") c #3FBF0B",
+"! c #44BA0B",
+"~ c #48B60B",
+"{ c #4DB10B",
+"] c #51AD0A",
+"^ c #56A80A",
+"/ c #5BA30A",
+"( c #5F9F09",
+"_ c #649A09",
+": c #689609",
+"< c #6D9109",
+"[ c #718D08",
+"} c #768808",
+"| c #7A8408",
+"1 c #7F7F07",
+"2 c #847A07",
+"3 c #887607",
+"4 c #8D7107",
+"5 c #916D06",
+"6 c #966806",
+"7 c #9A6406",
+"8 c #9F5F05",
+"9 c #A35B05",
+"0 c #A85605",
+"a c #AD5105",
+"b c #B14D04",
+"c c #B64804",
+"d c #BA4404",
+"e c #BF3F03",
+"f c #C33B03",
+"g c #C83603",
+"h c #CC3203",
+"i c #D12D02",
+"j c #D62802",
+"k c #DA2402",
+"l c #DF1F01",
+"m c #E31B01",
+"n c #E81601",
+"o c #EC1201",
+"p c #F10D00",
+"q c #F50900",
+"r c #FA0400",
+"s c #FF0000",
+"..+@#$%&*=-;>,')!~{]^/(_:<[}|1234567890abcdefghijklmnopqrs"};
diff --git a/wmapp/xpm/leds.xpm b/wmapp/xpm/leds.xpm
new file mode 100644
index 0000000..a9d1fa5
--- /dev/null
+++ b/wmapp/xpm/leds.xpm
@@ -0,0 +1,14 @@
+/* XPM for LED lights - taken from wmppp */
+static char * leds_xpm[] = {
+"16 4 7 1",
+" c None",
+". c #202020",
+"+ c #283C38",
+"@ c #00EB00",
+"# c #E7C308",
+"$ c #B60418",
+"% c #F7F3FF",
+".++..@@..##..$$.",
+"++++@%@@#%##$%$$",
+"++++@@@@####$$$$",
+".++..@@..##..$$."};
diff --git a/wmapp/xpm/tile.xpm b/wmapp/xpm/tile.xpm
new file mode 100644
index 0000000..e65c234
--- /dev/null
+++ b/wmapp/xpm/tile.xpm
@@ -0,0 +1,121 @@
+/* XPM */
+static char *tile_xpm[] = {
+"64 64 54 1",
+" c #F3CEF3CEF3CE",
+". c #000000000000",
+"X c #514461856185",
+"o c #A289A289B2CA",
+"O c #A289A289A289",
+"+ c #A2899248B2CA",
+"@ c #9248A289A289",
+"# c #A2899248A289",
+"$ c #92489248A289",
+"% c #924892489248",
+"& c #92488207A289",
+"* c #820792489248",
+"= c #924882079248",
+"- c #820782079248",
+"; c #820782078207",
+": c #820771C69248",
+"> c #618551446185",
+", c #9248A289B2CA",
+"< c #92489248B2CA",
+"1 c #82079248A289",
+"2 c #82078207A289",
+"3 c #71C682079248",
+"4 c #71C682078207",
+"5 c #514451446185",
+"6 c #514451445144",
+"7 c #820771C68207",
+"8 c #410351445144",
+"9 c #514441035144",
+"0 c #71C671C69248",
+"q c #71C671C68207",
+"w c #71C671C671C6",
+"e c #410341035144",
+"r c #71C661858207",
+"t c #618571C68207",
+"y c #410351444103",
+"u c #410341034103",
+"i c #618571C671C6",
+"p c #410330C24103",
+"a c #30C241034103",
+"s c #71C6618571C6",
+"d c #6185618571C6",
+"f c #618561858207",
+"g c #30C230C230C2",
+"h c #618561856185",
+"j c #30C230C24103",
+"k c #5144618571C6",
+"l c #30C2410330C2",
+"z c #6185514471C6",
+"x c #208130C230C2",
+"c c #30C2208130C2",
+"v c #5144514471C6",
+"b c #2081208130C2",
+"n c #208120812081",
+"m c #410330C25144",
+" .",
+" X.",
+" oOoO+O+O+O+@#$+@#$#$#$$$#$$%&%&%&%&*&*&*=-=*=-=-=--;---;:;:;>.",
+" oo at o,o at o@o at +@+@<@$@$@$@$@$1$$$*$*$*&*&*2*&*2*-*-*-----3-3-4-X.",
+" oO+OoO#O+@#@#@#$#@#$#%#$$%$%$%&%&*=%&*=*=*=-=-=--;-;-;:;:;:;5.",
+" ,ooo at +@+ at +@+@<@#@<@$$$$$$$$$*$1$*&*&*&*&*2*---*-----3---4:4:6.",
+" +O+O+O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=*=---=--;---;:;:4:;:45.",
+" @o at o@o at +@+@<@$@$@$$$@$1$1$*$*$*&*&*2*=*2*-*-*-----4-3-4:4-4:6.",
+" +O#O+@#@#@#$#$#$#%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:4745.",
+" @+ at +@+ at +@<@#@$@$$$$$$$$$*$*$*&*&*&*&*2*---*-----3---4:4:4:4:8.",
+" #O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=-=---=--;:;-;:;:4:4:474:49.",
+" @o@<@+@<@$@$@$$$$$1$1$*$*$*&*&*2*=*2*-*-*-----4-4-4:4:4:4:408.",
+" +@#@#@#$#$#$$%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:474747q9.",
+" @+ at +@<@$$$@$$$$$1$$$*&*$*&*&*&*&*2*---------3-3-4:4:4:4:404q8.",
+" #$#@#$#$#$$%$$$%&%&%&%&*=-&*=-=-=---=--;:;:;:;:4:4:474:47q7q9.",
+" @#@<@$@$@$$$$$*$1$*$*$*&*&*2*-*2*-*-*-3---4-4-4:4:4:4:404q4q8.",
+" #@#$#$#$$%$%$%&%$%&%&*=*=*=-=*=-=;=--;-;-;:;:47;:474747q7q7q9.",
+" @<@$$$@$$$$$1$$$*&*&*&*&*&*=*2*---------4-3-4:4:4:4:404qq04q8.",
+" #$#$#$$%$%$%&%&%&%&*=-&*=-=-=------;:;:;:;:4:4:47q747qqq7qqq9.",
+" @$@$@$$$$$*$1$*$*$*&*&*2*-*-*---*-3-3-4-4-4:4:4:4:404q4q4qqq8.",
+" #$#$$%$%$%&%&%&%&*=*=*=-=-=-=;=--;:;-;:;:474:474747q7q7qqwqw9.",
+" $$@$$$$$*$$$*&*&*&*&*2*=*2*---------4-3-4:4:4:4:404qqq4qqqqqe.",
+" #$$%$%$%&%&*&%&*=-&*=-=-=------;:;:;:;:4:4:47q7q7qqq7qqwrqqw9.",
+" @$$$$$*$1$*&*$*2*&*2*-*-*-----3-3-4-4-4:4:404:404q4q4qqqqqtqy.",
+" $%$%$%&%&%=%&*=*=*=-=-=--;=--;:;-;:;:474:474747q7q7qqwqwqwrwe.",
+" $$$$*$1$*&*&*&*&*2*--2*-----3---4:3-4:4:4:4:404qqqqqqqqqtqtqu.",
+" &%$%&%&*&*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqq7qqwrqrwrwrip.",
+" $$*$*$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q404q4q4qtqqqiqtqiru.",
+" $%&%&*=%&*=*=*=-=-=--;-;-;:;-;:;:474:47q747q7q7qqwqwqwrwrirwu.",
+" *$1$*&*&*&*&*2*---*-----3---4:4:4:4:4:4:404qqqqqqqqqtqtqirira.",
+" &%&*=*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqqqqqwrqrwrwriririp.",
+" *$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q4q4qqq4qtqtqiqiqiriqira.",
+" &*=*&*=*=*=-=-=--;-;-;:;:;:;:474:47q7q7q7q7qqwrwqwrwrirwrisip.",
+" *&*&*&*&*2*---*-----3---4:4:4:4:404:404qqqqqqqqqtqtqiriririra.",
+" =*&*=-=*=---=--;---;:;:4:;:474:47q7q7qqqqqqwrwrwrwriririsdrdp.",
+" *&*2*=*2*-*-*-----4-3-4:4-4:4:404q4q4qqqqqtqtqiqiqiriqifirifa.",
+" &*=*=*=-=-=--;-;-;:;:;:;:474747q7q7qqq7qqwrwqwrwrirwrisisisdp.",
+" *&*&*2*---*-----3-3-4:4:4:4:404qq04qqqqqtqqqirtqiririririfida.",
+" =-=-=---=--;:;-;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdrdsdddp.",
+" *=*2*-*-*-----4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiriqifififidida.",
+" =*=-=-=--;-;-;:;:4:;:474747q7q7qqwqwqwrwqwrwrirwrisdsisdsdsdp.",
+" *2*---------4-3-4:4:4:4:404qq04qqqqqtqqqiririririririfidddddg.",
+" =---=--;:;:;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdsdsddddddhj.",
+" *---*-3---4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiririfififidddidkdl.",
+" =;=--;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrirwrisdsdsdsdsddhzhj.",
+" --------4-3-4:4:4:4:404qq04qqqqqtqqqiririririfirifidddddddddx.",
+" ---;:;:;:;:4:4:47q747qqq7qqwqqqwrwrirwriririsdsdsddddddhzhzhc.",
+" --3-3-4-4-4:4:4:4:404q4q4qqqqqtqtqiriqiririfififidddddkdkdXdx.",
+" -;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrisisisdsdsdddsddhzhdhzhg.",
+" ----4-3-4:4:4:4:404qqq4qqqqqtqtqiriririrififdfidddddkdddkzkdx.",
+" :;:;:;:4:4:47q7q7qqq7qqwrqqwrwriririririsdsdsddddddhzhzhzhzXc.",
+" 3-4-4-4:4:404:404q4q4qqqqqtqtqiriqiririfidididddddkdkdXdXdXzx.",
+" -;:;:474:47q747q7q7qqwqwqwrwrirwrisisisdsdsddddddhzhdhzhzXzhc.",
+" 4:4-4:4:4:4:404qqqqqqqqqtqtqiriririrififdfidddddkdddkzkdXzXzx.",
+" :;:4:4:47q7q7qqq7qqwrqrwrwriririsirisdsdsddddddhzhzhzhzXzXzXc.",
+" 4-4:4:404q404qqq4qtqqqiqtqiriqiririfidididddddkdkdXdXdXzXzXvx.",
+" :474:47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddddddhzhzhzhzXzhzX>5c.",
+" 4:4:4:4:404qqqqqqqqqtqtqiririririfiddfidddddkdddXzkdXzXzXvXzx.",
+" :4:47q7q7qqqqqqwrwrwrwriririsdrisdddsddddddhzhzXzhzXzXzX>5>5c.",
+" 4:404q4q4qqqqqtqtqiqiqiriqiririfidididddddkdkdXzXdXzXzXvXvXvx.",
+" :47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddhdddhzhzhzhzXzXzX>5>5>5b.",
+" 404:404qqqqqqqqqiqtqiririririfidddidddddkdkdXzkzXzXzXvXv5vX5n.",
+" >65656569698989y9e9u9ueumueupupapaplpgjgjgjgcgcgcgcxcbcncnbnb.",
+" ..............................................................."};
diff --git a/wmapp/xpm/xbutton.xpm b/wmapp/xpm/xbutton.xpm
new file mode 100644
index 0000000..ba8e5e9
--- /dev/null
+++ b/wmapp/xpm/xbutton.xpm
@@ -0,0 +1,14 @@
+/* XPM */
+static char * xbutton_xpm[] = {
+"9 9 2 1",
+". c #AEAAAE",
+"+ c #000000",
+".........",
+".++...++.",
+".+++.+++.",
+"..+++++..",
+"...+++...",
+"..+++++..",
+".+++.+++.",
+".++...++.",
+"........."};
diff --git a/wmapp/xwrapper.cc b/wmapp/xwrapper.cc
new file mode 100644
index 0000000..44000e2
--- /dev/null
+++ b/wmapp/xwrapper.cc
@@ -0,0 +1,329 @@
+#include <iostream>
+#include "xwrapper.h"
+#include "wmwidget.h"
+using std::cerr;
+using std::endl;
+
+// This class includes most of the crap normally required to do X stuff.
+
+Xwrapper::Xwrapper()
+{
+ xDisplay = X::XOpenDisplay(0);
+ if (!xDisplay) { cerr << "Xwrapper: Could not open X display!" << endl; }
+ xRootWindow = DefaultRootWindow(xDisplay);
+ X::XGetWindowAttributes(xDisplay, xRootWindow, &xAttributes);
+
+ X::XGCValues gcv;
+ gcv.graphics_exposures = false;
+ xGC = X::XCreateGC(xDisplay, xRootWindow,
+ X_MACRO(GCGraphicsExposures), &gcv);
+}
+
+Xwrapper::~Xwrapper()
+{
+ //XXX: This is only the beginning...
+ X::XFreeGC(xDisplay, xGC);
+ X::XCloseDisplay(xDisplay);
+}
+
+void
+Xwrapper::set_GC(X::GC gc, Color c) const
+{
+ X::XSetForeground(xDisplay, gc, color_to_xcolor(c));
+ X::XSetFillStyle(xDisplay, gc, X_MACRO(FillSolid));
+}
+
+unsigned long
+Xwrapper::color_to_xcolor(Color c) const
+{
+ X::XColor xcolor;
+
+ xcolor.pixel = 0;
+ xcolor.flags = X_MACRO(DoRed | DoGreen | DoBlue);
+ // map the range 0 -> 0xff to the range 0 -> 0xffff
+ // (X insists on using "short" for color values)
+ xcolor.red = c.r() * 0x0101;
+ xcolor.green = c.g() * 0x0101;
+ xcolor.blue = c.b() * 0x0101;
+
+ if (X::XAllocColor(xDisplay, xAttributes.colormap, &xcolor))
+ X::XFreeColors(xDisplay, xAttributes.colormap, &xcolor.pixel, 1, 0);
+ //XXX: This is an incredibly stupid solution, but it works above 8-bit
+ //color. It appears that decent color management is a shortcoming of X.
+ return xcolor.pixel;
+}
+
+Color
+Xwrapper::get_point(const WMPixmap& src, int x, int y) const
+{
+ //magic incantaions to read a pixel from a pixmap
+ X::XGCValues gcvalues;
+ X::XGetGCValues(xDisplay, src.gc, GCPlaneMask, &gcvalues);
+
+ // XXX: Surely there's a better way than allocating an image every time
+ X::XImage* dest = XGetImage(xDisplay, src.pixmap, 0, 0, src.attr.width, src.attr.height, gcvalues.plane_mask, XYPixmap);
+
+ Color color = XGetPixel(dest, x, y);
+ XDestroyImage(dest);
+ return color;
+}
+
+bool
+Xwrapper::create_pixmap(WMPixmap & dest, char * pixmap_bytes[]) const
+{
+ dest.attr.exactColors = false;
+ dest.attr.closeness = 40000;
+ dest.attr.valuemask = X_MACRO(XpmExactColors | XpmCloseness |
+ XpmReturnPixels | XpmReturnExtensions);
+ int error = X::XpmCreatePixmapFromData(xDisplay, xRootWindow, pixmap_bytes,
+ &dest.pixmap, &dest.mask, &dest.attr);
+ if (error == X_MACRO(XpmSuccess)) {
+ X::XGCValues gcv;
+ gcv.clip_mask = dest.mask;
+ dest.gc = X::XCreateGC(xDisplay, dest.pixmap, X_MACRO(GCClipMask), &gcv);
+ return true;
+ }
+ else return false;
+}
+
+bool
+Xwrapper::create_pixmap(WMPixmap & dest, const WMPixmap & source) const
+{
+ create_pixmap(dest, source.attr.width, source.attr.height);
+ copy_rectangle(source, dest, 0, 0, source.attr.width, source.attr.height,
+ 0, 0);
+ return true;
+}
+
+bool
+Xwrapper::create_pixmap(WMPixmap & dest, const WMPixmap * source) const
+{ return source ? create_pixmap(dest, *source) : false; }
+
+bool
+Xwrapper::create_pixmap(WMPixmap & dest, int width, int height) const
+{
+ dest.attr.width = width;
+ dest.attr.height = height;
+ dest.pixmap = X::XCreatePixmap(xDisplay, xRootWindow, width, height,
+ DefaultDepth(xDisplay,
+ DefaultScreen(xDisplay)));
+ dest.mask = 0; //hope XCreateFoo never returns 0
+ X::XGCValues gcv;
+ dest.gc = X::XCreateGC(xDisplay, dest.pixmap, X_MACRO(None), &gcv);
+ return true;
+}
+
+bool
+Xwrapper::create_pixmap(WMPixmap & dest, int width, int height, int depth) const
+{
+ dest.attr.width = width;
+ dest.attr.height = height;
+ dest.pixmap = X::XCreatePixmap(xDisplay, xRootWindow, width, height, depth);
+ dest.mask = 0; //hope XCreateFoo never returns 0
+ X::XGCValues gcv;
+ dest.gc = X::XCreateGC(xDisplay, dest.pixmap, X_MACRO(None), &gcv);
+ return true;
+}
+
+void
+Xwrapper::free_pixmap(WMPixmap & dest) const
+{
+ X::XFreeGC(xDisplay, dest.gc);
+ X::XFreePixmap(xDisplay, dest.pixmap);
+ if (dest.mask) X::XFreePixmap(xDisplay, dest.mask);
+}
+
+void
+Xwrapper::draw_point(WMPixmap & dest, int x, int y, Color c) const
+{
+ set_GC(dest.gc, c);
+ X::XDrawPoint(xDisplay, dest.pixmap, dest.gc, x, y);
+}
+
+void
+Xwrapper::draw_line(WMPixmap & dest, int x1, int y1, int x2, int y2,
+ Color c) const
+{
+ set_GC(dest.gc, c);
+ X::XDrawLine(xDisplay, dest.pixmap, dest.gc, x1, y1, x2, y2);
+}
+
+void
+Xwrapper::draw_arc(WMPixmap & dest, int x, int y, int width, int height,
+ int angle1, int angle2, Color c)
+{
+ set_GC(dest.gc, c);
+ X::XDrawArc(xDisplay, dest.pixmap, dest.gc, x, y, width, height, angle1,
+ angle2);
+}
+
+void
+Xwrapper::draw_lines(WMPixmap & dest, const X::XPoint* points, int npoints,
+ Color c) const
+{
+ set_GC(dest.gc, c);
+ X::XDrawLines(xDisplay, dest.pixmap, dest.gc, const_cast<X::XPoint*>(points),
+ npoints, X_MACRO(CoordModeOrigin));
+}
+
+void
+Xwrapper::draw_horizontal_gradient(WMPixmap & dest, int x1, int y1, int x2,
+ int y2, Color c1, Color c2, double amount)
+{
+ if (!(x2 - x1) || !amount)
+ return; //gradient isn't wide enough, or none of it is to be drawn
+ if (x1 > x2) //put x1 on left while keeping colors straight
+ {
+ int tempx = x2; x2 = x1; x1 = tempx;
+ Color tempc = c2; c2 = c1; c1 = tempc;
+ }
+
+ int glinesm1 = x2 - x1;
+ int glines = glinesm1 + 1; //number of lines in the full gradient
+ double dlines = glines * amount; //number of lines that we want to show
+ int tdlines = static_cast<int> (dlines); //number of lines truncated to int
+ double residue = dlines - tdlines; //amount left over from integer truncation
+ for (int x = 0; x < tdlines; x++)
+ draw_line(dest, x1 + x, y1, x1 + x, y2, Color::alpha_blend(c2, c1,
+ 1.0 * x / glinesm1));
+ if (tdlines < glines) //correct undrawn line by using alpha blending
+ {
+ Color backcolor = get_point(dest, x1 + tdlines, y1);
+ Color forecolor = Color::alpha_blend(c2, c1, 1.0 * tdlines / glinesm1);
+ Color color = Color::alpha_blend(forecolor, backcolor, residue);
+ draw_line(dest, x1 + tdlines, y1, x1 + tdlines, y2, color);
+ }
+}
+
+void
+Xwrapper::draw_vertical_gradient(WMPixmap & dest, int x1, int y1, int x2,
+ int y2, Color c1, Color c2, double amount)
+{
+ if (!(y2 - y1) || !amount)
+ return; //gradient isn't high enough, or none of it is to be drawn
+ if (y1 > y2) //put y1 on left while keeping colors straight
+ {
+ int tempy = y2; y2 = y1; y1 = tempy;
+ Color tempc = c2; c2 = c1; c1 = tempc;
+ }
+
+ int glinesm1 = y2 - y1;
+ int glines = glinesm1 + 1; //number of lines in the full gradient
+ double dlines = glines * amount; //number of lines that we want to show
+ int tdlines = static_cast<int> (dlines); //number of lines truncated to int
+ double residue = dlines - tdlines; //amount left over from integer truncation
+ for (int y = 0; y < tdlines; y++)
+ draw_line(dest, x1, y1 + y, x2, y1 + y, Color::alpha_blend(c2, c1,
+ 1.0 * y / glinesm1));
+ if (tdlines < glines) //correct undrawn line by using alpha blending
+ {
+ Color backcolor = get_point(dest, x1, y1 + tdlines);
+ Color forecolor = Color::alpha_blend(c2, c1, 1.0 * tdlines / glinesm1);
+ Color color = Color::alpha_blend(forecolor, backcolor, residue);
+ draw_line(dest, x1, y1 + tdlines, x2, y1 + tdlines, color);
+ }
+}
+
+void
+Xwrapper::draw_border(WMPixmap & dest, int x, int y, int width, int height,
+ int thickness, Color topleft, Color botright,
+ Color corner) const
+{
+ if (width / 2 < thickness || height / 2 < thickness) return;
+
+ fill_rectangle(dest, x, y, width, thickness, topleft);
+ fill_rectangle(dest, x, y, thickness, height, topleft);
+ fill_rectangle(dest, x, y + height - thickness, width, thickness, botright);
+ fill_rectangle(dest, x + width - thickness, y, thickness, height, botright);
+ fill_rectangle(dest, x, y + height - thickness, thickness, thickness, corner);
+ fill_rectangle(dest, x + width - thickness, y, thickness, thickness, corner);
+}
+
+void
+Xwrapper::draw_border(WMPixmap & dest, const WMRectangle & r, int thickness,
+ Color topleft, Color botright, Color corner) const
+{
+ draw_border(dest, r.left(), r.top(), r.width(), r.height(), thickness,
+ topleft, botright, corner);
+}
+
+void
+Xwrapper::fill_rectangle(WMPixmap & dest, int x, int y,
+ int width, int height, Color c) const
+{
+ set_GC(dest.gc, c);
+ X::XFillRectangle(xDisplay, dest.pixmap, dest.gc, x, y, width, height);
+}
+
+void
+Xwrapper::fill_rectangle(WMPixmap & dest, const WMRectangle & r, Color c)
+const
+{ fill_rectangle(dest, r.left(), r.top(), r.width(), r.height(), c); }
+
+void
+Xwrapper::fill_arc(WMPixmap & dest, int x, int y, int width, int height,
+ int angle1, int angle2, Color c)
+{
+ set_GC(dest.gc, c);
+ X::XFillArc(xDisplay, dest.pixmap, dest.gc, x, y, width, height, angle1,
+ angle2);
+}
+
+void
+Xwrapper::fill_polygon(WMPixmap & dest, const X::XPoint* points, int npoints,
+ Color c, XShape shape) const
+{
+ set_GC(dest.gc, c);
+ X::XFillPolygon(xDisplay, dest.pixmap, dest.gc,
+ const_cast<X::XPoint*>(points), npoints, shape,
+ X_MACRO(CoordModeOrigin));
+}
+
+void
+Xwrapper::clear_rectangle(WMPixmap & dest, int x, int y,
+ int width, int height) const
+{
+ X::XClearArea(xDisplay, dest.pixmap, x, y, width, height,
+ /* don't generate expose events */ false);
+}
+
+void
+Xwrapper::clear_rectangle(WMPixmap & dest, const WMRectangle & r) const
+{ clear_rectangle(dest, r.left(), r.top(), r.width(), r.height()); }
+
+void
+Xwrapper::copy_rectangle(const WMPixmap & source, WMPixmap & dest,
+ int source_x, int source_y,
+ int source_w, int source_h,
+ int dest_x, int dest_y) const
+{
+ X::XCopyArea(xDisplay, source.pixmap, dest.pixmap, dest.gc, source_x,
+ source_y, source_w, source_h, dest_x, dest_y);
+}
+
+void
+Xwrapper::copy_rectangle(const WMPixmap & source, WMPixmap & dest,
+ const WMRectangle & r, int dest_x, int dest_y) const
+{
+ copy_rectangle(source, dest, r.left(), r.top(), r.width(), r.height(),
+ dest_x, dest_y);
+}
+
+void
+Xwrapper::copy_rectangle(const WMPixmap & source, X::Drawable & dest,
+ int source_x, int source_y,
+ int source_w, int source_h,
+ int dest_x, int dest_y) const
+{
+ X::XCopyArea(xDisplay, source.pixmap, dest, xGC, source_x, source_y,
+ source_w, source_h, dest_x, dest_y);
+}
+
+void
+Xwrapper::copy_rectangle(const WMPixmap & source, X::Drawable & dest,
+ const WMRectangle & r, int dest_x, int dest_y) const
+{
+ copy_rectangle(source, dest, r.left(), r.top(), r.width(), r.height(),
+ dest_x, dest_y);
+}
+
diff --git a/wmapp/xwrapper.h b/wmapp/xwrapper.h
new file mode 100644
index 0000000..4f1b038
--- /dev/null
+++ b/wmapp/xwrapper.h
@@ -0,0 +1,140 @@
+#include "colors.h"
+
+#ifndef _MY_XWRAPPER_H
+#define _MY_XWRAPPER_H
+
+//These must be included here so that important types and functions aren't
+//dragged into the X namespace, but left undefined in the global namespace.
+extern "C" {
+# include <stddef.h>
+# include <stdlib.h>
+# include <sys/types.h>
+# include <malloc.h>
+}
+namespace X {
+ // Unfortunately, many common X calls are actually macros and the X::
+ // prefix must be avoided when using them. Still, it is nice to use
+ // a separate namespace whenever possible.
+
+ // the next line ensures that X macros are expanded correctly into functions
+ // in the X namespace, since _XPrivDisplay appears to be the only
+ // real X object used by all X macros:
+# define _XPrivDisplay X::_XPrivDisplay
+
+ // this is just so I can easily see which identifiers are macros from Xlib
+ // that can't be prefixed by "X::"
+# define X_MACRO(x) (x)
+
+ extern "C" {
+# include <X11/X.h>
+# include <X11/Xlib.h>
+# include <X11/xpm.h>
+# include <X11/extensions/shape.h>
+ }
+};
+
+// forward declaration for rectangle
+struct WMRectangle;
+
+struct WMPixmap {
+ X::Pixmap pixmap;
+ X::Pixmap mask;
+ X::GC gc;
+ X::XpmAttributes attr;
+};
+
+// global X thingies
+extern X::Window wActiveWin, wProgramWin;
+extern X::Atom deleteWin, _XA_GNUSTEP_WM_FUNC;
+
+class Xwrapper {
+ private:
+ X::Display * xDisplay;
+ X::Window xRootWindow;
+ X::XWindowAttributes xAttributes;
+ mutable X::GC xGC;
+
+ unsigned long color_to_xcolor(Color) const;
+ void set_GC(X::GC, Color) const;
+
+ public:
+ Xwrapper();
+ ~Xwrapper();
+
+ X::Display * xdisplay() const;
+ const X::Window xrootwin() const;
+ X::GC get_GC() const;
+
+ bool create_pixmap(WMPixmap & dest, char * pixmap_bytes[]) const;
+ bool create_pixmap(WMPixmap & dest, const WMPixmap & source) const;
+ bool create_pixmap(WMPixmap & dest, const WMPixmap * source) const;
+ bool create_pixmap(WMPixmap & dest, int width, int height) const;
+ bool create_pixmap(WMPixmap & dest, int width, int height, int depth) const;
+
+ void free_pixmap(WMPixmap & dest) const;
+
+ Color get_point(const WMPixmap & src, int x, int y) const;
+
+ void draw_point(WMPixmap & dest, int x, int y, Color c) const;
+ void draw_line(WMPixmap & dest, int x1, int y1, int x2, int y2, Color c)
+ const;
+ void draw_arc(WMPixmap & dest, int x, int y, int width, int height,
+ int angle1, int angle2, Color c); //angles are in units of degrees * 64
+ void draw_lines(WMPixmap & dest, const X::XPoint* points, int npoints,
+ Color c) const; //X::XPoint is simply a struct { short x, y };
+
+ // draws a color gradient from left to right or bottom to top from color1
+ // to color2. amount is the proportion of the gradient to draw i.e. 0.5
+ // draws half the gradient. It should always be at least 2 pixels wide.
+ void draw_horizontal_gradient(WMPixmap & dest, int x1, int y1, int x2, int y2, Color c1, Color c2, double amount = 1.0);
+ void draw_vertical_gradient(WMPixmap & dest, int x1, int y1, int x2, int y2, Color c1, Color c2, double amount = 1.0);
+
+ void draw_border(WMPixmap & dest, int x, int y, int width, int height,
+ int thickness, Color topleft, Color botright, Color corner)
+ const;
+ void draw_border(WMPixmap & dest, const WMRectangle & posn, int thickness,
+ Color topleft, Color botright, Color corner) const;
+
+ void fill_rectangle(WMPixmap & dest, int x, int y, int width, int height,
+ Color c) const;
+ void fill_rectangle(WMPixmap & dest, const WMRectangle & posn, Color c)
+ const;
+
+ void fill_arc(WMPixmap & dest, int x, int y, int width, int height,
+ int angle1, int angle2, Color c); //angles are in units of degrees * 64
+
+ enum XShape { complex = X_MACRO(Complex), convex = X_MACRO(Convex),
+ nonconvex = X_MACRO(Nonconvex) };
+ void fill_polygon(WMPixmap & dest, const X::XPoint* points, int npoints,
+ Color c, XShape shape = complex) const;
+ //shape is simply a hint to the X server about what type of shape is
+ //being drawn. See XFillPolygon(3) for a complete description.
+
+ void clear_rectangle(WMPixmap & dest, int x, int y, int width, int height)
+ const;
+ void clear_rectangle(WMPixmap & dest, const WMRectangle & posn) const;
+
+ void copy_rectangle(const WMPixmap & source, WMPixmap & dest,
+ int source_x, int source_y, int source_w, int source_h,
+ int dest_x = 0, int dest_y = 0) const;
+ void copy_rectangle(const WMPixmap & source, WMPixmap & dest,
+ const WMRectangle & posn, int dest_x = 0, int dest_y = 0)
+ const;
+ void copy_rectangle(const WMPixmap & source, X::Drawable & dest,
+ int source_x, int source_y, int source_w, int source_h,
+ int dest_x = 0, int dest_y = 0) const;
+ void copy_rectangle(const WMPixmap & source, X::Drawable & dest,
+ const WMRectangle & posn, int dest_x = 0, int dest_y = 0)
+ const;
+};
+
+inline X::Display *
+Xwrapper::xdisplay() const { return xDisplay; }
+
+inline const X::Window
+Xwrapper::xrootwin() const { return xRootWindow; }
+
+inline X::GC
+Xwrapper::get_GC() const { return xGC; }
+
+#endif
diff --git a/3dObjects/ball-solid.wmc b/wmc/ball.wmc
similarity index 77%
rename from 3dObjects/ball-solid.wmc
rename to wmc/ball.wmc
index fa6f2ff..79b795f 100644
--- a/3dObjects/ball-solid.wmc
+++ b/wmc/ball.wmc
@@ -1,3 +1,5 @@
+# By wmCube author Robert Kling
+
WMCUBE_COORDINATES
1 -100 -100 100
2 100 -100 100
@@ -31,6 +33,57 @@ WMCUBE_COORDINATES
30 50 -50 -150
31 50 50 -150
32 -50 50 -150
+
+WMCUBE_LINES
+9 10
+10 6
+6 11
+11 12
+12 7
+7 13
+13 14
+14 8
+8 15
+15 16
+16 5
+5 9
+17 1
+1 18
+18 19
+19 2
+2 20
+20 21
+21 3
+3 22
+22 23
+23 4
+4 24
+24 17
+9 18
+10 19
+11 20
+12 21
+13 22
+14 23
+15 24
+16 17
+25 26
+26 27
+27 28
+28 25
+25 1
+26 2
+27 3
+28 4
+29 30
+30 31
+31 32
+32 29
+5 29
+6 30
+7 31
+8 32
+
WMCUBE_PLANES
1 18 19
1 19 2
diff --git a/wmc/cossin.wmc b/wmc/cossin.wmc
new file mode 100755
index 0000000..93dd0a1
--- /dev/null
+++ b/wmc/cossin.wmc
@@ -0,0 +1,362 @@
+WMCUBE_COORDINATES
+1 100 0 0
+2 54.030230586814 84.1470984807897 45.4648713412841
+3 -41.6146836547142 90.9297426825682 -37.8401247653964
+4 -98.9992496600445 14.1120008059867 -13.9707749099463
+5 -65.3643620863612 -75.6802495307928 49.4679123311691
+6 28.3662185463226 -95.8924274663138 -27.2010555444685
+7 96.0170286650366 -27.9415498198926 -26.8286459000217
+8 75.3902254343305 65.6986598718789 49.5303677847435
+9 -14.5500033808614 98.9358246623382 -14.3951658332533
+10 -91.1130261884677 41.2118485241757 -37.5493623385838
+11 -83.9071529076452 -54.402111088937 45.6472625363814
+12 0.442569798805079 -99.9990206550704 -0.442565464520194
+13 84.3853958732492 -53.6572918000435 -45.2789181003312
+14 90.7446781450196 42.0167036826641 38.1279225239801
+15 13.6737218207834 99.060735569487 13.5452894153935
+16 -75.9687912858821 65.0287840157117 -49.4015812046431
+17 -95.7659480323385 -28.7903316665065 27.5713340620845
+18 -27.5163338051597 -96.1397491879557 26.4541343060012
+19 66.031670824408 -75.0987246771676 -49.5889426721558
+20 98.8704618186669 14.9877209662952 14.8184289354693
+21 40.8082061813392 91.2945250727628 37.2556580239674
+22 -54.7729260224268 83.6655638536056 -45.8260773957817
+23 -99.9960826394637 -0.885130929040388 0.885096255270679
+24 -53.2833020333398 -84.6220404175171 45.0894173824405
+25 42.4179007336997 -90.5578362006624 -38.4127330661833
+26 99.1202811863474 -13.2351750097773 -13.1187426851964
+27 64.691932232864 76.2558450479603 49.3313796020243
+28 -29.2138808733836 95.6375928404503 -27.9394524425808
+29 -96.2605866313567 27.0905788307869 -26.0775501043456
+30 -74.8057529689 -66.3633884212967 49.6436324042268
+31 15.4251449887584 -98.8031624092862 -15.2405310551108
+32 91.4742357804531 -40.4037645323065 -36.9590348324611
+33 83.422336050651 55.1426681241691 46.0013019098395
+34 -1.32767472230595 99.9911860107267 -1.32755770119834
+35 -84.8570274784605 52.9082686120024 -44.8963840344646
+36 -90.3692205091507 -42.8182669496151 38.6945340778945
+37 -12.7963689627405 -99.1778853443116 12.6911681381018
+38 76.5414051945343 -64.3538133357 -49.2573130234124
+39 95.5073644047295 29.6368578709385 28.305381844909
+40 26.6642932359937 96.3795386284088 25.6989227993768
+41 -66.6938061652262 74.5113160479349 -49.6944326961688
+42 -98.7339277523826 -15.8622668804709 15.6614391216543
+43 -39.9985314988351 -91.6521547915634 36.6595160036646
+44 55.5113301520626 -83.1774742628598 -46.172922350203
+45 99.9843308647691 1.77019251054136 1.76991513668303
+46 52.532198881773 85.0903524534118 44.6998331800279
+47 -43.2177944884778 90.1788347648809 -38.9733034807902
+48 -99.2335469150929 12.3573122745224 -12.2625992733827
+49 -64.01443394692 -76.8254661323667 49.1793872717172
+50 30.0592543743637 -95.3752652759472 -28.6690935995211
+51 96.4966028492113 -26.2374853703929 -25.3182820554879
+52 74.2154196813783 67.0229175843375 49.7413395679203
+53 -16.2990780795705 98.6627592040485 -16.0811201581265
+54 -91.8282786212119 39.5925150181834 -36.3571250040426
+55 -82.930983286315 -55.8789048851616 46.3409252708893
+56 2.21267562619557 -99.975517335862 -2.21213390425355
+57 85.3220107722584 -52.1551002086912 -44.4997802183417
+58 89.9866826969194 43.6164755247825 39.2490194340655
+59 11.9180135448819 99.2872648084537 11.8330696682143
+60 -77.1080222975845 63.6738007139138 -49.0976084522042
+61 -95.2412980415156 -30.4810621102217 29.0305592106157
+62 -25.8101635938267 -96.6117770008393 24.9356576948197
+63 67.3507162323586 -73.9180696649223 -49.784349344459
+64 98.589658158255 16.7355700302807 16.4995412836891
+65 39.185723042955 92.0026038196791 36.0518855250866
+66 -56.2453851238172 82.6828679490103 -46.5052975093381
+67 -99.964745596635 -2.65511540239668 2.65417935730291
+68 -51.7769799789505 -85.5519978975322 44.2962408229974
+69 44.0143022496041 -89.7927680689291 -39.5216603361444
+70 99.3390379722272 -11.4784813783187 -11.4026129750431
+71 63.33192030863 77.3890681557889 49.0119829720156
+72 -30.9022728166071 95.1054653254375 -29.3897503583703
+73 -96.7250588273882 25.3823362762036 -24.5510796949235
+74 -73.6192718227316 -67.6771956887308 49.8234586560887
+75 17.1717341830778 -98.5146260468247 -16.9166697162138
+76 92.1751269724749 -38.778163540943 -35.7438214814582
+77 82.4331331107558 56.610763689818 46.6660261874431
+78 -3.09750317312165 99.9520158580731 -3.09601686280287
+79 -85.7803093244988 51.3978455987535 -44.089230940739
+80 -89.5970946790963 -44.4112668707508 39.7912048263728
+81 -11.0387243839048 -99.3888653923375 10.9712629189502
+82 77.6685982021631 -62.9887994274454 -48.922517539669
+83 94.9677697882543 31.3228782433085 29.7466389011604
+84 24.9540117973338 96.8364461100185 24.1645781864128
+85 -68.0023495587339 73.3190320073292 -49.858664438704
+86 -98.4376643394042 -17.6075619948587 17.3324727748515
+87 -38.3698444949742 -92.345844700406 35.4329570091161
+88 56.9750334265312 -82.1817836630823 -46.8230987125607
+89 99.9373283695125 3.53983027336607 3.53761180401726
+90 51.0177044941669 86.0069405812453 43.8787667902134
+91 -44.807361612917 89.3996663600558 -40.0576317866915
+92 -99.4367460928201 10.5987511751157 -10.5390532950096
+93 -62.6444447910339 -77.9466069615805 48.8292191645315
+94 31.7428701519702 -94.8282141269947 -30.1011968777642
+95 96.9459366669988 -24.5251985467654 -23.7761834506029
+96 73.017356099482 68.3261714736121 49.88996393403
+97 -18.0430449291084 98.3587745434345 -17.7469178825923
+98 -92.5147536596414 37.9607739027522 -35.1193164634246
+99 -81.9288245291459 -57.3381871990423 46.9765027784966
+100 3.98208803931389 -99.9206834186354 -3.97892958321418
+101 86.2318872287684 -50.6365641109759 -43.6648648606997
+102 89.200486978816 45.2025787178351 40.3209203432915
+103 10.1585703696621 99.4826791358406 10.1060179656396
+104 -78.2230889887116 62.2988631442349 -48.7320951562705
+105 -94.6868010751213 -32.1622403162531 30.453396509553
+106 -24.0959049236201 -97.0535283537485 23.3859259171379
+107 68.6486550906984 -72.7142500080853 -49.9173546898386
+108 98.2779582041221 18.4781744560667 18.159972568818
+109 37.5509597767012 92.6818505417785 34.8029244172456
+110 -57.7002178942952 81.6742606636317 -47.1262263664701
+111 -99.9020813314648 -4.4242678085071 4.41993562437658
+112 -50.2544319145385 -86.4551448610608 43.4475419108175
+113 45.5969104444276 -88.9995604366833 -40.5810498682487
+114 99.5266636217131 -9.7181905893209 -9.67219085795039
+115 61.952061255921 78.498038868131 48.6311531242812
+116 -32.5809805219964 94.543533402477 -30.8032102026682
+117 -97.1592190628802 23.6661393364286 -22.9938361616071
+118 -72.4097196700474 -68.9697940935389 49.9408345601404
+119 18.9129420528958 -98.1952169044084 -18.5716044718461
+120 92.8471320739076 -37.140410143809 -34.4838056590133
+121 81.4180970526562 58.0611184212314 47.2722577460558
+122 -4.86636092001539 99.881522472358 -4.86059537591122
+123 -86.676709105198 49.8713153896394 -43.2268149672136
+124 -88.7968906691855 -45.9903490689591 40.8379999811404
+125 -9.27762045976609 -99.5686986889179 9.2376059610859
+126 78.7714512144235 -61.6040459188656 -48.5264009770903
+127 94.3984139152314 32.9990825673782 31.1506105501826
+128 23.2359102029658 97.2630067242408 22.5999449031492
+129 -69.2895821920165 72.1037710501732 -49.9604017053531
+130 -98.1105522649388 -19.3473392038468 18.9817813414652
+131 -36.7291330454696 -93.0105950186762 34.1619851907925
+132 58.4208817109289 -81.16033871367 -47.4145854761024
+133 99.8590072439991 5.30835871460582 5.30087431335569
+134 49.487222040343 86.8965756214236 43.0027013232285
+135 -46.3828868851872 88.5924816459948 -41.091750550642
+136 -99.6087835141185 8.83686861040014 -8.80229732356057
+137 -61.25482394961 -79.0433206722889 48.4178469217362
+138 33.4165382630761 -94.2514454558251 -31.4955703342481
+139 97.3648893049518 -22.8052259500861 -22.2042830020455
+140 71.7964101410472 69.6080131224741 49.9760545924455
+141 -19.7813574004268 98.0239659440312 -19.3904710414615
+142 -93.172236174352 36.3171365373259 -33.8374882263192
+143 -80.9009906953598 -58.7795007167406 47.5531984056293
+144 5.75025253491242 -99.8345360873918 -5.7407379420833
+145 87.1147401032343 -49.1021593898469 -42.775218537541
+146 88.38633737085 46.7745162045133 41.3422816961041
+147 8.39594367418485 99.6469173121774 8.36629905059196
+148 -79.3136419166478 60.9044021883292 -48.3054994631265
+149 -94.1026309029144 -33.8333394324276 31.8380625282276
+150 -22.3740950135584 -97.4648648094495 21.8068814573024
+151 69.9250806478375 -71.4876429629165 -49.9877919950575
+152 97.9354596376429 20.2149881415654 19.797641552137
+153 35.9044286891116 93.3320523748862 33.5103401890253
+154 -59.1369684144325 80.6400580775486 -47.6880856746999
+155 -99.80810948185 -6.19203372560573 6.18015180000565
+156 -48.7161349803341 -87.3311982774648 42.544384432793
+157 47.1652293561339 -88.1784618814781 -41.5895737891102
+158 99.6830993361718 -7.95485428747221 -7.92964530142864
+159 60.552787498699 79.5824096527455 48.1893674033711
+160 -34.2494779115907 93.9519731713148 -32.1780602988131
+161 -97.5629312795237 21.9425258379005 -21.4077714042226
+162 -71.1774755635724 -70.2407785577371 49.9956129935963
+163 20.6482229337811 -97.845035079338 -20.203260972818
+164 93.490040489975 -35.4910175844935 -33.1805667100472
+165 80.3775459710974 59.4932778023209 47.8192367152731
+166 -6.63369363356237 99.7797279449891 -6.6190814602726
+167 -87.5459459043705 48.3291563728257 -42.3102170941926
+168 -87.9688592495152 -47.5550186871899 41.8336074550147
+169 -7.51360908983532 -99.717328877408 7.49237028667391
+170 79.8496186162556 -60.1999867677605 -48.069459841093
+171 93.7994752119442 34.664945549703 32.5155370081276
+172 21.5105268762141 97.6590867943566 21.0069841119653
+173 -70.55510066863 70.8659140182323 -49.9995169753086
+174 -97.7526940402531 -21.0810532913481 20.6072975243543
+175 -35.0769113209131 -93.6461974251213 32.848193626217
+176 59.84842190141 -80.1134595178041 -47.9466412520307
+177 99.7493920327152 7.07522360803452 7.05749253396957
+178 47.9412311470322 87.7589787777116 42.0727348680976
+179 -47.9438765629173 87.7575335804269 -42.0743635744605
+180 -99.7496052654355 7.07221672389912 -7.05450826560549
+181 -59.8460069057858 -80.115263573383 47.9457861707153
+
+WMCUBE_PLANES
+1 2 3
+2 3 4
+3 4 5
+4 5 6
+5 6 7
+6 7 8
+7 8 9
+8 9 10
+9 10 11
+10 11 12
+11 12 13
+12 13 14
+13 14 15
+14 15 16
+15 16 17
+16 17 18
+17 18 19
+18 19 20
+19 20 21
+20 21 22
+21 22 23
+22 23 24
+23 24 25
+24 25 26
+25 26 27
+26 27 28
+27 28 29
+28 29 30
+29 30 31
+30 31 32
+31 32 33
+32 33 34
+33 34 35
+34 35 36
+35 36 37
+36 37 38
+37 38 39
+38 39 40
+39 40 41
+40 41 42
+41 42 43
+42 43 44
+43 44 45
+44 45 46
+45 46 47
+46 47 48
+47 48 49
+48 49 50
+49 50 51
+50 51 52
+51 52 53
+52 53 54
+53 54 55
+54 55 56
+55 56 57
+56 57 58
+57 58 59
+58 59 60
+59 60 61
+60 61 62
+61 62 63
+62 63 64
+63 64 65
+64 65 66
+65 66 67
+66 67 68
+67 68 69
+68 69 70
+69 70 71
+70 71 72
+71 72 73
+72 73 74
+73 74 75
+74 75 76
+75 76 77
+76 77 78
+77 78 79
+78 79 80
+79 80 81
+80 81 82
+81 82 83
+82 83 84
+83 84 85
+84 85 86
+85 86 87
+86 87 88
+87 88 89
+88 89 90
+89 90 91
+90 91 92
+91 92 93
+92 93 94
+93 94 95
+94 95 96
+95 96 97
+96 97 98
+97 98 99
+98 99 100
+99 100 101
+100 101 102
+101 102 103
+102 103 104
+103 104 105
+104 105 106
+105 106 107
+106 107 108
+107 108 109
+108 109 110
+109 110 111
+110 111 112
+111 112 113
+112 113 114
+113 114 115
+114 115 116
+115 116 117
+116 117 118
+117 118 119
+118 119 120
+119 120 121
+120 121 122
+121 122 123
+122 123 124
+123 124 125
+124 125 126
+125 126 127
+126 127 128
+127 128 129
+128 129 130
+129 130 131
+130 131 132
+131 132 133
+132 133 134
+133 134 135
+134 135 136
+135 136 137
+136 137 138
+137 138 139
+138 139 140
+139 140 141
+140 141 142
+141 142 143
+142 143 144
+143 144 145
+144 145 146
+145 146 147
+146 147 148
+147 148 149
+148 149 150
+149 150 151
+150 151 152
+151 152 153
+152 153 154
+153 154 155
+154 155 156
+155 156 157
+156 157 158
+157 158 159
+158 159 160
+159 160 161
+160 161 162
+161 162 163
+162 163 164
+163 164 165
+164 165 166
+165 166 167
+166 167 168
+167 168 169
+168 169 170
+169 170 171
+170 171 172
+171 172 173
+172 173 174
+173 174 175
+174 175 176
+175 176 177
+176 177 178
+177 178 179
+178 179 180
diff --git a/wmc/coussin.bande.diag.wmc b/wmc/coussin.bande.diag.wmc
new file mode 100755
index 0000000..7287b32
--- /dev/null
+++ b/wmc/coussin.bande.diag.wmc
@@ -0,0 +1,124 @@
+WMCUBE_COORDINATES
+1 -3 -3 -0.989992496600445
+2 -3 -2 -0.923561053656561
+3 -3 -1 -0.875844530679003
+4 -3 0 -0.858525596664594
+5 -3 1 -0.875844530679003
+6 -3 2 -0.923561053656561
+7 -3 3 -0.989992496600445
+8 -2 -3 -0.923561053656561
+9 -2 -2 -0.416146836547142
+10 -2 -1 -0.0516802364419242
+11 -2 0 0.0806046117362795
+12 -2 1 -0.0516802364419242
+13 -2 2 -0.416146836547142
+14 -2 3 -0.923561053656561
+15 -1 -3 -0.875844530679003
+16 -1 -2 -0.0516802364419242
+17 -1 -1 0.54030230586814
+18 -1 0 0.755165123780746
+19 -1 1 0.54030230586814
+20 -1 2 -0.0516802364419242
+21 -1 3 -0.875844530679003
+22 0 -3 -0.858525596664594
+23 0 -2 0.0806046117362795
+24 0 -1 0.755165123780746
+25 0 0 1
+26 0 1 0.755165123780746
+27 0 2 0.0806046117362795
+28 0 3 -0.858525596664594
+29 1 -3 -0.875844530679003
+30 1 -2 -0.0516802364419242
+31 1 -1 0.54030230586814
+32 1 0 0.755165123780746
+33 1 1 0.54030230586814
+34 1 2 -0.0516802364419242
+35 1 3 -0.875844530679003
+36 2 -3 -0.923561053656561
+37 2 -2 -0.416146836547142
+38 2 -1 -0.0516802364419242
+39 2 0 0.0806046117362795
+40 2 1 -0.0516802364419242
+41 2 2 -0.416146836547142
+42 2 3 -0.923561053656561
+43 3 -3 -0.989992496600445
+44 3 -2 -0.923561053656561
+45 3 -1 -0.875844530679003
+46 3 0 -0.858525596664594
+47 3 1 -0.875844530679003
+48 3 2 -0.923561053656561
+49 3 3 -0.989992496600445
+
+WMCUBE_PLANES
+1 8 2
+8 2 9
+2 3 9
+9 10 3
+3 10 4
+10 4 11
+4 5 11
+11 12 5
+5 12 6
+12 6 13
+6 7 13
+13 14 7
+8 9 15
+15 16 9
+9 16 10
+16 10 17
+10 11 17
+17 18 11
+11 18 12
+18 12 19
+12 13 19
+19 20 13
+13 20 14
+20 14 21
+15 22 16
+22 16 23
+16 17 23
+23 24 17
+17 24 18
+24 18 25
+18 19 25
+25 26 19
+19 26 20
+26 20 27
+20 21 27
+27 28 21
+22 23 29
+29 30 23
+23 30 24
+30 24 31
+24 25 31
+31 32 25
+25 32 26
+32 26 33
+26 27 33
+33 34 27
+27 34 28
+34 28 35
+29 36 30
+36 30 37
+30 31 37
+37 38 31
+31 38 32
+38 32 39
+32 33 39
+39 40 33
+33 40 34
+40 34 41
+34 35 41
+41 42 35
+36 37 43
+43 44 37
+37 44 38
+44 38 45
+38 39 45
+45 46 39
+39 46 40
+46 40 47
+40 41 47
+47 48 41
+41 48 42
+48 42 49
diff --git a/3dObjects/cross2-solid.wmc b/wmc/cross2-solid.wmc
similarity index 100%
rename from 3dObjects/cross2-solid.wmc
rename to wmc/cross2-solid.wmc
diff --git a/3dObjects/cross3-solid.wmc b/wmc/cross3-solid.wmc
similarity index 100%
rename from 3dObjects/cross3-solid.wmc
rename to wmc/cross3-solid.wmc
diff --git a/3dObjects/cube-solid.wmc b/wmc/cube.wmc
similarity index 72%
rename from 3dObjects/cube-solid.wmc
rename to wmc/cube.wmc
index 31d6a7b..58219d0 100644
--- a/3dObjects/cube-solid.wmc
+++ b/wmc/cube.wmc
@@ -1,3 +1,5 @@
+# By wmCube author Robert Kling
+
WMCUBE_COORDINATES
1 -180 -180 180
2 180 -180 180
@@ -8,6 +10,20 @@ WMCUBE_COORDINATES
7 180 180 -180
8 -180 180 -180
+WMCUBE_LINES
+1 2
+2 3
+3 4
+4 1
+5 6
+6 7
+7 8
+8 5
+1 5
+2 6
+3 7
+4 8
+
WMCUBE_PLANES
1 2 3
1 3 4
diff --git a/wmc/diamond.wmc b/wmc/diamond.wmc
new file mode 100644
index 0000000..9821455
--- /dev/null
+++ b/wmc/diamond.wmc
@@ -0,0 +1,107 @@
+# This object is somewhat broken
+# Originally by Nicolas Mieville <nm at altern.org>
+
+WMCUBE_COORDINATES
+
+1 -50 0 0
+2 -35 0 35
+3 0 0 50
+4 35 0 35
+5 50 0 0
+6 35 0 -35
+7 0 0 -50
+8 -35 0 -35
+9 -32 17 13
+10 -13 17 32
+11 13 17 32
+12 32 17 13
+13 32 17 -13
+14 13 17 -32
+15 -13 17 -32
+16 -32 17 -13
+17 0 -60 0
+18 0 17 0
+
+WMCUBE_LINES
+
+1 2
+2 3
+3 4
+4 5
+5 6
+6 7
+7 8
+8 1
+
+9 10
+10 11
+11 12
+12 13
+13 14
+14 15
+15 16
+16 9
+
+1 9
+1 8
+2 10
+2 9
+3 11
+3 10
+4 12
+4 11
+5 13
+5 12
+6 14
+6 13
+7 15
+7 14
+8 16
+8 15
+
+17 1
+17 2
+17 3
+17 4
+17 5
+17 6
+17 7
+17 8
+
+WMCUBE_PLANES
+
+17 1 2
+17 2 3
+17 3 4
+17 4 5
+17 5 6
+17 6 7
+17 7 8
+17 8 1
+
+2 1 9
+2 9 10
+3 2 10
+3 10 11
+4 3 11
+4 11 12
+5 4 12
+5 12 13
+6 5 13
+6 13 14
+7 6 14
+7 14 15
+8 7 15
+8 15 16
+9 8 16
+9 1 16
+1 8 16
+
+9 18 10
+10 18 11
+11 18 12
+12 18 13
+13 18 14
+14 18 15
+15 18 16
+16 18 9
diff --git a/3dObjects/dice-solid.wmc b/wmc/dice.wmc
similarity index 78%
rename from 3dObjects/dice-solid.wmc
rename to wmc/dice.wmc
index cd561df..2de7139 100644
--- a/3dObjects/dice-solid.wmc
+++ b/wmc/dice.wmc
@@ -1,3 +1,5 @@
+# By Robert Kling
+
WMCUBE_COORDINATES
1 -70 -120 120
2 70 -120 120
@@ -26,6 +28,49 @@ WMCUBE_COORDINATES
23 120 120 -70
24 -120 120 -70
+WMCUBE_LINES
+
+1 2
+2 3
+3 4
+4 5
+5 6
+6 7
+7 8
+8 1
+
+9 10
+10 11
+11 12
+12 13
+13 14
+14 15
+15 16
+16 9
+
+1 17
+2 18
+3 18
+4 19
+5 19
+6 20
+7 20
+8 17
+
+9 21
+10 22
+11 22
+12 23
+13 23
+14 24
+15 24
+16 21
+
+17 21
+18 22
+19 23
+20 24
+
WMCUBE_PLANES
17 1 8
diff --git a/wmc/hyp_par.wmc b/wmc/hyp_par.wmc
new file mode 100644
index 0000000..1119522
--- /dev/null
+++ b/wmc/hyp_par.wmc
@@ -0,0 +1,70 @@
+WMCUBE_COORDINATES
+1 50 50 50
+2 -50 50 50
+3 -50 -50 50
+4 50 -50 50
+5 50 50 -50
+6 -50 50 -50
+7 -50 -50 -50
+8 50 -50 -50
+9 50 40 40
+10 -50 -40 40
+11 50 30 30
+12 -50 -30 30
+13 50 20 20
+14 -50 -20 20
+15 50 10 10
+16 -50 -10 10
+17 50 0 0
+18 -50 0 0
+19 50 -10 -10
+20 -50 10 -10
+21 50 -20 -20
+22 -50 20 -20
+23 50 -30 -30
+24 -50 30 -30
+25 50 -40 -40
+26 -50 40 -40
+27 -40 -40 50
+28 -40 40 -50
+29 -30 -30 50
+30 -30 30 -50
+31 -20 -20 50
+32 -20 20 -50
+
+33 -10 -10 50
+34 -10 10 -50
+35 0 0 50
+36 0 0 -50
+37 10 10 50
+38 10 -10 -50
+39 20 20 50
+40 20 -20 -50
+41 30 30 50
+42 30 -30 -50
+43 40 40 50
+44 40 -40 -50
+
+WMCUBE_LINES
+9 10
+11 12
+13 14
+15 16
+17 18
+19 20
+21 22
+23 24
+25 26
+27 28
+29 30
+31 32
+33 34
+35 36
+37 38
+39 40
+41 42
+43 44
+1 8
+8 6
+6 3
+3 1
diff --git a/wmc/judaspriest.wmc b/wmc/judaspriest.wmc
new file mode 100644
index 0000000..75f79db
--- /dev/null
+++ b/wmc/judaspriest.wmc
@@ -0,0 +1,239 @@
+WMCUBE_COORDINATES
+1 -66 100 35
+2 -27 17 35
+3 -106 17 35
+4 -130 55 35
+5 -162 21 35
+6 -117 -62 35
+7 -68 -108 35
+8 -7 -108 35
+9 -28 -60 35
+10 -64 -60 35
+11 -90 -24 35
+12 -8 -24 35
+13 37 -118 35
+14 83 -118 35
+15 37 -24 35
+16 120 -24 35
+17 114 -68 35
+18 101 -68 35
+19 122 -115 35
+20 146 -115 35
+21 164 -44 35
+22 132 27 35
+23 84 52 35
+24 101 17 35
+25 18 17 35
+26 -11 74 35
+
+27 -66 100 -35
+28 -27 17 -35
+29 -106 17 -35
+30 -130 55 -35
+31 -162 21 -35
+32 -117 -62 -35
+33 -68 -108 -35
+34 -7 -108 -35
+35 -28 -60 -35
+36 -64 -60 -35
+37 -90 -24 -35
+38 -8 -24 -35
+39 37 -118 -35
+40 83 -118 -35
+41 37 -24 -35
+42 120 -24 -35
+43 114 -68 -35
+44 101 -68 -35
+45 122 -115 -35
+46 146 -115 -35
+47 164 -44 -35
+48 132 27 -35
+49 84 52 -35
+50 101 17 -35
+51 18 17 -35
+52 -11 74 -35
+
+
+WMCUBE_LINES
+1 2
+2 3
+3 4
+4 5
+5 6
+6 7
+7 8
+8 9
+9 10
+10 11
+11 12
+12 13
+13 14
+14 15
+15 16
+16 17
+17 18
+18 19
+19 20
+20 21
+21 22
+22 23
+23 24
+24 25
+25 26
+26 1
+
+27 28
+28 29
+29 30
+30 31
+31 32
+32 33
+33 34
+34 35
+35 36
+36 37
+37 38
+38 39
+39 40
+40 41
+41 42
+42 43
+43 44
+44 45
+45 46
+46 47
+47 48
+48 49
+49 50
+50 51
+51 52
+52 27
+
+1 27
+2 28
+3 29
+4 30
+5 31
+6 32
+7 33
+8 34
+9 35
+10 36
+11 37
+12 38
+13 39
+14 40
+15 41
+16 42
+17 43
+18 44
+19 45
+20 46
+21 47
+22 48
+23 49
+24 50
+25 51
+26 52
+
+WMCUBE_PLANES
+1 2 26
+26 2 25
+26 2 15
+24 3 11
+24 11 16
+15 12 13
+15 2 13
+15 13 14
+23 24 22
+22 24 16
+22 16 21
+21 16 17
+21 17 20
+17 19 20
+17 18 19
+4 5 3
+3 5 6
+3 6 11
+11 6 10
+10 6 7
+9 10 7
+9 7 8
+
+52 28 27
+51 28 52
+41 28 52
+37 29 50
+42 37 50
+39 38 41
+39 28 41
+40 39 41
+48 50 49
+42 50 48
+47 42 48
+43 42 47
+46 43 47
+46 45 43
+45 44 43
+29 31 30
+32 31 29
+37 32 29
+36 32 37
+33 32 36
+33 36 35
+34 33 35
+
+13 1 27
+27 39 13
+28 29 3
+28 3 2
+29 24 50
+24 29 3
+30 4 29
+29 4 3
+31 4 30
+4 31 5
+32 6 5
+5 31 32
+7 6 32
+7 32 33
+33 34 7
+7 34 8
+8 35 9
+35 8 34
+36 9 35
+9 36 10
+10 37 11
+37 10 36
+12 37 38
+37 12 11
+13 40 14
+13 39 40
+14 41 15
+41 14 40
+16 41 42
+41 16 15
+42 16 37
+11 37 16
+17 16 42
+43 17 42
+17 43 44
+18 17 44
+44 19 18
+19 44 45
+20 45 46
+45 20 19
+20 47 21
+47 20 46
+21 48 22
+48 21 47
+22 49 23
+49 22 48
+23 49 24
+50 24 49
+51 24 50
+24 51 25
+25 52 26
+52 25 51
+27 1 52
+1 26 52
\ No newline at end of file
diff --git a/3dObjects/peace.wmc b/wmc/peace.wmc
similarity index 98%
rename from 3dObjects/peace.wmc
rename to wmc/peace.wmc
index 22b57cb..ff28e65 100644
--- a/3dObjects/peace.wmc
+++ b/wmc/peace.wmc
@@ -1,3 +1,5 @@
+#By Peter Kokles <kokles at bb.telecom.sk>
+
WMCUBE_COORDINATES
1 0 -120 10
2 -46 -111 10
diff --git a/3dObjects/radioactive.wmc b/wmc/radioactive.wmc
similarity index 98%
rename from 3dObjects/radioactive.wmc
rename to wmc/radioactive.wmc
index 675ee08..87f49f5 100644
--- a/3dObjects/radioactive.wmc
+++ b/wmc/radioactive.wmc
@@ -1,3 +1,5 @@
+#By Peter Kokles <kokles at bb.telecom.sk>
+
WMCUBE_COORDINATES
1 0 0 0
2 5 -19 0
diff --git a/3dObjects/cross4-solid.wmc b/wmc/star-solid.wmc
similarity index 60%
rename from 3dObjects/cross4-solid.wmc
rename to wmc/star-solid.wmc
index 371d57e..a52f95f 100644
--- a/3dObjects/cross4-solid.wmc
+++ b/wmc/star-solid.wmc
@@ -7,30 +7,30 @@ WMCUBE_COORDINATES
6 50 -50 -50
7 50 50 -50
8 -50 50 -50
-9 -50 -300 -50
-10 50 -300 -50
-11 300 -50 -50
-12 300 50 -50
-13 50 300 -50
-14 -50 300 -50
-15 -300 50 -50
-16 -300 -50 -50
-17 -300 -50 50
-18 -50 -300 50
-19 50 -300 50
-20 300 -50 50
-21 300 50 50
-22 50 300 50
-23 -50 300 50
-24 -300 50 50
-25 -50 -50 300
-26 50 -50 300
-27 50 50 300
-28 -50 50 300
-29 -50 -50 -300
-30 50 -50 -300
-31 50 50 -300
-32 -50 50 -300
+9 -10 -150 -10
+10 10 -150 -10
+11 150 -10 -10
+12 150 10 -10
+13 10 150 -10
+14 -10 150 -10
+15 -150 10 -10
+16 -150 -10 -10
+17 -150 -10 10
+18 -10 -150 10
+19 10 -150 10
+20 150 -10 10
+21 150 10 10
+22 10 150 10
+23 -10 150 10
+24 -150 10 10
+25 -10 -10 150
+26 10 -10 150
+27 10 10 150
+28 -10 10 150
+29 -10 -10 -150
+30 10 -10 -150
+31 10 10 -150
+32 -10 10 -150
WMCUBE_PLANES
1 18 19
diff --git a/3dObjects/wmlogo.wmc b/wmc/wmlogo.wmc
similarity index 92%
rename from 3dObjects/wmlogo.wmc
rename to wmc/wmlogo.wmc
index 8051cee..9378f68 100644
--- a/3dObjects/wmlogo.wmc
+++ b/wmc/wmlogo.wmc
@@ -1,3 +1,5 @@
+# By Rafael Garcia-Suarez <garcia-suarez at kazibao.net>
+
WMCUBE_COORDINATES
1 30 -30 10
2 -30 -30 10
diff --git a/wmcube.cc b/wmcube.cc
new file mode 100644
index 0000000..d529026
--- /dev/null
+++ b/wmcube.cc
@@ -0,0 +1,695 @@
+#include <stdio.h>
+#include <stdexcept>
+#include <sys/types.h>
+#include <dirent.h>
+#include <iostream>
+#include <vector>
+#include <math.h>
+#include <unistd.h>
+
+#include "WmcObject.h"
+#include "wmcube.h"
+
+using namespace std;
+
+/**************************************************
+
+ Defines
+
+**************************************************/
+
+#define DEFAULT_WMC_PATH "/usr/share/wmcube"
+#define WMC_REDRAW 2 // centiseconds (= 50 fps)
+#define CANVAS_BGCOLOR 0x202020
+#define CYAN 0x20B2AE
+
+#define WINDOW_NEW 0
+#define WINDOW_CLASSIC 1
+
+// Rotation speed (in radians) for each screen update
+#define ROT_SPEED_X (float)clopt_rspeed * (0.005 + (float)cpu_load / 3000.0)
+#define ROT_SPEED_Y (float)clopt_rspeed * (0.005 + (float)cpu_load / 3500.0)
+#define ROT_SPEED_Z (float)clopt_rspeed * (0.005 + (float)cpu_load / 4000.0)
+
+// Placement for the objects in new/classic mode
+#define XOFF_NEW 27
+#define YOFF_NEW 20
+#define ZOFF_NEW 400
+#define XOFF_CLASSIC XOFF_NEW
+#define YOFF_CLASSIC 27
+#define ZOFF_CLASSIC -ZOFF_NEW
+
+/**************************************************
+
+ Function predeclaration
+
+**************************************************/
+
+// Timer and widget callbacks
+void gatherStatistics(const WMApp *a, void *);
+void displayWmcObject(const WMApp *a, WMWidget *w, void *);
+void displayCpuText(const WMApp *a, WMWidget *w, void *);
+void displayCpuMeter(const WMApp *a, WMWidget *w, void *);
+void canvasClicked(const WMApp *a, WMWidget *w, void *);
+
+// Other funcs
+void switchWindow(WmcObject *currentwmc);
+void scanWmcDirectory(const char *dirname);
+char *nextObject();
+char *prevObject();
+void clearCanvas(WMCanvas *canvas);
+bool checkMouseRegion(const WMCanvas *c, int button, int ulx, int uly, int lrx, int lry);
+
+/**************************************************
+
+ Global variables
+
+**************************************************/
+
+// "Main" variables
+WMApp wmcube;
+CpuMonitor *cpumon = 0;
+WmcObject *wmc, *wmcnew, *wmcold;
+int cpu_load = 0;
+int switching = 0;
+int xoff = XOFF_NEW, yoff = YOFF_NEW, zoff = ZOFF_NEW;
+
+// A list of available object's filenames and an iterator
+vector <char *> objects;
+vector <char *>::const_iterator obj_iterator;
+
+// Variables for command line options (set to their defaults)
+char *clopt_object = 0;
+int clopt_cpu = -1;
+int clopt_update = 50;
+int clopt_window = WINDOW_NEW;
+float clopt_rspeed = 3;
+bool clopt_nice = true;
+unsigned clopt_fgcolor = CYAN;
+float clopt_shade = 90.0;
+unsigned clopt_bgcolor = CANVAS_BGCOLOR;
+int clopt_invert = false;
+int clopt_mode = SOLID;
+bool clopt_lsource = false;
+bool clopt_wheel = false;
+bool clopt_help = false;
+
+/**************************************************
+
+ Main
+
+**************************************************/
+int main(int argc, char *argv[])
+{
+ WMApp::initialize(argc, argv);
+
+ /**************************************************
+
+ Parse command line parameters
+
+ ***************************************************/
+ int c = 0;
+ char clstr[64] = "";
+
+ for (int i = 0; i < NUM_CL_OPT; i++)
+ {
+ clstr[c++] = CL_OPT[i].c;
+ if (strlen(CL_OPT[i].parms) > 0) clstr[c++] = ':';
+ }
+
+ clstr[c] = 0;
+
+ while ((c = getopt (argc, argv, clstr)) != -1)
+ {
+ switch (c)
+ {
+ case CL_OPT_OBJECT_INT:
+ clopt_object = strndup(optarg, 256);
+ break;
+ case CL_OPT_CPU_INT:
+ clopt_cpu = atoi(optarg);
+ break;
+ case CL_OPT_UPDATE_INT:
+ clopt_update = atoi(optarg);
+ break;
+ case CL_OPT_WINDOW_INT:
+ clopt_window = WINDOW_CLASSIC;
+ break;
+ case CL_OPT_RSPEED_INT:
+ clopt_rspeed = atoi(optarg);
+ break;
+ case CL_OPT_NICE_INT:
+ clopt_nice = false;
+ break;
+ case CL_OPT_FGCOLOR_INT:
+ sscanf(optarg, "%x", &clopt_fgcolor);
+ //printf("FGCOLOR = 0x%X shade = %.3f\n", clopt_fgcolor, clopt_shade);
+ break;
+ case CL_OPT_SHADE_INT:
+ clopt_shade = atoi(optarg);
+ break;
+ case CL_OPT_BGCOLOR_INT:
+ sscanf(optarg, "%x", &clopt_bgcolor);
+ //printf("BGCOLOR = 0x%X\n", clopt_bgcolor);
+ break;
+ case CL_OPT_INVERT_INT:
+ clopt_invert = true;
+ break;
+ case CL_OPT_MODE_INT:
+ clopt_mode = atoi(optarg);
+ break;
+ case CL_OPT_LSOURCE_INT:
+ clopt_lsource = true;
+ break;
+ case CL_OPT_WHEEL_INT:
+ clopt_wheel = true;
+ break;
+ case CL_OPT_HELP_INT:
+ clopt_help = true;
+ printUsage();
+ break;
+ default:
+ clopt_help = true;
+ printUsage();
+ break;
+ }
+ }
+
+
+ /**************************************************
+
+ Set up cpu monitor
+
+ ***************************************************/
+
+ try
+ {
+
+#ifdef DARWIN
+ cpumon = new CpuMonitor();
+#endif
+
+#ifdef FREEBSD
+ cpumon = new CpuMonitor(clopt_nice);
+#endif
+
+#ifdef LINUX
+ cpumon = new CpuMonitor(clopt_cpu, clopt_nice);
+#endif
+
+#ifdef NETBSD
+ cpumon = new CpuMonitor(clopt_nice);
+#endif
+
+#ifdef OPENBSD
+ cpumon = new CpuMonitor();
+#endif
+
+#ifdef SOLARIS
+ cpumon = new CpuMonitor(clopt_cpu);
+#endif
+
+ }
+ catch (exception &e)
+ {
+ cout << e.what() << endl;
+ return -1;
+ }
+
+ cpumon->setRange(99); // Only two digits fits in text area
+
+ /**************************************************
+
+ Scan wmc-directory and load (initial) object
+
+ **************************************************/
+ try
+ {
+ if (clopt_object == 0)
+ {
+ scanWmcDirectory(DEFAULT_WMC_PATH);
+ wmc = (objects.size() > 0) ? new WmcObject(nextObject()) : new WmcObject();
+ }
+ else
+ {
+ scanWmcDirectory(clopt_object);
+ wmc = (objects.size() > 0) ? new WmcObject(nextObject()) : new WmcObject(clopt_object);
+ }
+ }
+ catch (exception &e)
+ {
+ cout << e.what() << endl;
+ return -1;
+ }
+
+ wmc->setColorShading(clopt_fgcolor, clopt_shade);
+ wmc->setMode(clopt_mode);
+
+ printf("Objects in %s: %d\n", DEFAULT_WMC_PATH, objects.size());
+
+ /***********************************************************************
+
+ Set up the new style window
+
+ ***********************************************************************/
+
+ WMWindow nw;
+ WMFrame nmain, bottom, botleft, botright;
+ WMCanvasCallback ncanvas;
+ WMTextBar cpu("00", 0);
+ WMMeterBar meter(0, 100);
+
+ nw.setpadding(1);
+ nw.addchild(nmain);
+ nw.addchild(bottom);
+ nw.setorientation(Orientation::Vertical);
+ nw.setaspectratios(80, 21);
+ nw.add_timed_function(clopt_update, gatherStatistics, 0);
+ nw.add_timed_function(clopt_update, displayCpuText, &cpu, 0);
+ nw.add_timed_function(clopt_update, displayCpuMeter, &meter, 0);
+ nw.add_timed_function(WMC_REDRAW, displayWmcObject, &ncanvas, wmc);
+
+ ncanvas.addcallback(canvasClicked, &ncanvas, 0);
+
+ ncanvas.setbuffered(true);
+ meter.setstyle(WMMeterBar::Blue);
+
+ //bottom.setpadding(2);
+ //bottom.setborder(0);
+ nmain.addchild(ncanvas);
+ bottom.addchild(botleft);
+ bottom.addchild(botright);
+ bottom.setorientation(Orientation::Horizontal);
+ bottom.setaspectratios(4, 11);
+
+ meter.setorientation(Orientation::Horizontal);
+
+ botleft.addchild(cpu);
+ botright.setorientation(Orientation::Vertical);
+ botright.setpadding(2);
+ botright.addchild(meter);
+
+ /***********************************************************************
+
+ Set up the classic style window
+
+ ***********************************************************************/
+
+ WMWindow cw;
+ WMCanvasCallback ccanvas;
+
+ cw.setpadding(1);
+ cw.addchild(ccanvas);
+ cw.setaspectratios(1, 1);
+ cw.add_timed_function(clopt_update, gatherStatistics, 0);
+ cw.add_timed_function(WMC_REDRAW, displayWmcObject, &ccanvas, wmc);
+
+ ccanvas.addcallback(canvasClicked, &ccanvas, 0);
+ ccanvas.setbuffered(true);
+
+ /***********************************************************************
+
+ Ok we're more or less set to go..
+
+ ***********************************************************************/
+
+ wmcube.addwindow(nw);
+ wmcube.addwindow(cw);
+
+ // If the user selected to start in classic mode...
+ if (clopt_window == WINDOW_CLASSIC)
+ {
+ // .. we need to tell switchWindow that we currently are in new mode.
+ clopt_window = WINDOW_NEW;
+ switchWindow(wmc);
+ wmcube.run(cw);
+ }
+ else
+ wmcube.run(nw);
+
+ delete cpumon;
+ delete wmc;
+
+ return 0;
+}
+
+/********************************************************************************
+
+ void switchWindow(WmcObject *currentwmc)
+
+ Switch between new/classic mode.
+
+********************************************************************************/
+void switchWindow(WmcObject *currentwmc)
+{
+ //printf("switching windows\n"); fflush(stdout);
+
+ if (clopt_window == WINDOW_CLASSIC)
+ {
+ clopt_window = WINDOW_NEW;
+ xoff = XOFF_NEW;
+ yoff = YOFF_NEW;
+ zoff = ZOFF_NEW;
+ }
+ else
+ {
+ clopt_window = WINDOW_CLASSIC;
+ xoff = XOFF_CLASSIC;
+ yoff = YOFF_CLASSIC;
+ zoff = ZOFF_CLASSIC;
+ }
+
+ wmcube.switch_to(clopt_window);
+
+ // Zoom/translate object to fit current canvas size
+ currentwmc->modifyZOffset(zoff);
+ currentwmc->setYOffset(yoff);
+}
+
+/********************************************************************************
+
+ void canvasClicked(const WMApp *a, WMWidget *w, void *)
+
+ Event callback for everything that has to do with the canvas that the object(s)
+ are being drawn in.
+
+********************************************************************************/
+#define ZOOM_STEP 100
+#define LSOURCE_Z_OFF 10
+
+void canvasClicked(const WMApp *a, WMWidget *w, void *)
+{
+ WMCanvas *c = dynamic_cast<WMCanvas *>(w);
+ WmcObject *current;
+
+ if (!c) return;
+
+ current = switching ? wmcnew : wmc;
+
+ /*
+ Mouse-wheel zoom in and out (unless clopt_wheel == true).
+ */
+ if (((a->mouseclick().button == Button4) && (!clopt_wheel)) ||
+ checkMouseRegion(c, Button1, 47, 12, 65, 48))
+ {
+ current->modifyZOffset(-ZOOM_STEP);
+ return;
+ }
+ if (((a->mouseclick().button == Button5) && (!clopt_wheel)) ||
+ checkMouseRegion(c, Button1, 0, 12, 16, 48))
+ {
+ current->modifyZOffset( ZOOM_STEP);
+ return;
+ }
+
+ /*
+ Switch window mode
+ */
+ if (checkMouseRegion(c, Button1, 0, 0, 13, 13))
+ {
+ switchWindow(current);
+ return;
+ }
+
+ /*
+ Switch 3d mode
+ */
+ if ((a->mouseclick().button == Button2) || checkMouseRegion(c, Button1, 15, yoff-10, 48, yoff+10))
+ {
+ current->setMode(++clopt_mode % NUM_MODES);
+ return;
+ }
+
+ /*
+ Change lightsource position with right mouse button
+ */
+ if (a->mouseclick().button == Button3)
+ {
+ current->setLightSource(xoff - a->mouseclick().relative_to(c).x,
+ yoff - a->mouseclick().relative_to(c).y,
+ LSOURCE_Z_OFF);
+ return;
+ }
+
+ /*
+ Switch objects (if not already doing so)
+ */
+ if ((switching == 0) && (objects.size() > 0))
+ {
+ // Store a pointer to the old object so we can delete it later
+ wmcold = wmc;
+
+ // Switch object with mousewheel instead of zooming
+ if ((a->mouseclick().button == Button4) && clopt_wheel)
+ {
+ // Scrolling object up with mousewheel
+ switching = 1;
+ wmcnew = new WmcObject(nextObject());
+ }
+ else if ((a->mouseclick().button == Button5) && clopt_wheel)
+ {
+ // Scrolling object down with mousewheel
+ switching = -1;
+ wmcnew = new WmcObject(prevObject());
+ }
+ // Switch objects by clicking
+ else if (checkMouseRegion(c, Button1, 12, 0, 60, yoff - 5))
+ {
+ // Scrolling object up by clicking top of canvas
+ switching = 1;
+ wmcnew = new WmcObject(nextObject());
+ }
+ else if (checkMouseRegion(c, Button1, 12, yoff + 5, 60, 60))
+ {
+ // Scrolling object down by clicking bottom of canvas
+ switching = -1;
+ wmcnew = new WmcObject(prevObject());
+ }
+
+ if (clopt_window == WINDOW_CLASSIC) wmcnew->modifyZOffset(ZOFF_CLASSIC);
+ wmcnew->setColorShading(clopt_fgcolor, clopt_shade);
+ wmcnew->setMode(clopt_mode % NUM_MODES);
+
+ return;
+ }
+}
+
+/********************************************************************************
+
+ bool checkMouseRegion(const WMCanvas *c, int button, int ulx, int uly, int lrx, int lry)
+
+ ulx = upper left x, go figure on the rest..
+
+********************************************************************************/
+
+bool checkMouseRegion(const WMCanvas *c, int button, int ulx, int uly, int lrx, int lry)
+{
+ if ((c->app())->mouseclick().button != button) return false;
+ if (((c->app())->mouseclick().relative_to(c).y > lry) ||
+ ((c->app())->mouseclick().relative_to(c).y < uly)) return false;
+ if (((c->app())->mouseclick().relative_to(c).x < ulx) ||
+ ((c->app())->mouseclick().relative_to(c).x > lrx)) return false;
+
+ return true;
+}
+
+/********************************************************************************
+
+ void displayWmcObject(const WMApp *a, WMWidget *w, void *)
+
+ Timer-callback for drawing the object(s) in the canvas that is passed in w.
+
+ Defines are for the scroll-in/out-speed of the objects (SCROLL_SPEED) as well
+ as the initial displacement from the center for the new object (INITIAL_DISP).
+
+ Variable 'switching' take on values -1 (scrolling down), 0 (not switching)
+ and 1 (scrolling up).
+
+********************************************************************************/
+#define SCROLL_SPEED 2.0
+#define INITIAL_DISP switching * 2 * yoff
+
+void displayWmcObject(const WMApp *a, WMWidget *w, void *)
+{
+ static float yd = 0.0;
+ int local_yoff;
+ static float mlight = 0.0;
+ WMCanvas *c = dynamic_cast<WMCanvas *>(w);
+
+ if (!c) return;
+
+ clearCanvas(c);
+
+ if (switching != 0)
+ {
+ /*
+ We're currently switching objects - do alot of magic.
+ Basically we're scrolling 'wmcnew' in from top/bottom
+ while simultanously scrolling 'wmc' out.
+ */
+ yd += SCROLL_SPEED;
+ local_yoff = yoff - switching * (int)yd;
+
+ wmc->rotate(ROT_SPEED_X, ROT_SPEED_Y, ROT_SPEED_Z);
+ wmc->setYOffset(local_yoff);
+ wmc->draw(c);
+
+ wmcnew->setYOffset(yoff + INITIAL_DISP - switching * (int)yd);
+ wmcnew->rotate(ROT_SPEED_X, ROT_SPEED_Y, ROT_SPEED_Z);
+ wmcnew->draw(c);
+
+ if (yd >= switching * INITIAL_DISP)
+ {
+ // Finished switching, delete the old object
+ switching = 0;
+ yd = 0.0;
+ mlight = 0.0;
+ wmc = wmcnew;
+ delete wmcold;
+ }
+ }
+ else
+ {
+ wmc->rotate(ROT_SPEED_X, ROT_SPEED_Y, ROT_SPEED_Z);
+
+ if (clopt_lsource)
+ {
+ wmc->setLightSource(55.0 * cos(mlight*0.002), 50.0 * sin(mlight*0.040), LSOURCE_Z_OFF);
+ mlight += 1.0;
+ }
+
+ wmc->draw(c);
+ }
+
+ a->repaint();
+}
+
+/********************************************************************************
+
+ void gatherStatistics(const WMApp *a, void *)
+
+ Store the polled cpu-load in variable 'cpu_load'
+
+********************************************************************************/
+void gatherStatistics(const WMApp *a, void *)
+{
+ cpu_load = (int)cpumon->getLoad();
+}
+
+/********************************************************************************
+
+ void displayCpuText(const WMApp *a, WMWidget *w, void *)'
+
+ Display the cpu-load in the textbar passed in w.
+
+********************************************************************************/
+void displayCpuText(const WMApp *a, WMWidget *w, void *)
+{
+ char tmp[6];
+ WMTextBar *b = dynamic_cast<WMTextBar*>(w);
+
+ if (!b) return;
+
+ sprintf(tmp, "%2d", cpu_load);
+ b->settext(tmp);
+ a->repaint();
+}
+
+/********************************************************************************
+
+ void displayCpuMeter(const WMApp *a, WMWidget *w, void *)
+
+ Display the cpu-load in the meterbar passed in w.
+
+********************************************************************************/
+void displayCpuMeter(const WMApp *a, WMWidget *w, void *)
+{
+ WMMeterBar *m = dynamic_cast<WMMeterBar *>(w);
+
+ if (!m) return;
+
+ m->setvalue(cpu_load, true);
+ a->repaint();
+}
+
+/********************************************************************************
+
+ char *nextObject()
+
+ Returns the next objects' filename
+
+********************************************************************************/
+char *nextObject()
+{
+ if (obj_iterator == objects.end() - 1)
+ obj_iterator = objects.begin();
+ else
+ obj_iterator++;
+
+ //printf("returning next Object = %s\n", *obj_iterator); fflush(stdout);
+
+ return *obj_iterator;
+}
+
+/********************************************************************************
+
+ char *prevObject()
+
+ Returns the previous objects' filename
+
+********************************************************************************/
+char *prevObject()
+{
+ if (obj_iterator == objects.begin())
+ obj_iterator = objects.end() - 1;
+ else
+ obj_iterator--;
+
+ //printf("returning previous Object = %s\n", *obj_iterator); fflush(stdout);
+
+ return *obj_iterator;
+}
+
+/********************************************************************************
+
+ int scanWmcDirectory(const char *dirname)
+
+ Scans the directory 'dirname' and stores the full pathname of all found
+ wmc-files in the global vector 'objects'. This code should be POSIX compliant
+ which the old code was not (didnt work on Solaris for example). Objects are
+ listed in some seemingly random order (creation time?).
+
+********************************************************************************/
+void scanWmcDirectory(const char *dirname)
+{
+ DIR *dir_stream = opendir(dirname);
+ struct dirent *dirp;
+ char *strp;
+
+ if (dir_stream == NULL)
+ return; //throw runtime_error("scanWmcDirectory: Could not open directory.");
+
+ for (dirp = readdir(dir_stream); dirp != NULL; dirp = readdir(dir_stream))
+ {
+ if (strstr(dirp->d_name, ".wmc"))
+ {
+ // Make sure there's space for the dirname, a slash, filename and terminating zero
+ strp = new char[strlen(dirname) + strlen(dirp->d_name) + 2];
+ strcpy(strp, dirname);
+ strcat(strp, "/");
+ strcat(strp, dirp->d_name);
+ objects.push_back(strp);
+ //printf("%s\n", objects[objects.size() - 1]);
+ }
+ }
+
+ obj_iterator = objects.begin();
+ closedir(dir_stream);
+}
+
+void clearCanvas(WMCanvas *canvas)
+{
+ canvas->setcolor((WMColor::WMColor)clopt_bgcolor);
+ canvas->fill_rectangle(0, 0, 54, 54);
+ //canvas->draw_vertical_gradient(0,0,53,40, 0x000000, 0x555555);
+}
diff --git a/wmcube.h b/wmcube.h
new file mode 100644
index 0000000..d9052b5
--- /dev/null
+++ b/wmcube.h
@@ -0,0 +1,118 @@
+#ifndef _WMCUBE_HPP_
+#define _WMCUBE_HPP_
+
+#include "wmapp/wmwidget.h"
+#include "wmapp/wmapp.h"
+#include "wmapp/wmwindow.h"
+#include "wmapp/wmframe.h"
+#include "wmapp/wmcanvas.h"
+#include "wmapp/wmmeterbar.h"
+#include "wmapp/wmtextbar.h"
+#include "wmapp/wmcallback.h"
+
+#ifdef DARWIN
+#include "cpumoncc/darwin/CpuMonitor.h"
+#endif
+#ifdef FREEBSD
+#include "cpumoncc/freebsd/CpuMonitor.h"
+#endif
+#ifdef LINUX
+#include "cpumoncc/linux/CpuMonitor.h"
+#endif
+#ifdef NETBSD
+#include "cpumoncc/netbsd/CpuMonitor.h"
+#endif
+#ifdef OPENBSD
+#include "cpumoncc/openbsd/CpuMonitor.h"
+#endif
+#ifdef SOLARIS
+#include "cpumoncc/solaris/CpuMonitor.h"
+#endif
+
+#define WMCUBE_VERSION "0.99-pre1"
+#define WMCUBE_RELDATE "2003-02-28"
+
+typedef struct
+{
+ const int c;
+ const char *parms;
+ const char *desc;
+}
+cl_opt;
+
+#define CL_OPT_OBJECT_INT (int)'o'
+#define CL_OPT_CPU_INT (int)'c'
+#define CL_OPT_UPDATE_INT (int)'u'
+#define CL_OPT_WINDOW_INT (int)'k'
+#define CL_OPT_RSPEED_INT (int)'r'
+#define CL_OPT_NICE_INT (int)'n'
+#define CL_OPT_FGCOLOR_INT (int)'f'
+#define CL_OPT_SHADE_INT (int)'s'
+#define CL_OPT_BGCOLOR_INT (int)'b'
+#define CL_OPT_INVERT_INT (int)'i'
+#define CL_OPT_MODE_INT (int)'m'
+#define CL_OPT_LSOURCE_INT (int)'l'
+#define CL_OPT_WHEEL_INT (int)'w'
+#define CL_OPT_HELP_INT (int)'h'
+
+const cl_opt CL_OPT_OBJECT = { CL_OPT_OBJECT_INT,"filename/directory","load wmc-object or scan a directory for objects"};
+const cl_opt CL_OPT_CPU = { CL_OPT_CPU_INT ,"X","monitor cpu X (starts with 0, default average over all)" };
+const cl_opt CL_OPT_UPDATE = { CL_OPT_UPDATE_INT ,"X","read cpu load every X centiseconds (default 50)" };
+const cl_opt CL_OPT_WINDOW = { CL_OPT_WINDOW_INT,"","start in classic mode" };
+const cl_opt CL_OPT_RSPEED = { CL_OPT_RSPEED_INT ,"X","rotating speed 0-9 (default 3)" };
+const cl_opt CL_OPT_NICE = { CL_OPT_NICE_INT, "","exclude nice processes" };
+const cl_opt CL_OPT_FGCOLOR = { CL_OPT_FGCOLOR_INT,"0xXXXXXX","solid/wireframe color (default CYANish color)" };
+const cl_opt CL_OPT_SHADE = { CL_OPT_SHADE_INT,"X","amount of shading on solid objects 0-100 (default 80)" };
+const cl_opt CL_OPT_BGCOLOR = { CL_OPT_BGCOLOR_INT,"0xXXXXXX","background color (default 0x202020)" };
+const cl_opt CL_OPT_INVERT = { CL_OPT_INVERT_INT, "","invert rotating speed/cpu load relationship" };
+const cl_opt CL_OPT_MODE = { CL_OPT_MODE_INT,"wire/solid/solidwire","default mode for objects with multiple modes" };
+const cl_opt CL_OPT_LSOURCE = { CL_OPT_LSOURCE_INT,"","moving light source (default clickable light source)" };
+const cl_opt CL_OPT_WHEEL = { CL_OPT_WHEEL_INT,"","switch object with mouse wheel (default zoom)" };
+const cl_opt CL_OPT_HELP = { CL_OPT_HELP_INT,"","print help" };
+
+#define NUM_CL_OPT 11
+
+const cl_opt CL_OPT[NUM_CL_OPT] =
+{
+ CL_OPT_OBJECT,
+ CL_OPT_CPU,
+ CL_OPT_UPDATE,
+ CL_OPT_WINDOW,
+ CL_OPT_RSPEED,
+ CL_OPT_NICE,
+ CL_OPT_FGCOLOR,
+ CL_OPT_SHADE,
+ CL_OPT_BGCOLOR,
+ //CL_OPT_INVERT,
+ //CL_OPT_MODE,
+ CL_OPT_LSOURCE,
+ //CL_OPT_WHEEL,
+ CL_OPT_HELP
+};
+
+void printUsage()
+{
+ printf("wmCube %s (%s) (C) Robert Kling 2003\n\n", WMCUBE_VERSION, WMCUBE_RELDATE);
+ printf("Usage: wmcube [options]\n\n");
+
+ for (int i = 0; i < NUM_CL_OPT; i++)
+ {
+
+ printf(" -%c %s", CL_OPT[i].c, CL_OPT[i].parms);
+ for (int j = 0; j < 22 - strlen(CL_OPT[i].parms); j++) printf(" ");
+ printf("%s\n", CL_OPT[i].desc);
+ }
+
+// printf("\nThe -c option is only availible on Linux and Solaris.");
+// printf("\nThe -n option is only availible on FreeBSD, Linux and NetBSD.\n\n");
+ fflush(stdout);
+}
+
+class WMCanvasCallback : public WMCallback, public WMCanvas
+{
+public:
+ WMCanvasCallback() : WMCallback(), WMCanvas() { }
+};
+
+
+#endif
diff --git a/wmcube/Makefile b/wmcube/Makefile
deleted file mode 100644
index 1410b29..0000000
--- a/wmcube/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-CC = gcc
-OS = -DLINUX
-
-LIBDIR = -L/usr/X11R6/lib
-LIBDIR = -L/usr/X11R6/lib
-INCDIR = -I/usr/X11R6/share/include
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS =
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-CFLAGS = -Wall -O2 $(OS)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube $^ -lXext $(LIBDIR) $(LIBS)
-
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod 755 /usr/local/bin/wmcube
- chown root:root /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/Makefile.FREEBSD b/wmcube/Makefile.FREEBSD
deleted file mode 100644
index 815e32d..0000000
--- a/wmcube/Makefile.FREEBSD
+++ /dev/null
@@ -1,38 +0,0 @@
-CC = gcc
-OS = -DFREEBSD
-
-LIBDIR = -L/usr/X11R6/lib
-LIBDIR = -L/usr/X11R6/lib
-INCDIR = -I/usr/X11R6/include
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS = -lkvm
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-CFLAGS = -Wall -O2 $(OS)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube $(OBJS) -lXext $(LIBDIR) $(LIBS)
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod g+s /usr/local/bin/wmcube
- chown root.kmem /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/Makefile.LINUX b/wmcube/Makefile.LINUX
deleted file mode 100644
index 1410b29..0000000
--- a/wmcube/Makefile.LINUX
+++ /dev/null
@@ -1,39 +0,0 @@
-CC = gcc
-OS = -DLINUX
-
-LIBDIR = -L/usr/X11R6/lib
-LIBDIR = -L/usr/X11R6/lib
-INCDIR = -I/usr/X11R6/share/include
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS =
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-CFLAGS = -Wall -O2 $(OS)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube $^ -lXext $(LIBDIR) $(LIBS)
-
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod 755 /usr/local/bin/wmcube
- chown root:root /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/Makefile.NETBSD b/wmcube/Makefile.NETBSD
deleted file mode 100644
index 7d212aa..0000000
--- a/wmcube/Makefile.NETBSD
+++ /dev/null
@@ -1,36 +0,0 @@
-CC = gcc
-OS = -DNETBSD
-
-LIBDIR = -L/usr/X11R6/lib -L./libdocapp/
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS =
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-CFLAGS = -Wall -I/usr/X11R6/include -O2 $(OS)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube -lXext $(LIBDIR) $(LIBS) $(OBJS)
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod 755 /usr/local/bin/wmcube
- chown root:root /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/Makefile.OPENBSD b/wmcube/Makefile.OPENBSD
deleted file mode 100644
index 3cbae90..0000000
--- a/wmcube/Makefile.OPENBSD
+++ /dev/null
@@ -1,37 +0,0 @@
-CC = gcc
-OS = -DOPENBSD
-
-LIBDIR = -L/usr/X11R6/lib -L./libdocapp/
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS =
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-INCLUDES = -I/usr/X11R6/include
-CFLAGS = -Wall -O2 $(OS) $(INCLUDES)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube $^ -lXext $(LIBDIR) $(LIBS) $>
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod 755 /usr/local/bin/wmcube
- chown root:root /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/Makefile.SOLARIS b/wmcube/Makefile.SOLARIS
deleted file mode 100644
index 5ebc893..0000000
--- a/wmcube/Makefile.SOLARIS
+++ /dev/null
@@ -1,38 +0,0 @@
-CC = gcc
-OS = -DSOLARIS
-
-LIBDIR = -L/usr/X11R6/lib
-LIBDIR = -L/usr/openwin/lib -L/opt/sfw/lib -L/usr/local/lib -R/usr/openwin/lib -R/opt/sfw/lib -R/usr/local/lib
-INCDIR = -I/usr/openwin/include -I/opt/sfw/include -I/usr/local/include
-
-# Edit OSLIBS as appropriate to include OS specific libraries.
-
-OSLIBS = -lkstat
-LIBS = -lXpm -lXext -lX11 -lm $(OSLIBS)
-CFLAGS = -Wall -O2 $(OS)
-
-OBJS = wmcube.o \
- ../wmgeneral/wmgeneral.o \
- ../wmgeneral/misc.o \
- ../wmgeneral/list.o
-
-.c.o:
- $(CC) $(CFLAGS) $(INCDIR) -c $< -o $*.o
-
-wmcube: $(OBJS)
- $(CC) -o wmcube $^ -lXext $(LIBDIR) $(LIBS)
-
-all:: wmcube
-
-clean::
- for i in $(OBJS) ; do \
- rm -f $$i ; \
- done
- rm -f wmcube
- rm -f *~
-
-install:: wmcube
- cp -f wmcube /usr/local/bin/
- chmod 755 /usr/local/bin/wmcube
- chown root:root /usr/local/bin/wmcube
- @echo "wmCube installation finished..."
diff --git a/wmcube/wmcube.c b/wmcube/wmcube.c
deleted file mode 100644
index a586b55..0000000
--- a/wmcube/wmcube.c
+++ /dev/null
@@ -1,1351 +0,0 @@
-/*
-
- wmcube.c
- Version 0.98 (2000-10-20)
-
- Robert Kling (robkli-8 at student.luth.se)
- http://boombox.campus.luth.se/projects.php
-
- Contributions:
- -n option patch by Thorsten Jens (thodi at et-inf.fho-emden.de) (2000-05-12)
- Various bugfixes and optimizations by Jakob Borg (2000-05-13)
- Solaris Port by Dan Price (dp at rampant.org) (2000-07-16)
- OpenBSD Port by Brian Joseph Czapiga (rys at godsey.net) (2000-07-19)
- FreeBSD Port by Tai-hwa Liang (avatar at mmlab.cse.yzu.edu.tw) (2000-07-20)
- NetBSD Port by Jared Smolens <jsmolens+ at andrew.cmu.edu> (2000-09-23)
-
- This software is licensed through the GNU General Public Licence.
-
- See http://www.BenSinclair.com/dockapp/ for more wm dock apps.
-
- If you want to port wmcube to another OS the system specific code is
- sectioned the bottom of this file. See instructions there.
-
-*/
-
-#define WMCUBE_VERSION "0.98"
-#define REV_DATE "2000-10-23"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <math.h>
-
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <utmp.h>
-#include <dirent.h>
-
-#include <X11/Xlib.h>
-#include <X11/xpm.h>
-#include <X11/extensions/shape.h>
-
-#ifdef FREEBSD
-#include <kvm.h>
-#endif
-
-#include "../wmgeneral/wmgeneral.h"
-#include "../wmgeneral/misc.h"
-
-#include "wmcube.xpm"
-char wmcube_mask_bits[64*64];
-int wmcube_mask_width = 64;
-int wmcube_mask_height = 64;
-
-#define CHAR_WIDTH 5
-#define CHAR_HEIGHT 7
-#define PI 3.1415926535
-
-//**** Graphics ***********************************
-
-void putpixel(int x, int y, int c);
-void line(int x1, int y1, int x2, int y2, int c);
-void hline(int x1, int x2, int y, int c);
-void triangle(int x1, int y1, int x2, int y2, int x3, int y3, int c);
-void BlitString(char *name, int x, int y);
-void BlitNum(int num, int x, int y);
-void clearscr();
-void draw();
-void startup_seq();
-
-//**** 3d specific ********************************
-
-void setupobj(char *filename) ;
-void setUpAngles();
-void rotate(int xang, int yang, int zang);
-int normal(float p1[], float p2[], float p3[]);
-int luminate(float p1[], float p2[], float p3[]);
-void sortz(int nofelements);
-
-//**** Application Management, I/O etc. ***********
-
-void print_help();
-int loadobj(char *filename);
-void mem_alloc_error(void *block);
-int scan4objects(char *dir);
-int next_object();
-void die();
-
-//**** System specific functions ******************
-
-int init_calc_cpu();
-int calc_cpu_total();
-
-//**** Global variables ***************************
-
-int xcenter, ycenter, zoff;
-double cost[361], sint[361];
-double acost[100];
-float **matrix;
-float **rmatrix;
-int **planes;
-int *plane_color;
-int *zorder;
-int *cline;
-int nofcoords, noflines, nofplanes;
-char *objects[1000];
-int nof_objects = 0;
-int show_load = 1;
-int use_nice = 1;
-int which_cpu = -1;
-int planesORlines = 1;
-char *pname;
-
-float lum_vector[3] = { 0, 0, 100 }; // Lightsource vector
-
-#ifdef FREEBSD
-static kvm_t *kd;
-static struct nlist nlst[] = { {"_cp_time"}, {0} };
-#endif
-
-int main(int argc, char **argv)
-{
- int j, i = 0, rot_speed = 0, cpu_usage = 0, rot_step = 1;
- long screen_speed = 10000; // microseconds between screen updates (approx.)
- long cpu_update = 490000; // microseconds between cpu update (approx.)
- int but_stat = -1;
- int loop = 0;
- XEvent Event;
-
- char *rotdiv = {"25"};
- char *rotstep = {"1"};
- char *obj_filename = {""};
- int rot;
- int cube_color = 1;
- int c = 0;
- int invert_speed = 0;
-
- pname = strrchr(argv[0], '/');
- if (pname == NULL) pname = argv[0];
-
- srand((unsigned)time(NULL));
- opterr = 0;
-
- while ((c = getopt (argc, argv, "d:nhpbir:o:c:")) != -1) {
- switch (c)
- {
- case 'c':
- which_cpu = atoi(optarg);
- break;
- case 'd':
- rotstep = optarg;
- break;
- case 'h':
- print_help();
- return 1;
- case 'i':
- invert_speed = 1;
- break;
- case 'p':
- show_load = 0;
- break;
- case 'b':
- cube_color = 2;
- break;
- case 'r':
- rotdiv = optarg;
- break;
- case 'o':
- obj_filename = optarg;
- break;
- case 'n':
- use_nice = 0;
- break;
- case '?':
- print_help();
- return 1;
- default:
- abort();
- }
- }
-
- /*
- * Validate that wmcube can run on this system given the parameters,
- * then setup the statistics gathering subsystem.
- */
-
- if (init_calc_cpu() != 0) die();
-
- /*
- * Scan directory for .wmc files and choose one randomly. If the user
- * specified a particular file, load that one.
- */
-
-#ifndef SOLARIS // scan4objects doesnt work on Solaris, load object immediatly
- scan4objects(obj_filename);
-
- if (nof_objects != 0)
- next_object();
- else
-#endif
- setupobj(obj_filename);
-
- /*
- * Various initializion stuff for the 3d-engine etc.
- */
-
- setUpAngles();
-
- rot = atoi(rotdiv);
- if ((rot >= 1) && (rot <=100)) ; else rot = 25;
-
- rot_step = atoi(rotstep);
- if (rot_step < 0) rot_step = -rot_step;
-
- if (calc_cpu_total() == -1) die();
-
- cpu_update /= screen_speed;
-
- createXBMfromXPM(wmcube_mask_bits, wmcube_xpm, wmcube_mask_width, wmcube_mask_height);
- openXwindow(argc, argv, wmcube_xpm, wmcube_mask_bits, wmcube_mask_width, wmcube_mask_height);
-
- startup_seq();
-
- if (calc_cpu_total() == -1) die();
-
- // index, left, top, right, bottom
- AddMouseRegion(1, 45, 45, 58, 58); // + Zoom In
- AddMouseRegion(5, 5, 45, 20, 58); // - Zoom Out
- AddMouseRegion(3, 21, 45, 45, 58); // Show cpu-load
- AddMouseRegion(2, 5, 5, 55, 45); // Everywhere else (almost) to change object
-
- /*
- * Main loop begins here
- */
-
- while (1)
- {
- i = (i+rot_speed+rot_step) % 360;
-
- clearscr();
- rotate(i,i,i);
-
- draw(cube_color);
-
- if (show_load) {
- BlitNum(cpu_usage,24,49);
- BlitString("Z",38,49);
- }
-
- RedrawWindow();
-
- if (loop++ == cpu_update) {
- loop = 0;
-
- /*
- * call calc_cpu_total to update statistics. If some
- * sort of bad event occurs, calc_cpu_total will return
- * -1, and we exit.
- */
-
- if ((cpu_usage = calc_cpu_total()) == -1) {
- die();
- }
- rot_speed = abs( invert_speed*(100 / rot) - cpu_usage / rot);
- }
-
- // X Events
-
- while (XPending(display))
- {
- XNextEvent(display, &Event);
- switch (Event.type)
- {
- case Expose:
- RedrawWindow();
- break;
- case DestroyNotify:
- XCloseDisplay(display);
- exit(0);
- break;
- case ButtonPress:
- j = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
- but_stat = j;
-
- break;
- case ButtonRelease:
- j = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
-
- switch(j)
- {
- case 1:
- if (zoff > 750) {
- BlitString("�",48,48);
- RedrawWindow();
- zoff -= 150;
- }
- break;
-
- case 2:
- next_object();
- break;
-
- case 3:
- if (show_load == 1) show_load = 0; else show_load = 1;
- ycenter = 15 - 2*show_load;
- break;
-
- case 5:
- BlitString("�",11,49);
- RedrawWindow();
- zoff += 150;
- break;
- }
- }
- break;
- }
- usleep(screen_speed);
- }
-
- /*
- * Free up memory used by the object (dirty...)
- */
-
- free(matrix);
- free(rmatrix);
- free(cline);
-
- return 1;
-}
-
-
-//**** Graphics ***********************************
-//*************************************************
-
-void startup_seq()
-{
- char *tmp = malloc(32);
- int oldzoff = 3600;
-
- sprintf(tmp,"V%s",WMCUBE_VERSION);
-
- RedrawWindow();
- BlitString("WMCUBE",13,22);
- BlitString(tmp,15,31);
- RedrawWindow();
- RedrawWindow();
- usleep(3000000);
- RedrawWindow();
-
- zoff = 1200;
-
- for (;zoff < oldzoff; zoff += 35)
- {
- rotate((zoff-1200)/8,0,0);
- clearscr();
- BlitString("WMCUBE",13,22);
- BlitString(tmp,15,31);
- draw(1);
- RedrawWindow();
- usleep(9000);
- }
-
- zoff = 3600;
-}
-
-void draw(int color)
-{
- int i;
-
- if (planesORlines) {
-
- sortz(nofplanes);
- for (i = 0; i < nofplanes; i++) {
- if (normal(rmatrix[planes[zorder[i]][0]], rmatrix[planes[zorder[i]][1]], rmatrix[planes[zorder[i]][2]]) > 0) {
-
- triangle(xcenter+rmatrix[planes[zorder[i]][0]][0], ycenter+rmatrix[planes[zorder[i]][0]][1],
- xcenter+rmatrix[planes[zorder[i]][1]][0], ycenter+rmatrix[planes[zorder[i]][1]][1],
- xcenter+rmatrix[planes[zorder[i]][2]][0], ycenter+rmatrix[planes[zorder[i]][2]][1], plane_color[zorder[i]]);
- }
- }
-
- } else {
- for (i = 0; i < noflines; i += 2)
- line(xcenter+rmatrix[cline[i ]-1][0], ycenter+rmatrix[cline[i ]-1][1],
- xcenter+rmatrix[cline[i+1]-1][0], ycenter+rmatrix[cline[i+1]-1][1],color);
- }
-}
-
-void putpixel(int x, int y,int c)
-{
- if ((x > 4) && (x < 59) && (y > 4) && (y < 59))
- copyXPMArea(160-c,0,1,1,x,y);
-}
-
-void hline(int x1, int x2, int y, int c)
-{
- if ((y > 4) && (y < 59)) {
- if (x1 <= 4) x1 = 5; else if (x1 > 57) return;
- if (x2 > 57) x2 = 57; else if (x2 <= 4) return;
-
- copyXPMArea(105, 56+c + 9*(c/18), x2-x1, 1, x1, y);
- }
-}
-
-void triangle(int x1, int y1, int x2, int y2, int x3, int y3, int c) // Draws a filled triangle
-{
- int k,k2,x,x_2,i, tmp1;
-
- int x1t, x2t;
-
- if (y3<y2)
- {
- tmp1=y2;
- y2=y3;
- y3=tmp1;
- tmp1=x2;
- x2=x3;
- x3=tmp1;
- }
-
- if (y2<y1)
- {
- tmp1=y1;
- y1=y2;
- y2=tmp1;
- tmp1=x1;
- x1=x2;
- x2=tmp1;
- }
-
- if (y3<y2)
- {
- tmp1=y2;
- y2=y3;
- y3=tmp1;
- tmp1=x2;
- x2=x3;
- x3=tmp1;
- }
-
- if (y1!=y3) k=((x1-x3) << 6) / (y1-y3);
- else k=(x1-x3) << 6;
-
- if (y1!=y2) k2=((x1-x2) << 6) / (y1-y2);
- else k2=(x1-x2) << 6;
-
- x=x1 << 6;
- x_2=x;
- i=y1;
-
- if (i!=y2)
- do
- {
- x+=k;
- x_2+=k2;
- i++;
-
- if ((x1t = x >> 6) > (x2t = x_2 >> 6))
- hline(x2t, x1t, i, c);
- else
- hline(x1t, x2t, i, c);
- }
- while (i!=y2);
-
- if (i==y3) return;
-
- if (y2!=y3) k2=((x2-x3) << 6) / (y2-y3);
- else k2=((x2-x3) << 6);
-
- x_2=x2 << 6;
- i=y2;
- do
- {
- x+=k;
- x_2+=k2;
- i++;
-
- if ((x1t = x >> 6) > (x2t = x_2 >> 6))
- hline(x2t, x1t, i, c);
- else
- hline(x1t, x2t, i, c);
- }
- while (i!=y3);
-}
-
-void clearscr()
-{
- copyXPMArea(78,0,56,56,4,4);
-}
-
-// Blits a string at given co-ordinates
-void BlitString(char *name, int x, int y)
-{
- int i;
- int c;
- int k;
-
- k = x;
-
- copyXPMArea(73,64,1,8,k-1,y);
-
- for (i=0; name[i]; i++)
- {
- c = toupper(name[i]);
- //printf("%c",c);
-
- if (c >= 'A' && c <= 'Z')
- { // its a letter
- c -= 'A';
- if ( k > -2) copyXPMArea(c * 6, 74, 6, 8, k, y);
- k += 6;
- } else
- if (c >= '0' && c<= ':')
- { // its a number or symbol
- c -= '0';
- if ( k > -2) copyXPMArea(c * 6, 64, 6, 8, k, y);
- k += 6;
- } else
- if (c == 246) {
- if ( k > -2) copyXPMArea(0, 84, 6, 9, k, y);
- k += 6;
- } else
- if (c == 228) {
- if ( k > -2) copyXPMArea(6, 84, 6, 9, k, y);
- k += 6;
- } else
- if (c == 229) {
- if ( k > -2) copyXPMArea(12, 84, 6, 9, k, y);
- k += 6;
- } else
- { // its a blank or something else
- if ( k > -2) copyXPMArea(73,64,6,8,k,y);
- k += 6;
- }
- if (k >= 58) break;
- }
- copyXPMArea(73,64,1,8,k,y);
-
-}
-
-// Blits number to given coordinates.. two 0's, right justified
-
-void BlitNum(int num, int x, int y)
-{
- char buf[1024];
- int newx=x;
-
- if (num > 99)
- {
- newx -= CHAR_WIDTH;
- }
-
- if (num > 999)
- {
- newx -= CHAR_WIDTH;
- }
-
- sprintf(buf, "%02i", num);
-
- BlitString(buf, newx, y);
-}
-
-void line(int x1, int y1, int x2, int y2, int c)
-{
- int i, deltax, deltay, numpixels,
- d, dinc1, dinc2,
- x, xinc1, xinc2,
- y, yinc1, yinc2;
-
- deltax = abs(x2 - x1);
- deltay = abs(y2 - y1);
- if (deltax >= deltay)
- {
- numpixels = deltax + 1;
- d = (deltay << 1) - deltax;
- dinc1 = deltay << 1;
- dinc2 = (deltay - deltax) << 1;
- xinc1 = 1;
- xinc2 = 1;
- yinc1 = 0;
- yinc2 = 1;
- }
- else
- {
- numpixels = deltay + 1;
- d = (deltax << 1) - deltay;
- dinc1 = deltax << 1;
- dinc2 = (deltax - deltay) << 1;
- xinc1 = 0;
- xinc2 = 1;
- yinc1 = 1;
- yinc2 = 1;
- }
- if (x1 > x2)
- {
- xinc1 = - xinc1;
- xinc2 = - xinc2;
- }
- if (y1 > y2)
- {
- yinc1 = - yinc1;
- yinc2 = - yinc2;
- }
- x = x1;
- y = y1;
- for (i=1; i<numpixels; i++)
- {
- putpixel(x, y, c);
- if (d < 0)
- {
- d = d + dinc1;
- x = x + xinc1;
- y = y + yinc1;
- }
- else
- {
- d = d + dinc2;
- x = x + xinc2;
- y = y + yinc2;
- }
- }
-}
-
-
-//**** 3d specific ********************************
-//*************************************************
-
-void rotate(int xang, int yang, int zang)
-{
- float tx, ty, tz;
- int i;
-
- for (i = 0; i < nofcoords; i++)
- {
- tx = cost[yang]*matrix[i][0]-sint[yang]*matrix[i][2];
- tz = sint[yang]*matrix[i][0]+cost[yang]*matrix[i][2];
- ty = cost[zang]*matrix[i][1]-sint[zang]*tx;
-
- rmatrix[i][0] = (cost[zang]*tx+sint[zang]*matrix[i][1]);
- rmatrix[i][1] = (sint[xang]*tz+cost[xang]*ty);
- rmatrix[i][2] = (cost[xang]*tz-sint[xang]*ty);
- }
-
- if (planesORlines)
- for (i = 0; i < nofplanes; i++)
- if (normal(rmatrix[planes[i][0]], rmatrix[planes[i][1]], rmatrix[planes[i][2]]) > 0)
- plane_color[i] = luminate(rmatrix[planes[i][0]], rmatrix[planes[i][1]], rmatrix[planes[i][2]]);
-
- for (i = 0; i < nofcoords; i++) {
- // Perspective correcting lines...
- rmatrix[i][0] = (rmatrix[i][0] *256) / (2*rmatrix[i][2] - zoff) + xcenter;
- rmatrix[i][1] = (rmatrix[i][1] *256) / (2*rmatrix[i][2] - zoff) + ycenter;
- }
-}
-
-void sortz(int nofelements) { // Insertion-sort the planes in increasing z-distance
-
- int i, j, k;
- float key;
- float temparr[nofelements];
-
- for (i = 0; i < nofelements; i++)
- {
- zorder[i] = i;
- temparr[i] = rmatrix[planes[i][0]][2]+rmatrix[planes[i][1]][2]+rmatrix[planes[i][2]][2];
- }
-
- for (j = 1; j < nofelements; j++) {
-
- key = temparr[j];
- k = zorder[j];
- i = j - 1;
-
- while ((i > -1) && (temparr[i] > key)) {
- temparr[i+1] = temparr[i];
- zorder[i+1] = zorder[i--];
- }
-
- zorder[i+1] = k;
- temparr[i+1] = key;
- }
-}
-
-int normal(float p1[], float p2[], float p3[])
-{
- return ((p1[0]-p3[0])*(p2[1]-p3[1])-(p2[0]-p3[0])*(p1[1]-p3[1]));
-}
-
-int luminate(float p1[], float p2[], float p3[])
-{
- double x1 = (float)(p1[0]-p3[0]), y1 = (float)(p1[1]-p3[1]), z1 = (float)(p1[2]-p3[2]);
- double x2 = (float)(p2[0]-p3[0]), y2 = (float)(p2[1]-p3[1]), z2 = (float)(p2[2]-p3[2]);
- double nx = y1*z2-y2*z1, ny =-(x1*z2-x2*z1),nz = x1*y2-y1*x2;
-
- return (int)(53 * (acost[(int)(50 + 50*(nx*lum_vector[0]+ny*lum_vector[1]+nz*lum_vector[2])/
- (sqrt(nx*nx+ny*ny+nz*nz)*
- sqrt(lum_vector[0]*lum_vector[0]+lum_vector[1]*lum_vector[1]+
- lum_vector[2]*lum_vector[2])))] / PI));
-
- // Do I smell optimization? :-)
-}
-
-void setUpAngles()
-{
- int i;
- for (i = 0; i < 361; i++) {
- cost[i] = cos((double)i*(2*PI/(double)360));
- sint[i] = sin((double)i*(2*PI/(double)360));
- }
-
- for (i = 0; i < 100; i++) acost[i] = acos((double)(-50+i)/50);
-}
-
-void setupobj(char *filename)
-{
- int i, j = 0;
- int biggest = 0;
- float scale = 1;
-
- xcenter = 16;
- ycenter = 15 - 2*show_load;
-
- if (strcmp(filename,"") != 0)
- loadobj(filename);
- else
- {
- nofcoords = 8;
- noflines = 24;
- nofplanes = 12;
- planesORlines = 1;
-
- matrix = (float **)malloc(nofcoords*sizeof(float *)); mem_alloc_error(matrix);
- planes = (int **)malloc(nofplanes*sizeof(int *)); mem_alloc_error(planes);
- plane_color = (int *)malloc(nofplanes*sizeof(int)); mem_alloc_error(plane_color);
- zorder = (int *)malloc(nofplanes*sizeof(int)); mem_alloc_error(zorder);
-
- for (i = 0; i < nofplanes; i++) zorder[i] = i;
-
- for (i = 0; i < nofcoords; i++) {
- matrix[i] = (float *)malloc(3*sizeof(float));
- mem_alloc_error(matrix[i]);
- }
-
- for (i = 0; i < nofplanes; i++) {
- planes[i] = (int *)malloc(3*sizeof(int));
- mem_alloc_error(planes[i]);
- }
-
- cline = (int *)malloc((noflines+1)*sizeof(int)); mem_alloc_error(cline);
-
- matrix[0][0] = -180; matrix[0][1] = -180; matrix[0][2] = 180; // 0
- matrix[1][0] = 180; matrix[1][1] = -180; matrix[1][2] = 180; // 1
- matrix[2][0] = 180; matrix[2][1] = 180; matrix[2][2] = 180; // 2
- matrix[3][0] = -180; matrix[3][1] = 180; matrix[3][2] = 180; // 3
- matrix[4][0] = -180; matrix[4][1] = -180; matrix[4][2] = -180; // 4
- matrix[5][0] = 180; matrix[5][1] = -180; matrix[5][2] = -180; // 5
- matrix[6][0] = 180; matrix[6][1] = 180; matrix[6][2] = -180; // 6
- matrix[7][0] = -180; matrix[7][1] = 180; matrix[7][2] = -180; // 7
-
- cline[0] = 1; cline[1] = 2;
- cline[2] = 2; cline[3] = 3;
- cline[4] = 3; cline[5] = 4;
- cline[6] = 4; cline[7] = 1;
- cline[8] = 5; cline[9] = 6;
- cline[10] = 6; cline[11] = 7;
- cline[12] = 7; cline[13] = 8;
- cline[14] = 8; cline[15] = 5;
- cline[16] = 1; cline[17] = 5;
- cline[18] = 2; cline[19] = 6;
- cline[20] = 3; cline[21] = 7;
- cline[22] = 4; cline[23] = 8;
-
- planes[0][0] = 0; planes[0][1] = 1; planes[0][2] = 3;
- planes[1][0] = 1; planes[1][1] = 2; planes[1][2] = 3;
- planes[2][0] = 1; planes[2][1] = 5; planes[2][2] = 6;
- planes[3][0] = 1; planes[3][1] = 6; planes[3][2] = 2;
-
- planes[4][0] = 4; planes[4][1] = 0; planes[4][2] = 3;
- planes[5][0] = 4; planes[5][1] = 3; planes[5][2] = 7;
- planes[6][0] = 3; planes[6][1] = 2; planes[6][2] = 7;
- planes[7][0] = 7; planes[7][1] = 2; planes[7][2] = 6;
-
- planes[8][0] = 4; planes[8][1] = 1; planes[8][2] = 0;
- planes[9][0] = 4; planes[9][1] = 5; planes[9][2] = 1;
- planes[10][0] = 5; planes[10][1] = 4; planes[10][2] = 7;
- planes[11][0] = 5; planes[11][1] = 7; planes[11][2] = 6;
- }
-
- rmatrix = (float **)realloc(rmatrix,nofcoords*sizeof(float *)); mem_alloc_error(rmatrix);
- for (i = 0; i < nofcoords; i++) {
- rmatrix[i] = (float *)malloc(3*sizeof(float));
- mem_alloc_error(rmatrix[i]);
- }
-
- /*
- * Find the longest discance between all coordinates relative to the origin
- */
-
- for (i = 0; i < nofcoords; i++) {
- j = (int)sqrt((pow(matrix[i][0],2)+pow(matrix[i][1],2)+pow(matrix[i][2],2)));
- if (j > biggest) biggest = j;
- }
-
- /*
- * Scale every coordinate using the calculated factor
- */
-
- scale = 280 / (float)biggest;
-
- for (i = 0; i < nofcoords; i++) {
- matrix[i][0] *= scale;
- matrix[i][1] *= scale;
- matrix[i][2] *= scale;
- }
-}
-
-
-
-
-//**** Application Management, I/O etc. ***********
-//*************************************************
-
-void print_help() {
- printf("\nwmCube %s (%s)\n\n", WMCUBE_VERSION, REV_DATE);
-
-#ifndef SOLARIS
- printf(" -o <filename or directory>: load external 3d-object(s).\n\n");
-#else
- printf(" -o <filename>: load external 3d-object.\n\n");
-#endif
-
- printf(" -d x: rotate x degrees/step when the cpu is idle. (default 1)\n");
- printf(" -r x: rotate 1 degree faster every x percent of cpu-usage. (default 25)\n");
-
-#ifdef LINUX
- printf(" -c x: which cpu (0,1,2..) to monitor. (default average over all)\n");
- printf(" -n : exclude \"nice\" processes. (default OFF)\n");
-#endif
-
-#ifdef SOLARIS
- printf(" -c x: which cpu (0,1,2..) to monitor. (default average over all)\n");
-#endif
-
-#ifdef FREEBSD
- printf(" -n : exclude \"nice\" processes. (default OFF)\n");
-#endif
-
-#ifdef NETBSD
- printf(" -n : exclude \"nice\" processes. (default OFF)\n");
-#endif
-
- printf(" -b : draw the cube in a brighter color. (default OFF)\n");
- printf(" -i : invert cube speed. (default OFF)\n");
- printf(" -p : do not display cpu-load (default OFF)\n");
- printf(" -h : display this helptext.\n\n");
-}
-
-void die()
-{
- fprintf(stderr, "%s: exiting", pname);
- exit (1);
-}
-
-#ifndef SOLARIS // scan4objects doesnt work on Solaris because of alphasort
-int scan4objects(char *dir)
-{
- struct dirent **names;
- int n;
-
- n = scandir(dir,&names,0,alphasort);
-
- while (n-- > 0)
- if (strstr(names[n]->d_name,".wmc") != NULL)
- {
- objects[nof_objects] = (char *)malloc(strlen(dir)+strlen(names[n]->d_name)+2);
- strcpy(objects[nof_objects],dir);
- if (dir[strlen(dir)] != '/') strcat(objects[nof_objects],"/");
- strcat(objects[nof_objects++],names[n]->d_name);
- }
-
- return nof_objects;
-}
-#endif
-
-int next_object()
-{
- if (nof_objects == 0) return -1;
- setupobj(objects[rand() % (nof_objects )]);
-
- return 0;
-}
-
-
-int loadobj(char *filename) {
-
- FILE *fp;
- char tmp[64] = {""};
- int i = 0, counter = 1;
-
- //printf("\nLoading file %s...",filename); fflush(stdout);
-
- if ((fp = fopen(filename,"rt")) == NULL) {
- printf("\nERROR: wmCube object-file not found (%s).\n\n",filename);
- exit(0);
- }
-
- fscanf(fp,"%s",tmp);
-
- if (strcmp(tmp,"WMCUBE_COORDINATES") != 0) {
- printf("\nError in objectfile: it must start with WMCUBE_COORDINATES\n\n");
- fclose(fp);
- exit(0);
- }
-
- fscanf(fp,"%s",tmp);
- counter = atoi(tmp);
-
- while ((strcmp(tmp,"WMCUBE_LINES") != 0) && (strcmp(tmp,"WMCUBE_PLANES") != 0)) {
-
- matrix = (float **)realloc(matrix,(i+1)*sizeof(float *)); mem_alloc_error(matrix);
- matrix[i] = (float *)malloc(3*sizeof(float)); mem_alloc_error(matrix[i]);
- fscanf(fp,"%f %f %f",&matrix[i][0],&matrix[i][1],&matrix[i][2]);
- //printf("\n%d: %f %f %f",atoi(tmp), matrix[i][0],matrix[i][1],matrix[i][2]);
-
- if (atoi(tmp) != (++i)) {
-
- printf("\nError in objectfile (WMCUBE_COORDINATES section):\n"
- "the coordinates must be listed in order 1..n\n\n");
- fclose(fp);
- exit(0);
- }
- fscanf(fp,"%s",tmp);
-
- if (feof(fp)) {
- printf("\nError in objectfile: you must have a section WMCUBE_LINES or WMCUBE_PLANES\n\n");
- fclose(fp);
- exit(0);
- }
- }
-
- nofcoords = i;
- i = 0;
-
- if (strcmp(tmp,"WMCUBE_LINES") == 0) {
-
- planesORlines = 0;
- while (1) {
-
- cline = (int *)realloc(cline,(i+2)*sizeof(int)); mem_alloc_error(cline);
- fscanf(fp,"%d %d",&cline[i++],&cline[i++]);
- //printf("\n%d %d",cline[i-2],cline[i-1]);
- if (feof(fp)) break;
-
- if (cline[i-2] > nofcoords || cline[i-1] > nofcoords) {
- printf("\nError in objectfile (WMCUBE_LINES section):\n"
- "coordinates %d or/and %d doesnt exist\n\n",cline[i-2],cline[i-1]);
- fclose(fp);
- exit(0);
- }
- }
- noflines = i-2;
- }
- else if (strcmp(tmp,"WMCUBE_PLANES") == 0) {
-
- planesORlines = 1;
- while (1) {
- planes = (int **)realloc(planes,(i+1)*sizeof(int *)); mem_alloc_error(planes);
- planes[i] = (int *)malloc(3*sizeof(int)); mem_alloc_error(planes[i]);
- fscanf(fp,"%d %d %d",&planes[i][0],&planes[i][1],&planes[i][2]);
- //printf("\n%d: %d %d %d",i,planes[i][0],planes[i][1],planes[i][2]);
-
- planes[i][0]--; planes[i][1]--; planes[i][2]--;
- //printf("\n%d: %d %d %d\n",i,planes[i][0],planes[i][1],planes[i][2]);
-
- if (feof(fp)) break;
-
- if (planes[i][0] > nofcoords || planes[i][1] > nofcoords || planes[i][2] > nofcoords) {
- printf("\nError in objectfile (WMCUBE_PLANES section):\n"
- "coordinates %d or/and %d or/and %d doesnt exist\n\n",planes[i][0],planes[i][1],planes[i][2]);
- fclose(fp);
- exit(0);
- }
- i++;
- }
- nofplanes = i;
- plane_color = (int *)malloc(nofplanes*sizeof(int)); mem_alloc_error(plane_color);
- zorder = (int *)malloc(nofplanes*sizeof(int)); mem_alloc_error(zorder);
- for (i = 0; i < nofplanes; i++) zorder[i] = i;
-
- } else {
- printf("\nError in objectfile: you must have a section WMCUBE_LINES or WMCUBE_PLANES\n\n");
- fclose(fp);
- exit(0);
- }
-
- fclose(fp);
- return 1;
-}
-
-void mem_alloc_error(void *block) {
- if (block == NULL) {
- printf("\nError allocating memory!\n\n");
- exit(0);
- }
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Begin System Specific Code. If you wish to port wmcube to a new platform,
- * you'll need to implement the following operations:
- *
- * int init_calc_cpu();
- * Perform feature tests to determine whether wmcube can run, and set up
- * any files/data structures/etc. to gather statistics.
- *
- * int calc_cpu_total();
- * return an integer reflecting the current CPU load
- */
-
-#if defined LINUX
-
-/*
- * init_calc_cpu doesn't have much to do on Linux, but it can check to see if
- * /proc/stat is available; if the user selected to monitor a particular CPU,
- * it can check it's existence.
- */
-int init_calc_cpu()
-{
- FILE *fp;
- int i;
- char cpuid[6];
- char check_cpu[6];
-
- sprintf(check_cpu, "cpu%d", which_cpu);
-
- if ((fp = fopen("/proc/stat","rb")) == NULL) {
- perror("/proc/stat required for this system");
- return -1;
- }
-
- if (which_cpu == -1)
- return 0;
-
- for (i = -2; i < which_cpu; i++) {
- fscanf(fp, "%s", cpuid);
- }
-
- if (strcmp(check_cpu,cpuid) != 0) {
- fprintf(stderr, "ERROR: could not read cpu-load on %s. Are you "
- "sure you have an SMP system?\n",check_cpu);
- return -1;
- }
- return (0);
-}
-
-int calc_cpu_total() {
- int total, used, t=0, i;
- static int previous_total = 0, previous_used = 0;
- char cpuid[6];
- int cpu,nice,system,idle;
- FILE *fp;
-
- fp = fopen("/proc/stat","rt");
-
- for (i = -2; i < which_cpu; i++) {
- fscanf(fp,"%s %d %d %d %d",cpuid,&cpu,&nice,&system,&idle);
- }
-
- fclose(fp);
-
- used = cpu + system + use_nice*nice;
- total = used + idle + (1-use_nice)*nice;
-
- t = 100 * (double)(used - previous_used) / (double)(total - previous_total);
- previous_total = total;
- previous_used = used;
-
- return t;
-}
-
-#elif defined SOLARIS
-#include <sys/types.h>
-#include <sys/sysinfo.h>
-#include <kstat.h>
-
-static kstat_ctl_t *kc;
-static kstat_t **cpu_ksp_list;
-static kstat_t *the_cpu;
-static int ncpus;
-
-/*
- * The biggest subtlety of the Solaris port is that init_calc_cpu can be called
- * after the initial program setup. This occurs when a 'kstat state change'
- * occurs. Usually this means that a CPU has been taken on or off-line using
- * the psradm command. Another possibility is that on server systems, a new
- * CPU might have been hot-added to a running system.
- *
- * As a result, init_calc_cpu frees any resources it might have setup if needed,
- * and reinitializes everything.
- */
-int init_calc_cpu()
-{
- kstat_t *ksp;
- int i = 0;
-
- if (kc == NULL) {
- if ((kc = kstat_open()) == NULL) {
- fprintf(stderr, "wmcube: can't open /dev/kstat\n");
- return -1;
- }
- }
-
- if (which_cpu != -1) {
- /*
- * User selected to monitor a particlur CPU. find it...
- */
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- if ((strcmp(ksp->ks_module, "cpu_stat") == 0) &&
- (ksp->ks_instance == which_cpu)) {
- the_cpu = ksp;
- break;
- }
- }
- if (the_cpu == NULL) {
- fprintf(stderr, "CPU %d not found\n", which_cpu);
- return -1;
- }
- } else {
- /*
- * User selected to monitor all CPUs. First, count them.
- */
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- if (strcmp(ksp->ks_module, "cpu_stat") == 0)
- i++;
- }
-
- if (cpu_ksp_list) {
- free(cpu_ksp_list);
- }
- cpu_ksp_list = (kstat_t **) calloc(i * sizeof (kstat_t *), 1);
- ncpus = i;
-
- /*
- * stash the ksp for each CPU.
- */
- i = 0;
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
- if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
- cpu_ksp_list[i] = ksp;
- i++;
- }
- }
- }
- return 0;
-}
-
-int calc_cpu_total()
-{
- int i;
- cpu_stat_t stat;
- static int previous_total = 0, previous_used = 0;
- int used, total, t, user = 0, wait = 0, kern = 0, idle = 0;
-
- /*
- * Read each cpu's data. If the kstat chain has changed (a state change
- * has happened, maybe a new cpu was added to the system or one went
- * away), then reinitialize everything with init_calc_cpu(). Finally,
- * recursively call calc_cpu_total.
- *
- * We'll need to do a little better than this in the future, since we
- * could recurse too much in the pathological case here.
- */
- if (which_cpu == -1) {
- for (i = 0; i < ncpus; i++) {
- if (kstat_read(kc, cpu_ksp_list[i],
- (void *)&stat) == -1) {
- if (init_calc_cpu() != 0) {
- fprintf(stderr, "failed to "
- "reinitialize following state "
- "change\n");
- return (-1);
- }
- return (calc_cpu_total());
- }
- user += stat.cpu_sysinfo.cpu[CPU_USER]; /* user */
- wait += stat.cpu_sysinfo.cpu[CPU_WAIT]; /* io wait */
- kern += stat.cpu_sysinfo.cpu[CPU_KERNEL]; /* sys */
- idle += stat.cpu_sysinfo.cpu[CPU_IDLE]; /*idle("free")*/
- }
- } else {
- if (kstat_read(kc, the_cpu, (void *)&stat) == -1) {
- if (init_calc_cpu() != 0) {
- fprintf(stderr, "failed to reinitialize "
- "following state change\n");
- return (-1);
- }
- return (calc_cpu_total());
- }
- user += stat.cpu_sysinfo.cpu[CPU_USER]; /* user */
- wait += stat.cpu_sysinfo.cpu[CPU_WAIT]; /* io wait */
- kern += stat.cpu_sysinfo.cpu[CPU_KERNEL]; /* sys */
- idle += stat.cpu_sysinfo.cpu[CPU_IDLE]; /* idle("free") */
- }
-
- used = user + wait + kern;
- total = used + idle;
- t = 100 * (double)(used - previous_used) /
- (double)(total - previous_total);
- previous_total = total;
- previous_used = used;
- return (t);
-}
-
-#elif defined FREEBSD
-#include <nlist.h>
-#include <fcntl.h>
-#include <sys/dkstat.h>
-
-int init_calc_cpu()
-{
-
- if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
- {
- printf("\nError: unable to open kvm\n\n");
- exit(0);
- }
- kvm_nlist(kd, nlst);
- if (nlst[0].n_type == 0)
- {
- printf("\nError: unable to get nlist\n\n");
- exit(1);
- }
-
- return 0;
-}
-
-int calc_cpu_total() {
- int total, used, t=0;
- static int previous_total = 0, previous_used = 0;
- int cpu,nice,system,idle;
- unsigned long int cpu_time[CPUSTATES];
-
- if (kvm_read(kd, nlst[0].n_value, &cpu_time, sizeof(cpu_time))
- != sizeof(cpu_time))
- {
- printf("\nError reading kvm\n\n");
- exit(0);
- }
-
- cpu = cpu_time[CP_USER];
- nice = cpu_time[CP_NICE];
- system = cpu_time[CP_SYS];
- idle = cpu_time[CP_IDLE];
-
- used = cpu + system + use_nice*nice;
- total = used + idle + (1-use_nice)*nice;
-
- t = 100 * (double)(used - previous_used) / (double)(total - previous_total);
- previous_total = total;
- previous_used = used;
-
- return t;
-}
-
-#elif defined OPENBSD
-
-int init_calc_cpu()
-{
- return 0;
-}
-
-int calc_cpu_total() {
- double avenrun[3];
-
- (void) getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0]));
- return(((5.0*avenrun[0] + 0.5) > 50) ? 50 : (5.0*avenrun[0] + 0.5))*2;
-}
-
-
-#elif defined NETBSD /* END OPENBSD */
-#include <sys/sched.h>
-#include <sys/sysctl.h>
-
-int init_calc_cpu ()
-{
- return 0;
-}
-
-int calc_cpu_total ()
-{
- static u_int64_t last_cp_time[CPUSTATES] = { 0, 0, 0, 0, 0 };
- u_int64_t curr_cp_time[CPUSTATES];
- u_int64_t total_time = 0, idle_time = 0;
- int mib[2];
- int i;
- size_t ssize;
- const int IDLE_TIME = 4;
- const int NICE_TIME = 1;
-
- ssize = sizeof ( curr_cp_time );
- mib[0] = CTL_KERN;
- mib[1] = KERN_CP_TIME;
- if ( sysctl ( mib, 2, curr_cp_time, &ssize, NULL, 0 ) ) {
- fprintf ( stderr, "wmcube: unable to read CP_TIME from sysctl()\n" );
- exit ( 0 );
- }
- if ( !use_nice )
- curr_cp_time[NICE_TIME] = 0;
-
- /* NetBSD gives 5 CPUSTATES -
- * User, Nice, System, Interrupt, Idle
- */
- idle_time = curr_cp_time[IDLE_TIME] - last_cp_time[IDLE_TIME];
- for ( i = 0; i < CPUSTATES; i++ ) {
- total_time += ( curr_cp_time[i] - last_cp_time[i] );
- last_cp_time[i] = curr_cp_time[i];
- }
-
- /* Calculate the % CPU usage as the User+Nice+System+Interrupt/Total
- * for the interval
- */
- return ( 100 * (int) ( total_time - idle_time ) / total_time );
-
-}
-
-#else /* END NETBSD */
-
-/*
- * This is a stub which will compile for platforms other than LINUX or SOLARIS.
- * Use these to start your port to a new platform.
- */
-int init_calc_cpu()
-{
- return 0;
-}
-
-int calc_cpu_total()
-{
- return 0;
-}
-
-#endif /* OS SPECIFIC CODE */
diff --git a/wmcube/wmcube.xpm b/wmcube/wmcube.xpm
deleted file mode 100644
index f72c004..0000000
--- a/wmcube/wmcube.xpm
+++ /dev/null
@@ -1,142 +0,0 @@
-/* XPM */
-static char * wmcube_xpm[] = {
-"160 100 39 1",
-" c blue",
-". c #202020",
-"X c black",
-"o c #C7C3C7",
-"O c #20B2AE",
-"+ c #007D71",
-"@ c #B60418",
-"# c #00EB00",
-"$ c #283C38",
-"% c #F7F3FF",
-"& c #004941",
-"! c #1A8E8A",
-"A c #20AFAB",
-"B c #1FACA9",
-"C c #1EA9A5",
-"D c #1EA5A1",
-"E c #1DA19E",
-"F c #1C9C99",
-"G c #1B9894",
-"H c #1B928F",
-"I c #1A8E8A",
-"J c #198985",
-"K c #178480",
-"L c #177F7B",
-"M c #167A77",
-"N c #157672",
-"P c #14716E",
-"Q c #136C69",
-"R c #136764",
-"S c #116360",
-"T c #115E5A",
-"U c #115D5B",
-"V c #0F5956",
-"W c #0F5351",
-"Y c #0E4E4D",
-"Z c #0E4E4C",
-"1 c #0D4A48",
-"2 c #0C4644",
-"3 c #0C4240",
-" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX O!",
-" .............oX......................................................o ",
-" .............oX......................................................o ",
-" .............oX......................................................o ",
-" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .............oX......................................................o ",
-" .......................................................o .............oX......................................................o ",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX..............................................&&......o..........................",
-" .......................................................o .............oX..............................................&&......o..........................",
-" .......................................................o .............oX.....&&&&&&.................................&&&&&&....o..........................",
-" .......................................................o .............oX.....&&&&&&.................................&&&&&&....o..........................",
-" .......................................................o .............oX..............................................&&......o..........................",
-" .......................................................o .............oX..............................................&&......o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o .............oX......................................................o..........................",
-" .......................................................o oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo..........................",
-" .......................................................o . OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-" .......................................................o . AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-" .......................................................o . BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
-" oooooooooooooooooooooooooooooooooooooooooooooooooooooooo . CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
-" . EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
-" . FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-" . GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
-" . HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH",
-"............................................................................... IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
-"..OOO.....+..+OOO+.+OOO+.+...+.+OOO+.+OOO+.+OOO+.+OOO+.+OOO+................... JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ",
-".O...O....O......O.....O.O...O.O.....O.........O.O...O.O...O............O...... KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK",
-".O...O....O......O.....O.O...O.O.....O.........O.O...O.O...O............O...... LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL",
-".+...+....+..+OOO+..OOO+.+OOO+.+OOO+.+OOO+.....+.&OOO&.+OOO+...........O....... MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM",
-".O...O....O..O.........O.....O.....O.O...O.....O.O...O.....O...........O....... NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
-".O...O....O..O.........O.....O.....O.O...O.....O.O...O.....O...O...O..O.....O.. PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
-"..OOO.....O..+OOO+.+OOO+.....+.+OOO+.+OOO+.....+.+OOO+.+OOO+...+...+..O.....+.. QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ",
-"............................................................................... RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR",
-" SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
-"................................................................................................................................................................",
-".&OOO&.+OOO..+OOO+.+OOO..+OOO+.+OOO+.+OOO+.+...+...+.......+.+...+.+.....O...O.+OOO..+OOO+.+OOO+.+OOO+.+OOO+.+OOO+.+OOO+.+...+.+...+.+...+.+...+.+...+..........",
-".O...O.O...O.O.....O...O.O.....O.....O.....O...O...O.......O.O...O.O.....OO.OO.O...O.O...O.O...O.O...O.O...O.O.......O...O...O.O...O.O...O.O...O.O...O.O...O....",
-".O...O.O...O.O.....O...O.O.....O.....O.....O...O...O.......O.O..O..O.....O.O.O.O...O.O...O.O...O.O...O.O...O.O.......O...O...O.O...O.O...O..O.O..O...O....O.....",
-".+OOO+.+OOO..+.....+...+.+OOO..+OOO..+.OO+.+OOO+...+.......+.+OO&..+.....+...+.+...+.+...+.+OOO+.+O..+.+OOO..+OOO+...+...+...+.+...+.+...+..&O&..+OOO+...O......",
-".O...O.O...O.O.....O...O.O.....O.....O...O.O...O...O.......O.O..O..O.....O...O.O...O.O...O.O.....O.O.O.O...O.....O...O...O...O.O+.+O.O.O.O..O.O......O..O.......",
-".O...O.O...O.O.....O...O.O.....O.....O...O.O...O...O.......O.O...O.O.....O...O.O...O.O...O.O.....O..OO.O...O.....O...O...O...O..O+O..OO.OO.O...O.....O.O...O....",
-".+...+.+OOO..+OOO+.OOOO..+OOO+.O.....+OOO+.+...+...O...+OOO+.+...+.+OOO&.+...+.O...O.+OOO+.+.....+OOO+.+...+.+OOO+...+...&OOOO...O...O...O.+...O.+OOO+..........",
-"................................................................................................................................................................",
-" TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT",
-"...............O... UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
-"...++.............. VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV",
-"...++........&OOO&. WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
-".++++++++++++O...O. YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
-".++++++++++++O...O. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
-"...++........+OOO+. 11111111111111111111111111111111111111111111111111111111",
-"...++........O...O. 22222222222222222222222222222222222222222222222222222222",
-".............+...+. 33333333333333333333333333333333333333333333333333333333",
-"................... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/wmgeneral/list.c b/wmgeneral/list.c
deleted file mode 100644
index f804b2c..0000000
--- a/wmgeneral/list.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Generic single linked list to keep various information
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
-
-Author: Kresten Krab Thorup
-
-Many modifications by Alfredo K. Kojima
-
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with files compiled with
- GCC to produce an executable, this does not cause the resulting executable
- to be covered by the GNU General Public License. This exception does not
- however invalidate any other reasons why the executable file might be
- covered by the GNU General Public License. */
-
-#include "list.h"
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#include <stdlib.h>
-
-/* Return a cons cell produced from (head . tail) */
-
-INLINE LinkedList*
-list_cons(void* head, LinkedList* tail)
-{
- LinkedList* cell;
-
- cell = (LinkedList*)malloc(sizeof(LinkedList));
- cell->head = head;
- cell->tail = tail;
- return cell;
-}
-
-/* Return the length of a list, list_length(NULL) returns zero */
-
-INLINE int
-list_length(LinkedList* list)
-{
- int i = 0;
- while(list)
- {
- i += 1;
- list = list->tail;
- }
- return i;
-}
-
-/* Return the Nth element of LIST, where N count from zero. If N
- larger than the list length, NULL is returned */
-
-INLINE void*
-list_nth(int index, LinkedList* list)
-{
- while(index-- != 0)
- {
- if(list->tail)
- list = list->tail;
- else
- return 0;
- }
- return list->head;
-}
-
-/* Remove the element at the head by replacing it by its successor */
-
-INLINE void
-list_remove_head(LinkedList** list)
-{
- if (!*list) return;
- if ((*list)->tail)
- {
- LinkedList* tail = (*list)->tail; /* fetch next */
- *(*list) = *tail; /* copy next to list head */
- free(tail); /* free next */
- }
- else /* only one element in list */
- {
- free(*list);
- (*list) = 0;
- }
-}
-
-
-/* Remove the element with `car' set to ELEMENT */
-/*
-INLINE void
-list_remove_elem(LinkedList** list, void* elem)
-{
- while (*list)
- {
- if ((*list)->head == elem)
- list_remove_head(list);
- *list = (*list ? (*list)->tail : NULL);
- }
-}*/
-
-INLINE LinkedList *
-list_remove_elem(LinkedList* list, void* elem)
-{
- LinkedList *tmp;
-
- if (list) {
- if (list->head == elem) {
- tmp = list->tail;
- free(list);
- return tmp;
- }
- list->tail = list_remove_elem(list->tail, elem);
- return list;
- }
- return NULL;
-}
-
-
-/* Return element that has ELEM as car */
-
-INLINE LinkedList*
-list_find(LinkedList* list, void* elem)
-{
- while(list)
- {
- if (list->head == elem)
- return list;
- list = list->tail;
- }
- return NULL;
-}
-
-/* Free list (backwards recursive) */
-
-INLINE void
-list_free(LinkedList* list)
-{
- if(list)
- {
- list_free(list->tail);
- free(list);
- }
-}
-
-/* Map FUNCTION over all elements in LIST */
-
-INLINE void
-list_mapcar(LinkedList* list, void(*function)(void*))
-{
- while(list)
- {
- (*function)(list->head);
- list = list->tail;
- }
-}
diff --git a/wmgeneral/list.h b/wmgeneral/list.h
deleted file mode 100644
index af0f22c..0000000
--- a/wmgeneral/list.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Generic single linked list to keep various information
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
-Author: Kresten Krab Thorup
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with files compiled with
- GCC to produce an executable, this does not cause the resulting executable
- to be covered by the GNU General Public License. This exception does not
- however invalidate any other reasons why the executable file might be
- covered by the GNU General Public License. */
-
-#ifndef __LIST_H_
-#define __LIST_H_
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-# define INLINE inline
-#else
-# define INLINE
-#endif
-
-typedef struct LinkedList {
- void *head;
- struct LinkedList *tail;
-} LinkedList;
-
-INLINE LinkedList* list_cons(void* head, LinkedList* tail);
-
-INLINE int list_length(LinkedList* list);
-
-INLINE void* list_nth(int index, LinkedList* list);
-
-INLINE void list_remove_head(LinkedList** list);
-
-INLINE LinkedList *list_remove_elem(LinkedList* list, void* elem);
-
-INLINE void list_mapcar(LinkedList* list, void(*function)(void*));
-
-INLINE LinkedList*list_find(LinkedList* list, void* elem);
-
-INLINE void list_free(LinkedList* list);
-
-#endif
diff --git a/wmgeneral/misc.c b/wmgeneral/misc.c
deleted file mode 100644
index 34281e2..0000000
--- a/wmgeneral/misc.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* dock.c- built-in Dock module for WindowMaker
- *
- * WindowMaker window manager
- *
- * Copyright (c) 1997 Alfredo K. Kojima
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "list.h"
-#include "misc.h"
-
-/*
- *----------------------------------------------------------------------
- * parse_command--
- * Divides a command line into a argv/argc pair.
- *----------------------------------------------------------------------
- */
-#define PRC_ALPHA 0
-#define PRC_BLANK 1
-#define PRC_ESCAPE 2
-#define PRC_DQUOTE 3
-#define PRC_EOS 4
-#define PRC_SQUOTE 5
-
-typedef struct {
- short nstate;
- short output;
-} DFA;
-
-
-static DFA mtable[9][6] = {
- {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
- {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
- {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
- {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
- {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
- {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
- {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
- {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
- {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
-};
-
-char*
-next_token(char *word, char **next)
-{
- char *ptr;
- char *ret, *t;
- int state, ctype;
-
- t = ret = malloc(strlen(word)+1);
- ptr = word;
-
- state = 0;
- *t = 0;
- while (1) {
- if (*ptr==0)
- ctype = PRC_EOS;
- else if (*ptr=='\\')
- ctype = PRC_ESCAPE;
- else if (*ptr=='"')
- ctype = PRC_DQUOTE;
- else if (*ptr=='\'')
- ctype = PRC_SQUOTE;
- else if (*ptr==' ' || *ptr=='\t')
- ctype = PRC_BLANK;
- else
- ctype = PRC_ALPHA;
-
- if (mtable[state][ctype].output) {
- *t = *ptr; t++;
- *t = 0;
- }
- state = mtable[state][ctype].nstate;
- ptr++;
- if (mtable[state][0].output<0) {
- break;
- }
- }
-
- if (*ret==0)
- t = NULL;
- else
- t = strdup(ret);
-
- free(ret);
-
- if (ctype==PRC_EOS)
- *next = NULL;
- else
- *next = ptr;
-
- return t;
-}
-
-
-extern void
-parse_command(char *command, char ***argv, int *argc)
-{
- LinkedList *list = NULL;
- char *token, *line;
- int count, i;
-
- line = command;
- do {
- token = next_token(line, &line);
- if (token) {
- list = list_cons(token, list);
- }
- } while (token!=NULL && line!=NULL);
-
- count = list_length(list);
- *argv = malloc(sizeof(char*)*count);
- i = count;
- while (list!=NULL) {
- (*argv)[--i] = list->head;
- list_remove_head(&list);
- }
- *argc = count;
-}
-
-extern pid_t
-execCommand(char *command)
-{
- pid_t pid;
- char **argv;
- int argc;
-
- parse_command(command, &argv, &argc);
-
- if (argv==NULL) {
- return 0;
- }
-
- if ((pid=fork())==0) {
- char **args;
- int i;
-
- args = malloc(sizeof(char*)*(argc+1));
- if (!args)
- exit(10);
- for (i=0; i<argc; i++) {
- args[i] = argv[i];
- }
- args[argc] = NULL;
- execvp(argv[0], args);
- exit(10);
- }
- return pid;
-}
diff --git a/wmgeneral/misc.h b/wmgeneral/misc.h
deleted file mode 100644
index 602e1b7..0000000
--- a/wmgeneral/misc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __MISC_H
-#define __MISC_H
-
-#include <unistd.h>
-
-extern void parse_command(char *, char ***, int *);
-
-extern pid_t execCommand(char *);
-#endif /* __MISC_H */
diff --git a/wmgeneral/wmgeneral.c b/wmgeneral/wmgeneral.c
deleted file mode 100644
index 56b7bd6..0000000
--- a/wmgeneral/wmgeneral.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- Best viewed with vim5, using ts=4
-
- wmgeneral was taken from wmppp.
-
- It has a lot of routines which most of the wm* programs use.
-
- ------------------------------------------------------------
-
- Author: Martijn Pieterse (pieterse at xs4all.nl)
-
- ---
- CHANGES:
- ---
- 14/09/1998 (Dave Clark, clarkd at skyia.com)
- * Updated createXBMfromXPM routine
- * Now supports >256 colors
- 11/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * Removed a bug from parse_rcfile. You could
- not use "start" in a command if a label was
- also start.
- * Changed the needed geometry string.
- We don't use window size, and don't support
- negative positions.
- 03/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * Added parse_rcfile2
- 02/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * Added -geometry support (untested)
- 28/08/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * Added createXBMfromXPM routine
- * Saves a lot of work with changing xpm's.
- 02/05/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
- * debugged the parse_rc file.
- 30/04/1998 (Martijn Pieterse, pieterse at xs4all.nl)
- * Ripped similar code from all the wm* programs,
- and put them in a single file.
-
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-#include <X11/Xlib.h>
-#include <X11/xpm.h>
-#include <X11/extensions/shape.h>
-
-#include "wmgeneral.h"
-
- /*****************/
- /* X11 Variables */
-/*****************/
-
-Window Root;
-int screen;
-int x_fd;
-int d_depth;
-XSizeHints mysizehints;
-XWMHints mywmhints;
-Pixel back_pix, fore_pix;
-char *Geometry = "";
-Window iconwin, win;
-GC NormalGC;
-XpmIcon wmgen;
-Pixmap pixmask;
-
- /*****************/
- /* Mouse Regions */
-/*****************/
-
-typedef struct {
- int enable;
- int top;
- int bottom;
- int left;
- int right;
-} MOUSE_REGION;
-
-MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
-
- /***********************/
- /* Function Prototypes */
-/***********************/
-
-static void GetXPM(XpmIcon *, char **);
-static Pixel GetColor(char *);
-void RedrawWindow(void);
-void AddMouseRegion(int, int, int, int, int);
-int CheckMouseRegion(int, int);
-
-/*******************************************************************************\
-|* parse_rcfile *|
-\*******************************************************************************/
-
-void parse_rcfile(const char *filename, rckeys *keys) {
-
- char *p,*q;
- char temp[128];
- char *tokens = " :\t\n";
- FILE *fp;
- int i,key;
-
- fp = fopen(filename, "r");
- if (fp) {
- while (fgets(temp, 128, fp)) {
- key = 0;
- q = strdup(temp);
- q = strtok(q, tokens);
- while (key >= 0 && keys[key].label) {
- if ((!strcmp(q, keys[key].label))) {
- p = strstr(temp, keys[key].label);
- p += strlen(keys[key].label);
- p += strspn(p, tokens);
- if ((i = strcspn(p, "#\n"))) p[i] = 0;
- free(*keys[key].var);
- *keys[key].var = strdup(p);
- key = -1;
- } else key++;
- }
- free(q);
- }
- fclose(fp);
- }
-}
-
-/*******************************************************************************\
-|* parse_rcfile2 *|
-\*******************************************************************************/
-
-void parse_rcfile2(const char *filename, rckeys2 *keys) {
-
- char *p;
- char temp[128];
- char *tokens = " :\t\n";
- FILE *fp;
- int i,key;
- char *family = NULL;
-
- fp = fopen(filename, "r");
- if (fp) {
- while (fgets(temp, 128, fp)) {
- key = 0;
- while (key >= 0 && keys[key].label) {
- if ((p = strstr(temp, keys[key].label))) {
- p += strlen(keys[key].label);
- p += strspn(p, tokens);
- if ((i = strcspn(p, "#\n"))) p[i] = 0;
- free(*keys[key].var);
- *keys[key].var = strdup(p);
- key = -1;
- } else key++;
- }
- }
- fclose(fp);
- }
- free(family);
-}
-
-
-/*******************************************************************************\
-|* GetXPM *|
-\*******************************************************************************/
-
-static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
-
- XWindowAttributes attributes;
- int err;
-
- /* For the colormap */
- XGetWindowAttributes(display, Root, &attributes);
-
- wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
-
- err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
- &(wmgen->mask), &(wmgen->attributes));
-
- if (err != XpmSuccess) {
- fprintf(stderr, "Not enough free colorcells.\n");
- exit(1);
- }
-}
-
-/*******************************************************************************\
-|* GetColor *|
-\*******************************************************************************/
-
-static Pixel GetColor(char *name) {
-
- XColor color;
- XWindowAttributes attributes;
-
- XGetWindowAttributes(display, Root, &attributes);
-
- color.pixel = 0;
- if (!XParseColor(display, attributes.colormap, name, &color)) {
- fprintf(stderr, "wm.app: can't parse %s.\n", name);
- } else if (!XAllocColor(display, attributes.colormap, &color)) {
- fprintf(stderr, "wm.app: can't allocate %s.\n", name);
- }
- return color.pixel;
-}
-
-/*******************************************************************************\
-|* flush_expose *|
-\*******************************************************************************/
-
-static int flush_expose(Window w) {
-
- XEvent dummy;
- int i=0;
-
- while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
- i++;
-
- return i;
-}
-
-/*******************************************************************************\
-|* RedrawWindow *|
-\*******************************************************************************/
-
-void RedrawWindow(void) {
-
- flush_expose(iconwin);
- XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
- 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
- flush_expose(win);
- XCopyArea(display, wmgen.pixmap, win, NormalGC,
- 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
-}
-
-/*******************************************************************************\
-|* RedrawWindowXY *|
-\*******************************************************************************/
-
-void RedrawWindowXY(int x, int y) {
-
- flush_expose(iconwin);
- XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
- x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
- flush_expose(win);
- XCopyArea(display, wmgen.pixmap, win, NormalGC,
- x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
-}
-
-/*******************************************************************************\
-|* AddMouseRegion *|
-\*******************************************************************************/
-
-void AddMouseRegion(int index, int left, int top, int right, int bottom) {
-
- if (index < MAX_MOUSE_REGION) {
- mouse_region[index].enable = 1;
- mouse_region[index].top = top;
- mouse_region[index].left = left;
- mouse_region[index].bottom = bottom;
- mouse_region[index].right = right;
- }
-}
-
-/*******************************************************************************\
-|* CheckMouseRegion *|
-\*******************************************************************************/
-
-int CheckMouseRegion(int x, int y) {
-
- int i;
- int found;
-
- found = 0;
-
- for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
- if (mouse_region[i].enable &&
- x <= mouse_region[i].right &&
- x >= mouse_region[i].left &&
- y <= mouse_region[i].bottom &&
- y >= mouse_region[i].top)
- found = 1;
- }
- if (!found) return -1;
- return (i-1);
-}
-
-/*******************************************************************************\
-|* createXBMfromXPM *|
-\*******************************************************************************/
-void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
-
- int i,j,k;
- int width, height, numcol, depth;
- int zero=0;
- unsigned char bwrite;
- int bcount;
- int curpixel;
-
- sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
-
-
- for (k=0; k!=depth; k++)
- {
- zero <<=8;
- zero |= xpm[1][k];
- }
-
- for (i=numcol+1; i < numcol+sy+1; i++) {
- bcount = 0;
- bwrite = 0;
- for (j=0; j<sx*depth; j+=depth) {
- bwrite >>= 1;
-
- curpixel=0;
- for (k=0; k!=depth; k++)
- {
- curpixel <<=8;
- curpixel |= xpm[i][j+k];
- }
-
- if ( curpixel != zero ) {
- bwrite += 128;
- }
- bcount++;
- if (bcount == 8) {
- *xbm = bwrite;
- xbm++;
- bcount = 0;
- bwrite = 0;
- }
- }
- }
-}
-
-/*******************************************************************************\
-|* copyXPMArea *|
-\*******************************************************************************/
-
-void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
-
- XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
-
-}
-
-/*******************************************************************************\
-|* copyXBMArea *|
-\*******************************************************************************/
-
-void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
-
- XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
-}
-
-
-/*******************************************************************************\
-|* setMaskXY *|
-\*******************************************************************************/
-
-void setMaskXY(int x, int y) {
-
- XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
- XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
-}
-
-/*******************************************************************************\
-|* openXwindow *|
-\*******************************************************************************/
-void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
-
- unsigned int borderwidth = 1;
- XClassHint classHint;
- char *display_name = NULL;
- char *wname = argv[0];
- XTextProperty name;
-
- XGCValues gcv;
- unsigned long gcm;
-
- char *geometry = NULL;
-
- int dummy=0;
- int i, wx, wy;
-
- for (i=1; argv[i]; i++) {
- if (!strcmp(argv[i], "-display")) {
- display_name = argv[i+1];
- i++;
- }
- if (!strcmp(argv[i], "-geometry")) {
- geometry = argv[i+1];
- i++;
- }
- }
-
- if (!(display = XOpenDisplay(display_name))) {
- fprintf(stderr, "%s: can't open display %s\n",
- wname, XDisplayName(display_name));
- exit(1);
- }
- screen = DefaultScreen(display);
- Root = RootWindow(display, screen);
- d_depth = DefaultDepth(display, screen);
- x_fd = XConnectionNumber(display);
-
- /* Convert XPM to XImage */
- GetXPM(&wmgen, pixmap_bytes);
-
- /* Create a window to hold the stuff */
- mysizehints.flags = USSize | USPosition;
- mysizehints.x = 0;
- mysizehints.y = 0;
-
- back_pix = GetColor("white");
- fore_pix = GetColor("black");
-
- XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
- &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
-
- mysizehints.width = 64;
- mysizehints.height = 64;
-
- win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
- mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
-
- iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
- mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
-
- /* Activate hints */
- XSetWMNormalHints(display, win, &mysizehints);
- classHint.res_name = wname;
- classHint.res_class = wname;
- XSetClassHint(display, win, &classHint);
-
- XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
- XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
-
- if (XStringListToTextProperty(&wname, 1, &name) == 0) {
- fprintf(stderr, "%s: can't allocate window name\n", wname);
- exit(1);
- }
-
- XSetWMName(display, win, &name);
-
- /* Create GC for drawing */
-
- gcm = GCForeground | GCBackground | GCGraphicsExposures;
- gcv.foreground = fore_pix;
- gcv.background = back_pix;
- gcv.graphics_exposures = 0;
- NormalGC = XCreateGC(display, Root, gcm, &gcv);
-
- /* ONLYSHAPE ON */
-
- pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
-
- XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
- XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
-
- /* ONLYSHAPE OFF */
-
- 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(display, win, &mywmhints);
-
- XSetCommand(display, win, argv, argc);
- XMapWindow(display, win);
-
- if (geometry) {
- if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
- fprintf(stderr, "Bad geometry string.\n");
- exit(1);
- }
- XMoveWindow(display, win, wx, wy);
- }
-}
diff --git a/wmgeneral/wmgeneral.h b/wmgeneral/wmgeneral.h
deleted file mode 100644
index e9d6ca6..0000000
--- a/wmgeneral/wmgeneral.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef WMGENERAL_H_INCLUDED
-#define WMGENERAL_H_INCLUDED
-
- /***********/
- /* Defines */
-/***********/
-
-#define MAX_MOUSE_REGION (16)
-
- /************/
- /* Typedefs */
-/************/
-
-typedef struct _rckeys rckeys;
-
-struct _rckeys {
- const char *label;
- char **var;
-};
-
-typedef struct _rckeys2 rckeys2;
-
-struct _rckeys2 {
- const char *family;
- const char *label;
- char **var;
-};
-
-typedef struct {
- Pixmap pixmap;
- Pixmap mask;
- XpmAttributes attributes;
-} XpmIcon;
-
- /*******************/
- /* Global variable */
-/*******************/
-
-Display *display;
-
- /***********************/
- /* Function Prototypes */
-/***********************/
-
-void AddMouseRegion(int index, int left, int top, int right, int bottom);
-int CheckMouseRegion(int x, int y);
-
-void openXwindow(int argc, char *argv[], char **, char *, int, int);
-void RedrawWindow(void);
-void RedrawWindowXY(int x, int y);
-
-void createXBMfromXPM(char *, char **, int, int);
-void copyXPMArea(int, int, int, int, int, int);
-void copyXBMArea(int, int, int, int, int, int);
-void setMaskXY(int, int);
-
-void parse_rcfile(const char *, rckeys *);
-
-#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmcube.git
More information about the Pkg-wmaker-commits
mailing list