summaryrefslogtreecommitdiff
path: root/noncore
Side-by-side diff
Diffstat (limited to 'noncore') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/dictionary/dictionary.pro14
-rw-r--r--noncore/apps/dictionary/dicttool.cpp59
-rw-r--r--noncore/apps/dictionary/dicttool.h46
-rw-r--r--noncore/apps/dictionary/dicttoolbase.ui412
-rw-r--r--noncore/apps/dictionary/main.cpp31
-rw-r--r--noncore/apps/tableviewer/.cvsignore5
-rw-r--r--noncore/apps/tableviewer/Makefile.in330
-rw-r--r--noncore/apps/tableviewer/README29
-rw-r--r--noncore/apps/tableviewer/browsekeyentry.cpp242
-rw-r--r--noncore/apps/tableviewer/db.xmlt6279
-rw-r--r--noncore/apps/tableviewer/db/.cvsignore3
-rw-r--r--noncore/apps/tableviewer/db/common.cpp1470
-rw-r--r--noncore/apps/tableviewer/db/common.h285
-rw-r--r--noncore/apps/tableviewer/db/csvsource.cpp207
-rw-r--r--noncore/apps/tableviewer/db/csvsource.h53
-rw-r--r--noncore/apps/tableviewer/db/datacache.cpp293
-rw-r--r--noncore/apps/tableviewer/db/datacache.h130
-rw-r--r--noncore/apps/tableviewer/db/xmlsource.cpp295
-rw-r--r--noncore/apps/tableviewer/db/xmlsource.h119
-rw-r--r--noncore/apps/tableviewer/keyentry.cw55
-rw-r--r--noncore/apps/tableviewer/main.cpp32
-rw-r--r--noncore/apps/tableviewer/qpe-tableviewer.control10
-rw-r--r--noncore/apps/tableviewer/tableviewer.cpp455
-rw-r--r--noncore/apps/tableviewer/tableviewer.h109
-rw-r--r--noncore/apps/tableviewer/tableviewer.pro36
-rw-r--r--noncore/apps/tableviewer/ui/.cvsignore8
-rw-r--r--noncore/apps/tableviewer/ui/browsekeyentry.cpp206
-rw-r--r--noncore/apps/tableviewer/ui/browsekeyentry.h75
-rw-r--r--noncore/apps/tableviewer/ui/commonwidgets.cpp209
-rw-r--r--noncore/apps/tableviewer/ui/commonwidgets.h98
-rw-r--r--noncore/apps/tableviewer/ui/filterkeyentry.cpp208
-rw-r--r--noncore/apps/tableviewer/ui/filterkeyentry.h96
-rw-r--r--noncore/apps/tableviewer/ui/tvbrowseview.cpp122
-rw-r--r--noncore/apps/tableviewer/ui/tvbrowseview.h55
-rw-r--r--noncore/apps/tableviewer/ui/tveditview.cpp235
-rw-r--r--noncore/apps/tableviewer/ui/tveditview.h62
-rw-r--r--noncore/apps/tableviewer/ui/tvfilterview.cpp304
-rw-r--r--noncore/apps/tableviewer/ui/tvfilterview.h88
-rw-r--r--noncore/apps/tableviewer/ui/tvkeyedit.cpp254
-rw-r--r--noncore/apps/tableviewer/ui/tvkeyedit.h56
-rw-r--r--noncore/apps/tableviewer/ui/tvkeyedit_gen.ui239
-rw-r--r--noncore/apps/tableviewer/ui/tvlistview.cpp315
-rw-r--r--noncore/apps/tableviewer/ui/tvlistview.h92
-rw-r--r--noncore/comm/keypebble/.cvsignore5
-rw-r--r--noncore/comm/keypebble/LICENSE.GPL286
-rw-r--r--noncore/comm/keypebble/Makefile.in286
-rw-r--r--noncore/comm/keypebble/README.html206
-rw-r--r--noncore/comm/keypebble/d3des.c439
-rw-r--r--noncore/comm/keypebble/d3des.h50
-rw-r--r--noncore/comm/keypebble/keypebble.pro38
-rw-r--r--noncore/comm/keypebble/krfbbuffer.cpp163
-rw-r--r--noncore/comm/keypebble/krfbbuffer.h62
-rw-r--r--noncore/comm/keypebble/krfbcanvas.cpp169
-rw-r--r--noncore/comm/keypebble/krfbcanvas.h54
-rw-r--r--noncore/comm/keypebble/krfbconnection.cpp242
-rw-r--r--noncore/comm/keypebble/krfbconnection.h152
-rw-r--r--noncore/comm/keypebble/krfbdecoder.cpp839
-rw-r--r--noncore/comm/keypebble/krfbdecoder.h134
-rw-r--r--noncore/comm/keypebble/krfblogin.cpp255
-rw-r--r--noncore/comm/keypebble/krfblogin.h62
-rw-r--r--noncore/comm/keypebble/krfboptions.cpp52
-rw-r--r--noncore/comm/keypebble/krfboptions.h31
-rw-r--r--noncore/comm/keypebble/krfbserverinfo.h42
-rw-r--r--noncore/comm/keypebble/kvnc.cpp191
-rw-r--r--noncore/comm/keypebble/kvnc.h56
-rw-r--r--noncore/comm/keypebble/kvncconnectdlg.cpp79
-rw-r--r--noncore/comm/keypebble/kvncconnectdlg.h39
-rw-r--r--noncore/comm/keypebble/kvncoptionsdlg.cpp53
-rw-r--r--noncore/comm/keypebble/kvncoptionsdlg.h30
-rw-r--r--noncore/comm/keypebble/main.cpp18
-rw-r--r--noncore/comm/keypebble/qpe-keypebble.control10
-rw-r--r--noncore/comm/keypebble/vncauth.c160
-rw-r--r--noncore/comm/keypebble/vncauth.h30
-rw-r--r--noncore/comm/keypebble/vncoptionsbase.ui270
-rw-r--r--noncore/games/chess/Makefile.in134
-rw-r--r--noncore/games/chess/boardview.cw23
-rw-r--r--noncore/games/chess/chess.cpp358
-rw-r--r--noncore/games/chess/chess.db2
-rw-r--r--noncore/games/chess/chess.h128
-rw-r--r--noncore/games/chess/chess.pro14
-rw-r--r--noncore/games/chess/main.cpp51
-rw-r--r--noncore/games/chess/mainwindow.ui220
-rw-r--r--noncore/games/chess/pieces.pngbin0 -> 5696 bytes
-rw-r--r--noncore/games/chess/qpe-chess.control9
-rw-r--r--noncore/games/chess/simple-l.pngbin0 -> 16143 bytes
-rw-r--r--noncore/games/fifteen/.cvsignore2
-rw-r--r--noncore/games/fifteen/Makefile.in118
-rw-r--r--noncore/games/fifteen/fifteen.cpp364
-rw-r--r--noncore/games/fifteen/fifteen.h83
-rw-r--r--noncore/games/fifteen/fifteen.pro10
-rw-r--r--noncore/games/fifteen/main.cpp33
-rw-r--r--noncore/games/fifteen/qpe-fifteen.control11
-rw-r--r--noncore/games/go/.cvsignore2
-rw-r--r--noncore/games/go/Makefile.in158
-rw-r--r--noncore/games/go/README3
-rw-r--r--noncore/games/go/README.AMIGO42
-rw-r--r--noncore/games/go/README.XAMIGO26
-rw-r--r--noncore/games/go/amigo.c656
-rw-r--r--noncore/games/go/amigo.h146
-rw-r--r--noncore/games/go/go.h81
-rw-r--r--noncore/games/go/go.pro19
-rw-r--r--noncore/games/go/goplayer.c1499
-rw-r--r--noncore/games/go/goplayutils.c1317
-rw-r--r--noncore/games/go/goplayutils.h85
-rw-r--r--noncore/games/go/gowidget.cpp449
-rw-r--r--noncore/games/go/gowidget.h111
-rw-r--r--noncore/games/go/killable.c373
-rw-r--r--noncore/games/go/main.cpp35
-rw-r--r--noncore/games/go/qpe-go.control9
-rw-r--r--noncore/games/mindbreaker/.cvsignore4
-rw-r--r--noncore/games/mindbreaker/Makefile.in117
-rw-r--r--noncore/games/mindbreaker/main.cpp35
-rw-r--r--noncore/games/mindbreaker/mindbreaker.cpp818
-rw-r--r--noncore/games/mindbreaker/mindbreaker.h122
-rw-r--r--noncore/games/mindbreaker/mindbreaker.pro12
-rw-r--r--noncore/games/mindbreaker/qpe-mindbreaker.control9
-rw-r--r--noncore/games/minesweep/.cvsignore2
-rw-r--r--noncore/games/minesweep/Makefile.in134
-rw-r--r--noncore/games/minesweep/main.cpp34
-rw-r--r--noncore/games/minesweep/minefield.cpp623
-rw-r--r--noncore/games/minesweep/minefield.h87
-rw-r--r--noncore/games/minesweep/minesweep.cpp390
-rw-r--r--noncore/games/minesweep/minesweep.h67
-rw-r--r--noncore/games/minesweep/minesweep.pro14
-rw-r--r--noncore/games/minesweep/qpe-minesweep.control9
-rw-r--r--noncore/games/parashoot/.cvsignore3
-rw-r--r--noncore/games/parashoot/Makefile.in203
-rw-r--r--noncore/games/parashoot/base.cpp71
-rw-r--r--noncore/games/parashoot/base.h38
-rw-r--r--noncore/games/parashoot/bullet.cpp142
-rw-r--r--noncore/games/parashoot/bullet.h51
-rw-r--r--noncore/games/parashoot/cannon.cpp140
-rw-r--r--noncore/games/parashoot/cannon.h58
-rw-r--r--noncore/games/parashoot/codes.h25
-rw-r--r--noncore/games/parashoot/helicopter.cpp114
-rw-r--r--noncore/games/parashoot/helicopter.h45
-rw-r--r--noncore/games/parashoot/interface.cpp247
-rw-r--r--noncore/games/parashoot/interface.h79
-rw-r--r--noncore/games/parashoot/main.cpp36
-rw-r--r--noncore/games/parashoot/man.cpp174
-rw-r--r--noncore/games/parashoot/man.h52
-rw-r--r--noncore/games/parashoot/parashoot.pro11
-rw-r--r--noncore/games/parashoot/qpe-parashoot.control9
-rw-r--r--noncore/games/qasteroids/.cvsignore2
-rw-r--r--noncore/games/qasteroids/Makefile.in155
-rw-r--r--noncore/games/qasteroids/ledmeter.cpp135
-rw-r--r--noncore/games/qasteroids/ledmeter.h72
-rw-r--r--noncore/games/qasteroids/main.cpp36
-rw-r--r--noncore/games/qasteroids/qasteroids.pro11
-rw-r--r--noncore/games/qasteroids/qpe-qasteroids.control9
-rw-r--r--noncore/games/qasteroids/sprites.h147
-rw-r--r--noncore/games/qasteroids/toplevel.cpp514
-rw-r--r--noncore/games/qasteroids/toplevel.h99
-rw-r--r--noncore/games/qasteroids/view.cpp884
-rw-r--r--noncore/games/qasteroids/view.h156
-rw-r--r--noncore/games/snake/.cvsignore3
-rw-r--r--noncore/games/snake/Makefile.in159
-rw-r--r--noncore/games/snake/codes.h20
-rw-r--r--noncore/games/snake/interface.cpp224
-rw-r--r--noncore/games/snake/interface.h69
-rw-r--r--noncore/games/snake/main.cpp35
-rw-r--r--noncore/games/snake/obstacle.cpp51
-rw-r--r--noncore/games/snake/obstacle.h30
-rw-r--r--noncore/games/snake/qpe-snake.control9
-rw-r--r--noncore/games/snake/snake.cpp246
-rw-r--r--noncore/games/snake/snake.h64
-rw-r--r--noncore/games/snake/snake.pro11
-rw-r--r--noncore/games/snake/target.cpp77
-rw-r--r--noncore/games/snake/target.h37
-rw-r--r--noncore/games/solitaire/.cvsignore3
-rw-r--r--noncore/games/solitaire/Makefile.in235
-rw-r--r--noncore/games/solitaire/canvascard.cpp282
-rw-r--r--noncore/games/solitaire/canvascard.h82
-rw-r--r--noncore/games/solitaire/canvascardgame.cpp380
-rw-r--r--noncore/games/solitaire/canvascardgame.h95
-rw-r--r--noncore/games/solitaire/canvascardwindow.cpp227
-rw-r--r--noncore/games/solitaire/canvascardwindow.h70
-rw-r--r--noncore/games/solitaire/canvasshapes.cpp92
-rw-r--r--noncore/games/solitaire/canvasshapes.h55
-rw-r--r--noncore/games/solitaire/card.cpp53
-rw-r--r--noncore/games/solitaire/card.h84
-rw-r--r--noncore/games/solitaire/carddeck.cpp81
-rw-r--r--noncore/games/solitaire/carddeck.h49
-rw-r--r--noncore/games/solitaire/cardgame.cpp35
-rw-r--r--noncore/games/solitaire/cardgame.h45
-rw-r--r--noncore/games/solitaire/cardgamelayout.cpp61
-rw-r--r--noncore/games/solitaire/cardgamelayout.h42
-rw-r--r--noncore/games/solitaire/cardpile.cpp114
-rw-r--r--noncore/games/solitaire/cardpile.h101
-rw-r--r--noncore/games/solitaire/freecellcardgame.cpp137
-rw-r--r--noncore/games/solitaire/freecellcardgame.h152
-rw-r--r--noncore/games/solitaire/main.cpp36
-rw-r--r--noncore/games/solitaire/patiencecardgame.cpp234
-rw-r--r--noncore/games/solitaire/patiencecardgame.h206
-rw-r--r--noncore/games/solitaire/qpe-solitaire.control9
-rwxr-xr-xnoncore/games/solitaire/solitaire.pro18
-rw-r--r--noncore/games/tetrix/.cvsignore3
-rw-r--r--noncore/games/tetrix/Makefile.in157
-rw-r--r--noncore/games/tetrix/gtetrix.cpp514
-rw-r--r--noncore/games/tetrix/gtetrix.h104
-rw-r--r--noncore/games/tetrix/main.cpp33
-rw-r--r--noncore/games/tetrix/qpe-tetrix.control10
-rw-r--r--noncore/games/tetrix/qtetrix.cpp170
-rw-r--r--noncore/games/tetrix/qtetrix.h78
-rw-r--r--noncore/games/tetrix/qtetrixb.cpp251
-rw-r--r--noncore/games/tetrix/qtetrixb.h80
-rw-r--r--noncore/games/tetrix/tetrix.pro17
-rw-r--r--noncore/games/tetrix/tpiece.cpp201
-rw-r--r--noncore/games/tetrix/tpiece.h62
-rw-r--r--noncore/games/wordgame/.cvsignore6
-rw-r--r--noncore/games/wordgame/Makefile.in168
-rwxr-xr-xnoncore/games/wordgame/calcdist27
-rw-r--r--noncore/games/wordgame/main.cpp34
-rw-r--r--noncore/games/wordgame/newgamebase.ui337
-rw-r--r--noncore/games/wordgame/qpe-wordgame.control10
-rw-r--r--noncore/games/wordgame/rulesbase.ui274
-rw-r--r--noncore/games/wordgame/wordgame.cpp1476
-rw-r--r--noncore/games/wordgame/wordgame.h376
-rw-r--r--noncore/games/wordgame/wordgame.pro13
-rw-r--r--noncore/multimedia/showimg/.cvsignore2
-rw-r--r--noncore/multimedia/showimg/Makefile.in119
-rw-r--r--noncore/multimedia/showimg/README14
-rw-r--r--noncore/multimedia/showimg/main.cpp33
-rw-r--r--noncore/multimedia/showimg/qpe-showimg.control10
-rw-r--r--noncore/multimedia/showimg/showimg.cpp557
-rw-r--r--noncore/multimedia/showimg/showimg.h143
-rw-r--r--noncore/multimedia/showimg/showimg.pro19
-rw-r--r--noncore/settings/.cvsignore13
-rw-r--r--noncore/settings/language/.cvsignore4
-rw-r--r--noncore/settings/language/Makefile.in135
-rw-r--r--noncore/settings/language/language.cpp150
-rw-r--r--noncore/settings/language/language.pro12
-rw-r--r--noncore/settings/language/languagesettingsbase.ui51
-rw-r--r--noncore/settings/language/main.cpp36
-rw-r--r--noncore/settings/language/qpe-language.control9
-rw-r--r--noncore/settings/language/settings.h58
-rw-r--r--noncore/settings/sound/.cvsignore5
-rw-r--r--noncore/settings/sound/Makefile.in135
-rw-r--r--noncore/settings/sound/main.cpp36
-rw-r--r--noncore/settings/sound/qpe-sound.control10
-rw-r--r--noncore/settings/sound/sound.pro10
-rw-r--r--noncore/settings/sound/soundsettings.cpp64
-rw-r--r--noncore/settings/sound/soundsettings.h44
-rw-r--r--noncore/settings/sound/soundsettingsbase.ui281
-rw-r--r--noncore/settings/sysinfo/.cvsignore3
-rw-r--r--noncore/settings/sysinfo/Makefile.in193
-rw-r--r--noncore/settings/sysinfo/graph.cpp183
-rw-r--r--noncore/settings/sysinfo/graph.h89
-rw-r--r--noncore/settings/sysinfo/load.cpp207
-rw-r--r--noncore/settings/sysinfo/load.h60
-rw-r--r--noncore/settings/sysinfo/main.cpp34
-rw-r--r--noncore/settings/sysinfo/memory.cpp94
-rw-r--r--noncore/settings/sysinfo/memory.h48
-rw-r--r--noncore/settings/sysinfo/qpe-sysinfo.control9
-rw-r--r--noncore/settings/sysinfo/storage.cpp220
-rw-r--r--noncore/settings/sysinfo/storage.h87
-rw-r--r--noncore/settings/sysinfo/sysinfo.cpp53
-rw-r--r--noncore/settings/sysinfo/sysinfo.h29
-rw-r--r--noncore/settings/sysinfo/sysinfo.pro25
-rw-r--r--noncore/settings/sysinfo/versioninfo.cpp109
-rw-r--r--noncore/settings/sysinfo/versioninfo.h34
-rw-r--r--noncore/tools/calc2/Makefile138
-rw-r--r--noncore/tools/calc2/binary/Makefile146
-rw-r--r--noncore/tools/calc2/binary/README1
-rw-r--r--noncore/tools/calc2/binary/binary.pro16
-rw-r--r--noncore/tools/calc2/binary/binary.ui177
-rw-r--r--noncore/tools/calc2/binary/binaryfactory.cpp51
-rw-r--r--noncore/tools/calc2/binary/binaryfactory.h46
-rw-r--r--noncore/tools/calc2/binary/binaryimpl.cpp110
-rw-r--r--noncore/tools/calc2/binary/binaryimpl.h50
-rw-r--r--noncore/tools/calc2/calc.cpp104
-rw-r--r--noncore/tools/calc2/calc.h69
-rw-r--r--noncore/tools/calc2/calc.pro11
-rw-r--r--noncore/tools/calc2/engine.cpp214
-rw-r--r--noncore/tools/calc2/engine.h111
-rw-r--r--noncore/tools/calc2/instruction.h69
-rw-r--r--noncore/tools/calc2/main.cpp34
-rw-r--r--noncore/tools/calc2/plugininterface.h45
-rw-r--r--noncore/tools/calc2/simple/README1
-rw-r--r--noncore/tools/calc2/simple/simple.pro14
-rw-r--r--noncore/tools/calc2/simple/simple.ui704
-rw-r--r--noncore/tools/calc2/simple/simplefactory.cpp51
-rw-r--r--noncore/tools/calc2/simple/simplefactory.h46
-rw-r--r--noncore/tools/calc2/simple/simpleimpl.cpp120
-rw-r--r--noncore/tools/calc2/simple/simpleimpl.h65
-rw-r--r--noncore/tools/calc2/stdinstructions.h125
-rw-r--r--noncore/tools/calculator/.cvsignore4
-rw-r--r--noncore/tools/calculator/Makefile.in139
-rw-r--r--noncore/tools/calculator/calculator.pro13
-rw-r--r--noncore/tools/calculator/calculator.ui1026
-rw-r--r--noncore/tools/calculator/calculatorimpl.cpp601
-rw-r--r--noncore/tools/calculator/calculatorimpl.h135
-rw-r--r--noncore/tools/calculator/main.cpp35
-rw-r--r--noncore/tools/calculator/qpe-calculator.control10
-rw-r--r--noncore/tools/clock/.cvsignore2
-rw-r--r--noncore/tools/clock/Makefile.in118
-rw-r--r--noncore/tools/clock/clock.cpp319
-rw-r--r--noncore/tools/clock/clock.h87
-rw-r--r--noncore/tools/clock/clock.pro13
-rw-r--r--noncore/tools/clock/main.cpp34
-rw-r--r--noncore/tools/clock/qpe-clock.control9
-rw-r--r--noncore/unsupported/filebrowser/.cvsignore2
-rw-r--r--noncore/unsupported/filebrowser/Makefile.in136
-rw-r--r--noncore/unsupported/filebrowser/filebrowser.cpp850
-rw-r--r--noncore/unsupported/filebrowser/filebrowser.h141
-rw-r--r--noncore/unsupported/filebrowser/filebrowser.pro12
-rw-r--r--noncore/unsupported/filebrowser/inlineedit.cpp30
-rw-r--r--noncore/unsupported/filebrowser/inlineedit.h39
-rw-r--r--noncore/unsupported/filebrowser/main.cpp41
-rw-r--r--noncore/unsupported/filebrowser/qpe-filebrowser.control9
-rw-r--r--noncore/unsupported/oipkg/.cvsignore10
-rw-r--r--noncore/unsupported/oipkg/Makefile.in203
-rw-r--r--noncore/unsupported/oipkg/ipkg/available2256
-rw-r--r--noncore/unsupported/oipkg/ipkg/status418
-rw-r--r--noncore/unsupported/oipkg/main.cpp33
-rw-r--r--noncore/unsupported/oipkg/packagemanager.cpp897
-rw-r--r--noncore/unsupported/oipkg/packagemanager.h94
-rw-r--r--noncore/unsupported/oipkg/packagemanagerbase.ui268
-rw-r--r--noncore/unsupported/oipkg/pkdesc.ui96
-rw-r--r--noncore/unsupported/oipkg/pkfind.ui51
-rw-r--r--noncore/unsupported/oipkg/pksettings.ui176
-rw-r--r--noncore/unsupported/oipkg/qipkg.pro13
-rw-r--r--noncore/unsupported/oipkg/qpe-qipkg.control9
323 files changed, 53678 insertions, 0 deletions
diff --git a/noncore/apps/dictionary/dictionary.pro b/noncore/apps/dictionary/dictionary.pro
new file mode 100644
index 0000000..e829e68
--- a/dev/null
+++ b/noncore/apps/dictionary/dictionary.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = ../bin
+
+HEADERS = dicttool.h
+SOURCES = dicttool.cpp main.cpp
+
+INTERFACES = dicttoolbase.ui
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TARGET = dictionary
diff --git a/noncore/apps/dictionary/dicttool.cpp b/noncore/apps/dictionary/dicttool.cpp
new file mode 100644
index 0000000..a0f2f9d
--- a/dev/null
+++ b/noncore/apps/dictionary/dicttool.cpp
@@ -0,0 +1,59 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "dicttool.h"
+#include "global.h"
+#include <qstringlist.h>
+#include <qlineedit.h>
+
+DictTool::DictTool( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : DictToolBase( parent, name, modal, fl )
+{
+}
+
+DictTool::~DictTool()
+{
+}
+
+void DictTool::setDictionary(int d)
+{
+ dict = (DictType)d;
+}
+
+void DictTool::setPattern(const QString& s)
+{
+ qWarning( "DictTool::setPattern(const QString&) not yet implemented!" );
+}
+
+void DictTool::setPickboardSet(const QString& s)
+{
+ QStringList sets = QStringList::split(" ",s);
+ qWarning( "DictTool::setPickboardSet(const QString&) not yet implemented!" );
+}
+
+void DictTool::addWord()
+{
+ Global::addWords(word->text());
+}
+
+void DictTool::removeWord()
+{
+ qWarning( "DictTool::removeWord() not yet implemented!" );
+}
+
diff --git a/noncore/apps/dictionary/dicttool.h b/noncore/apps/dictionary/dicttool.h
new file mode 100644
index 0000000..702b772
--- a/dev/null
+++ b/noncore/apps/dictionary/dicttool.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DICTTOOL_H
+#define DICTTOOL_H
+#include "dicttoolbase.h"
+
+class DictTool : public DictToolBase
+{
+ Q_OBJECT
+
+public:
+ DictTool( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~DictTool();
+
+public slots:
+ void setDictionary(int);
+ void setPattern(const QString&);
+ void setPickboardSet(const QString&);
+
+private slots:
+ void addWord();
+ void removeWord();
+
+private:
+ enum DictType { All, Local, System };
+ DictType dict;
+};
+
+#endif // DICTTOOL_H
diff --git a/noncore/apps/dictionary/dicttoolbase.ui b/noncore/apps/dictionary/dicttoolbase.ui
new file mode 100644
index 0000000..25ef00e
--- a/dev/null
+++ b/noncore/apps/dictionary/dicttoolbase.ui
@@ -0,0 +1,412 @@
+<!DOCTYPE UI><UI>
+<class>DictToolBase</class><comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dicttoolbase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>258</width>
+ <height>375</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>MyDialog1</string>
+ </property>
+ <property stdset="1">
+ <name>sizeGripEnabled</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>All dictionaries</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Personal dictionary</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>System dictionary (English)</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dictionary_choice</cstring>
+ </property>
+ <property>
+ <name>whatsThis</name>
+ <string>Selects the dictionary to manipulate.</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabWidget</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Widget4</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Search</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Pattern</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>pattern</cstring>
+ </property>
+ <property>
+ <name>whatsThis</name>
+ <string>Enter your search pattern here. You may use &lt;big&gt;&lt;tt&gt;?&lt;/tt&gt;&lt;/big&gt; to represent any one letter, &lt;big&gt;&lt;tt&gt;*&lt;/tt&gt;&lt;/big&gt; to represent zero or more arbitrary letters, or &lt;big&gt;&lt;tt&gt;[&lt;i&gt;abc&lt;/i&gt;]&lt;/tt&gt;&lt;/big&gt; to represent any one of the letters &lt;big&gt;&lt;tt&gt;&lt;i&gt;abc&lt;/i&gt;&lt;/tt&gt;&lt;/big&gt;.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox4</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Matches</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>output</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Widget5</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Pickboard</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Letter sets</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>sets</cstring>
+ </property>
+ <property>
+ <name>whatsThis</name>
+ <string>Enter sets of letters here, seperated by spaces in the same way as the sets of letters appear at the bottom of the Pickboard. The list below will show the largest sets of words that could be typed ambiguously. This information helps you tune the letter sets for your dictionary.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox2</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Longest ambiguities</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ambiguities</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Edit words</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>word</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>add</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Add</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>remove</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Remove</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>readonly_message</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>This dictionary is read-only.</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>pattern</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>dicttoolbase</receiver>
+ <slot>setPattern(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>dictionary_choice</sender>
+ <signal>activated(int)</signal>
+ <receiver>dicttoolbase</receiver>
+ <slot>setDictionary(int)</slot>
+ </connection>
+ <connection>
+ <sender>sets</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>dicttoolbase</receiver>
+ <slot>setPickboardSet(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>add</sender>
+ <signal>clicked()</signal>
+ <receiver>dicttoolbase</receiver>
+ <slot>addWord()</slot>
+ </connection>
+ <connection>
+ <sender>remove</sender>
+ <signal>clicked()</signal>
+ <receiver>dicttoolbase</receiver>
+ <slot>removeWord()</slot>
+ </connection>
+ <slot access="protected">addWord()</slot>
+ <slot access="protected">removeWord()</slot>
+ <slot access="public">setDictionary(int)</slot>
+ <slot access="public">setPattern(const QString&amp;)</slot>
+ <slot access="public">setPickboardSet(const QString&amp;)</slot>
+</connections>
+</UI>
diff --git a/noncore/apps/dictionary/main.cpp b/noncore/apps/dictionary/main.cpp
new file mode 100644
index 0000000..7e9d8c1
--- a/dev/null
+++ b/noncore/apps/dictionary/main.cpp
@@ -0,0 +1,31 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpeapplication.h>
+#include "dicttool.h"
+
+main(int argc, char** argv)
+{
+ QPEApplication a(argc,argv);
+
+ DictTool m;
+ a.showMainWidget(&m);
+
+ return a.exec();
+}
diff --git a/noncore/apps/tableviewer/.cvsignore b/noncore/apps/tableviewer/.cvsignore
new file mode 100644
index 0000000..93eb983
--- a/dev/null
+++ b/noncore/apps/tableviewer/.cvsignore
@@ -0,0 +1,5 @@
+moc_*
+Makefile
+tvbrowseview_gen.h
+tvfilterview_gen.h
+tvkeyedit_gen.h
diff --git a/noncore/apps/tableviewer/Makefile.in b/noncore/apps/tableviewer/Makefile.in
new file mode 100644
index 0000000..8c5dc26
--- a/dev/null
+++ b/noncore/apps/tableviewer/Makefile.in
@@ -0,0 +1,330 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I../library
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = tableviewer
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = tableviewer.h \
+ ui/commonwidgets.h \
+ ui/tvbrowseview.h \
+ ui/tvlistview.h \
+ ui/tvfilterview.h \
+ ui/tveditview.h \
+ ui/browsekeyentry.h \
+ ui/filterkeyentry.h \
+ ui/tvkeyedit.h \
+ db/datacache.h \
+ db/common.h \
+ db/xmlsource.h \
+ db/csvsource.h
+SOURCES = main.cpp \
+ tableviewer.cpp \
+ ui/commonwidgets.cpp \
+ ui/tvbrowseview.cpp \
+ ui/tvfilterview.cpp \
+ ui/browsekeyentry.cpp \
+ ui/filterkeyentry.cpp \
+ ui/tvlistview.cpp \
+ ui/tveditview.cpp \
+ ui/tvkeyedit.cpp \
+ db/datacache.cpp \
+ db/xmlsource.cpp \
+ db/csvsource.cpp \
+ db/common.cpp
+OBJECTS = main.o \
+ tableviewer.o \
+ ui/commonwidgets.o \
+ ui/tvbrowseview.o \
+ ui/tvfilterview.o \
+ ui/browsekeyentry.o \
+ ui/filterkeyentry.o \
+ ui/tvlistview.o \
+ ui/tveditview.o \
+ ui/tvkeyedit.o \
+ db/datacache.o \
+ db/xmlsource.o \
+ db/csvsource.o \
+ db/common.o \
+ ui/tvkeyedit_gen.o
+INTERFACES = ui/tvkeyedit_gen.ui
+UICDECLS = ui/tvkeyedit_gen.h
+UICIMPLS = ui/tvkeyedit_gen.cpp
+SRCMOC = moc_tableviewer.cpp \
+ ui/moc_commonwidgets.cpp \
+ ui/moc_tvbrowseview.cpp \
+ ui/moc_tvlistview.cpp \
+ ui/moc_tvfilterview.cpp \
+ ui/moc_tveditview.cpp \
+ ui/moc_browsekeyentry.cpp \
+ ui/moc_filterkeyentry.cpp \
+ ui/moc_tvkeyedit.cpp \
+ ui/moc_tvkeyedit_gen.cpp
+OBJMOC = moc_tableviewer.o \
+ ui/moc_commonwidgets.o \
+ ui/moc_tvbrowseview.o \
+ ui/moc_tvlistview.o \
+ ui/moc_tvfilterview.o \
+ ui/moc_tveditview.o \
+ ui/moc_browsekeyentry.o \
+ ui/moc_filterkeyentry.o \
+ ui/moc_tvkeyedit.o \
+ ui/moc_tvkeyedit_gen.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake: Makefile.in
+
+Makefile.in: tableviewer.pro
+ tmake tableviewer.pro -o Makefile.in
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ tableviewer.h \
+ db/common.h \
+ ../library/fileselector.h \
+ ../library/filemanager.h \
+ ../library/applnk.h \
+ ../library/qpeapplication.h \
+ ../library/qpedecoration_qws.h
+
+tableviewer.o: tableviewer.cpp \
+ tableviewer.h \
+ db/common.h \
+ ../library/fileselector.h \
+ ../library/filemanager.h \
+ ../library/applnk.h \
+ ui/tvbrowseview.h \
+ ui/tvfilterview.h \
+ ui/tvlistview.h \
+ ui/tveditview.h \
+ ui/tvkeyedit.h \
+ tvkeyedit_gen.h \
+ db/datacache.h \
+ ../library/resource.h
+
+ui/commonwidgets.o: ui/commonwidgets.cpp \
+ ../library/datebookmonth.h \
+ ../library/organizer.h \
+ ../library/xmlreader.h \
+ ../library/calendar.h \
+ ui/commonwidgets.h
+
+ui/tvbrowseview.o: ui/tvbrowseview.cpp \
+ ui/tvbrowseview.h \
+ ui/../db/common.h \
+ ui/browsekeyentry.h
+
+ui/tvfilterview.o: ui/tvfilterview.cpp \
+ ui/tvfilterview.h \
+ ui/filterkeyentry.h \
+ ui/../db/common.h
+
+ui/browsekeyentry.o: ui/browsekeyentry.cpp \
+ ui/browsekeyentry.h \
+ ui/../db/common.h \
+ ui/commonwidgets.h
+
+ui/filterkeyentry.o: ui/filterkeyentry.cpp \
+ ui/filterkeyentry.h \
+ ui/../db/common.h \
+ ui/commonwidgets.h
+
+ui/tvlistview.o: ui/tvlistview.cpp \
+ ui/tvlistview.h \
+ ui/../db/common.h
+
+ui/tveditview.o: ui/tveditview.cpp \
+ ui/tveditview.h \
+ ui/../db/common.h \
+ ui/commonwidgets.h
+
+ui/tvkeyedit.o: ui/tvkeyedit.cpp \
+ ui/tvkeyedit.h \
+ tvkeyedit_gen.h \
+ ui/../db/common.h
+
+db/datacache.o: db/datacache.cpp \
+ db/datacache.h \
+ db/common.h \
+ db/xmlsource.h \
+ db/csvsource.h
+
+db/xmlsource.o: db/xmlsource.cpp \
+ db/xmlsource.h \
+ db/datacache.h \
+ db/common.h
+
+db/csvsource.o: db/csvsource.cpp \
+ db/csvsource.h \
+ db/datacache.h \
+ db/common.h
+
+db/common.o: db/common.cpp \
+ ../library/timestring.h \
+ db/common.h \
+ db/datacache.h
+
+ui/tvkeyedit_gen.h: ui/tvkeyedit_gen.ui
+ $(UIC) ui/tvkeyedit_gen.ui -o $(INTERFACE_DECL_PATH)/ui/tvkeyedit_gen.h
+
+tvkeyedit_gen.h: ui/tvkeyedit_gen.ui
+ $(UIC) ui/tvkeyedit_gen.ui -o tvkeyedit_gen.h
+
+ui/tvkeyedit_gen.cpp: ui/tvkeyedit_gen.ui
+ $(UIC) ui/tvkeyedit_gen.ui -i tvkeyedit_gen.h -o ui/tvkeyedit_gen.cpp
+
+ui/tvkeyedit_gen.o: ui/tvkeyedit_gen.cpp \
+ ui/tvkeyedit_gen.h \
+ ui/tvkeyedit_gen.ui
+
+moc_tableviewer.o: moc_tableviewer.cpp \
+ tableviewer.h \
+ db/common.h \
+ ../library/fileselector.h \
+ ../library/filemanager.h \
+ ../library/applnk.h
+
+ui/moc_commonwidgets.o: ui/moc_commonwidgets.cpp \
+ ui/commonwidgets.h
+
+ui/moc_tvbrowseview.o: ui/moc_tvbrowseview.cpp \
+ ui/tvbrowseview.h \
+ ui/../db/common.h
+
+ui/moc_tvlistview.o: ui/moc_tvlistview.cpp \
+ ui/tvlistview.h \
+ ui/../db/common.h
+
+ui/moc_tvfilterview.o: ui/moc_tvfilterview.cpp \
+ ui/tvfilterview.h \
+ ui/filterkeyentry.h \
+ ui/../db/common.h
+
+ui/moc_tveditview.o: ui/moc_tveditview.cpp \
+ ui/tveditview.h \
+ ui/../db/common.h
+
+ui/moc_browsekeyentry.o: ui/moc_browsekeyentry.cpp \
+ ui/browsekeyentry.h \
+ ui/../db/common.h
+
+ui/moc_filterkeyentry.o: ui/moc_filterkeyentry.cpp \
+ ui/filterkeyentry.h \
+ ui/../db/common.h
+
+ui/moc_tvkeyedit.o: ui/moc_tvkeyedit.cpp \
+ ui/tvkeyedit.h \
+ tvkeyedit_gen.h \
+ ui/../db/common.h
+
+ui/moc_tvkeyedit_gen.o: ui/moc_tvkeyedit_gen.cpp \
+ ui/tvkeyedit_gen.h
+
+moc_tableviewer.cpp: tableviewer.h
+ $(MOC) tableviewer.h -o moc_tableviewer.cpp
+
+ui/moc_commonwidgets.cpp: ui/commonwidgets.h
+ $(MOC) ui/commonwidgets.h -o ui/moc_commonwidgets.cpp
+
+ui/moc_tvbrowseview.cpp: ui/tvbrowseview.h
+ $(MOC) ui/tvbrowseview.h -o ui/moc_tvbrowseview.cpp
+
+ui/moc_tvlistview.cpp: ui/tvlistview.h
+ $(MOC) ui/tvlistview.h -o ui/moc_tvlistview.cpp
+
+ui/moc_tvfilterview.cpp: ui/tvfilterview.h
+ $(MOC) ui/tvfilterview.h -o ui/moc_tvfilterview.cpp
+
+ui/moc_tveditview.cpp: ui/tveditview.h
+ $(MOC) ui/tveditview.h -o ui/moc_tveditview.cpp
+
+ui/moc_browsekeyentry.cpp: ui/browsekeyentry.h
+ $(MOC) ui/browsekeyentry.h -o ui/moc_browsekeyentry.cpp
+
+ui/moc_filterkeyentry.cpp: ui/filterkeyentry.h
+ $(MOC) ui/filterkeyentry.h -o ui/moc_filterkeyentry.cpp
+
+ui/moc_tvkeyedit.cpp: ui/tvkeyedit.h
+ $(MOC) ui/tvkeyedit.h -o ui/moc_tvkeyedit.cpp
+
+ui/moc_tvkeyedit_gen.cpp: ui/tvkeyedit_gen.h
+ $(MOC) ui/tvkeyedit_gen.h -o ui/moc_tvkeyedit_gen.cpp
+
+
diff --git a/noncore/apps/tableviewer/README b/noncore/apps/tableviewer/README
new file mode 100644
index 0000000..cd479e5
--- a/dev/null
+++ b/noncore/apps/tableviewer/README
@@ -0,0 +1,29 @@
+Table Viewer;
+
+This application is still in development, very buggy and leaks memory like
+a sieve. There are still a few major features/design work to be done. Once
+The app has settled (i.e. implementation of initial design completed) the
+focus will switch from features to making the code worthy of Trolltech.
+This means finding all the memory leaks, possibly some restructoring of code
+for future maintainability and ensuring that the code is readable
+(reasonable names for classes and vars.)
+
+For convenience there is a db.xml file included that is generated from the
+CIA World fact book, 11-May-01. The current version of this file should always work with the current version of the tableviewer application
+
+Major design work yet to be completed
+
+* ensure that only reasonable controls are enabled.
+* implement delete item & delete keys
+* loading dialogs
+* filterview -> dialog
+* only do sensible things if no keys set. includes;
+ No list view,
+ No filter view,
+ No edit item.
+* Tool bar in both 'views'
+* only build widgets as needed
+* click on scrollview to change key type, (remove key dialog)
+* fix navigate buttons
+
+This README will also be removed once the major design work is done.
diff --git a/noncore/apps/tableviewer/browsekeyentry.cpp b/noncore/apps/tableviewer/browsekeyentry.cpp
new file mode 100644
index 0000000..04e7902
--- a/dev/null
+++ b/noncore/apps/tableviewer/browsekeyentry.cpp
@@ -0,0 +1,242 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "browsekeyentry.h"
+
+#include <qtoolbutton.h>
+#include <qwidgetstack.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qpopupmenu.h>
+#include <qhbox.h>
+#include <qdatetime.h>
+
+//#include <iostream.h>
+#include <qheader.h>
+// For qWarning(const char *)
+
+/*!
+ \class TVBrowseKeyEntry
+ \brief a Widget used enter keys into the TVBrowseViewWidget
+
+ The TVBrowseKeyEntry Widget provides the facility to enter
+ various key types to be search on in the table. The key can be changed
+ and the entry field will update to the correct sort of widget appropriately
+*/
+
+/*!
+ Constructs the widget
+*/
+TVBrowseKeyEntry::TVBrowseKeyEntry(QWidget *parent, const char *name, WFlags f)
+ : QWidget(parent, name, f)
+{
+ int stack_elem = 0;
+ QHBoxLayout *h_layout = new QHBoxLayout(this);
+
+ textKey = new QLineEdit(this, 0);
+
+ dateKey = new QHBox(this, 0);
+ dayKey = new QLineEdit(dateKey, 0);
+ monthKey = new QLineEdit(dateKey, 0);
+ yearKey = new QLineEdit(dateKey, 0);
+
+ timeKey = new QHBox(this, 0);
+ hourKey = new QLineEdit(timeKey, 0);
+ minuteKey = new QLineEdit(timeKey, 0);
+ secondKey = new QLineEdit(timeKey, 0);
+
+ resetButton = new QPushButton(this, "reset");
+ resetButton->setMinimumSize(QSize(50, 0));
+ resetButton->setText(tr("Reset"));
+
+ changeKeyButton = new QToolButton(this, "changekey");
+ // TODO The icon stuff.
+ changeKeyButton->setText(tr("key"));
+
+ totalKeys = 0;
+ ts = 0;
+ keyMenu = new QPopupMenu(this, "keymenu");
+
+ ws = new QWidgetStack(this, 0);
+ ws->addWidget(textKey, stack_elem++);
+ ws->addWidget(timeKey, stack_elem++);
+ ws->addWidget(dateKey, stack_elem++);
+
+ ws->raiseWidget(0);
+
+ // TODO connect slots and signals....
+ connect(changeKeyButton, SIGNAL(clicked()),
+ this, SLOT(changeKeyMenuSlot()));
+ connect(resetButton, SIGNAL(clicked()),
+ this, SLOT(resetKeySlot()));
+
+ connect(textKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+
+ connect(dayKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+ connect(monthKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+ connect(yearKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+
+ connect(secondKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+ connect(minuteKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+ connect(hourKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+
+ h_layout->addWidget(ws);
+ h_layout->addWidget(resetButton);
+ h_layout->addWidget(changeKeyButton);
+}
+
+/*!
+ Destructs the widget
+*/
+TVBrowseKeyEntry::~TVBrowseKeyEntry()
+{
+}
+
+/*!
+ Changes which key the user intends to search on
+
+ \param id_param the index of the key future searches should be base on
+*/
+void TVBrowseKeyEntry::changeKeySlot(int id_param)
+{
+ emit sortChanged(id_param);
+ switch(ts->kRep->getKeyType(ts->current_column)) {
+ /* work out what to raise */
+ case kt_string:
+ case kt_int:
+ ws->raiseWidget(0);
+ break;
+ case kt_time:
+ ws->raiseWidget(1);
+ break;
+ case kt_date:
+ ws->raiseWidget(2);
+ break;
+ default:
+ return;
+ }
+}
+
+/*!
+ Opens the change key menu
+*/
+void TVBrowseKeyEntry::changeKeyMenuSlot()
+{
+ if(ts)
+ keyMenu->exec(changeKeyButton->mapToGlobal(QPoint(0,0)));
+}
+/*!
+ Blanks the key entry widget
+ \TODO the actual implmentation
+*/
+void TVBrowseKeyEntry::resetKeySlot() {
+ ;
+}
+
+void TVBrowseKeyEntry::setTableState(TableState *t) {
+ int i;
+ ts = t;
+
+ /* clear the old */
+ keyMenu->clear();
+
+ for (i = 0; i < t->kRep->getNumFields(); i++) {
+ keyMenu->insertItem(ts->kRep->getKeyName(i), this,
+ SLOT(changeKeySlot(int)), 0, i);
+ keyMenu->setItemParameter(i, i);
+ }
+}
+
+/*!
+ Searches on the current value of the key entry provided that the
+ current key is of type text WARNING, TODO fix memory leaks
+*/
+void TVBrowseKeyEntry::searchOnText()
+{
+ void *sendkey;
+ int tmp;
+
+ switch(ts->kRep->getKeyType(ts->current_column)) {
+ /* work out what to raise */
+ case kt_string:
+ sendkey = (void *)new QString(textKey->text());
+ break;
+ case kt_int: {
+ bool ok;
+ tmp = textKey->text().toInt(&ok);
+ sendkey = &tmp;
+ if (!ok)
+ return;
+ break;
+ }
+ case kt_time: {
+ bool ok;
+ int s,m,h;
+ s = secondKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ m = minuteKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ h = hourKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ if(!QTime::isValid(h, m, s))
+ return;
+ sendkey = (void *) new QTime(h, m, s);
+ break;
+ }
+ case kt_date: {
+ bool ok;
+ int d,m,y;
+ d = dayKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ m = monthKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ y = yearKey->text().toInt(&ok);
+ if (!ok)
+ return;
+ if(!QDate::isValid(y, m, d))
+ return;
+ sendkey = (void *) new QDate(y, m, d);
+ break;
+ }
+ default:
+ qWarning("TVBrowseKeyEntry::searchOnText() "
+ "cannot work out data type");
+ return;
+ }
+ emit searchOnKey(ts->current_column, sendkey);
+}
+
+/*! \fn void TVBrowseKeyEntry::searchOnKey(int currentKeyId, void *v)
+
+ This signal indicates that a search on key index currentKeyId should be
+ done searching for the value v.
+*/
diff --git a/noncore/apps/tableviewer/db.xmlt b/noncore/apps/tableviewer/db.xmlt
new file mode 100644
index 0000000..d7734f6
--- a/dev/null
+++ b/noncore/apps/tableviewer/db.xmlt
@@ -0,0 +1,6279 @@
+<database name="World fact book">
+<header>
+<key name="Location" type="String">Location</key>
+<key name="Geographiccoordinates" type="String">Geographic coordinates</key>
+<key name="Area" type="Int">Area</key>
+<key name="Climate" type="String">Climate</key>
+<key name="Naturalresources" type="String">Natural resources</key>
+<key name="Population" type="Int">Population</key>
+<key name="Populationgrowthrate" type="String">Population growth rate</key>
+<key name="Sexratio" type="String">Sex ratio</key>
+<key name="Religions" type="String">Religions</key>
+<key name="Countryname" type="String">Country name</key>
+<key name="Capital" type="String">Capital</key>
+<key name="Flagdescription" type="String">Flag description</key>
+<key name="GDP" type="String">GDP</key>
+<key name="Industries" type="String">Industries</key>
+<key name="Exports" type="String">Exports</key>
+<key name="Imports" type="String">Imports</key>
+<key name="Currency" type="String">Currency</key>
+<key name="Airports" type="String">Airports</key>
+<key name="Illicitdrugs" type="String">Illicit drugs</key>
+</header>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, north of Venezuela</Location>
+<Geographiccoordinates>12 30 N, 69 58 W</Geographiccoordinates>
+<Area>193</Area>
+<Climate>tropical marine; little seasonal temperature variation</Climate>
+<Naturalresources>NEGL; white sandy beaches</Naturalresources>
+<Population>69539</Population>
+<Populationgrowthrate>0.7% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.08 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 82%, Protestant 8%, Hindu, Muslim, Confucian, Jewish</Religions>
+<Countryname>Aruba </Countryname>
+<Capital>Oranjestad</Capital>
+<Flagdescription>blue, with two narrow, horizontal, yellow stripes across the lower portion and a red, four-pointed star outlined in white in the upper hoist-side corner</Flagdescription>
+<GDP>purchasing power parity - $1.6 billion (1998 est.)</GDP>
+<Industries>tourism, transshipment facilities, oil refining</Industries>
+<Exports>$1.17 billion (including oil reexports)(1998)</Exports>
+<Imports>$1.52 billion (1998)</Imports>
+<Currency>1 Aruban florin (Af.) = 100 cents</Currency>
+<Airports>2 (1999 est.)</Airports>
+<Illicitdrugs>drug-money-laundering center and transit point for narcotics bound for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, islands between the Caribbean Sea and the North Atlantic Ocean, east-southeast of Puerto Rico</Location>
+<Geographiccoordinates>17 03 N, 61 48 W</Geographiccoordinates>
+<Area>442</Area>
+<Climate>tropical marine; little seasonal temperature variation</Climate>
+<Naturalresources>NEGL; pleasant climate fosters tourism</Naturalresources>
+<Population>66422</Population>
+<Populationgrowthrate>0.73% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican (predominant), other Protestant, some Roman Catholic</Religions>
+<Countryname>Antigua and Barbuda </Countryname>
+<Capital>Saint John's</Capital>
+<Flagdescription>red, with an inverted isosceles triangle based on the top edge of the flag; the triangle contains three horizontal bands of black (top), light blue, and white, with a yellow rising sun in the black band</Flagdescription>
+<GDP>purchasing power parity - $524 million (1999 est.)</GDP>
+<Industries>tourism, construction, light manufacturing (clothing, alcohol, household appliances)</Industries>
+<Exports>$38 million (1998)</Exports>
+<Imports>$330 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+<Illicitdrugs>considered a minor transshipment point for narcotics bound for the US and Europe; more significant as a drug-money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Asia, north and west of Pakistan, east of Iran</Location>
+<Geographiccoordinates>33 00 N, 65 00 E</Geographiccoordinates>
+<Area>652000</Area>
+<Climate>arid to semiarid; cold winters and hot summers</Climate>
+<Naturalresources>natural gas, petroleum, coal, copper, chromite, talc, barites, sulfur, lead, zinc, iron ore, salt, precious and semiprecious stones</Naturalresources>
+<Population>25838797</Population>
+<Populationgrowthrate>3.54% (2000 est.)
+note: this rate reflects the continued return of refugees from Iran</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.08 male(s)/female
+65 years and over: 1.12 male(s)/female
+total population: 1.06 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 84%, Shi'a Muslim 15%, other 1%</Religions>
+<Countryname>Afghanistan </Countryname>
+<Capital>Kabul</Capital>
+<Flagdescription>three equal horizontal bands of green (top), white, and black with a gold emblem centered on the three bands; the emblem features a temple-like structure with Islamic inscriptions above and below, encircled by a wreath on the left and right and by a bolder Islamic inscription above, all of which are encircled by two crossed scimitars
+note: the Taliban uses a plain white flag</Flagdescription>
+<GDP>purchasing power parity - $21 billion (1999 est.)</GDP>
+<Industries>small-scale production of textiles, soap, furniture, shoes, fertilizer, and cement; handwoven carpets; natural gas, oil, coal, copper</Industries>
+<Exports>$80 million (does not include opium) (1996 est.)</Exports>
+<Imports>$150 million (1996 est.)</Imports>
+<Currency>1 afghani (AF) = 100 puls</Currency>
+<Airports>46 (1999 est.)</Airports>
+<Illicitdrugs>world's largest illicit opium producer, surpassing Burma (potential production in 1999 - 1,670 metric tons; cultivation in 1999 - 51,500 hectares, a 23% increase over 1998); a major source of hashish; increasing number of heroin-processing laboratories being set up in the country; major political factions in the country profit from drug trade</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Africa, bordering the Mediterranean Sea, between Morocco and Tunisia</Location>
+<Geographiccoordinates>28 00 N, 3 00 E</Geographiccoordinates>
+<Area>2381740</Area>
+<Climate>arid to semiarid; mild, wet winters with hot, dry summers along coast; drier with cold winters and hot summers on high plateau; sirocco is a hot, dust/sand-laden wind especially common in summer</Climate>
+<Naturalresources>petroleum, natural gas, iron ore, phosphates, uranium, lead, zinc</Naturalresources>
+<Population>31193917</Population>
+<Populationgrowthrate>1.74% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.86 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim (state religion) 99%, Christian and Jewish 1%</Religions>
+<Countryname>Algeria </Countryname>
+<Capital>Algiers</Capital>
+<Flagdescription>two equal vertical bands of green (hoist side) and white with a red, five-pointed star within a red crescent; the crescent, star, and color green are traditional symbols of Islam (the state religion)</Flagdescription>
+<GDP>purchasing power parity - $147.6 billion (1999 est.)</GDP>
+<Industries>petroleum, natural gas, light industries, mining, electrical, petrochemical, food processing</Industries>
+<Exports>$13.7 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$9.3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Algerian dinar (DA) = 100 centimes</Currency>
+<Airports>137 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southwestern Asia, bordering the Caspian Sea, between Iran and Russia</Location>
+<Geographiccoordinates>40 30 N, 47 30 E</Geographiccoordinates>
+<Area>86600</Area>
+<Climate>dry, semiarid steppe</Climate>
+<Naturalresources>petroleum, natural gas, iron ore, nonferrous metals, alumina</Naturalresources>
+<Population>7748163</Population>
+<Populationgrowthrate>0.27% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.65 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 93.4%, Russian Orthodox 2.5%, Armenian Orthodox 2.3%, other 1.8% (1995 est.)
+note: religious affiliation is still nominal in Azerbaijan; percentages for actual practicing adherents are much lower</Religions>
+<Countryname>Azerbaijan </Countryname>
+<Capital>Baku (Baki)</Capital>
+<Flagdescription>three equal horizontal bands of blue (top), red, and green; a crescent and eight-pointed star in white are centered in red band</Flagdescription>
+<GDP>purchasing power parity - $14 billion (1999 est.)</GDP>
+<Industries>petroleum and natural gas, petroleum products, oilfield equipment; steel, iron ore, cement; chemicals and petrochemicals; textiles</Industries>
+<Exports>$885 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.62 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 manat = 100 gopiks</Currency>
+<Airports>69 (1996 est.)</Airports>
+<Illicitdrugs>limited illicit cultivation of cannabis and opium poppy, mostly for CIS consumption; limited government eradication program; transshipment point for opiates via Iran, Central Asia, and Russia to Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Adriatic Sea and Ionian Sea, between Greece and Serbia and Montenegro</Location>
+<Geographiccoordinates>41 00 N, 20 00 E</Geographiccoordinates>
+<Area>28748</Area>
+<Climate>mild temperate; cool, cloudy, wet winters; hot, clear, dry summers; interior is cooler and wetter</Climate>
+<Naturalresources>petroleum, natural gas, coal, chromium, copper, timber, nickel, hydropower</Naturalresources>
+<Population>3490435</Population>
+<Populationgrowthrate>0.26% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.77 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 70%, Albanian Orthodox 20%, Roman Catholic 10%
+note: all mosques and churches were closed in 1967 and religious observances prohibited; in November 1990, Albania began allowing private religious practice</Religions>
+<Countryname>Albania </Countryname>
+<Capital>Tirana</Capital>
+<Flagdescription>red with a black two-headed eagle in the center</Flagdescription>
+<GDP>purchasing power parity - $5.6 billion (1999 est.)</GDP>
+<Industries>food processing, textiles and clothing; lumber, oil, cement, chemicals, mining, basic metals, hydropower</Industries>
+<Exports>$242 million (f.o.b., 1999 est.)</Exports>
+<Imports>$925 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 lek (L) = 100 qintars</Currency>
+<Airports>10 (1999 est.)</Airports>
+<Illicitdrugs>increasingly active transshipment point for Southwest Asian opiates, hashish, and cannabis transiting the Balkan route and - to a far lesser extent - cocaine from South America destined for Western Europe; limited opium and cannabis production; ethnic Albanian narcotrafficking organizations active and rapidly expanding in Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southwestern Asia, east of Turkey</Location>
+<Geographiccoordinates>40 00 N, 45 00 E</Geographiccoordinates>
+<Area>29800</Area>
+<Climate>highland continental, hot summers, cold winters</Climate>
+<Naturalresources>small deposits of gold, copper, molybdenum, zinc, alumina</Naturalresources>
+<Population>3344336</Population>
+<Populationgrowthrate>-0.28% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Armenian Orthodox 94%</Religions>
+<Countryname>Armenia </Countryname>
+<Capital>Yerevan</Capital>
+<Flagdescription>three equal horizontal bands of red (top), blue, and orange</Flagdescription>
+<GDP>purchasing power parity - $9.9 billion (1999 est.)</GDP>
+<Industries>metal-cutting machine tools, forging-pressing machines, electric motors, tires, knitted wear, hosiery, shoes, silk fabric, washing machines, chemicals, trucks, watches, instruments, microelectronics</Industries>
+<Exports>$240 million (1999 est.)</Exports>
+<Imports>$782 million (1999 est.)</Imports>
+<Currency>1 dram = 100 luma</Currency>
+<Airports>11 (1996 est.)</Airports>
+<Illicitdrugs>illicit cultivator of cannabis mostly for domestic consumption; increasingly used as a transshipment point for illicit drugs - mostly opium and hashish - to Western Europe and the US via Iran, Central Asia, and Russia</Illicitdrugs>
+</record>
+<record>
+<Location>Southwestern Europe, between France and Spain</Location>
+<Geographiccoordinates>42 30 N, 1 30 E</Geographiccoordinates>
+<Area>468</Area>
+<Climate>temperate; snowy, cold winters and warm, dry summers</Climate>
+<Naturalresources>hydropower, mineral water, timber, iron ore, lead</Naturalresources>
+<Population>66824</Population>
+<Populationgrowthrate>1.22% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.1 male(s)/female
+15-64 years: 1.11 male(s)/female
+65 years and over: 1.01 male(s)/female
+total population: 1.1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic (predominant)</Religions>
+<Countryname>Andorra </Countryname>
+<Capital>Andorra la Vella</Capital>
+<Flagdescription>three equal vertical bands of blue (hoist side), yellow, and red with the national coat of arms centered in the yellow band; the coat of arms features a quartered shield; similar to the flags of Chad and Romania, which do not have a national coat of arms in the center, and the flag of Moldova, which does bear a national emblem</Flagdescription>
+<GDP>purchasing power parity - $1.2 billion (1996 est.)</GDP>
+<Industries>tourism (particularly skiing), cattle raising, timber, tobacco, banking</Industries>
+<Exports>$58 million (f.o.b., 1998)</Exports>
+<Imports>$1.077 billion (c.i.f., 1998)</Imports>
+<Currency>1 French franc (F) = 100 centimes; 1 peseta (Pta) = 100 centimos; the French and Spanish currencies are used</Currency>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Southern Africa, bordering the South Atlantic Ocean, between Namibia and Democratic Republic of the Congo</Location>
+<Geographiccoordinates>12 30 S, 18 30 E</Geographiccoordinates>
+<Area>1246700</Area>
+<Climate>semiarid in south and along coast to Luanda; north has cool, dry season (May to October) and hot, rainy season (November to April)</Climate>
+<Naturalresources>petroleum, diamonds, iron ore, phosphates, copper, feldspar, gold, bauxite, uranium</Naturalresources>
+<Population>10145267</Population>
+<Populationgrowthrate>2.15% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 47%, Roman Catholic 38%, Protestant 15% (1998 est.)</Religions>
+<Countryname>Angola </Countryname>
+<Capital>Luanda</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and black with a centered yellow emblem consisting of a five-pointed star within half a cogwheel crossed by a machete (in the style of a hammer and sickle)</Flagdescription>
+<GDP>purchasing power parity - $11.6 billion (1999 est.)</GDP>
+<Industries>petroleum; diamonds, iron ore, phosphates, feldspar, bauxite, uranium, and gold; cement; basic metal products; fish processing; food processing; brewing; tobacco products; sugar; textiles</Industries>
+<Exports>$5 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 kwanza (NKz) = 100 lwei</Currency>
+<Airports>249 (1999 est.)</Airports>
+<Illicitdrugs>increasingly used as a transshipment point for cocaine and heroin destined for Western Europe and other African states</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, group of islands in the South Pacific Ocean, about one-half of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>14 20 S, 170 00 W</Geographiccoordinates>
+<Area>199</Area>
+<Climate>tropical marine, moderated by southeast trade winds; annual rainfall averages about 3 m; rainy season from November to April, dry season from May to October; little seasonal temperature variation</Climate>
+<Naturalresources>pumice, pumicite</Naturalresources>
+<Population>65446</Population>
+<Populationgrowthrate>2.53% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 1.1 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian Congregationalist 50%, Roman Catholic 20%, Protestant and other 30%</Religions>
+<Countryname>American Samoa </Countryname>
+<Capital>Pago Pago</Capital>
+<Flagdescription>blue, with a white triangle edged in red that is based on the outer side and extends to the hoist side; a brown and white American bald eagle flying toward the hoist side is carrying two traditional Samoan symbols of authority, a staff and a war club</Flagdescription>
+<GDP>purchasing power parity - $150 million (1995 est.)</GDP>
+<Industries>tuna canneries (largely dependent on foreign fishing vessels), handicrafts</Industries>
+<Exports>$313 million (1996)</Exports>
+<Imports>$471 million (1996)</Imports>
+<Currency>1 US dollar (US$) = 100 cents</Currency>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern South America, bordering the South Atlantic Ocean, between Chile and Uruguay</Location>
+<Geographiccoordinates>34 00 S, 64 00 W</Geographiccoordinates>
+<Area>2766890</Area>
+<Climate>mostly temperate; arid in southeast; subantarctic in southwest</Climate>
+<Naturalresources>fertile plains of the pampas, lead, zinc, tin, copper, iron ore, manganese, petroleum, uranium</Naturalresources>
+<Population>36955182</Population>
+<Populationgrowthrate>1.16% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>nominally Roman Catholic 92% (less than 20% practicing), Protestant 2%, Jewish 2%, other 4%</Religions>
+<Countryname>Argentina </Countryname>
+<Capital>Buenos Aires</Capital>
+<Flagdescription>three equal horizontal bands of light blue (top), white, and light blue; centered in the white band is a radiant yellow sun with a human face known as the Sun of May</Flagdescription>
+<GDP>purchasing power parity - $367 billion (1999 est.)</GDP>
+<Industries>food processing, motor vehicles, consumer durables, textiles, chemicals and petrochemicals, printing, metallurgy, steel</Industries>
+<Exports>$23 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$25 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 peso = 100 centavos</Currency>
+<Airports>1,359 (1999 est.)</Airports>
+<Illicitdrugs>increasing use as a transshipment country for cocaine headed for Europe and the US; increasing use as a money-laundering center; domestic consumption of drugs has skyrocketed</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, continent between the Indian Ocean and the South Pacific Ocean</Location>
+<Geographiccoordinates>27 00 S, 133 00 E</Geographiccoordinates>
+<Area>7686850</Area>
+<Climate>generally arid to semiarid; temperate in south and east; tropical in north</Climate>
+<Naturalresources>bauxite, coal, iron ore, copper, tin, silver, uranium, nickel, tungsten, mineral sands, lead, zinc, diamonds, natural gas, petroleum</Naturalresources>
+<Population>19169083</Population>
+<Populationgrowthrate>1.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 26.1%, Roman Catholic 26%, other Christian 24.3%, non-Christian 11%</Religions>
+<Countryname>Australia </Countryname>
+<Capital>Canberra</Capital>
+<Flagdescription>blue with the flag of the UK in the upper hoist-side quadrant and a large seven-pointed star in the lower hoist-side quadrant; the remaining half is a representation of the Southern Cross constellation in white with one small five-pointed star and four, larger, seven-pointed stars</Flagdescription>
+<GDP>purchasing power parity - $416.2 billion (1999 est.)</GDP>
+<Industries>mining, industrial and transportation equipment, food processing, chemicals, steel</Industries>
+<Exports>$58 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$67 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>408 (1999 est.)</Airports>
+<Illicitdrugs>Tasmania is one of the world's major suppliers of licit opiate products; government maintains strict controls over areas of opium poppy cultivation and output of poppy straw concentrate</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, islands in the Indian Ocean, northwest of Australia</Location>
+<Geographiccoordinates>12 14 S, 123 05 E</Geographiccoordinates>
+<Area>5</Area>
+<Climate>tropical</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population></Population>
+<Countryname>Ashmore and Cartier Islands </Countryname>
+<Flagdescription>the flag of Australia is used</Flagdescription>
+</record>
+<record>
+<Location>Central Europe, north of Italy and Slovenia</Location>
+<Geographiccoordinates>47 20 N, 13 20 E</Geographiccoordinates>
+<Area>83858</Area>
+<Climate>temperate; continental, cloudy; cold winters with frequent rain in lowlands and snow in mountains; cool summers with occasional showers</Climate>
+<Naturalresources>iron ore, oil, timber, magnesite, lead, coal, lignite, copper, hydropower</Naturalresources>
+<Population>8131111</Population>
+<Populationgrowthrate>0.25% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.61 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 78%, Protestant 5%, Muslim and other 17%</Religions>
+<Countryname>Austria </Countryname>
+<Capital>Vienna</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and red</Flagdescription>
+<GDP>purchasing power parity - $190.6 billion (1999 est.)</GDP>
+<Industries>construction, machinery, vehicles and parts, food, chemicals, lumber and wood processing, paper and paperboard, communications equipment, tourism (1997)</Industries>
+<Exports>$62.9 billion (1999 est.)</Exports>
+<Imports>$69.9 billion (1999 est.)</Imports>
+<Currency>1 Austrian schilling (AS) = 100 groschen</Currency>
+<Airports>55 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for Southwest Asian heroin and South American cocaine destined for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, east of Puerto Rico</Location>
+<Geographiccoordinates>18 15 N, 63 10 W</Geographiccoordinates>
+<Area>91</Area>
+<Climate>tropical; moderated by northeast trade winds</Climate>
+<Naturalresources>salt, fish, lobster</Naturalresources>
+<Population>11797</Population>
+<Populationgrowthrate>2.93% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.79 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 40%, Methodist 33%, Seventh-Day Adventist 7%, Baptist 5%, Roman Catholic 3%, other 12%</Religions>
+<Countryname>Anguilla </Countryname>
+<Capital>The Valley</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and the Anguillan coat of arms centered in the outer half of the flag; the coat of arms depicts three orange dolphins in an interlocking circular design on a white background with blue wavy water below</Flagdescription>
+<GDP>purchasing power parity - $88 million (1998 est.)</GDP>
+<Industries>tourism, boat building, offshore financial services</Industries>
+<Exports>$4.5 million (1998)</Exports>
+<Imports>$57.6 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>continent mostly south of the Antarctic Circle</Location>
+<Geographiccoordinates>90 00 S, 0 00 E</Geographiccoordinates>
+<Area>14000000</Area>
+<Climate>severe low temperatures vary with latitude, elevation, and distance from the ocean; East Antarctica is colder than West Antarctica because of its higher elevation; Antarctic Peninsula has the most moderate climate; higher temperatures occur in January along the coast and average slightly below freezing</Climate>
+<Naturalresources>none presently exploited; iron ore, chromium, copper, gold, nickel, platinum and other minerals, and coal and hydrocarbons have been found in small, uncommercial quantities</Naturalresources>
+<Population></Population>
+<Countryname>Antarctica </Countryname>
+<Airports>18
+note: 27 stations, operated by 16 national governments party to the Antarctic Treaty, have landing facilities for either helicopters and/or fixed-wing aircraft; commercial enterprises operate two additional air facilities; helicopter pads are available at 27 stations; runways at 15 locations are gravel, sea-ice, blue-ice, or compacted snow suitable for landing wheeled, fixed-wing aircraft; of these, 1 is greater than 3 km in length, 6 are between 2 km and 3 km in length, 3 are between 1 km and 2 km in length, 3 are less than 1 km in length, and 2 are of unknown length; snow surface skiways, limited to use by ski-equipped, fixed-wing aircraft,are available at another 15 locations; of these, 4 are greater than 3 km in length, 3 are between 2 km and 3 km in length, 2 are between 1 km and 2 km in length, 2 are less than 1 km in length, and 4 are of unknown length; airports generally subject to severe restrictions and limitations resulting from extreme seasonal and geographic conditions; airports do not meet ICAO standards; advance approval from the respective governmental or nongovernmental operating organization required for landing (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, archipelago in the Persian Gulf, east of Saudi Arabia</Location>
+<Geographiccoordinates>26 00 N, 50 33 E</Geographiccoordinates>
+<Area>620</Area>
+<Climate>arid; mild, pleasant winters; very hot, humid summers</Climate>
+<Naturalresources>oil, associated and nonassociated natural gas, fish</Naturalresources>
+<Population>634137</Population>
+<Populationgrowthrate>1.78% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.46 male(s)/female
+65 years and over: 1.04 male(s)/female
+total population: 1.3 male(s)/female (2000 est.)</Sexratio>
+<Religions>Shi'a Muslim 75%, Sunni Muslim 25%</Religions>
+<Countryname>Bahrain </Countryname>
+<Capital>Manama</Capital>
+<Flagdescription>red with a white serrated band (eight white points) on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $8.6 billion (1999 est.)</GDP>
+<Industries>petroleum processing and refining, aluminum smelting, offshore banking, ship repairing; tourism</Industries>
+<Exports>$3.3 billion (f.o.b., 1998)</Exports>
+<Imports>$3.5 billion (f.o.b., 1998)</Imports>
+<Currency>1 Bahraini dinar (BD) = 1,000 fils</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and the North Atlantic Ocean, northeast of Venezuela</Location>
+<Geographiccoordinates>13 10 N, 59 32 W</Geographiccoordinates>
+<Area>430</Area>
+<Climate>tropical; rainy season (June to October)</Climate>
+<Naturalresources>petroleum, fish, natural gas</Naturalresources>
+<Population>274540</Population>
+<Populationgrowthrate>0.55% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.63 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 67% (Anglican 40%, Pentecostal 8%, Methodist 7%, other 12%), Roman Catholic 4%, none 17%, other 12%</Religions>
+<Countryname>Barbados </Countryname>
+<Capital>Bridgetown</Capital>
+<Flagdescription>three equal vertical bands of blue (hoist side), gold, and blue with the head of a black trident centered on the gold band; the trident head represents independence and a break with the past (the colonial coat of arms contained a complete trident)</Flagdescription>
+<GDP>purchasing power parity - $2.9 billion (1998 est.)</GDP>
+<Industries>tourism, sugar, light manufacturing, component assembly for export</Industries>
+<Exports>$211.2 million (1998)</Exports>
+<Imports>$1.01 billion (1998)</Imports>
+<Currency>1 Barbadian dollar (Bds$) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+<Illicitdrugs>one of many Caribbean transshipment points for narcotics bound for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, north of South Africa</Location>
+<Geographiccoordinates>22 00 S, 24 00 E</Geographiccoordinates>
+<Area>600370</Area>
+<Climate>semiarid; warm winters and hot summers</Climate>
+<Naturalresources>diamonds, copper, nickel, salt, soda ash, potash, coal, iron ore, silver</Naturalresources>
+<Population>1576470</Population>
+<Populationgrowthrate>0.76% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 50%, Christian 50%</Religions>
+<Countryname>Botswana </Countryname>
+<Capital>Gaborone</Capital>
+<Flagdescription>light blue with a horizontal white-edged black stripe in the center</Flagdescription>
+<GDP>purchasing power parity - $5.7 billion (1999 est.)</GDP>
+<Industries>diamonds, copper, nickel, coal, salt, soda ash, potash; livestock processing</Industries>
+<Exports>$2.36 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2.05 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 pula (P) = 100 thebe</Currency>
+<Airports>92 (1999 est.)</Airports>
+</record>
+<record>
+<Location>North America, group of islands in the North Atlantic Ocean, east of North Carolina (US)</Location>
+<Geographiccoordinates>32 20 N, 64 45 W</Geographiccoordinates>
+<Area>58</Area>
+<Climate>subtropical; mild, humid; gales, strong winds common in winter</Climate>
+<Naturalresources>limestone, pleasant climate fostering tourism</Naturalresources>
+<Population>62997</Population>
+<Populationgrowthrate>0.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 0.98 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>non-Anglican Protestant 39%, Anglican 27%, Roman Catholic 15%, other 19%</Religions>
+<Countryname>Bermuda </Countryname>
+<Capital>Hamilton</Capital>
+<Flagdescription>red, with the flag of the UK in the upper hoist-side quadrant and the Bermudian coat of arms (white and blue shield with a red lion holding a scrolled shield showing the sinking of the ship Sea Venture off Bermuda in 1609) centered on the outer half of the flag</Flagdescription>
+<GDP>purchasing power parity - $2 billion (1999 est.)</GDP>
+<Industries>tourism, finance, insurance, structural concrete products, paints, perfumes, pharmaceuticals, ship repairing</Industries>
+<Exports>$32 million (1998 est.)</Exports>
+<Imports>$624 million (1998 est.)</Imports>
+<Currency>1 Bermudian dollar (Bd$) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Europe, bordering the North Sea, between France and the Netherlands</Location>
+<Geographiccoordinates>50 50 N, 4 00 E</Geographiccoordinates>
+<Area>30510</Area>
+<Climate>temperate; mild winters, cool summers; rainy, humid, cloudy</Climate>
+<Naturalresources>coal, natural gas</Naturalresources>
+<Population>10241506</Population>
+<Populationgrowthrate>0.18% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 75%, Protestant or other 25%</Religions>
+<Countryname>Belgium </Countryname>
+<Capital>Brussels</Capital>
+<Flagdescription>three equal vertical bands of black (hoist side), yellow, and red; the design was based on the flag of France</Flagdescription>
+<GDP>purchasing power parity - $243.4 billion (1999 est.)</GDP>
+<Industries>engineering and metal products, motor vehicle assembly, processed food and beverages, chemicals, basic metals, textiles, glass, petroleum, coal</Industries>
+<Exports>$187.3 billion (f.o.b., 1999)</Exports>
+<Imports>$172.8 billion (f.o.b., 1999)</Imports>
+<Currency>1 Belgian franc (BF) = 100 centimes</Currency>
+<Airports>42 (1999 est.)</Airports>
+<Illicitdrugs>source of precursor chemicals for South American cocaine processors; transshipment point for cocaine, heroin, hashish, and marijuana entering Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, chain of islands in the North Atlantic Ocean, southeast of Florida</Location>
+<Geographiccoordinates>24 15 N, 76 00 W</Geographiccoordinates>
+<Area>13940</Area>
+<Climate>tropical marine; moderated by warm waters of Gulf Stream</Climate>
+<Naturalresources>salt, aragonite, timber</Naturalresources>
+<Population>294982</Population>
+<Populationgrowthrate>1.01% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.02 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Baptist 32%, Anglican 20%, Roman Catholic 19%, Methodist 6%, Church of God 6%, other Protestant 12%, none or unknown 3%, other 2%</Religions>
+<Countryname>The Bahamas </Countryname>
+<Capital>Nassau</Capital>
+<Flagdescription>three equal horizontal bands of aquamarine (top), gold, and aquamarine, with a black equilateral triangle based on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $5.58 billion (1998 est.)</GDP>
+<Industries>tourism, banking, cement, oil refining and transshipment, salt, rum, aragonite, pharmaceuticals, spiral-welded steel pipe</Industries>
+<Exports>$362.8 million (1998)</Exports>
+<Imports>$1.74 billion (1998)</Imports>
+<Currency>1 Bahamian dollar (B$) = 100 cents</Currency>
+<Airports>62 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine and marijuana bound for US and Europe; banking industry vulnerable to money laundering</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Asia, bordering the Bay of Bengal, between Burma and India</Location>
+<Geographiccoordinates>24 00 N, 90 00 E</Geographiccoordinates>
+<Area>144000</Area>
+<Climate>tropical; cool, dry winter (October to March); hot, humid summer (March to June); cool, rainy monsoon (June to October)</Climate>
+<Naturalresources>natural gas, arable land, timber</Naturalresources>
+<Population>129194224</Population>
+<Populationgrowthrate>1.59% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 1.19 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 88.3%, Hindu 10.5%, other 1.2%</Religions>
+<Countryname>Bangladesh </Countryname>
+<Capital>Dhaka</Capital>
+<Flagdescription>green with a large red disk slightly to the hoist side of center; the red sun of freedom represents the blood shed to achieve independence; the green field symbolizes the lush countryside, and secondarily, the traditional color of Islam</Flagdescription>
+<GDP>purchasing power parity - $187 billion (1999 est.)</GDP>
+<Industries>cotton textiles, jute, garments, tea processing, paper newsprint, cement, chemical fertilizer, light engineering, sugar</Industries>
+<Exports>$5.1 billion (1998)</Exports>
+<Imports>$8.01 billion (1998)</Imports>
+<Currency>1 taka (Tk) = 100 poisha</Currency>
+<Airports>16 (1999 est.)</Airports>
+<Illicitdrugs>transit country for illegal drugs produced in neighboring countries</Illicitdrugs>
+</record>
+<record>
+<Location>Middle America, bordering the Caribbean Sea, between Guatemala and Mexico</Location>
+<Geographiccoordinates>17 15 N, 88 45 W</Geographiccoordinates>
+<Area>22960</Area>
+<Climate>tropical; very hot and humid; rainy season (May to February)</Climate>
+<Naturalresources>arable land potential, timber, fish, hydropower</Naturalresources>
+<Population>249183</Population>
+<Populationgrowthrate>2.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.95 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 62%, Protestant 30% (Anglican 12%, Methodist 6%, Mennonite 4%, Seventh-Day Adventist 3%, Pentecostal 2%, Jehovah's Witnesses 1%, other 2%), none 2%, other 6% (1980)</Religions>
+<Countryname>Belize </Countryname>
+<Capital>Belmopan</Capital>
+<Flagdescription>blue with a narrow red stripe along the top and the bottom edges; centered is a large white disk bearing the coat of arms; the coat of arms features a shield flanked by two workers in front of a mahogany tree with the related motto SUB UMBRA FLOREO (I Flourish in the Shade) on a scroll at the bottom, all encircled by a green garland</Flagdescription>
+<GDP>purchasing power parity - $740 million (1999 est.)</GDP>
+<Industries>garment production, food processing, tourism, construction</Industries>
+<Exports>$150 million (f.o.b., 1998)</Exports>
+<Imports>$320 million (c.i.f., 1998)</Imports>
+<Currency>1 Belizean dollar (Bz$) = 100 cents</Currency>
+<Airports>44 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine; small-scale illicit producer of cannabis for the international drug trade; minor money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Adriatic Sea and Croatia</Location>
+<Geographiccoordinates>44 00 N, 18 00 E</Geographiccoordinates>
+<Area>51129</Area>
+<Climate>hot summers and cold winters; areas of high elevation have short, cool summers and long, severe winters; mild, rainy winters along coast</Climate>
+<Naturalresources>coal, iron, bauxite, manganese, forests, copper, chromium, lead, zinc, hydropower</Naturalresources>
+<Population>3835777</Population>
+<Populationgrowthrate>3.1% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.06 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 40%, Orthodox 31%, Roman Catholic 15%, Protestant 4%, other 10%</Religions>
+<Countryname>Bosnia and Herzegovina </Countryname>
+<Capital>Sarajevo</Capital>
+<Flagdescription>a wide medium blue vertical band on the fly side with a yellow isosceles triangle abutting the band and the top of the flag; the remainder of the flag is medium blue with seven full five-pointed white stars and two half stars top and bottom along the hypotenuse of the triangle</Flagdescription>
+<GDP>purchasing power parity - $6.2 billion (1999 est.)</GDP>
+<Industries>steel, coal, iron ore, lead, zinc, manganese, bauxite, vehicle assembly, textiles, tobacco products, wooden furniture, tank and aircraft assembly, domestic appliances, oil refining (much of capacity damaged or shut down) (1995)</Industries>
+<Exports>$450 million (1997 est.)</Exports>
+<Imports>$2.95 billion (1997 est.)</Imports>
+<Currency>1 convertible marka (KM) = 100 convertible pfenniga</Currency>
+<Airports>27 (1999 est.)</Airports>
+<Illicitdrugs>minor transit point for marijuana and opiate trafficking routes to Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Central South America, southwest of Brazil</Location>
+<Geographiccoordinates>17 00 S, 65 00 W</Geographiccoordinates>
+<Area>1098580</Area>
+<Climate>varies with altitude; humid and tropical to cold and semiarid</Climate>
+<Naturalresources>tin, natural gas, petroleum, zinc, tungsten, antimony, silver, iron, lead, gold, timber, hydropower</Naturalresources>
+<Population>8152620</Population>
+<Populationgrowthrate>1.83% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.82 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95%, Protestant (Evangelical Methodist)</Religions>
+<Countryname>Bolivia </Countryname>
+<Capital>La Paz (seat of government); Sucre (legal capital and seat of judiciary)</Capital>
+<Flagdescription>three equal horizontal bands of red (top), yellow, and green with the coat of arms centered on the yellow band; similar to the flag of Ghana, which has a large black five-pointed star centered in the yellow band</Flagdescription>
+<GDP>purchasing power parity - $24.2 billion (1999 est.)</GDP>
+<Industries>mining, smelting, petroleum, food and beverages, tobacco, handicrafts, clothing</Industries>
+<Exports>$1.1 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$1.6 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 boliviano ($B) = 100 centavos</Currency>
+<Airports>1,109 (1999 est.)</Airports>
+<Illicitdrugs>world's third-largest cultivator of coca (after Peru and Colombia) with an estimated 21,800 hectares under cultivation in 1999, a 45% decrease in overall cultivation of coca from 1998 levels; intermediate coca products and cocaine exported to or through Colombia, Brazil, Argentina, and Chile to the US and other international drug markets; alternative crop program aims to reduce illicit coca cultivation</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, bordering the Andaman Sea and the Bay of Bengal, between Bangladesh and Thailand</Location>
+<Geographiccoordinates>22 00 N, 98 00 E</Geographiccoordinates>
+<Area>678500</Area>
+<Climate>tropical monsoon; cloudy, rainy, hot, humid summers (southwest monsoon, June to September); less cloudy, scant rainfall, mild temperatures, lower humidity during winter (northeast monsoon, December to April)</Climate>
+<Naturalresources>petroleum, timber, tin, antimony, zinc, copper, tungsten, lead, coal, some marble, limestone, precious stones, natural gas, hydropower</Naturalresources>
+<Population>41734853</Population>
+<Populationgrowthrate>0.64% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist 89%, Christian 4% (Baptist 3%, Roman Catholic 1%), Muslim 4%, animist 1%, other 2%</Religions>
+<Countryname>Burma </Countryname>
+<Capital>Rangoon (regime refers to the capital as Yangon)</Capital>
+<Flagdescription>red with a blue rectangle in the upper hoist-side corner bearing, all in white, 14 five-pointed stars encircling a cogwheel containing a stalk of rice; the 14 stars represent the 14 administrative divisions</Flagdescription>
+<GDP>purchasing power parity - $59.4 billion (1999 est.)</GDP>
+<Industries>agricultural processing; textiles and footwear; wood and wood products; copper, tin, tungsten, iron; construction materials; pharmaceuticals; fertilizer</Industries>
+<Exports>$1.2 billion (1998)</Exports>
+<Imports>$2.5 billion (1998)</Imports>
+<Currency>1 kyat (K) = 100 pyas</Currency>
+<Airports>80 (1999 est.)</Airports>
+<Illicitdrugs>world's second largest producer of illicit opium, after Afghanistan (potential production in 1999 - 1,090 metric tons, down 38% due to drought; cultivation in 1999 - 89,500 hectares, a 31% decline from 1998); surrender of drug warlord KHUN SA's Mong Tai Army in January 1996 was hailed by Rangoon as a major counternarcotics success, but lack of government will and ability to take on major narcotrafficking groups and lack of serious commitment against money laundering continues to hinder the overall antidrug effort; becoming a major source of methamphetamines for regional consumption</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Nigeria and Togo</Location>
+<Geographiccoordinates>9 30 N, 2 15 E</Geographiccoordinates>
+<Area>112620</Area>
+<Climate>tropical; hot, humid in south; semiarid in north</Climate>
+<Naturalresources>small offshore oil deposits, limestone, marble, timber</Naturalresources>
+<Population>6395919</Population>
+<Populationgrowthrate>3.03% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 70%, Muslim 15%, Christian 15%</Religions>
+<Countryname>Benin </Countryname>
+<Capital>Porto-Novo is the official capital; Cotonou is the seat of government</Capital>
+<Flagdescription>two equal horizontal bands of yellow (top) and red with a vertical green band on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $8.1 billion (1999 est.)</GDP>
+<Industries>textiles, cigarettes; beverages, food; construction materials, petroleum</Industries>
+<Exports>$396 million (f.o.b., 1999)</Exports>
+<Imports>$566 million (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>5 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for narcotics associated with Nigerian trafficking organizations and most commonly destined for Western Europe and the US</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Europe, east of Poland</Location>
+<Geographiccoordinates>53 00 N, 28 00 E</Geographiccoordinates>
+<Area>207600</Area>
+<Climate>cold winters, cool and moist summers; transitional between continental and maritime</Climate>
+<Naturalresources>forests, peat deposits, small quantities of oil and natural gas</Naturalresources>
+<Population>10366719</Population>
+<Populationgrowthrate>-0.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.94 male(s)/female
+65 years and over: 0.49 male(s)/female
+total population: 0.88 male(s)/female (2000 est.)</Sexratio>
+<Religions>Eastern Orthodox 80%, other (including Roman Catholic, Protestant, Jewish, and Muslim) 20% (1997 est.)</Religions>
+<Countryname>Belarus </Countryname>
+<Capital>Minsk</Capital>
+<Flagdescription>red horizontal band (top) and green horizontal band one-half the width of the red band; a white vertical stripe on the hoist side bears the Belarusian national ornament in red</Flagdescription>
+<GDP>purchasing power parity - $55.2 billion (1999 est.)</GDP>
+<Industries>metal-cutting machine tools, tractors, trucks, earth movers, motorcycles, TV sets, chemical fibers, fertilizer, textiles, radios, refrigerators</Industries>
+<Exports>$6 billion (f.o.b., 1999)</Exports>
+<Imports>$6.4 billion (c.i.f., 1999)</Imports>
+<Currency>Belarusian rubel (BR)</Currency>
+<Airports>118 (1996 est.)</Airports>
+<Illicitdrugs>limited cultivation of opium poppy and cannabis, mostly for the domestic market; transshipment point for illicit drugs to and via Russia, and to the Baltics and Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, group of islands in the South Pacific Ocean, east of Papua New Guinea</Location>
+<Geographiccoordinates>8 00 S, 159 00 E</Geographiccoordinates>
+<Area>28450</Area>
+<Climate>tropical monsoon; few extremes of temperature and weather</Climate>
+<Naturalresources>fish, forests, gold, bauxite, phosphates, lead, zinc, nickel</Naturalresources>
+<Population>466194</Population>
+<Populationgrowthrate>3.04% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.97 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 34%, Roman Catholic 19%, Baptist 17%, United (Methodist/Presbyterian) 11%, Seventh-Day Adventist 10%, other Protestant 5%, indigenous beliefs 4%</Religions>
+<Countryname>Solomon Islands </Countryname>
+<Capital>Honiara</Capital>
+<Flagdescription>divided diagonally by a thin yellow stripe from the lower hoist-side corner; the upper triangle (hoist side) is blue with five white five-pointed stars arranged in an X pattern; the lower triangle is green</Flagdescription>
+<GDP>purchasing power parity - $1.21 billion (1999 est.)</GDP>
+<Industries>fish (tuna), mining, timber</Industries>
+<Exports>$142 million (f.o.b., 1998 est.)</Exports>
+<Imports>$160 million (c.i.f., 1998 est.)</Imports>
+<Currency>1 Solomon Islands dollar (SI$) = 100 cents</Currency>
+<Airports>33 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, about one-fourth of the way from Haiti to Jamaica</Location>
+<Geographiccoordinates>18 25 N, 75 02 W</Geographiccoordinates>
+<Area>5</Area>
+<Climate>marine, tropical</Climate>
+<Naturalresources>guano</Naturalresources>
+<Population></Population>
+<Countryname>Navassa Island </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+</record>
+<record>
+<Location>Eastern South America, bordering the Atlantic Ocean</Location>
+<Geographiccoordinates>10 00 S, 55 00 W</Geographiccoordinates>
+<Area>8511965</Area>
+<Climate>mostly tropical, but temperate in south</Climate>
+<Naturalresources>bauxite, gold, iron ore, manganese, nickel, phosphates, platinum, tin, uranium, petroleum, hydropower, timber</Naturalresources>
+<Population>172860370</Population>
+<Populationgrowthrate>0.94% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic (nominal) 80%</Religions>
+<Countryname>Brazil </Countryname>
+<Capital>Brasilia</Capital>
+<Flagdescription>green with a large yellow diamond in the center bearing a blue celestial globe with 27 white five-pointed stars (one for each state and the Federal District) arranged in the same pattern as the night sky over Brazil; the globe has a white equatorial band with the motto ORDEM E PROGRESSO (Order and Progress)</Flagdescription>
+<GDP>purchasing power parity - $1.057 trillion (1999 est.)</GDP>
+<Industries>textiles, shoes, chemicals, cement, lumber, iron ore, tin, steel, aircraft, motor vehicles and parts, other machinery and equipment</Industries>
+<Exports>$46.9 billion (f.o.b., 1999)</Exports>
+<Imports>$48.7 billion (f.o.b., 1999)</Imports>
+<Currency>1 real (R$) = 100 centavos</Currency>
+<Airports>3,277 (1999 est.)</Airports>
+<Illicitdrugs>limited illicit producer of cannabis, minor coca cultivation in the Amazon region, mostly used for domestic consumption; government has a large-scale eradication program to control cannabis; important transshipment country for Bolivian, Colombian, and Peruvian cocaine headed for the US and Europe; increasingly used by traffickers as a way station for narcotics air transshipments between Peru and Colombia; upsurge in drug-related violence and weapons smuggling</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, islands in the southern Mozambique Channel, about one-half of the way from Madagascar to Mozambique</Location>
+<Geographiccoordinates>21 30 S, 39 50 E</Geographiccoordinates>
+<Area>0</Area>
+<Climate>tropical</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Bassas da India </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+</record>
+<record>
+<Location>Southern Asia, between China and India</Location>
+<Geographiccoordinates>27 30 N, 90 30 E</Geographiccoordinates>
+<Area>47000</Area>
+<Climate>varies; tropical in southern plains; cool winters and hot summers in central valleys; severe winters and cool summers in Himalayas</Climate>
+<Naturalresources>timber, hydropower, gypsum, calcium carbide</Naturalresources>
+<Population>2005222</Population>
+<Populationgrowthrate>2.19% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.08 male(s)/female
+15-64 years: 1.06 male(s)/female
+65 years and over: 1.03 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Lamaistic Buddhist 75%, Indian- and Nepalese-influenced Hinduism 25%</Religions>
+<Countryname>Bhutan </Countryname>
+<Capital>Thimphu</Capital>
+<Flagdescription>divided diagonally from the lower hoist side corner; the upper triangle is yellow and the lower triangle is orange; centered along the dividing line is a large black and white dragon facing away from the hoist side</Flagdescription>
+<GDP>purchasing power parity - $2.1 billion (1999 est.)</GDP>
+<Industries>cement, wood products, processed fruits, alcoholic beverages, calcium carbide</Industries>
+<Exports>$111 million (f.o.b., 1998)</Exports>
+<Imports>$136 million (c.i.f., 1998)</Imports>
+<Currency>1 ngultrum (Nu) = 100 chetrum; note - Indian currency is also legal tender</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Black Sea, between Romania and Turkey</Location>
+<Geographiccoordinates>43 00 N, 25 00 E</Geographiccoordinates>
+<Area>110910</Area>
+<Climate>temperate; cold, damp winters; hot, dry summers</Climate>
+<Naturalresources>bauxite, copper, lead, zinc, coal, timber, arable land</Naturalresources>
+<Population>7796694</Population>
+<Populationgrowthrate>-1.16% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.74 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Bulgarian Orthodox 83.5%, Muslim 13%, Roman Catholic 1.5%, Jewish 0.8%, Uniate Catholic 0.2%, Protestant, Gregorian-Armenian, and other 1% (1998)</Religions>
+<Countryname>Bulgaria </Countryname>
+<Capital>Sofia</Capital>
+<Flagdescription>three equal horizontal bands of white (top), green, and red; the national emblem formerly on the hoist side of the white stripe has been removed - it contained a rampant lion within a wreath of wheat ears below a red five-pointed star and above a ribbon bearing the dates 681 (first Bulgarian state established) and 1944 (liberation from Nazi control)</Flagdescription>
+<GDP>purchasing power parity - $34.9 billion (1999 est.)</GDP>
+<Industries>machine building and metal working, food processing, chemicals, construction materials, ferrous and nonferrous metals, nuclear fuel</Industries>
+<Exports>$3.8 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$5.3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 lev (Lv) = 100 stotinki</Currency>
+<Airports>216 (1999 est.)</Airports>
+<Illicitdrugs>major European transshipment point for Southwest Asian heroin and, to a lesser degree, South American cocaine for the European market; limited producer of precursor chemicals</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, island in the South Atlantic Ocean, south-southwest of the Cape of Good Hope (South Africa)</Location>
+<Geographiccoordinates>54 26 S, 3 24 E</Geographiccoordinates>
+<Area>58</Area>
+<Climate>antarctic</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Bouvet Island </Countryname>
+<Flagdescription>the flag of Norway is used</Flagdescription>
+</record>
+<record>
+<Location>Southeastern Asia, bordering the South China Sea and Malaysia</Location>
+<Geographiccoordinates>4 30 N, 114 40 E</Geographiccoordinates>
+<Area>5770</Area>
+<Climate>tropical; hot, humid, rainy</Climate>
+<Naturalresources>petroleum, natural gas, timber</Naturalresources>
+<Population>336376</Population>
+<Populationgrowthrate>2.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.14 male(s)/female
+65 years and over: 0.94 male(s)/female
+total population: 1.1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim (official) 67%, Buddhist 13%, Christian 10%, indigenous beliefs and other 10%</Religions>
+<Countryname>Brunei </Countryname>
+<Capital>Bandar Seri Begawan</Capital>
+<Flagdescription>yellow with two diagonal bands of white (top, almost double width) and black starting from the upper hoist side; the national emblem in red is superimposed at the center; the emblem includes a swallow-tailed flag on top of a winged column within an upturned crescent above a scroll and flanked by two upraised hands</Flagdescription>
+<GDP>purchasing power parity - $5.6 billion (1999 est.)</GDP>
+<Industries>petroleum, petroleum refining, liquefied natural gas, construction</Industries>
+<Exports>$2.04 billion (f.o.b., 1998 est.)</Exports>
+<Imports>$1.38 billion (c.i.f., 1998 est.)</Imports>
+<Currency>1 Bruneian dollar (B$) = 100 cents</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Africa, east of Democratic Republic of the Congo</Location>
+<Geographiccoordinates>3 30 S, 30 00 E</Geographiccoordinates>
+<Area>27830</Area>
+<Climate>equatorial; high plateau with considerable altitude variation (772 m to 2,670 m); average annual temperature varies with altitude from 23 to 17 degrees centigrade but is generally moderate as the average altitude is about 1,700 m; average annual rainfall is about 150 cm; wet seasons from February to May and September to November, and dry seasons from June to August and December to January</Climate>
+<Naturalresources>nickel, uranium, rare earth oxides, peat, cobalt, copper, platinum (not yet exploited), vanadium, arable land, hydropower</Naturalresources>
+<Population>6054714</Population>
+<Populationgrowthrate>3.15% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 67% (Roman Catholic 62%, Protestant 5%), indigenous beliefs 23%, Muslim 10%</Religions>
+<Countryname>Burundi </Countryname>
+<Capital>Bujumbura</Capital>
+<Flagdescription>divided by a white diagonal cross into red panels (top and bottom) and green panels (hoist side and outer side) with a white disk superimposed at the center bearing three red six-pointed stars outlined in green arranged in a triangular design (one star above, two stars below)</Flagdescription>
+<GDP>purchasing power parity - $4.2 billion (1999 est.)</GDP>
+<Industries>light consumer goods such as blankets, shoes, soap; assembly of imported components; public works construction; food processing</Industries>
+<Exports>$56 million (f.o.b., 1999)</Exports>
+<Imports>$108 million (f.o.b., 1999)</Imports>
+<Currency>1 Burundi franc (FBu) = 100 centimes</Currency>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern North America, bordering the North Atlantic Ocean and North Pacific Ocean, north of the conterminous US</Location>
+<Geographiccoordinates>60 00 N, 95 00 W</Geographiccoordinates>
+<Area>9976140</Area>
+<Climate>varies from temperate in south to subarctic and arctic in north</Climate>
+<Naturalresources>iron ore, nickel, zinc, copper, gold, lead, molybdenum, potash, silver, fish, timber, wildlife, coal, petroleum, natural gas, hydropower</Naturalresources>
+<Population>31281092</Population>
+<Populationgrowthrate>1.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.74 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 42%, Protestant 40%, other 18%</Religions>
+<Countryname>Canada </Countryname>
+<Capital>Ottawa</Capital>
+<Flagdescription>three vertical bands of red (hoist side), white (double width, square), and red with a red maple leaf centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $722.3 billion (1999 est.)</GDP>
+<Industries>processed and unprocessed minerals, food products, wood and paper products, transportation equipment, chemicals, fish products, petroleum and natural gas</Industries>
+<Exports>$277 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$259.3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Canadian dollar (Can$) = 100 cents</Currency>
+<Airports>1,411 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis for the domestic drug market; use of hydroponics technology permits growers to plant large quantities of high-quality marijuana indoors; growing role as a transit point for heroin and cocaine entering the US market</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, bordering the Gulf of Thailand, between Thailand, Vietnam, and Laos</Location>
+<Geographiccoordinates>13 00 N, 105 00 E</Geographiccoordinates>
+<Area>181040</Area>
+<Climate>tropical; rainy, monsoon season (May to November); dry season (December to April); little seasonal temperature variation</Climate>
+<Naturalresources>timber, gemstones, some iron ore, manganese, phosphates, hydropower potential</Naturalresources>
+<Population>12212306</Population>
+<Populationgrowthrate>2.27% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.88 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Theravada Buddhist 95%, other 5%</Religions>
+<Countryname>Cambodia </Countryname>
+<Capital>Phnom Penh</Capital>
+<Flagdescription>three horizontal bands of blue (top), red (double width), and blue with a white three-towered temple representing Angkor Wat outlined in black in the center of the red band</Flagdescription>
+<GDP>purchasing power parity - $8.2 billion (1999 est.)</GDP>
+<Industries>garments, rice milling, fishing, wood and wood products, rubber, cement, gem mining, textiles</Industries>
+<Exports>$821 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 new riel (CR) = 100 sen</Currency>
+<Airports>19 (1999 est.)</Airports>
+<Illicitdrugs>transshipment site for Golden Triangle heroin; possible money laundering; narcotics-related corruption reportedly involving some in the government, military, and police; possible small-scale opium, heroin, and amphetamine production; large producer of cannabis for the international market</Illicitdrugs>
+</record>
+<record>
+<Location>Central Africa, south of Libya</Location>
+<Geographiccoordinates>15 00 N, 19 00 E</Geographiccoordinates>
+<Area>1000000</Area>
+<Climate>tropical in south, desert in north</Climate>
+<Naturalresources>petroleum (unexploited but exploration under way), uranium, natron, kaolin, fish (Lake Chad)</Naturalresources>
+<Population>8424504</Population>
+<Populationgrowthrate>3.31% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.89 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 50%, Christian 25%, indigenous beliefs (mostly animism) 25%</Religions>
+<Countryname>Chad </Countryname>
+<Capital>N'Djamena</Capital>
+<Flagdescription>three equal vertical bands of blue (hoist side), yellow, and red; similar to the flag of Romania; also similar to the flags of Andorra and Moldova, both of which have a national coat of arms centered in the yellow band; design was based on the flag of France</Flagdescription>
+<GDP>purchasing power parity - $7.6 billion (1999 est.)</GDP>
+<Industries>cotton textiles, meat packing, beer brewing, natron (sodium carbonate), soap, cigarettes, construction materials</Industries>
+<Exports>$288 million (f.o.b., 1999 est.)</Exports>
+<Imports>$359 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>49 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Asia, island in the Indian Ocean, south of India</Location>
+<Geographiccoordinates>7 00 N, 81 00 E</Geographiccoordinates>
+<Area>65610</Area>
+<Climate>tropical monsoon; northeast monsoon (December to March); southwest monsoon (June to October)</Climate>
+<Naturalresources>limestone, graphite, mineral sands, gems, phosphates, clay, hydropower</Naturalresources>
+<Population>19238575</Population>
+<Populationgrowthrate>0.89% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.93 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist 70%, Hindu 15%, Christian 8%, Muslim 7% (1999)</Religions>
+<Countryname>Sri Lanka </Countryname>
+<Capital>Colombo</Capital>
+<Flagdescription>yellow with two panels; the smaller hoist-side panel has two equal vertical bands of green (hoist side) and orange; the other panel is a large dark red rectangle with a yellow lion holding a sword, and there is a yellow bo leaf in each corner; the yellow field appears as a border that goes around the entire flag and extends between the two panels</Flagdescription>
+<GDP>purchasing power parity - $50.5 billion (1999 est.)</GDP>
+<Industries>processing of rubber, tea, coconuts, and other agricultural commodities; clothing, cement, petroleum refining, textiles, tobacco</Industries>
+<Exports>$4.7 billion (f.o.b., 1998)</Exports>
+<Imports>$5.3 billion (f.o.b., 1998)</Imports>
+<Currency>1 Sri Lankan rupee (SLRe) = 100 cents</Currency>
+<Airports>14 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the South Atlantic Ocean, between Angola and Gabon</Location>
+<Geographiccoordinates>1 00 S, 15 00 E</Geographiccoordinates>
+<Area>342000</Area>
+<Climate>tropical; rainy season (March to June); dry season (June to October); constantly high temperatures and humidity; particularly enervating climate astride the Equator</Climate>
+<Naturalresources>petroleum, timber, potash, lead, zinc, uranium, copper, phosphates, natural gas, hydropower</Naturalresources>
+<Population>2830961</Population>
+<Populationgrowthrate>2.23% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.67 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 50%, animist 48%, Muslim 2%</Religions>
+<Countryname>Republic of the Congo </Countryname>
+<Capital>Brazzaville</Capital>
+<Flagdescription>divided diagonally from the lower hoist side by a yellow band; the upper triangle (hoist side) is green and the lower triangle is red; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $4.15 billion (1999 est.)</GDP>
+<Industries>petroleum extraction, cement kilning, lumbering, brewing, sugar milling, palm oil, soap, cigarette making</Industries>
+<Exports>$1.7 billion (f.o.b., 1999)</Exports>
+<Imports>$770 million (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>36 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Africa, northeast of Angola</Location>
+<Geographiccoordinates>0 00 N, 25 00 E</Geographiccoordinates>
+<Area>2345410</Area>
+<Climate>tropical; hot and humid in equatorial river basin; cooler and drier in southern highlands; cooler and wetter in eastern highlands; north of Equator - wet season April to October, dry season December to February; south of Equator - wet season November to March, dry season April to October</Climate>
+<Naturalresources>cobalt, copper, cadmium, petroleum, industrial and gem diamonds, gold, silver, zinc, manganese, tin, germanium, uranium, radium, bauxite, iron ore, coal, hydropower, timber</Naturalresources>
+<Population>51964999</Population>
+<Populationgrowthrate>3.19% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.74 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 50%, Protestant 20%, Kimbanguist 10%, Muslim 10%, other syncretic sects and indigenous beliefs 10%</Religions>
+<Countryname>Democratic Republic of the Congo </Countryname>
+<Capital>Kinshasa</Capital>
+<Flagdescription>light blue with a large yellow five-pointed star in the center and a columnar arrangement of six small yellow five-pointed stars along the hoist side</Flagdescription>
+<GDP>purchasing power parity - $35.7 billion (1999 est.)</GDP>
+<Industries>mining, mineral processing, consumer products (including textiles, footwear, cigarettes, processed foods and beverages), cement, diamonds</Industries>
+<Exports>$530 million (f.o.b., 1998 est.)</Exports>
+<Imports>$460 million (f.o.b., 1998 est.)</Imports>
+<Currency>Congolese franc (CF)</Currency>
+<Airports>232 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis, mostly for domestic consumption</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Asia, bordering the East China Sea, Korea Bay, Yellow Sea, and South China Sea, between North Korea and Vietnam</Location>
+<Geographiccoordinates>35 00 N, 105 00 E</Geographiccoordinates>
+<Area>9596960</Area>
+<Climate>extremely diverse; tropical in south to subarctic in north</Climate>
+<Naturalresources>coal, iron ore, petroleum, natural gas, mercury, tin, tungsten, antimony, manganese, molybdenum, vanadium, magnetite, aluminum, lead, zinc, uranium, hydropower potential (world's largest)</Naturalresources>
+<Population>1261832482</Population>
+<Populationgrowthrate>0.9% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.15 male(s)/female
+under 15 years: 1.1 male(s)/female
+15-64 years: 1.06 male(s)/female
+65 years and over: 0.88 male(s)/female
+total population: 1.06 male(s)/female (2000 est.)</Sexratio>
+<Religions>Daoist (Taoist), Buddhist, Muslim 2%-3%, Christian 1% (est.)
+note: officially atheist</Religions>
+<Countryname>China </Countryname>
+<Capital>Beijing</Capital>
+<Flagdescription>red with a large yellow five-pointed star and four smaller yellow five-pointed stars (arranged in a vertical arc toward the middle of the flag) in the upper hoist-side corner</Flagdescription>
+<GDP>purchasing power parity - $4.8 trillion (1999 est.)</GDP>
+<Industries>iron and steel, coal, machine building, armaments, textiles and apparel, petroleum, cement, chemical fertilizers, footwear, toys, food processing, automobiles, consumer electronics, telecommunications</Industries>
+<Exports>$194.9 billion (f.o.b., 1999)</Exports>
+<Imports>$165.8 billion (c.i.f., 1999)</Imports>
+<Currency>1 yuan = 10 jiao</Currency>
+<Airports>206 (1996 est.)</Airports>
+<Illicitdrugs>major transshipment point for heroin produced in the Golden Triangle; growing domestic drug abuse problem</Illicitdrugs>
+</record>
+<record>
+<Location>Southern South America, bordering the South Atlantic Ocean and South Pacific Ocean, between Argentina and Peru</Location>
+<Geographiccoordinates>30 00 S, 71 00 W</Geographiccoordinates>
+<Area>756950</Area>
+<Climate>temperate; desert in north; Mediterranean in central region; cool and damp in south</Climate>
+<Naturalresources>copper, timber, iron ore, nitrates, precious metals, molybdenum, hydropower</Naturalresources>
+<Population>15153797</Population>
+<Populationgrowthrate>1.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 89%, Protestant 11%, Jewish NEGL</Religions>
+<Countryname>Chile </Countryname>
+<Capital>Santiago</Capital>
+<Flagdescription>two equal horizontal bands of white (top) and red; there is a blue square the same height as the white band at the hoist-side end of the white band; the square bears a white five-pointed star in the center; design was based on the US flag</Flagdescription>
+<GDP>purchasing power parity - $185.1 billion (1999 est.)</GDP>
+<Industries>copper, other minerals, foodstuffs, fish processing, iron and steel, wood and wood products, transport equipment, cement, textiles</Industries>
+<Exports>$15.6 billion (f.o.b., 1999)</Exports>
+<Imports>$13.9 billion (c.i.f., 1999)</Imports>
+<Currency>1 Chilean peso (Ch$) = 100 centavos</Currency>
+<Airports>370 (1999 est.)</Airports>
+<Illicitdrugs>a growing transshipment country for cocaine destined for the US and Europe; economic prosperity has made Chile more attractive to traffickers seeking to launder drug profits; imported precursors passed on to Bolivia; domestic cocaine consumption is rising</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, island group in Caribbean Sea, nearly one-half of the way from Cuba to Honduras</Location>
+<Geographiccoordinates>19 30 N, 80 30 W</Geographiccoordinates>
+<Area>259</Area>
+<Climate>tropical marine; warm, rainy summers (May to October) and cool, relatively dry winters (November to April)</Climate>
+<Naturalresources>fish, climate and beaches that foster tourism</Naturalresources>
+<Population>34763</Population>
+<Populationgrowthrate>2.22% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 0.86 male(s)/female
+under 15 years: 0.94 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.85 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>United Church (Presbyterian and Congregational), Anglican, Baptist, Roman Catholic, Church of God, other Protestant</Religions>
+<Countryname>Cayman Islands </Countryname>
+<Capital>George Town</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and the Caymanian coat of arms on a white disk centered on the outer half of the flag; the coat of arms includes a pineapple and turtle above a shield with three stars (representing the three islands) and a scroll at the bottom bearing the motto HE HATH FOUNDED IT UPON THE SEAS</Flagdescription>
+<GDP>purchasing power parity - $930 million (1997 est.)</GDP>
+<Industries>tourism, banking, insurance and finance, construction, construction materials, furniture</Industries>
+<Exports>$2.17 million (1997)</Exports>
+<Imports>$432 million (1997)</Imports>
+<Currency>1 Caymanian dollar (CI$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+<Illicitdrugs>vulnerable to drug money laundering and drug transshipment</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, group of islands in the Indian Ocean, south of Indonesia, about one-half of the way from Australia to Sri Lanka</Location>
+<Geographiccoordinates>12 30 S, 96 50 E</Geographiccoordinates>
+<Area>14</Area>
+<Climate>pleasant, modified by the southeast trade winds for about nine months of the year; moderate rainfall</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>635</Population>
+<Populationgrowthrate>-0.21% (2000 est.)</Populationgrowthrate>
+<Religions>Sunni Muslim 57%, Christian 22%, other 21% (1981 est.)</Religions>
+<Countryname>Cocos (Keeling) Islands </Countryname>
+<Capital>West Island</Capital>
+<Flagdescription>the flag of Australia is used</Flagdescription>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>copra products and tourism</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the Bight of Biafra, between Equatorial Guinea and Nigeria</Location>
+<Geographiccoordinates>6 00 N, 12 00 E</Geographiccoordinates>
+<Area>475440</Area>
+<Climate>varies with terrain, from tropical along coast to semiarid and hot in north</Climate>
+<Naturalresources>petroleum, bauxite, iron ore, timber, hydropower</Naturalresources>
+<Population>15421937</Population>
+<Populationgrowthrate>2.47% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.86 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 40%, Christian 40%, Muslim 20%</Religions>
+<Countryname>Cameroon </Countryname>
+<Capital>Yaounde</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), red, and yellow with a yellow five-pointed star centered in the red band; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $31.5 billion (1999 est.)</GDP>
+<Industries>petroleum production and refining, food processing, light consumer goods, textiles, lumber</Industries>
+<Exports>$2 billion (f.o.b., 1999)</Exports>
+<Imports>$1.5 billion (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>50 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, group of islands in the Mozambique Channel, about two-thirds of the way between northern Madagascar and northern Mozambique</Location>
+<Geographiccoordinates>12 10 S, 44 15 E</Geographiccoordinates>
+<Area>2170</Area>
+<Climate>tropical marine; rainy season (November to May)</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>578400</Population>
+<Populationgrowthrate>3.05% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.91 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 98%, Roman Catholic 2%</Religions>
+<Countryname>Comoros </Countryname>
+<Capital>Moroni</Capital>
+<Flagdescription>green with a white crescent in the center of the field, its points facing downward; there are four white five-pointed stars placed in a line between the points of the crescent; the crescent, stars, and color green are traditional symbols of Islam; the four stars represent the four main islands of the archipelago - Mwali, Njazidja, Nzwani, and Mayotte (a territorial collectivity of France, but claimed by Comoros); the design, the most recent of several, is described in the constitution approved by referendum on 7 June 1992</Flagdescription>
+<GDP>purchasing power parity - $410 million (1998 est.)</GDP>
+<Industries>tourism, perfume distillation, textiles, furniture, jewelry, construction materials, soft drinks</Industries>
+<Exports>$9.3 million (f.o.b., 1998 est.)</Exports>
+<Imports>$49.5 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 Comoran franc (CF) = 100 centimes</Currency>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern South America, bordering the Caribbean Sea, between Panama and Venezuela, and bordering the North Pacific Ocean, between Ecuador and Panama</Location>
+<Geographiccoordinates>4 00 N, 72 00 W</Geographiccoordinates>
+<Area>1138910</Area>
+<Climate>tropical along coast and eastern plains; cooler in highlands</Climate>
+<Naturalresources>petroleum, natural gas, coal, iron ore, nickel, gold, copper, emeralds, hydropower</Naturalresources>
+<Population>39685655</Population>
+<Populationgrowthrate>1.68% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.82 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%</Religions>
+<Countryname>Colombia </Countryname>
+<Capital>Bogota</Capital>
+<Flagdescription>three horizontal bands of yellow (top, double-width), blue, and red; similar to the flag of Ecuador, which is longer and bears the Ecuadorian coat of arms superimposed in the center</Flagdescription>
+<GDP>purchasing power parity - $245.1 billion (1999 est.)</GDP>
+<Industries>textiles, food processing, oil, clothing and footwear, beverages, chemicals, cement; gold, coal, emeralds</Industries>
+<Exports>$11.5 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$10 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Colombian peso (Col$) = 100 centavos</Currency>
+<Airports>1,101 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of coca, opium poppies, and cannabis; world's leading coca cultivator (cultivation of coca in 1998 - 101,500 hectares, a 28% increase over 1997); cultivation of opium in 1998 remained steady at 6,600 hectares; potential production of opium in 1997 - 66 metric tons, a 5% increase over 1996; the world's largest processor of coca derivatives into cocaine; supplier of cocaine to the US and other international drug markets, and an important supplier of heroin to the US market; active aerial eradication program</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, islands in the North Pacific Ocean, about three-quarters of the way from Hawaii to the Philippines</Location>
+<Geographiccoordinates>15 12 N, 145 45 E</Geographiccoordinates>
+<Area>477</Area>
+<Climate>tropical marine; moderated by northeast trade winds, little seasonal temperature variation; dry season December to June, rainy season July to October</Climate>
+<Naturalresources>arable land, fish</Naturalresources>
+<Population>71912</Population>
+<Populationgrowthrate>3.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.96 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian (Roman Catholic majority, although traditional beliefs and taboos may still be found)</Religions>
+<Countryname>Northern Mariana Islands </Countryname>
+<Capital>Saipan</Capital>
+<Flagdescription>blue, with a white, five-pointed star superimposed on the gray silhouette of a latte stone (a traditional foundation stone used in building) in the center, surrounded by a wreath</Flagdescription>
+<GDP>purchasing power parity - $524 million (1996 est.)
+note: GDP numbers reflect US spending</GDP>
+<Industries>tourism, construction, garments, handicrafts</Industries>
+<Exports>$1 billion (1998)</Exports>
+<Imports>$NA</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>6 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, islands in the Coral Sea, northeast of Australia</Location>
+<Geographiccoordinates>18 00 S, 152 00 E</Geographiccoordinates>
+<Area></Area>
+<Climate>tropical</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population></Population>
+<Countryname>Coral Sea Islands </Countryname>
+<Flagdescription>the flag of Australia is used</Flagdescription>
+</record>
+<record>
+<Location>Middle America, bordering both the Caribbean Sea and the North Pacific Ocean, between Nicaragua and Panama</Location>
+<Geographiccoordinates>10 00 N, 84 00 W</Geographiccoordinates>
+<Area>51100</Area>
+<Climate>tropical and subtropical; dry season (December to April); rainy season (May to November); cooler in highlands</Climate>
+<Naturalresources>hydropower</Naturalresources>
+<Population>3710558</Population>
+<Populationgrowthrate>1.69% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.87 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 85%, Evangelical Protestant, approximately 14%, other less than 1%</Religions>
+<Countryname>Costa Rica </Countryname>
+<Capital>San Jose</Capital>
+<Flagdescription>five horizontal bands of blue (top), white, red (double width), white, and blue, with the coat of arms in a white disk on the hoist side of the red band</Flagdescription>
+<GDP>purchasing power parity - $26 billion (1999 est.)</GDP>
+<Industries>microprocessors, food processing, textiles and clothing, construction materials, fertilizer, plastic products</Industries>
+<Exports>$6.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$6.5 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Costa Rican colon (C) = 100 centimos</Currency>
+<Airports>155 (1999 est.)</Airports>
+<Illicitdrugs>transshipment country for cocaine and heroin from South America; illicit production of cannabis on small, scattered plots; domestic cocaine consumption has risen</Illicitdrugs>
+</record>
+<record>
+<Location>Central Africa, north of Democratic Republic of the Congo</Location>
+<Geographiccoordinates>7 00 N, 21 00 E</Geographiccoordinates>
+<Area>622984</Area>
+<Climate>tropical; hot, dry winters; mild to hot, wet summers</Climate>
+<Naturalresources>diamonds, uranium, timber, gold, oil, hydropower</Naturalresources>
+<Population>3512751</Population>
+<Populationgrowthrate>1.77% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 24%, Protestant 25%, Roman Catholic 25%, Muslim 15%, other 11%
+note: animistic beliefs and practices strongly influence the Christian majority</Religions>
+<Countryname>Central African Republic </Countryname>
+<Capital>Bangui</Capital>
+<Flagdescription>four equal horizontal bands of blue (top), white, green, and yellow with a vertical red band in center; there is a yellow five-pointed star on the hoist side of the blue band</Flagdescription>
+<GDP>purchasing power parity - $5.8 billion (1999 est.)</GDP>
+<Industries>diamond mining, sawmills, breweries, textiles, footwear, assembly of bicycles and motorcycles</Industries>
+<Exports>$195 million (f.o.b., 1999)</Exports>
+<Imports>$170 million (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>52 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and the North Atlantic Ocean, south of Florida</Location>
+<Geographiccoordinates>21 30 N, 80 00 W</Geographiccoordinates>
+<Area>110860</Area>
+<Climate>tropical; moderated by trade winds; dry season (November to April); rainy season (May to October)</Climate>
+<Naturalresources>cobalt, nickel, iron ore, copper, manganese, salt, timber, silica, petroleum, arable land</Naturalresources>
+<Population>11141997</Population>
+<Populationgrowthrate>0.39% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.87 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>nominally 85% Roman Catholic prior to CASTRO assuming power; Protestants, Jehovah's Witnesses, Jews, and Santeria are also represented</Religions>
+<Countryname>Cuba </Countryname>
+<Capital>Havana</Capital>
+<Flagdescription>five equal horizontal bands of blue (top and bottom) alternating with white; a red equilateral triangle based on the hoist side bears a white, five-pointed star in the center</Flagdescription>
+<GDP>purchasing power parity - $18.6 billion (1999 est.)</GDP>
+<Industries>sugar, petroleum, food, tobacco, textiles, chemicals, paper and wood products, metals (particularly nickel), cement, fertilizers, consumer goods, agricultural machinery</Industries>
+<Exports>$1.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.2 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Cuban peso (Cu$) = 100 centavos</Currency>
+<Airports>170 (1999 est.)</Airports>
+<Illicitdrugs>territorial waters and air space serve as transshipment zone for cocaine bound for the US and Europe; established the death penalty for certain drug-related crimes in 1999</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, group of islands in the North Atlantic Ocean, west of Senegal</Location>
+<Geographiccoordinates>16 00 N, 24 00 W</Geographiccoordinates>
+<Area>4033</Area>
+<Climate>temperate; warm, dry summer; precipitation meager and very erratic</Climate>
+<Naturalresources>salt, basalt rock, pozzuolana (a siliceous volcanic ash used to produce hydraulic cement), limestone, kaolin, fish</Naturalresources>
+<Population>401343</Population>
+<Populationgrowthrate>0.98% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.65 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic (infused with indigenous beliefs); Protestant (mostly Church of the Nazarene)</Religions>
+<Countryname>Cape Verde </Countryname>
+<Capital>Praia</Capital>
+<Flagdescription>three horizontal bands of light blue (top, double width), white (with a horizontal red stripe in the middle third), and light blue; a circle of 10 yellow five-pointed stars is centered on the hoist end of the red stripe and extends into the upper and lower blue bands</Flagdescription>
+<GDP>purchasing power parity - $618 million (1999 est.)</GDP>
+<Industries>food and beverages, fish processing, shoes and garments, salt mining, ship repair</Industries>
+<Exports>$38 million (f.o.b., 1999 est.)</Exports>
+<Imports>$225 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 Cape Verdean escudo (CVEsc) = 100 centavos</Currency>
+<Airports>6 (1999 est.)</Airports>
+<Illicitdrugs>used as a transshipment point for illicit drugs moving from Latin America and Africa destined for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, group of islands in the South Pacific Ocean, about one-half of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>21 14 S, 159 46 W</Geographiccoordinates>
+<Area>240</Area>
+<Climate>tropical; moderated by trade winds</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>20407</Population>
+<Populationgrowthrate>1.6% (2000 est.)</Populationgrowthrate>
+<Religions>Christian (majority of populace are members of the Cook Islands Christian Church)</Religions>
+<Countryname>Cook Islands </Countryname>
+<Capital>Avarua</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and a large circle of 15 white five-pointed stars (one for every island) centered in the outer half of the flag</Flagdescription>
+<GDP>purchasing power parity - $112 million (1998 est.)</GDP>
+<Industries>fruit processing, tourism</Industries>
+<Exports>$4.2 million (f.o.b., 1994 est.)</Exports>
+<Imports>$85 million (c.i.f., 1994)</Imports>
+<Currency>1 New Zealand dollar (NZ$) = 100 cents</Currency>
+<Airports>7 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, island in the Mediterranean Sea, south of Turkey</Location>
+<Geographiccoordinates>35 00 N, 33 00 E</Geographiccoordinates>
+<Area>9250</Area>
+<Climate>temperate, Mediterranean with hot, dry summers and cool, winters</Climate>
+<Naturalresources>copper, pyrites, asbestos, gypsum, timber, salt, marble, clay earth pigment</Naturalresources>
+<Population>758363</Population>
+<Populationgrowthrate>0.6% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.77 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Greek Orthodox 78%, Muslim 18%, Maronite, Armenian Apostolic, and other 4%</Religions>
+<Countryname>Cyprus </Countryname>
+<Capital>Nicosia
+note: the Turkish Cypriot area's capital is Lefkosa (Nicosia)</Capital>
+<Flagdescription>white with a copper-colored silhouette of the island (the name Cyprus is derived from the Greek word for copper) above two green crossed olive branches in the center of the flag; the branches symbolize the hope for peace and reconciliation between the Greek and Turkish communities
+note: the Turkish Cypriot flag has a horizontal red stripe at the top and bottom between which is a red crescent and red star on a white field</Flagdescription>
+<GDP>Greek Cypriot area: purchasing power parity - $9 billion; Turkish Cypriot area: purchasing power parity - $820 million (1998 est.)</GDP>
+<Industries>food, beverages, textiles, chemicals, metal products, tourism, wood products</Industries>
+<Exports>Greek Cypriot area: $1.1 billion (f.o.b., 1998 est.); Turkish Cypriot area: $63.9 million (f.o.b., 1998)</Exports>
+<Imports>Greek Cypriot area: $3.5 billion (f.o.b., 1998 est.); Turkish Cypriot area: $374 million (f.o.b., 1997)</Imports>
+<Currency>Greek Cypriot area: 1 Cypriot pound = 100 cents; Turkish Cypriot area: 1 Turkish lira (TL) = 100 kurus</Currency>
+<Airports>15 (1999 est.)</Airports>
+<Illicitdrugs>minor transit point for heroin and hashish via air routes and container traffic to Europe, especially from Lebanon and Turkey; some cocaine transits as well</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Europe, bordering the Baltic Sea and the North Sea, on a peninsula north of Germany</Location>
+<Geographiccoordinates>56 00 N, 10 00 E</Geographiccoordinates>
+<Area>43094</Area>
+<Climate>temperate; humid and overcast; mild, windy winters and cool summers</Climate>
+<Naturalresources>petroleum, natural gas, fish, salt, limestone, stone, gravel and sand</Naturalresources>
+<Population>5336394</Population>
+<Populationgrowthrate>0.31% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran 97%, other Protestant and Roman Catholic, other</Religions>
+<Countryname>Denmark </Countryname>
+<Capital>Copenhagen</Capital>
+<Flagdescription>red with a white cross that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side, and that design element of the Dannebrog (Danish flag) was subsequently adopted by the other Nordic countries of Finland, Iceland, Norway, and Sweden</Flagdescription>
+<GDP>purchasing power parity - $127.7 billion (1999 est.)</GDP>
+<Industries>food processing, machinery and equipment, textiles and clothing, chemical products, electronics, construction, furniture, and other wood products, shipbuilding</Industries>
+<Exports>$49.5 billion (f.o.b., 1999)</Exports>
+<Imports>$43.9 billion (f.o.b., 1999)</Imports>
+<Currency>1 Danish krone (DKr) = 100 oere</Currency>
+<Airports>118 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Africa, bordering the Gulf of Aden and the Red Sea, between Eritrea and Somalia</Location>
+<Geographiccoordinates>11 30 N, 43 00 E</Geographiccoordinates>
+<Area>22000</Area>
+<Climate>desert; torrid, dry</Climate>
+<Naturalresources>geothermal areas</Naturalresources>
+<Population>451442</Population>
+<Populationgrowthrate>1.45% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 1.12 male(s)/female
+65 years and over: 1.08 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 94%, Christian 6%</Religions>
+<Countryname>Djibouti </Countryname>
+<Capital>Djibouti</Capital>
+<Flagdescription>two equal horizontal bands of light blue (top) and light green with a white isosceles triangle based on the hoist side bearing a red five-pointed star in the center</Flagdescription>
+<GDP>purchasing power parity - $550 million (1999 est.)</GDP>
+<Industries>limited to a few small-scale enterprises, such as dairy products and mineral-water bottling</Industries>
+<Exports>$260 million (f.o.b., 1999 est.)</Exports>
+<Imports>$440 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 Djiboutian franc (DF) = 100 centimes</Currency>
+<Airports>12 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and the North Atlantic Ocean, about one-half of the way from Puerto Rico to Trinidad and Tobago</Location>
+<Geographiccoordinates>15 25 N, 61 20 W</Geographiccoordinates>
+<Area>754</Area>
+<Climate>tropical; moderated by northeast trade winds; heavy rainfall</Climate>
+<Naturalresources>timber, hydropower, arable land</Naturalresources>
+<Population>71540</Population>
+<Populationgrowthrate>-1.14% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 77%, Protestant 15% (Methodist 5%, Pentecostal 3%, Seventh-Day Adventist 3%, Baptist 2%, other 2%), none 2%, other 6%</Religions>
+<Countryname>Dominica </Countryname>
+<Capital>Roseau</Capital>
+<Flagdescription>green, with a centered cross of three equal bands - the vertical part is yellow (hoist side), black, and white and the horizontal part is yellow (top), black, and white; superimposed in the center of the cross is a red disk bearing a sisserou parrot encircled by 10 green, five-pointed stars edged in yellow; the 10 stars represent the 10 administrative divisions (parishes)</Flagdescription>
+<GDP>purchasing power parity - $225 million (1998 est.)</GDP>
+<Industries>soap, coconut oil, tourism, copra, furniture, cement blocks, shoes</Industries>
+<Exports>$60.8 million (1998)</Exports>
+<Imports>$120.4 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>2 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for narcotics bound for the US and Europe; minor cannabis producer; banking industry is vulnerable to money laundering</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, island in the South Pacific Ocean, about one-half of the way from Hawaii to the Cook Islands</Location>
+<Geographiccoordinates>0 22 S, 160 03 W</Geographiccoordinates>
+<Area>4</Area>
+<Climate>tropical; scant rainfall, constant wind, burning sun</Climate>
+<Naturalresources>guano (deposits worked until late 1800s)</Naturalresources>
+<Population></Population>
+<Countryname>Jarvis Island </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+</record>
+<record>
+<Location>Caribbean, eastern two-thirds of the island of Hispaniola, between the Caribbean Sea and the North Atlantic Ocean, east of Haiti</Location>
+<Geographiccoordinates>19 00 N, 70 40 W</Geographiccoordinates>
+<Area>48730</Area>
+<Climate>tropical maritime; little seasonal temperature variation; seasonal variation in rainfall</Climate>
+<Naturalresources>nickel, bauxite, gold, silver</Naturalresources>
+<Population>8442533</Population>
+<Populationgrowthrate>1.64% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.91 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95%</Religions>
+<Countryname>Dominican Republic </Countryname>
+<Capital>Santo Domingo</Capital>
+<Flagdescription>a centered white cross that extends to the edges divides the flag into four rectangles - the top ones are blue (hoist side) and red, and the bottom ones are red (hoist side) and blue; a small coat of arms is at the center of the cross</Flagdescription>
+<GDP>purchasing power parity - $43.7 billion (1999 est.)</GDP>
+<Industries>tourism, sugar processing, ferronickel and gold mining, textiles, cement, tobacco</Industries>
+<Exports>$5.1 billion (f.o.b., 1999)</Exports>
+<Imports>$8.2 billion (f.o.b., 1999)</Imports>
+<Currency>1 Dominican peso (RD$) = 100 centavos</Currency>
+<Airports>28 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American drugs destined for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Western South America, bordering the Pacific Ocean at the Equator, between Colombia and Peru</Location>
+<Geographiccoordinates>2 00 S, 77 30 W</Geographiccoordinates>
+<Area>283560</Area>
+<Climate>tropical along coast, becoming cooler inland at higher elevations; tropical in Amazonian jungle lowlands</Climate>
+<Naturalresources>petroleum, fish, timber, hydropower</Naturalresources>
+<Population>12920092</Population>
+<Populationgrowthrate>2.04% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.87 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95%</Religions>
+<Countryname>Ecuador </Countryname>
+<Capital>Quito</Capital>
+<Flagdescription>three horizontal bands of yellow (top, double width), blue, and red with the coat of arms superimposed at the center of the flag; similar to the flag of Colombia which is shorter and does not bear a coat of arms</Flagdescription>
+<GDP>purchasing power parity - $54.5 billion (1999 est.)</GDP>
+<Industries>petroleum, food processing, textiles, metal work, paper products, wood products, chemicals, plastics, fishing, lumber</Industries>
+<Exports>$4.1 billion (f.o.b., 1999)</Exports>
+<Imports>$2.8 billion (c.i.f., 1999)</Imports>
+<Currency>1 sucre (S/) = 100 centavos</Currency>
+<Airports>182 (1999 est.)</Airports>
+<Illicitdrugs>significant transit country for cocaine and derivatives of coca originating in Colombia and Peru; importer of precursor chemicals used in production of illicit narcotics; important money-laundering hub; increased activity on frontiers by trafficking groups and Colombian insurgents</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Africa, bordering the Mediterranean Sea, between Libya and the Gaza Strip</Location>
+<Geographiccoordinates>27 00 N, 30 00 E</Geographiccoordinates>
+<Area>1001450</Area>
+<Climate>desert; hot, dry summers with moderate winters</Climate>
+<Naturalresources>petroleum, natural gas, iron ore, phosphates, manganese, limestone, gypsum, talc, asbestos, lead, zinc</Naturalresources>
+<Population>68359979</Population>
+<Populationgrowthrate>1.72% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.79 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim (mostly Sunni) 94%, Coptic Christian and other 6%</Religions>
+<Countryname>Egypt </Countryname>
+<Capital>Cairo</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and black with the national emblem (a shield superimposed on a golden eagle facing the hoist side above a scroll bearing the name of the country in Arabic) centered in the white band; similar to the flag of Yemen, which has a plain white band; also similar to the flag of Syria, which has two green stars, and to the flag of Iraq, which has three green stars (plus an Arabic inscription) in a horizontal line centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $200 billion (1999 est.)</GDP>
+<Industries>textiles, food processing, tourism, chemicals, petroleum, construction, cement, metals</Industries>
+<Exports>$4.6 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$15.8 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Egyptian pound = 100 piasters</Currency>
+<Airports>90 (1999 est.)</Airports>
+<Illicitdrugs>a transit point for Southwest Asian and Southeast Asian heroin and opium moving to Europe, Africa, and the US; popular transit stop for Nigerian couriers</Illicitdrugs>
+</record>
+<record>
+<Location>Western Europe, occupying five-sixths of the island of Ireland in the North Atlantic Ocean, west of Great Britain</Location>
+<Geographiccoordinates>53 00 N, 8 00 W</Geographiccoordinates>
+<Area>70280</Area>
+<Climate>temperate maritime; modified by North Atlantic Current; mild winters, cool summers; consistently humid; overcast about half the time</Climate>
+<Naturalresources>zinc, lead, natural gas, barite, copper, gypsum, limestone, dolomite, peat, silver</Naturalresources>
+<Population>3797257</Population>
+<Populationgrowthrate>1.16% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 91.6%, Church of Ireland 2.5%, other 5.9% (1998)</Religions>
+<Countryname>Ireland </Countryname>
+<Capital>Dublin</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), white, and orange; similar to the flag of Cote d'Ivoire, which is shorter and has the colors reversed - orange (hoist side), white, and green; also similar to the flag of Italy, which is shorter and has colors of green (hoist side), white, and red</Flagdescription>
+<GDP>purchasing power parity - $73.7 billion (1999 est.)</GDP>
+<Industries>food products, brewing, textiles, clothing; chemicals, pharmaceuticals, machinery, transportation equipment, glass and crystal; software</Industries>
+<Exports>$66 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$44 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Irish pound = 100 pence</Currency>
+<Airports>44 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for and consumer of hashish from North Africa to the UK and Netherlands and of European-produced synthetic drugs; minor transshipment point for heroin and cocaine destined for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the Bight of Biafra, between Cameroon and Gabon</Location>
+<Geographiccoordinates>2 00 N, 10 00 E</Geographiccoordinates>
+<Area>28051</Area>
+<Climate>tropical; always hot, humid</Climate>
+<Naturalresources>oil, petroleum, timber, small unexploited deposits of gold, manganese, uranium</Naturalresources>
+<Population>474214</Population>
+<Populationgrowthrate>2.47% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>nominally Christian and predominantly Roman Catholic, pagan practices</Religions>
+<Countryname>Equatorial Guinea </Countryname>
+<Capital>Malabo</Capital>
+<Flagdescription>three equal horizontal bands of green (top), white, and red with a blue isosceles triangle based on the hoist side and the coat of arms centered in the white band; the coat of arms has six yellow six-pointed stars (representing the mainland and five offshore islands) above a gray shield bearing a silk-cotton tree and below which is a scroll with the motto UNIDAD, PAZ, JUSTICIA (Unity, Peace, Justice)</Flagdescription>
+<GDP>purchasing power parity - $960 million (1999 est.)</GDP>
+<Industries>petroleum, fishing, sawmilling, natural gas</Industries>
+<Exports>$555 million (f.o.b., 1999)</Exports>
+<Imports>$300 million (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Europe, bordering the Baltic Sea and Gulf of Finland, between Latvia and Russia</Location>
+<Geographiccoordinates>59 00 N, 26 00 E</Geographiccoordinates>
+<Area>45226</Area>
+<Climate>maritime, wet, moderate winters, cool summers</Climate>
+<Naturalresources>shale oil (kukersite), peat, phosphorite, amber, cambrian blue clay, limestone, dolomite, arable land</Naturalresources>
+<Population>1431471</Population>
+<Populationgrowthrate>-0.59% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.48 male(s)/female
+total population: 0.87 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran, Russian Orthodox, Estonian Orthodox, Baptist, Methodist, Seventh-Day Adventist, Roman Catholic, Pentecostal, Word of Life, Jewish</Religions>
+<Countryname>Estonia </Countryname>
+<Capital>Tallinn</Capital>
+<Flagdescription>pre-1940 flag restored by Supreme Soviet in May 1990 - three equal horizontal bands of blue (top), black, and white</Flagdescription>
+<GDP>purchasing power parity - $7.9 billion (1999 est.)</GDP>
+<Industries>oil shale, shipbuilding, phosphates, electric motors, excavators, cement, furniture, clothing, textiles, paper, shoes, apparel</Industries>
+<Exports>$2.5 billion (f.o.b., 1999)</Exports>
+<Imports>$3.4 billion (f.o.b., 1999)</Imports>
+<Currency>1 Estonian kroon (EEK) = 100 sents</Currency>
+<Airports>5 (1997 est.)</Airports>
+<Illicitdrugs>transshipment point for opiates and cannabis from Southwest Asia and the Caucasus via Russia, cocaine from Latin America to Western Europe and Scandinavia, and synthetic drugs from Western Europe to Scandinavia; possible precursor manufacturing and/or trafficking</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, bordering the Red Sea, between Djibouti and Sudan</Location>
+<Geographiccoordinates>15 00 N, 39 00 E</Geographiccoordinates>
+<Area>121320</Area>
+<Climate>hot, dry desert strip along Red Sea coast; cooler and wetter in the central highlands (up to 61 cm of rainfall annually); semiarid in western hills and lowlands; rainfall heaviest during June-September except in coastal desert</Climate>
+<Naturalresources>gold, potash, zinc, copper, salt, possibly oil and natural gas, fish</Naturalresources>
+<Population>4135933</Population>
+<Populationgrowthrate>3.86% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 1.04 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim, Coptic Christian, Roman Catholic, Protestant</Religions>
+<Countryname>Eritrea </Countryname>
+<Capital>Asmara (formerly Asmera)</Capital>
+<Flagdescription>red isosceles triangle (based on the hoist side) dividing the flag into two right triangles; the upper triangle is green, the lower one is blue; a gold wreath encircling a gold olive branch is centered on the hoist side of the red triangle</Flagdescription>
+<GDP>purchasing power parity - $2.9 billion (1999 est.)</GDP>
+<Industries>food processing, beverages, clothing and textiles</Industries>
+<Exports>$52.9 million (f.o.b., 1997)</Exports>
+<Imports>$489.4 million (c.i.f., 1997)</Imports>
+<Currency>1 nafka = 100 cents</Currency>
+<Airports>21 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle America, bordering the North Pacific Ocean, between Guatemala and Honduras</Location>
+<Geographiccoordinates>13 50 N, 88 55 W</Geographiccoordinates>
+<Area>21040</Area>
+<Climate>tropical; rainy season (May to October); dry season (November to April); tropical on coast; temperate in uplands</Climate>
+<Naturalresources>hydropower, geothermal power, petroleum, arable land</Naturalresources>
+<Population>6122515</Population>
+<Populationgrowthrate>1.87% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.83 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 86%
+note: there is extensive activity by Protestant groups throughout the country; by the end of 1992, there were an estimated 1 million Protestant evangelicals in El Salvador</Religions>
+<Countryname>El Salvador </Countryname>
+<Capital>San Salvador</Capital>
+<Flagdescription>three equal horizontal bands of blue (top), white, and blue with the national coat of arms centered in the white band; the coat of arms features a round emblem encircled by the words REPUBLICA DE EL SALVADOR EN LA AMERICA CENTRAL; similar to the flag of Nicaragua, which has a different coat of arms centered in the white band - it features a triangle encircled by the words REPUBLICA DE NICARAGUA on top and AMERICA CENTRAL on the bottom; also similar to the flag of Honduras, which has five blue stars arranged in an X pattern centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $18.1 billion (1999 est.)</GDP>
+<Industries>food processing, beverages, petroleum, chemicals, fertilizer, textiles, furniture, light metals</Industries>
+<Exports>$2.5 billion (f.o.b., 1999)</Exports>
+<Imports>$4.15 billion (c.i.f., 1999)</Imports>
+<Currency>1 Salvadoran colon (C) = 100 centavos</Currency>
+<Airports>85 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine; marijuana produced for local consumption; domestic drug abuse on the rise</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, west of Somalia</Location>
+<Geographiccoordinates>8 00 N, 38 00 E</Geographiccoordinates>
+<Area>1127127</Area>
+<Climate>tropical monsoon with wide topographic-induced variation</Climate>
+<Naturalresources>small reserves of gold, platinum, copper, potash, natural gas, hydropower</Naturalresources>
+<Population>64117452</Population>
+<Populationgrowthrate>2.76% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 45%-50%, Ethiopian Orthodox 35%-40%, animist 12%, other 3%-8%</Religions>
+<Countryname>Ethiopia </Countryname>
+<Capital>Addis Ababa</Capital>
+<Flagdescription>three equal horizontal bands of green (top), yellow, and red with a yellow pentagram and single yellow rays emanating from the angles between the points on a light blue disk centered on the three bands; Ethiopia is the oldest independent country in Africa, and the colors of her flag were so often adopted by other African countries upon independence that they became known as the pan-African colors</Flagdescription>
+<GDP>purchasing power parity - $33.3 billion (1999 est.)</GDP>
+<Industries>food processing, beverages, textiles, chemicals, metals processing, cement</Industries>
+<Exports>$420 million (f.o.b., 1998)</Exports>
+<Imports>$1.25 billion (f.o.b., 1998 est.)</Imports>
+<Currency>1 birr (Br) = 100 cents</Currency>
+<Airports>85 (1999 est.)</Airports>
+<Illicitdrugs>transit hub for heroin originating in Southwest and Southeast Asia and destined for Europe and North America as well as cocaine destined for markets in southern Africa; cultivates qat (chat) for local use and regional export, principally to Djibouti and Somalia</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, island in the Mozambique Channel, about one-half of the way from southern Madagascar to southern Mozambique</Location>
+<Geographiccoordinates>22 20 S, 40 22 E</Geographiccoordinates>
+<Area>28</Area>
+<Climate>tropical</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population></Population>
+<Countryname>Europa Island </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Europe, southeast of Germany</Location>
+<Geographiccoordinates>49 45 N, 15 30 E</Geographiccoordinates>
+<Area>78866</Area>
+<Climate>temperate; cool summers; cold, cloudy, humid winters</Climate>
+<Naturalresources>hard coal, soft coal, kaolin, clay, graphite, timber</Naturalresources>
+<Population>10272179</Population>
+<Populationgrowthrate>-0.08% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>atheist 39.8%, Roman Catholic 39.2%, Protestant 4.6%, Orthodox 3%, other 13.4%</Religions>
+<Countryname>Czech Republic </Countryname>
+<Capital>Prague</Capital>
+<Flagdescription>two equal horizontal bands of white (top) and red with a blue isosceles triangle based on the hoist side (almost identical to the flag of the former Czechoslovakia)</Flagdescription>
+<GDP>purchasing power parity - $120.8 billion (1999 est.)</GDP>
+<Industries>fuels, ferrous metallurgy, machinery and equipment, coal, motor vehicles, glass, armaments</Industries>
+<Exports>$26.9 billion (f.o.b., 1999)</Exports>
+<Imports>$29 billion (f.o.b., 1999)</Imports>
+<Currency>1 koruna (Kc) = 100 haleru</Currency>
+<Airports>114 (1999 est.)</Airports>
+<Illicitdrugs>major transshipment point for Southwest Asian heroin and minor transit point for Latin American cocaine to Western Europe; domestic consumption - especially of locally produced synthetic drugs - on the rise</Illicitdrugs>
+</record>
+<record>
+<Location>Southern South America, islands in the South Atlantic Ocean, east of southern Argentina</Location>
+<Geographiccoordinates>51 45 S, 59 00 W</Geographiccoordinates>
+<Area>12173</Area>
+<Climate>cold marine; strong westerly winds, cloudy, humid; rain occurs on more than half of days in year; occasional snow all year, except in January and February, but does not accumulate</Climate>
+<Naturalresources>fish, wildlife</Naturalresources>
+<Population>2826</Population>
+<Populationgrowthrate>2.44% (2000 est.)</Populationgrowthrate>
+<Religions>primarily Anglican, Roman Catholic, United Free Church, Evangelist Church, Jehovah's Witnesses, Lutheran, Seventh-Day Adventist</Religions>
+<Countryname>Falkland Islands (Islas Malvinas) </Countryname>
+<Capital>Stanley</Capital>
+<Flagdescription>blue with the flag of the UK in the upper hoist-side quadrant and the Falkland Island coat of arms in a white disk centered on the outer half of the flag; the coat of arms contains a white ram (sheep raising is the major economic activity) above the sailing ship Desire (whose crew discovered the islands) with a scroll at the bottom bearing the motto DESIRE THE RIGHT</Flagdescription>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>wool and fish processing; sale of stamps and coins</Industries>
+<Exports>$7.6 million (1995)</Exports>
+<Imports>$24.7 million (1995)</Imports>
+<Currency>1 Falkland pound = 100 pence</Currency>
+<Airports>5 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern South America, bordering the North Atlantic Ocean, between Brazil and Suriname</Location>
+<Geographiccoordinates>4 00 N, 53 00 W</Geographiccoordinates>
+<Area>91000</Area>
+<Climate>tropical; hot, humid; little seasonal temperature variation</Climate>
+<Naturalresources>bauxite, timber, gold (widely scattered), cinnabar, kaolin, fish</Naturalresources>
+<Population>172605</Population>
+<Populationgrowthrate>2.93% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.18 male(s)/female
+65 years and over: 1.02 male(s)/female
+total population: 1.13 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic</Religions>
+<Countryname>French Guiana </Countryname>
+<Capital>Cayenne</Capital>
+<Flagdescription>the flag of France is used</Flagdescription>
+<GDP>purchasing power parity - $1 billion (1998 est.)</GDP>
+<Industries>construction, shrimp processing, forestry products, rum, gold mining</Industries>
+<Exports>$155 million (f.o.b., 1997)</Exports>
+<Imports>$625 million (c.i.f., 1997)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>11 (1999 est.)</Airports>
+<Illicitdrugs>small amount of marijuana grown for local consumption; minor transshipment point to Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Europe, bordering the Baltic Sea, Gulf of Bothnia, and Gulf of Finland, between Sweden and Russia</Location>
+<Geographiccoordinates>64 00 N, 26 00 E</Geographiccoordinates>
+<Area>337030</Area>
+<Climate>cold temperate; potentially subarctic, but comparatively mild because of moderating influence of the North Atlantic Current, Baltic Sea, and more than 60,000 lakes</Climate>
+<Naturalresources>timber, copper, zinc, iron ore, silver</Naturalresources>
+<Population>5167486</Population>
+<Populationgrowthrate>0.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran 89%, Greek Orthodox 1%, none 9%, other 1%</Religions>
+<Countryname>Finland </Countryname>
+<Capital>Helsinki</Capital>
+<Flagdescription>white with a blue cross that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side in the style of the Dannebrog (Danish flag)</Flagdescription>
+<GDP>purchasing power parity - $108.6 billion (1999 est.)</GDP>
+<Industries>metal products, shipbuilding, pulp and paper, copper refining, foodstuffs, chemicals, textiles, clothing</Industries>
+<Exports>$43 billion (f.o.b., 1998)</Exports>
+<Imports>$30.7 billion (f.o.b., 1998)</Imports>
+<Currency>1 markka (FMk) or Finmark = 100 pennia</Currency>
+<Airports>157 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, island group in the South Pacific Ocean, about two-thirds of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>18 00 S, 175 00 E</Geographiccoordinates>
+<Area>18270</Area>
+<Climate>tropical marine; only slight seasonal temperature variation</Climate>
+<Naturalresources>timber, fish, gold, copper, offshore oil potential, hydropower</Naturalresources>
+<Population>832494</Population>
+<Populationgrowthrate>1.41% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.88 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 52% (Methodist 37%, Roman Catholic 9%), Hindu 38%, Muslim 8%, other 2%
+note: Fijians are mainly Christian, Indians are Hindu, and there is a Muslim minority (1986)</Religions>
+<Countryname>Fiji </Countryname>
+<Capital>Suva</Capital>
+<Flagdescription>light blue with the flag of the UK in the upper hoist-side quadrant and the Fijian shield centered on the outer half of the flag; the shield depicts a yellow lion above a white field quartered by the cross of Saint George featuring stalks of sugarcane, a palm tree, bananas, and a white dove</Flagdescription>
+<GDP>purchasing power parity - $5.9 billion (1999 est.)</GDP>
+<Industries>tourism, sugar, clothing, copra, gold, silver, lumber, small cottage industries</Industries>
+<Exports>$393 million (f.o.b., 1998)</Exports>
+<Imports>$612 million (f.o.b., 1998)</Imports>
+<Currency>1 Fijian dollar (F$) = 100 cents</Currency>
+<Airports>25 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, island group in the North Pacific Ocean, about three-quarters of the way from Hawaii to Indonesia</Location>
+<Geographiccoordinates>6 55 N, 158 15 E</Geographiccoordinates>
+<Area>702</Area>
+<Climate>tropical; heavy year-round rainfall, especially in the eastern islands; located on southern edge of the typhoon belt with occasionally severe damage</Climate>
+<Naturalresources>forests, marine products, deep-seabed minerals</Naturalresources>
+<Population>133144</Population>
+<Populationgrowthrate>3.28% (2000 est.)</Populationgrowthrate>
+<Religions>Roman Catholic 50%, Protestant 47%, other and none 3%</Religions>
+<Countryname>Federated States of Micronesia </Countryname>
+<Capital>Palikir</Capital>
+<Flagdescription>light blue with four white five-pointed stars centered; the stars are arranged in a diamond pattern</Flagdescription>
+<GDP>purchasing power parity - $240 million (1997 est.)
+note: GDP is supplemented by grant aid, averaging perhaps $100 million annually</GDP>
+<Industries>tourism, construction, fish processing, craft items from shell, wood, and pearls</Industries>
+<Exports>$73 million (f.o.b., 1996 est.)</Exports>
+<Imports>$168 million (c.i.f., 1996 est.)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>6 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Europe, island group between the Norwegian Sea and the north Atlantic Ocean, about one-half of the way from Iceland to Norway</Location>
+<Geographiccoordinates>62 00 N, 7 00 W</Geographiccoordinates>
+<Area>1399</Area>
+<Climate>mild winters, cool summers; usually overcast; foggy, windy</Climate>
+<Naturalresources>fish, whales, hydropower</Naturalresources>
+<Population>45296</Population>
+<Populationgrowthrate>0.83% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1.14 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1.06 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran</Religions>
+<Countryname>Faroe Islands </Countryname>
+<Capital>Torshavn</Capital>
+<Flagdescription>white with a red cross outlined in blue that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side in the style of the Dannebrog (Danish flag)</Flagdescription>
+<GDP>purchasing power parity - $700 million (1996 est.)</GDP>
+<Industries>fishing, shipbuilding, construction, handicrafts</Industries>
+<Exports>$362 million (f.o.b., 1995)</Exports>
+<Imports>$315.6 million (c.i.f., 1995)</Imports>
+<Currency>1 Danish krone (DKr) = 100 oere</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, archipelago in the South Pacific Ocean, about one-half of the way from South America to Australia</Location>
+<Geographiccoordinates>15 00 S, 140 00 W</Geographiccoordinates>
+<Area>4167</Area>
+<Climate>tropical, but moderate</Climate>
+<Naturalresources>timber, fish, cobalt, hydropower</Naturalresources>
+<Population>249110</Population>
+<Populationgrowthrate>1.78% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.09 male(s)/female
+65 years and over: 1.01 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 54%, Roman Catholic 30%, other 16%</Religions>
+<Countryname>French Polynesia </Countryname>
+<Capital>Papeete</Capital>
+<Flagdescription>two narrow red horizontal bands encase a wide white band; centered on the white band is a disk with blue and white wave pattern on the lower half and gold and white ray pattern on the upper half; a stylized red, blue and white ship rides on the wave pattern; the French flag is used for official occasions</Flagdescription>
+<GDP>purchasing power parity - $2.6 billion (1997 est.)</GDP>
+<Industries>tourism, pearls, agricultural processing, handicrafts</Industries>
+<Exports>$212 million (f.o.b., 1996)</Exports>
+<Imports>$860 million (c.i.f., 1996)</Imports>
+<Currency>1 Comptoirs Francais du Pacifique franc (CFPF) = 100 centimes</Currency>
+<Airports>45 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, atoll in the North Pacific Ocean, about one-half of the way from Hawaii to Australia</Location>
+<Geographiccoordinates>0 13 N, 176 31 W</Geographiccoordinates>
+<Area>1</Area>
+<Climate>equatorial; scant rainfall, constant wind, burning sun</Climate>
+<Naturalresources>guano (deposits worked until 1891)</Naturalresources>
+<Population></Population>
+<Countryname>Baker Island </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>1 abandoned World War II runway of 1,665 m, completely covered with vegetation and unusable</Airports>
+</record>
+<record>
+<Location>Western Europe, bordering the Bay of Biscay and English Channel, between Belgium and Spain, southeast of the UK; bordering the Mediterranean Sea, between Italy and Spain</Location>
+<Geographiccoordinates>46 00 N, 2 00 E</Geographiccoordinates>
+<Area>547030</Area>
+<Climate>generally cool winters and mild summers, but mild winters and hot summers along the Mediterranean</Climate>
+<Naturalresources>coal, iron ore, bauxite, fish, timber, zinc, potash</Naturalresources>
+<Population>59329691</Population>
+<Populationgrowthrate>0.38% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%, Protestant 2%, Jewish 1%, Muslim (North African workers) 1%, unaffiliated 6%</Religions>
+<Countryname>France </Countryname>
+<Capital>Paris</Capital>
+<Flagdescription>three equal vertical bands of blue (hoist side), white, and red; known as the French Tricouleur (Tricolor); the design and colors are similar to a number of other flags, including those of Belgium, Chad, Ireland, Cote d'Ivoire, and Luxembourg; the official flag for all French dependent areas</Flagdescription>
+<GDP>purchasing power parity - $1.373 trillion (1999 est.)</GDP>
+<Industries>steel, machinery, chemicals, automobiles, metallurgy, aircraft, electronics, mining; textiles, food processing; tourism</Industries>
+<Exports>$304.7 billion (f.o.b., 1999)</Exports>
+<Imports>$280.8 billion (f.o.b., 1999)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>474 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for and consumer of South American cocaine and Southwest Asian heroin</Illicitdrugs>
+</record>
+<record>
+<Location>south of Africa, islands in the southern Indian Ocean, about equidistant between Africa, Antarctica, and Australia; note - French Southern and Antarctic Lands includes Ile Amsterdam, Ile Saint-Paul, Iles Crozet, and Iles Kerguelen in the southern Indian Ocean, along with the French-claimed sector of Antarctica, "Adelie Land"; the US does not recognize the French claim to "Adelie Land"</Location>
+<Geographiccoordinates>43 00 S, 67 00 E</Geographiccoordinates>
+<Area>7781</Area>
+<Climate>antarctic</Climate>
+<Naturalresources>fish, crayfish</Naturalresources>
+<Population></Population>
+<Countryname>French Southern and Antarctic Lands </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean and Senegal</Location>
+<Geographiccoordinates>13 28 N, 16 34 W</Geographiccoordinates>
+<Area>11300</Area>
+<Climate>tropical; hot, rainy season (June to November); cooler, dry season (November to May)</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>1367124</Population>
+<Populationgrowthrate>3.2% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 1.11 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 90%, Christian 9%, indigenous beliefs 1%</Religions>
+<Countryname>The Gambia </Countryname>
+<Capital>Banjul</Capital>
+<Flagdescription>three equal horizontal bands of red (top), blue with white edges, and green</Flagdescription>
+<GDP>purchasing power parity - $1.4 billion (1999 est.)</GDP>
+<Industries>processing peanuts, fish, and hides; tourism; beverages; agricultural machinery assembly, woodworking, metalworking; clothing</Industries>
+<Exports>$132 million (f.o.b., 1998)</Exports>
+<Imports>$201 million (f.o.b., 1998)</Imports>
+<Currency>1 dalasi (D) = 100 butut</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the Atlantic Ocean at the Equator, between Republic of the Congo and Equatorial Guinea</Location>
+<Geographiccoordinates>1 00 S, 11 45 E</Geographiccoordinates>
+<Area>267667</Area>
+<Climate>tropical; always hot, humid</Climate>
+<Naturalresources>petroleum, manganese, uranium, gold, timber, iron ore, hydropower</Naturalresources>
+<Population>1208436</Population>
+<Populationgrowthrate>1.08% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.98 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 55%-75%, Muslim less than 1%, animist</Religions>
+<Countryname>Gabon </Countryname>
+<Capital>Libreville</Capital>
+<Flagdescription>three equal horizontal bands of green (top), yellow, and blue</Flagdescription>
+<GDP>purchasing power parity - $7.9 billion (1999 est.)</GDP>
+<Industries>food and beverage; textile; lumbering and plywood; cement; petroleum extraction and refining; manganese, uranium, and gold mining; chemicals; ship repair</Industries>
+<Exports>$2.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$1.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>61 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southwestern Asia, bordering the Black Sea, between Turkey and Russia</Location>
+<Geographiccoordinates>42 00 N, 43 30 E</Geographiccoordinates>
+<Area>69700</Area>
+<Climate>warm and pleasant; Mediterranean-like on Black Sea coast</Climate>
+<Naturalresources>forests, hydropower, manganese deposits, iron ore, copper, minor coal and oil deposits; coastal climate and soils allow for important tea and citrus growth</Naturalresources>
+<Population>5019538</Population>
+<Populationgrowthrate>-0.62% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.63 male(s)/female
+total population: 0.91 male(s)/female (2000 est.)</Sexratio>
+<Religions>Georgian Orthodox 65%, Muslim 11%, Russian Orthodox 10%, Armenian Apostolic 8%, unknown 6%</Religions>
+<Countryname>Georgia </Countryname>
+<Capital>T'bilisi</Capital>
+<Flagdescription>maroon field with small rectangle in upper hoist side corner; rectangle divided horizontally with black on top, white below</Flagdescription>
+<GDP>purchasing power parity - $11.7 billion (1999 est.)</GDP>
+<Industries>steel, aircraft, machine tools, electric locomotives, trucks, tractors, textiles, shoes, chemicals, wood products, wine</Industries>
+<Exports>$330 million (1999 est.)</Exports>
+<Imports>$840 million (1999 est.)</Imports>
+<Currency>1 lari (GEL) = 100 tetri</Currency>
+<Airports>28 (1994 est.)</Airports>
+<Illicitdrugs>limited cultivation of cannabis and opium poppy, mostly for domestic consumption; used as transshipment point for opiates via Central Asia to Western Europe and Russia</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the Gulf of Guinea, between Cote d'Ivoire and Togo</Location>
+<Geographiccoordinates>8 00 N, 2 00 W</Geographiccoordinates>
+<Area>238540</Area>
+<Climate>tropical; warm and comparatively dry along southeast coast; hot and humid in southwest; hot and dry in north</Climate>
+<Naturalresources>gold, timber, industrial diamonds, bauxite, manganese, fish, rubber, hydropower</Naturalresources>
+<Population>19533560</Population>
+<Populationgrowthrate>1.87% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.91 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 38%, Muslim 30%, Christian 24%, other 8%</Religions>
+<Countryname>Ghana </Countryname>
+<Capital>Accra</Capital>
+<Flagdescription>three equal horizontal bands of red (top), yellow, and green with a large black five-pointed star centered in the yellow band; uses the popular pan-African colors of Ethiopia; similar to the flag of Bolivia, which has a coat of arms centered in the yellow band</Flagdescription>
+<GDP>purchasing power parity - $35.5 billion (1999 est.)</GDP>
+<Industries>mining, lumbering, light manufacturing, aluminum smelting, food processing</Industries>
+<Exports>$1.7 billion (f.o.b., 1999)</Exports>
+<Imports>$2.5 billion (f.o.b., 1999)</Imports>
+<Currency>1 new cedi (C) = 100 pesewas</Currency>
+<Airports>12 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis for the international drug trade; transit hub for Southwest and Southeast Asian heroin and South American cocaine destined for Europe and the US</Illicitdrugs>
+</record>
+<record>
+<Location>Southwestern Europe, bordering the Strait of Gibraltar, which links the Mediterranean Sea and the North Atlantic Ocean, on the southern coast of Spain</Location>
+<Geographiccoordinates>36 11 N, 5 22 W</Geographiccoordinates>
+<Area>6</Area>
+<Climate>Mediterranean with mild winters and warm summers</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>29481</Population>
+<Populationgrowthrate>0.91% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.14 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 76.9%, Church of England 6.9%, Muslim 6.9%, Jewish 2.3%, none or other 7% (1991)</Religions>
+<Countryname>Gibraltar </Countryname>
+<Capital>Gibraltar</Capital>
+<Flagdescription>two horizontal bands of white (top, double width) and red with a three-towered red castle in the center of the white band; hanging from the castle gate is a gold key centered in the red band</Flagdescription>
+<GDP>purchasing power parity - $500 million (1997 est.)</GDP>
+<Industries>tourism, banking and finance, ship-building and repairing; support to large UK naval and air bases; tobacco, mineral water, beer, canned fish</Industries>
+<Exports>$81.1 million (f.o.b., 1997)</Exports>
+<Imports>$492 million (c.i.f., 1997)</Imports>
+<Currency>1 Gibraltar pound = 100 pence</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and Atlantic Ocean, north of Trinidad and Tobago</Location>
+<Geographiccoordinates>12 07 N, 61 40 W</Geographiccoordinates>
+<Area>340</Area>
+<Climate>tropical; tempered by northeast trade winds</Climate>
+<Naturalresources>timber, tropical fruit, deepwater harbors</Naturalresources>
+<Population>89018</Population>
+<Populationgrowthrate>-0.36% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.02 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.12 male(s)/female
+65 years and over: 0.83 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 53%, Anglican 13.8%, other Protestant 33.2%</Religions>
+<Countryname>Grenada </Countryname>
+<Capital>Saint George's</Capital>
+<Flagdescription>a rectangle divided diagonally into yellow triangles (top and bottom) and green triangles (hoist side and outer side), with a red border around the flag; there are seven yellow, five-pointed stars with three centered in the top red border, three centered in the bottom red border, and one on a red disk superimposed at the center of the flag; there is also a symbolic nutmeg pod on the hoist-side triangle (Grenada is the world's second-largest producer of nutmeg, after Indonesia); the seven stars represent the seven administrative divisions</Flagdescription>
+<GDP>purchasing power parity - $360 million (1999 est.)</GDP>
+<Industries>food and beverages, textiles, light assembly operations, tourism, construction</Industries>
+<Exports>$26.8 million (1998)</Exports>
+<Imports>$200 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+<Illicitdrugs>small-scale cannabis cultivation; lesser transshipment point for marijuana and cocaine to US</Illicitdrugs>
+</record>
+<record>
+<Location>Western Europe, islands in the English Channel, northwest of France</Location>
+<Geographiccoordinates>49 28 N, 2 35 W</Geographiccoordinates>
+<Area>194</Area>
+<Climate>temperate with mild winters and cool summers; about 50% of days are overcast</Climate>
+<Naturalresources>cropland</Naturalresources>
+<Population>64080</Population>
+<Populationgrowthrate>0.42% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican, Roman Catholic, Presbyterian, Baptist, Congregational, Methodist</Religions>
+<Countryname>Guernsey </Countryname>
+<Capital>Saint Peter Port</Capital>
+<Flagdescription>white with the red cross of Saint George (patron saint of England) extending to the edges of the flag and a yellow equal-armed cross of William the Conqueror superimposed on the Saint George cross</Flagdescription>
+<GDP>purchasing power parity - $1.15 billion (1997 est.)</GDP>
+<Industries>tourism, banking</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Guernsey pound = 100 pence</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern North America, island between the Arctic Ocean and the North Atlantic Ocean, northeast of Canada</Location>
+<Geographiccoordinates>72 00 N, 40 00 W</Geographiccoordinates>
+<Area>2175600</Area>
+<Climate>arctic to subarctic; cool summers, cold winters</Climate>
+<Naturalresources>zinc, lead, iron ore, coal, molybdenum, gold, platinum, uranium, fish, seals, whales</Naturalresources>
+<Population>56309</Population>
+<Populationgrowthrate>0.09% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.21 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1.13 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran</Religions>
+<Countryname>Greenland </Countryname>
+<Capital>Nuuk (Godthab)</Capital>
+<Flagdescription>two equal horizontal bands of white (top) and red with a large disk slightly to the hoist side of center - the top half of the disk is red, the bottom half is white</Flagdescription>
+<GDP>purchasing power parity - $945 million (1997 est.)</GDP>
+<Industries>fish processing (mainly shrimp), handicrafts, furs, small shipyards</Industries>
+<Exports>$363.4 million (f.o.b., 1995)</Exports>
+<Imports>$421 million (c.i.f., 1995)</Imports>
+<Currency>1 Danish krone (DKr) = 100 oere</Currency>
+<Airports>14 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Europe, bordering the Baltic Sea and the North Sea, between the Netherlands and Poland, south of Denmark</Location>
+<Geographiccoordinates>51 00 N, 9 00 E</Geographiccoordinates>
+<Area>357021</Area>
+<Climate>temperate and marine; cool, cloudy, wet winters and summers; occasional warm foehn wind</Climate>
+<Naturalresources>iron ore, coal, potash, timber, lignite, uranium, copper, natural gas, salt, nickel, arable land</Naturalresources>
+<Population>82797408</Population>
+<Populationgrowthrate>0.29% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 38%, Roman Catholic 34%, Muslim 1.7%, unaffiliated or other 26.3%</Religions>
+<Countryname>Germany </Countryname>
+<Capital>Berlin</Capital>
+<Flagdescription>three equal horizontal bands of black (top), red, and gold</Flagdescription>
+<GDP>purchasing power parity - $1.864 trillion (1999 est.)</GDP>
+<Industries>among world's largest and technologically advanced producers of iron, steel, coal, cement, chemicals, machinery, vehicles, machine tools, electronics, food and beverages; shipbuilding; textiles</Industries>
+<Exports>$610 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$587 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 deutsche mark (DM) = 100 pfennige</Currency>
+<Airports>615 (1999 est.)</Airports>
+<Illicitdrugs>source of precursor chemicals for South American cocaine processors; transshipment point for and consumer of Southwest Asian heroin, Latin American cocaine, and European-produced synthetic drugs</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, group of islands in the Indian Ocean, northwest of Madagascar</Location>
+<Geographiccoordinates>11 30 S, 47 20 E</Geographiccoordinates>
+<Area>5</Area>
+<Climate>tropical</Climate>
+<Naturalresources>guano, coconuts</Naturalresources>
+<Population></Population>
+<Countryname>Glorioso Islands </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, islands in the eastern Caribbean Sea, southeast of Puerto Rico</Location>
+<Geographiccoordinates>16 15 N, 61 35 W</Geographiccoordinates>
+<Area>1780</Area>
+<Climate>subtropical tempered by trade winds; moderately high humidity</Climate>
+<Naturalresources>cultivable land, beaches and climate that foster tourism</Naturalresources>
+<Population>426493</Population>
+<Populationgrowthrate>1.11% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95%, Hindu and pagan African 4%, Protestant 1%</Religions>
+<Countryname>Guadeloupe </Countryname>
+<Capital>Basse-Terre</Capital>
+<Flagdescription>three horizontal bands, a narrow green band (top), a wide red band, and a narrow green band; the green bands are separated from the red band by two narrow white stripes; a gold five-pointed star is centered in the red band toward the hoist side; the flag of France is used for official occasions</Flagdescription>
+<GDP>purchasing power parity - $3.7 billion (1996 est.)</GDP>
+<Industries>construction, cement, rum, sugar, tourism</Industries>
+<Exports>$140 million (f.o.b., 1997)</Exports>
+<Imports>$1.7 billion (c.i.f., 1997)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>9 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, island in the North Pacific Ocean, about three-quarters of the way from Hawaii to the Philippines</Location>
+<Geographiccoordinates>13 28 N, 144 47 E</Geographiccoordinates>
+<Area>541</Area>
+<Climate>tropical marine; generally warm and humid, moderated by northeast trade winds; dry season from January to June, rainy season from July to December; little seasonal temperature variation</Climate>
+<Naturalresources>fishing (largely undeveloped), tourism (especially from Japan)</Naturalresources>
+<Population>154623</Population>
+<Populationgrowthrate>1.67% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.14 male(s)/female
+under 15 years: 1.1 male(s)/female
+15-64 years: 1.11 male(s)/female
+65 years and over: 1.01 male(s)/female
+total population: 1.1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 85%, other 15% (1999 est.)</Religions>
+<Countryname>Guam </Countryname>
+<Capital>Hagatna (Agana)</Capital>
+<Flagdescription>territorial flag is dark blue with a narrow red border on all four sides; centered is a red-bordered, pointed, vertical ellipse containing a beach scene, outrigger canoe with sail, and a palm tree with the word GUAM superimposed in bold red letters; US flag is the national flag</Flagdescription>
+<GDP>purchasing power parity - $3 billion (1996 est.)</GDP>
+<Industries>US military, tourism, construction, transshipment services, concrete products, printing and publishing, food processing, textiles</Industries>
+<Exports>$86.1 million (f.o.b., 1992)</Exports>
+<Imports>$202.4 million (c.i.f., 1992)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>5 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Europe, bordering the Aegean Sea, Ionian Sea, and the Mediterranean Sea, between Albania and Turkey</Location>
+<Geographiccoordinates>39 00 N, 22 00 E</Geographiccoordinates>
+<Area>131940</Area>
+<Climate>temperate; mild, wet winters; hot, dry summers</Climate>
+<Naturalresources>bauxite, lignite, magnesite, petroleum, marble, hydropower</Naturalresources>
+<Population>10601527</Population>
+<Populationgrowthrate>0.21% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Greek Orthodox 98%, Muslim 1.3%, other 0.7%</Religions>
+<Countryname>Greece </Countryname>
+<Capital>Athens</Capital>
+<Flagdescription>nine equal horizontal stripes of blue alternating with white; there is a blue square in the upper hoist-side corner bearing a white cross; the cross symbolizes Greek Orthodoxy, the established religion of the country</Flagdescription>
+<GDP>purchasing power parity - $149.2 billion (1999 est.)</GDP>
+<Industries>tourism; food and tobacco processing, textiles; chemicals, metal products; mining, petroleum</Industries>
+<Exports>$12.4 billion (f.o.b., 1998)</Exports>
+<Imports>$27.7 billion (c.i.f., 1998)</Imports>
+<Currency>1 drachma (Dr) = 100 lepta</Currency>
+<Airports>80 (1999 est.)</Airports>
+<Illicitdrugs>a gateway to Europe for traffickers smuggling cannabis and heroin from the Middle East and Southwest Asia to the West and precursor chemicals to the East; some South American cocaine transits or is consumed in Greece</Illicitdrugs>
+</record>
+<record>
+<Location>Middle America, bordering the Caribbean Sea, between Honduras and Belize and bordering the North Pacific Ocean, between El Salvador and Mexico</Location>
+<Geographiccoordinates>15 30 N, 90 15 W</Geographiccoordinates>
+<Area>108890</Area>
+<Climate>tropical; hot, humid in lowlands; cooler in highlands</Climate>
+<Naturalresources>petroleum, nickel, rare woods, fish, chicle, hydropower</Naturalresources>
+<Population>12639939</Population>
+<Populationgrowthrate>2.63% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.88 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic, Protestant, indigenous Mayan beliefs</Religions>
+<Countryname>Guatemala </Countryname>
+<Capital>Guatemala</Capital>
+<Flagdescription>three equal vertical bands of light blue (hoist side), white, and light blue with the coat of arms centered in the white band; the coat of arms includes a green and red quetzal (the national bird) and a scroll bearing the inscription LIBERTAD 15 DE SEPTIEMBRE DE 1821 (the original date of independence from Spain) all superimposed on a pair of crossed rifles and a pair of crossed swords and framed by a wreath</Flagdescription>
+<GDP>purchasing power parity - $47.9 billion (1999 est.)</GDP>
+<Industries>sugar, textiles and clothing, furniture, chemicals, petroleum, metals, rubber, tourism</Industries>
+<Exports>$2.4 billion (f.o.b., 1999)</Exports>
+<Imports>$4.5 billion (c.i.f., 1999)</Imports>
+<Currency>1 quetzal (Q) = 100 centavos</Currency>
+<Airports>477 (1999 est.)</Airports>
+<Illicitdrugs>transit country for cocaine shipments; minor producer of illicit opium poppy and cannabis for the international drug trade; active eradication program in 1996 effectively eliminated the cannabis crop; proximity to Mexico makes Guatemala a major staging area for drugs (cocaine shipments)</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Guinea-Bissau and Sierra Leone</Location>
+<Geographiccoordinates>11 00 N, 10 00 W</Geographiccoordinates>
+<Area>245857</Area>
+<Climate>generally hot and humid; monsoonal-type rainy season (June to November) with southwesterly winds; dry season (December to May) with northeasterly harmattan winds</Climate>
+<Naturalresources>bauxite, iron ore, diamonds, gold, uranium, hydropower, fish</Naturalresources>
+<Population>7466200</Population>
+<Populationgrowthrate>1.95% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 85%, Christian 8%, indigenous beliefs 7%</Religions>
+<Countryname>Guinea </Countryname>
+<Capital>Conakry</Capital>
+<Flagdescription>three equal vertical bands of red (hoist side), yellow, and green; uses the popular pan-African colors of Ethiopia; similar to the flag of Rwanda, which has a large black letter R centered in the yellow band</Flagdescription>
+<GDP>purchasing power parity - $9.2 billion (1999 est.)</GDP>
+<Industries>bauxite, gold, diamonds; alumina refining; light manufacturing and agricultural processing industries</Industries>
+<Exports>$695 million (f.o.b., 1998 est.)</Exports>
+<Imports>$560 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 Guinean franc (FG) = 100 centimes</Currency>
+<Airports>15 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern South America, bordering the North Atlantic Ocean, between Suriname and Venezuela</Location>
+<Geographiccoordinates>5 00 N, 59 00 W</Geographiccoordinates>
+<Area>214970</Area>
+<Climate>tropical; hot, humid, moderated by northeast trade winds; two rainy seasons (May to mid-August, mid-November to mid-January)</Climate>
+<Naturalresources>bauxite, gold, diamonds, hardwood timber, shrimp, fish</Naturalresources>
+<Population>697286</Population>
+<Populationgrowthrate>-0.1% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 50%, Hindu 33%, Muslim 9%, other 8%</Religions>
+<Countryname>Guyana </Countryname>
+<Capital>Georgetown</Capital>
+<Flagdescription>green, with a red isosceles triangle (based on the hoist side) superimposed on a long, yellow arrowhead; there is a narrow, black border between the red and yellow, and a narrow, white border between the yellow and the green</Flagdescription>
+<GDP>purchasing power parity - $1.86 billion (1999 est.)</GDP>
+<Industries>bauxite, sugar, rice milling, timber, fishing (shrimp), textiles, gold mining</Industries>
+<Exports>$574 million (f.o.b., 1999 est.)</Exports>
+<Imports>$620 million (c.i.f., 1999 est.)</Imports>
+<Currency>1 Guyanese dollar (G$) = 100 cents</Currency>
+<Airports>51 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for narcotics from South America - primarily Venezuela - to Europe and the US; producer of cannabis</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Mediterranean Sea, between Egypt and Israel</Location>
+<Geographiccoordinates>31 25 N, 34 20 E</Geographiccoordinates>
+<Area>360</Area>
+<Climate>temperate, mild winters, dry and warm to hot summers</Climate>
+<Naturalresources>arable land</Naturalresources>
+<Population>1132063</Population>
+<Populationgrowthrate>3.97% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim (predominantly Sunni) 98.7%, Christian 0.7%, Jewish 0.6%</Religions>
+<Countryname>Gaza Strip </Countryname>
+<GDP>purchasing power parity - $1.17 billion (1999 est.)</GDP>
+<Industries>generally small family businesses that produce textiles, soap, olive-wood carvings, and mother-of-pearl souvenirs; the Israelis have established some small-scale modern industries in an industrial center</Industries>
+<Exports>$682 million (includes West Bank) (f.o.b., 1998 est.)</Exports>
+<Imports>$2.5 billion (c.i.f., 1998 est.) (includes West Bank)</Imports>
+<Currency>1 new Israeli shekel (NIS) = 100 new agorot</Currency>
+<Airports>2 (1999 est.)
+note: includes Gaza International Airport that opened on 24 November 1998 as part of agreements stipulated in the September 1995 Oslo II Accord and the 23 October 1998 Wye River Memorandum</Airports>
+</record>
+<record>
+<Location>Caribbean, western one-third of the island of Hispaniola, between the Caribbean Sea and the North Atlantic Ocean, west of the Dominican Republic</Location>
+<Geographiccoordinates>19 00 N, 72 25 W</Geographiccoordinates>
+<Area>27750</Area>
+<Climate>tropical; semiarid where mountains in east cut off trade winds</Climate>
+<Naturalresources>bauxite, copper, calcium carbonate, gold, marble, hydropower</Naturalresources>
+<Population>6867995</Population>
+<Populationgrowthrate>1.39% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.95 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 80%, Protestant 16% (Baptist 10%, Pentecostal 4%, Adventist 1%, other 1%), none 1%, other 3% (1982)
+note: roughly one-half of the population also practices Voodoo</Religions>
+<Countryname>Haiti </Countryname>
+<Capital>Port-au-Prince</Capital>
+<Flagdescription>two equal horizontal bands of blue (top) and red with a centered white rectangle bearing the coat of arms, which contains a palm tree flanked by flags and two cannons above a scroll bearing the motto L'UNION FAIT LA FORCE (Union Makes Strength)</Flagdescription>
+<GDP>purchasing power parity - $9.2 billion (1999 est.)</GDP>
+<Industries>sugar refining, flour milling, textiles, cement, tourism, light assembly industries based on imported parts</Industries>
+<Exports>$322 million (f.o.b., 1999)</Exports>
+<Imports>$762 million (c.i.f., 1999)</Imports>
+<Currency>1 gourde (G) = 100 centimes</Currency>
+<Airports>13 (1999 est.)</Airports>
+<Illicitdrugs>major Caribbean transshipment point for cocaine en route to the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Asia, bordering the South China Sea and China</Location>
+<Geographiccoordinates>22 15 N, 114 10 E</Geographiccoordinates>
+<Area>1092</Area>
+<Climate>tropical monsoon; cool and humid in winter, hot and rainy from spring through summer, warm and sunny in fall</Climate>
+<Naturalresources>outstanding deepwater harbor, feldspar</Naturalresources>
+<Population>7116302</Population>
+<Populationgrowthrate>1.35% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.12 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>eclectic mixture of local religions 90%, Christian 10%</Religions>
+<Countryname>Hong Kong </Countryname>
+<Flagdescription>red with a stylized, white, five-petal bauhinia flower in the center</Flagdescription>
+<GDP>purchasing power parity - $158.2 billion (1999 est.)</GDP>
+<Industries>textiles, clothing, tourism, electronics, plastics, toys, watches, clocks</Industries>
+<Exports>$169.98 billion (including reexports; f.o.b., 1999 est.)</Exports>
+<Imports>$174.4 billion (c.i.f., 1999)</Imports>
+<Currency>1 Hong Kong dollar (HK$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+<Illicitdrugs>a hub for Southeast Asian heroin trade; transshipment and money-laundering center; increasing indigenous amphetamine abuse</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, islands in the Indian Ocean, about two-thirds of the way from Madagascar to Antarctica</Location>
+<Geographiccoordinates>53 06 S, 72 31 E</Geographiccoordinates>
+<Area>412</Area>
+<Climate>antarctic</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Heard Island and McDonald Islands </Countryname>
+<Flagdescription>the flag of Australia is used</Flagdescription>
+</record>
+<record>
+<Location>Middle America, bordering the Caribbean Sea, between Guatemala and Nicaragua and bordering the North Pacific Ocean, between El Salvador and Nicaragua</Location>
+<Geographiccoordinates>15 00 N, 86 30 W</Geographiccoordinates>
+<Area>112090</Area>
+<Climate>subtropical in lowlands, temperate in mountains</Climate>
+<Naturalresources>timber, gold, silver, copper, lead, zinc, iron ore, antimony, coal, fish, hydropower</Naturalresources>
+<Population>6249598</Population>
+<Populationgrowthrate>2.52% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.9 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 97%, Protestant minority</Religions>
+<Countryname>Honduras </Countryname>
+<Capital>Tegucigalpa</Capital>
+<Flagdescription>three equal horizontal bands of blue (top), white, and blue with five blue five-pointed stars arranged in an X pattern centered in the white band; the stars represent the members of the former Federal Republic of Central America - Costa Rica, El Salvador, Guatemala, Honduras, and Nicaragua; similar to the flag of El Salvador, which features a round emblem encircled by the words REPUBLICA DE EL SALVADOR EN LA AMERICA CENTRAL centered in the white band; also similar to the flag of Nicaragua, which features a triangle encircled by the word REPUBLICA DE NICARAGUA on top and AMERICA CENTRAL on the bottom, centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $14.1 billion (1999 est.)</GDP>
+<Industries>sugar, coffee, textiles, clothing, wood products</Industries>
+<Exports>$1.6 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2.7 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 lempira (L) = 100 centavos</Currency>
+<Airports>119 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for drugs and narcotics; illicit producer of cannabis, cultivated on small plots and used principally for local consumption; corruption is a major problem</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, island in the North Pacific Ocean, about one-half of the way from Hawaii to Australia</Location>
+<Geographiccoordinates>0 48 N, 176 38 W</Geographiccoordinates>
+<Area>1</Area>
+<Climate>equatorial; scant rainfall, constant wind, burning sun</Climate>
+<Naturalresources>guano (deposits worked until late 1800s)</Naturalresources>
+<Population></Population>
+<Countryname>Howland Island </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>airstrip constructed in 1937 for scheduled refueling stop on the round-the-world flight of Amelia EARHART and Fred NOONAN - they left Lae, New Guinea, for Howland Island, but were never seen again; the airstrip is no longer serviceable</Airports>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Adriatic Sea, between Bosnia and Herzegovina and Slovenia</Location>
+<Geographiccoordinates>45 10 N, 15 30 E</Geographiccoordinates>
+<Area>56538</Area>
+<Climate>Mediterranean and continental; continental climate predominant with hot summers and cold winters; mild winters, dry summers along coast</Climate>
+<Naturalresources>oil, some coal, bauxite, low-grade iron ore, calcium, natural asphalt, silica, mica, clays, salt, hydropower</Naturalresources>
+<Population>4282216</Population>
+<Populationgrowthrate>0.93% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.59 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 76.5%, Orthodox 11.1%, Muslim 1.2%, Protestant 0.4%, others and unknown 10.8% (1991)</Religions>
+<Countryname>Croatia </Countryname>
+<Capital>Zagreb</Capital>
+<Flagdescription>red, white, and blue horizontal bands with Croatian coat of arms (red and white checkered)</Flagdescription>
+<GDP>purchasing power parity - $23.9 billion (1999 est.)</GDP>
+<Industries>chemicals and plastics, machine tools, fabricated metal, electronics, pig iron and rolled steel products, aluminum, paper, wood products, construction materials, textiles, shipbuilding, petroleum and petroleum refining, food and beverages; tourism</Industries>
+<Exports>$4.5 billion (f.o.b., 1998)</Exports>
+<Imports>$8.4 billion (c.i.f., 1998)</Imports>
+<Currency>1 Croatian kuna (HRK) = 100 lipas</Currency>
+<Airports>67 (1999 est.)</Airports>
+<Illicitdrugs>transit point along the Balkan route for Southwest Asian heroin to Western Europe; a minor transit point for maritime shipments of South American cocaine bound for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Central Europe, northwest of Romania</Location>
+<Geographiccoordinates>47 00 N, 20 00 E</Geographiccoordinates>
+<Area>93030</Area>
+<Climate>temperate; cold, cloudy, humid winters; warm summers</Climate>
+<Naturalresources>bauxite, coal, natural gas, fertile soils, arable land</Naturalresources>
+<Population>10138844</Population>
+<Populationgrowthrate>-0.33% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.59 male(s)/female
+total population: 0.91 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 67.5%, Calvinist 20%, Lutheran 5%, atheist and other 7.5%</Religions>
+<Countryname>Hungary </Countryname>
+<Capital>Budapest</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and green</Flagdescription>
+<GDP>purchasing power parity - $79.4 billion (1999 est.)</GDP>
+<Industries>mining, metallurgy, construction materials, processed foods, textiles, chemicals (especially pharmaceuticals), motor vehicles</Industries>
+<Exports>$22.6 billion (f.o.b., 1999)</Exports>
+<Imports>$25.1 billion (f.o.b., 1999)</Imports>
+<Currency>1 forint (Ft) = 100 filler</Currency>
+<Airports>43 (1999 est.)</Airports>
+<Illicitdrugs>major transshipment point for Southwest Asian heroin and cannabis and transit point for South American cocaine destined for Western Europe; limited producer of precursor chemicals, particularly for amphetamines and methamphetamines</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Europe, island between the Greenland Sea and the North Atlantic Ocean, northwest of the UK</Location>
+<Geographiccoordinates>65 00 N, 18 00 W</Geographiccoordinates>
+<Area>103000</Area>
+<Climate>temperate; moderated by North Atlantic Current; mild, windy winters; damp, cool summers</Climate>
+<Naturalresources>fish, hydropower, geothermal power, diatomite</Naturalresources>
+<Population>276365</Population>
+<Populationgrowthrate>0.57% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran 91%, other Protestant and Roman Catholic, none (1997)</Religions>
+<Countryname>Iceland </Countryname>
+<Capital>Reykjavik</Capital>
+<Flagdescription>blue with a red cross outlined in white that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side in the style of the Dannebrog (Danish flag)</Flagdescription>
+<GDP>purchasing power parity - $6.42 billion (1999 est.)</GDP>
+<Industries>fish processing; aluminum smelting, ferrosilicon production, geothermal power; tourism</Industries>
+<Exports>$1.9 billion (f.o.b., 1998)</Exports>
+<Imports>$2.4 billion (f.o.b., 1998)</Imports>
+<Currency>1 Icelandic krona (IKr) = 100 aurar</Currency>
+<Airports>86 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, archipelago between the Indian Ocean and the Pacific Ocean</Location>
+<Geographiccoordinates>5 00 S, 120 00 E</Geographiccoordinates>
+<Area>1919440</Area>
+<Climate>tropical; hot, humid; more moderate in highlands</Climate>
+<Naturalresources>petroleum, tin, natural gas, nickel, timber, bauxite, copper, fertile soils, coal, gold, silver</Naturalresources>
+<Population>224784210</Population>
+<Populationgrowthrate>1.63% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 88%, Protestant 5%, Roman Catholic 3%, Hindu 2%, Buddhist 1%, other 1% (1998)</Religions>
+<Countryname>Indonesia </Countryname>
+<Capital>Jakarta</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and white; similar to the flag of Monaco, which is shorter; also similar to the flag of Poland, which is white (top) and red</Flagdescription>
+<GDP>purchasing power parity - $610 billion (1999 est.)</GDP>
+<Industries>petroleum and natural gas; textiles, apparel, and footwear; mining, cement, chemical fertilizers, plywood; rubber; food; tourism</Industries>
+<Exports>$48 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$24 billion (c.i.f., 1999 est.)</Imports>
+<Currency>Indonesian rupiah (Rp) = 100 sen</Currency>
+<Airports>446 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis largely for domestic use; possible growing role as transshipment point for Golden Triangle heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Western Europe, island in the Irish Sea, between Great Britain and Ireland</Location>
+<Geographiccoordinates>54 15 N, 4 30 W</Geographiccoordinates>
+<Area>572</Area>
+<Climate>cool summers and mild winters; temperate; overcast about one-third of the time</Climate>
+<Naturalresources>none</Naturalresources>
+<Population>73117</Population>
+<Populationgrowthrate>0.52% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.66 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican, Roman Catholic, Methodist, Baptist, Presbyterian, Society of Friends</Religions>
+<Countryname>Isle of Man </Countryname>
+<Capital>Douglas</Capital>
+<Flagdescription>red with the Three Legs of Man emblem (Trinacria), in the center; the three legs are joined at the thigh and bent at the knee; in order to have the toes pointing clockwise on both sides of the flag, a two-sided emblem is used</Flagdescription>
+<GDP>purchasing power parity - $1.2 billion (1998 est.)</GDP>
+<Industries>financial services, light manufacturing, tourism</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Manx pound = 100 pence</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Asia, bordering the Arabian Sea and the Bay of Bengal, between Burma and Pakistan</Location>
+<Geographiccoordinates>20 00 N, 77 00 E</Geographiccoordinates>
+<Area>3287590</Area>
+<Climate>varies from tropical monsoon in south to temperate in north</Climate>
+<Naturalresources>coal (fourth-largest reserves in the world), iron ore, manganese, mica, bauxite, titanium ore, chromite, natural gas, diamonds, petroleum, limestone, arable land</Naturalresources>
+<Population>1014003817</Population>
+<Populationgrowthrate>1.58% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.08 male(s)/female
+65 years and over: 1.03 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Hindu 80%, Muslim 14%, Christian 2.4%, Sikh 2%, Buddhist 0.7%, Jains 0.5%, other 0.4%</Religions>
+<Countryname>India </Countryname>
+<Capital>New Delhi</Capital>
+<Flagdescription>three equal horizontal bands of orange (top), white, and green with a blue chakra (24-spoked wheel) centered in the white band; similar to the flag of Niger, which has a small orange disk centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $1.805 trillion (1999 est.)</GDP>
+<Industries>textiles, chemicals, food processing, steel, transportation equipment, cement, mining, petroleum, machinery</Industries>
+<Exports>$36.3 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$50.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Indian rupee (Re) = 100 paise</Currency>
+<Airports>346 (1999 est.)</Airports>
+<Illicitdrugs>world's largest producer of licit opium for the pharmaceutical trade, but an undetermined quantity of opium is diverted to illicit international drug markets; major transit country for illicit narcotics produced in neighboring countries; illicit producer of hashish and methaqualone</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Asia, archipelago in the Indian Ocean, about one-half the way from Africa to Indonesia</Location>
+<Geographiccoordinates>6 00 S, 71 30 E</Geographiccoordinates>
+<Area>60</Area>
+<Climate>tropical marine; hot, humid, moderated by trade winds</Climate>
+<Naturalresources>coconuts, fish</Naturalresources>
+<Population></Population>
+<Countryname>British Indian Ocean Territory </Countryname>
+<Flagdescription>white with six blue wavy horizontal stripes; the flag of the UK is in the upper hoist-side quadrant; the striped section bears a palm tree and yellow crown centered on the outer half of the flag</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle America, atoll in the North Pacific Ocean, 1,120 km southwest of Mexico</Location>
+<Geographiccoordinates>10 17 N, 109 13 W</Geographiccoordinates>
+<Area>7</Area>
+<Climate>tropical, humid, average temperature 20-32 degrees C, rains May-October</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Clipperton Island </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+</record>
+<record>
+<Location>Middle East, bordering the Gulf of Oman, the Persian Gulf, and the Caspian Sea, between Iraq and Pakistan</Location>
+<Geographiccoordinates>32 00 N, 53 00 E</Geographiccoordinates>
+<Area>1000000</Area>
+<Climate>mostly arid or semiarid, subtropical along Caspian coast</Climate>
+<Naturalresources>petroleum, natural gas, coal, chromium, copper, iron ore, lead, manganese, zinc, sulfur</Naturalresources>
+<Population>65619636</Population>
+<Populationgrowthrate>0.83% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 1.12 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Shi'a Muslim 89%, Sunni Muslim 10%, Zoroastrian, Jewish, Christian, and Baha'i 1%</Religions>
+<Countryname>Iran </Countryname>
+<Capital>Tehran</Capital>
+<Flagdescription>three equal horizontal bands of green (top), white, and red; the national emblem (a stylized representation of the word Allah) in red is centered in the white band; ALLAH AKBAR (God is Great) in white Arabic script is repeated 11 times along the bottom edge of the green band and 11 times along the top edge of the red band</Flagdescription>
+<GDP>purchasing power parity - $347.6 billion (1999 est.)</GDP>
+<Industries>petroleum, petrochemicals, textiles, cement and other construction materials, food processing (particularly sugar refining and vegetable oil production), metal fabricating, armaments</Industries>
+<Exports>$12.2 billion (f.o.b., 1998 est.)</Exports>
+<Imports>$13.8 billion (f.o.b., 1998 est.)</Imports>
+<Currency>10 Iranian rials (IR) = 1 toman; note - domestic figures are generally referred to in terms of the toman</Currency>
+<Airports>288 (1999 est.)</Airports>
+<Illicitdrugs>despite substantial interdiction efforts, Iran remains a key transshipment point for Southwest Asian heroin to Europe; domestic consumption of narcotics remains a persistent problem and Iranian press reports estimate that there are at least 1.2 million drug users in the country</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Mediterranean Sea, between Egypt and Lebanon</Location>
+<Geographiccoordinates>31 30 N, 34 45 E</Geographiccoordinates>
+<Area>20770</Area>
+<Climate>temperate; hot and dry in southern and eastern desert areas</Climate>
+<Naturalresources>copper, phosphates, bromide, potash, clay, sand, sulfur, asphalt, manganese, small amounts of natural gas and crude oil</Naturalresources>
+<Population>5842454</Population>
+<Populationgrowthrate>1.67% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Jewish 80.1%, Muslim 14.6% (mostly Sunni Muslim), Christian 2.1%, other 3.2% (1996 est.)</Religions>
+<Countryname>Israel </Countryname>
+<Capital>Jerusalem
+note: Israel proclaimed Jerusalem as its capital in 1950, but the US, like nearly all other countries, maintains its Embassy in Tel Aviv</Capital>
+<Flagdescription>white with a blue hexagram (six-pointed linear star) known as the Magen David (Shield of David) centered between two equal horizontal blue bands near the top and bottom edges of the flag</Flagdescription>
+<GDP>purchasing power parity - $105.4 billion (1999 est.)</GDP>
+<Industries>food processing, diamond cutting and polishing, textiles and apparel, chemicals, metal products, military equipment, transport equipment, electrical equipment, potash mining, high-technology electronics, tourism</Industries>
+<Exports>$23.5 billion (f.o.b., 1999)</Exports>
+<Imports>$30.6 billion (f.o.b., 1999)</Imports>
+<Currency>1 new Israeli shekel (NIS) = 100 new agorot</Currency>
+<Airports>58 (1999 est.)</Airports>
+<Illicitdrugs>increasingly concerned about cocaine and heroin abuse; drugs arrive in country from Lebanon and increasingly Jordan</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Europe, a peninsula extending into the central Mediterranean Sea, northeast of Tunisia</Location>
+<Geographiccoordinates>42 50 N, 12 50 E</Geographiccoordinates>
+<Area>301230</Area>
+<Climate>predominantly Mediterranean; Alpine in far north; hot, dry in south</Climate>
+<Naturalresources>mercury, potash, marble, sulfur, dwindling natural gas and crude oil reserves, fish, coal, arable land</Naturalresources>
+<Population>57634327</Population>
+<Populationgrowthrate>0.09% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>predominately Roman Catholic with mature Protestant and Jewish communities and a growing Muslim immigrant community</Religions>
+<Countryname>Italy </Countryname>
+<Capital>Rome</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), white, and red; similar to the flag of Ireland, which is longer and is green (hoist side), white, and orange; also similar to the flag of the Cote d'Ivoire, which has the colors reversed - orange (hoist side), white, and green
+note: inspired by the French flag brought to Italy by Napoleon in 1797</Flagdescription>
+<GDP>purchasing power parity - $1.212 trillion (1999 est.)</GDP>
+<Industries>tourism, machinery, iron and steel, chemicals, food processing, textiles, motor vehicles, clothing, footwear, ceramics</Industries>
+<Exports>$242.6 billion (f.o.b., 1998)</Exports>
+<Imports>$206.9 billion (f.o.b., 1998)</Imports>
+<Currency>1 Italian lira (Lit) = 100 centesimi</Currency>
+<Airports>136 (1999 est.)</Airports>
+<Illicitdrugs>important gateway for and consumer of Latin American cocaine and Southwest Asian heroin entering the European market</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Ghana and Liberia</Location>
+<Geographiccoordinates>8 00 N, 5 00 W</Geographiccoordinates>
+<Area>322460</Area>
+<Climate>tropical along coast, semiarid in far north; three seasons - warm and dry (November to March), hot and dry (March to May), hot and wet (June to October)</Climate>
+<Naturalresources>petroleum, diamonds, manganese, iron ore, cobalt, bauxite, copper, hydropower</Naturalresources>
+<Population>15980950</Population>
+<Populationgrowthrate>2.58% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1.06 male(s)/female
+65 years and over: 1 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 60%, Christian 22%, indigenous 18% (some of these are also numbered among the Christians and Muslims)</Religions>
+<Countryname>Cote d'Ivoire </Countryname>
+<Capital>Yamoussoukro
+note: although Yamoussoukro has been the capital since 1983, Abidjan remains the administrative center; the US, like other countries, maintains its Embassy in Abidjan</Capital>
+<Flagdescription>three equal vertical bands of orange (hoist side), white, and green; similar to the flag of Ireland, which is longer and has the colors reversed - green (hoist side), white, and orange; also similar to the flag of Italy, which is green (hoist side), white, and red; design was based on the flag of France</Flagdescription>
+<GDP>purchasing power parity - $25.7 billion (1999 est.)</GDP>
+<Industries>foodstuffs, beverages; wood products, oil refining, automobile assembly, textiles, fertilizer, construction materials, electricity</Industries>
+<Exports>$3.9 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2.6 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>36 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis, mostly for local consumption; minor transshipment point for Southwest and Southeast Asian heroin to Europe and occasionally to the US, and for Latin American cocaine destined for Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Persian Gulf, between Iran and Kuwait</Location>
+<Geographiccoordinates>33 00 N, 44 00 E</Geographiccoordinates>
+<Area>437072</Area>
+<Climate>mostly desert; mild to cool winters with dry, hot, cloudless summers; northern mountainous regions along Iranian and Turkish borders experience cold winters with occasionally heavy snows that melt in early spring, sometimes causing extensive flooding in central and southern Iraq</Climate>
+<Naturalresources>petroleum, natural gas, phosphates, sulfur</Naturalresources>
+<Population>22675617</Population>
+<Populationgrowthrate>2.86% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.88 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 97% (Shi'a 60%-65%, Sunni 32%-37%), Christian or other 3%</Religions>
+<Countryname>Iraq </Countryname>
+<Capital>Baghdad</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and black with three green five-pointed stars in a horizontal line centered in the white band; the phrase ALLAHU AKBAR (God is Great) in green Arabic script - Allahu to the right of the middle star and Akbar to the left of the middle star - was added in January 1991 during the Persian Gulf crisis; similar to the flag of Syria which has two stars but no script and the flag of Yemen which has a plain white band; also similar to the flag of Egypt which has a symbolic eagle centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $59.9 billion (1999 est.)</GDP>
+<Industries>petroleum, chemicals, textiles, construction materials, food processing</Industries>
+<Exports>$12.7 billion (1999 est.)</Exports>
+<Imports>$8.9 billion (1999 est.)</Imports>
+<Currency>1 Iraqi dinar (ID) = 1,000 fils</Currency>
+<Airports>113 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Asia, island chain between the North Pacific Ocean and the Sea of Japan, east of the Korean Peninsula</Location>
+<Geographiccoordinates>36 00 N, 138 00 E</Geographiccoordinates>
+<Area>377835</Area>
+<Climate>varies from tropical in south to cool temperate in north</Climate>
+<Naturalresources>negligible mineral resources, fish</Naturalresources>
+<Population>126549976</Population>
+<Populationgrowthrate>0.18% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>observe both Shinto and Buddhist 84%, other 16% (including Christian 0.7%)</Religions>
+<Countryname>Japan </Countryname>
+<Capital>Tokyo</Capital>
+<Flagdescription>white with a large red disk (representing the sun without rays) in the center</Flagdescription>
+<GDP>purchasing power parity - $2.95 trillion (1999 est.)</GDP>
+<Industries>among world's largest and technologically advanced producers of motor vehicles, electronic equipment, machine tools, steel and nonferrous metals, ships, chemicals; textiles, processed foods</Industries>
+<Exports>$413 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$306 billion (c.i.f., 1999 est.)</Imports>
+<Currency>yen</Currency>
+<Airports>171 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Europe, island in the English Channel, northwest of France</Location>
+<Geographiccoordinates>49 15 N, 2 10 W</Geographiccoordinates>
+<Area>116</Area>
+<Climate>temperate; mild winters and cool summers</Climate>
+<Naturalresources>arable land</Naturalresources>
+<Population>88915</Population>
+<Populationgrowthrate>0.52% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.11 male(s)/female
+under 15 years: 1.08 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.74 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican, Roman Catholic, Baptist, Congregational New Church, Methodist, Presbyterian</Religions>
+<Countryname>Jersey </Countryname>
+<Capital>Saint Helier</Capital>
+<Flagdescription>white with a diagonal red cross extending to the corners of the flag and in the upper quadrant, surmounted by a yellow crown, a red shield holding the three lions of England in yellow</Flagdescription>
+<GDP>purchasing power parity - $2.2 billion (1999 est.)</GDP>
+<Industries>tourism, banking and finance, dairy</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Jersey pound = 100 pence</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, south of Cuba</Location>
+<Geographiccoordinates>18 15 N, 77 30 W</Geographiccoordinates>
+<Area>10990</Area>
+<Climate>tropical; hot, humid; temperate interior</Climate>
+<Naturalresources>bauxite, gypsum, limestone</Naturalresources>
+<Population>2652689</Population>
+<Populationgrowthrate>0.46% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 61.3% (Church of God 21.2%, Baptist 8.8%, Anglican 5.5%, Seventh-Day Adventist 9%, Pentecostal 7.6%, Methodist 2.7%, United Church 2.7%, Brethren 1.1%, Jehovah's Witness 1.6%, Moravian 1.1%), Roman Catholic 4%, other, including some spiritual cults 34.7%</Religions>
+<Countryname>Jamaica </Countryname>
+<Capital>Kingston</Capital>
+<Flagdescription>diagonal yellow cross divides the flag into four triangles - green (top and bottom) and black (hoist side and outer side)</Flagdescription>
+<GDP>purchasing power parity - $8.8 billion (1999 est.)</GDP>
+<Industries>tourism, bauxite, textiles, food processing, light manufactures, rum, cement, metal, paper, chemical products</Industries>
+<Exports>$1.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2.7 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Jamaican dollar (J$) = 100 cents</Currency>
+<Airports>36 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine from Central and South America to North America and Europe; illicit cultivation of cannabis; government has an active manual cannabis eradication program</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Europe, island between the Greenland Sea and the Norwegian Sea, northeast of Iceland</Location>
+<Geographiccoordinates>71 00 N, 8 00 W</Geographiccoordinates>
+<Area>373</Area>
+<Climate>arctic maritime with frequent storms and persistent fog</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Jan Mayen </Countryname>
+<Flagdescription>the flag of Norway is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, northwest of Saudi Arabia</Location>
+<Geographiccoordinates>31 00 N, 36 00 E</Geographiccoordinates>
+<Area>89213</Area>
+<Climate>mostly arid desert; rainy season in west (November to April)</Climate>
+<Naturalresources>phosphates, potash, shale oil</Naturalresources>
+<Population>4998564</Population>
+<Populationgrowthrate>3.1% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.14 male(s)/female
+65 years and over: 0.98 male(s)/female
+total population: 1.1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 96%, Christian 4% (1997 est.)</Religions>
+<Countryname>Jordan </Countryname>
+<Capital>Amman</Capital>
+<Flagdescription>three equal horizontal bands of black (top), white, and green with a red isosceles triangle based on the hoist side bearing a small white seven-pointed star; the seven points on the star represent the seven fundamental laws of the Koran</Flagdescription>
+<GDP>purchasing power parity - $16 billion (1999 est.)</GDP>
+<Industries>phosphate mining, petroleum refining, cement, potash, light manufacturing, tourism</Industries>
+<Exports>$1.8 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.3 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Jordanian dinar (JD) = 1,000 fils</Currency>
+<Airports>20 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, atoll in the North Pacific Ocean, about one-third of the way from Hawaii to the Marshall Islands</Location>
+<Geographiccoordinates>16 45 N, 169 30 W</Geographiccoordinates>
+<Area>2</Area>
+<Climate>tropical, but generally dry; consistent northeast trade winds with little seasonal temperature variation</Climate>
+<Naturalresources>NA; guano deposits worked until depletion about 1890</Naturalresources>
+<Population></Population>
+<Countryname>Johnston Atoll </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, island in the Mozambique Channel, about one-third of the way between Madagascar and Mozambique</Location>
+<Geographiccoordinates>17 03 S, 42 45 E</Geographiccoordinates>
+<Area>4</Area>
+<Climate>tropical</Climate>
+<Naturalresources>guano deposits and other fertilizers</Naturalresources>
+<Population></Population>
+<Countryname>Juan de Nova Island </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Africa, bordering the Indian Ocean, between Somalia and Tanzania</Location>
+<Geographiccoordinates>1 00 N, 38 00 E</Geographiccoordinates>
+<Area>582650</Area>
+<Climate>varies from tropical along coast to arid in interior</Climate>
+<Naturalresources>gold, limestone, soda ash, salt barites, rubies, fluorspar, garnets, wildlife, hydropower</Naturalresources>
+<Population>30339770</Population>
+<Populationgrowthrate>1.53% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.79 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 38%, Roman Catholic 28%, indigenous beliefs 26%, Muslim 7%, other 1%</Religions>
+<Countryname>Kenya </Countryname>
+<Capital>Nairobi</Capital>
+<Flagdescription>three equal horizontal bands of black (top), red, and green; the red band is edged in white; a large warrior's shield covering crossed spears is superimposed at the center</Flagdescription>
+<GDP>purchasing power parity - $45.1 billion (1999 est.)</GDP>
+<Industries>small-scale consumer goods (plastic, furniture, batteries, textiles, soap, cigarettes, flour), agricultural products processing; oil refining, cement; tourism</Industries>
+<Exports>$2.2 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Kenyan shilling (KSh) = 100 cents</Currency>
+<Airports>230 (1999 est.)</Airports>
+<Illicitdrugs>widespread harvesting of small, wild plots of marijuana and qat (chat); transit country for South Asian heroin destined for Europe and, sometimes, North America; Indian methaqualone also transits on way to South Africa</Illicitdrugs>
+</record>
+<record>
+<Location>Central Asia, west of China</Location>
+<Geographiccoordinates>41 00 N, 75 00 E</Geographiccoordinates>
+<Area>198500</Area>
+<Climate>dry continental to polar in high Tien Shan; subtropical in southwest (Fergana Valley); temperate in northern foothill zone</Climate>
+<Naturalresources>abundant hydropower; significant deposits of gold and rare earth metals; locally exploitable coal, oil, and natural gas; other deposits of nepheline, mercury, bismuth, lead, and zinc</Naturalresources>
+<Population>4685230</Population>
+<Populationgrowthrate>1.43% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.6 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 75%, Russian Orthodox 20%, other 5%</Religions>
+<Countryname>Kyrgyzstan </Countryname>
+<Capital>Bishkek</Capital>
+<Flagdescription>red field with a yellow sun in the center having 40 rays representing the 40 Kirghiz tribes; on the obverse side the rays run counterclockwise, on the reverse, clockwise; in the center of the sun is a red ring crossed by two sets of three lines, a stylized representation of the roof of the traditional Kirghiz yurt</Flagdescription>
+<GDP>purchasing power parity - $10.3 billion (1999 est.)</GDP>
+<Industries>small machinery, textiles, food processing, cement, shoes, sawn logs, refrigerators, furniture, electric motors, gold, rare earth metals</Industries>
+<Exports>$515 million (1999 est.)</Exports>
+<Imports>$590 million (1999 est.)</Imports>
+<Currency>1 Kyrgyzstani som (KGS) = 100 tyiyn</Currency>
+<Airports>54 (1994 est.)</Airports>
+<Illicitdrugs>limited illicit cultivator of cannabis and opium poppy, mostly for CIS consumption; limited government eradication program; increasingly used as transshipment point for illicit drugs to Russia and Western Europe from Southwest Asia</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Asia, northern half of the Korean Peninsula bordering the Korea Bay and the Sea of Japan, between China and South Korea</Location>
+<Geographiccoordinates>40 00 N, 127 00 E</Geographiccoordinates>
+<Area>120540</Area>
+<Climate>temperate with rainfall concentrated in summer</Climate>
+<Naturalresources>coal, lead, tungsten, zinc, graphite, magnesite, iron ore, copper, gold, pyrites, salt, fluorspar, hydropower</Naturalresources>
+<Population>21687550</Population>
+<Populationgrowthrate>1.35% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.46 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>traditionally Buddhist and Confucianist, some Christian and syncretic Chondogyo (Religion of the Heavenly Way)
+note: autonomous religious activities now almost nonexistent; government-sponsored religious groups exist to provide illusion of religious freedom</Religions>
+<Countryname>North Korea </Countryname>
+<Capital>P'yongyang</Capital>
+<Flagdescription>three horizontal bands of blue (top), red (triple width), and blue; the red band is edged in white; on the hoist side of the red band is a white disk with a red five-pointed star</Flagdescription>
+<GDP>purchasing power parity - $22.6 billion (1999 est.)</GDP>
+<Industries>military products; machine building, electric power, chemicals; mining (coal, iron ore, magnesite, graphite, copper, zinc, lead, and precious metals), metallurgy; textiles, food processing; tourism</Industries>
+<Exports>$680 million (f.o.b., 1998 est.)</Exports>
+<Imports>$954 million (c.i.f., 1998 est.)</Imports>
+<Currency>1 North Korean won (Wn) = 100 chon</Currency>
+<Airports>49 (1994 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, reef in the North Pacific Ocean, about one-half of the way from Hawaii to American Samoa</Location>
+<Geographiccoordinates>6 24 N, 162 24 W</Geographiccoordinates>
+<Area>1</Area>
+<Climate>tropical, but moderated by prevailing winds</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Kingman Reef </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>lagoon was used as a halfway station between Hawaii and American Samoa by Pan American Airways for flying boats in 1937 and 1938</Airports>
+</record>
+<record>
+<Location>Oceania, group of islands in the Pacific Ocean, straddling the equator, about one-half of the way from Hawaii to Australia; note - on 1 January 1995, Kiribati unilaterally moved the International Date Line from the middle of the country to include its easternmost islands and make it the same day throughout the country</Location>
+<Geographiccoordinates>1 25 N, 173 00 E</Geographiccoordinates>
+<Area>717</Area>
+<Climate>tropical; marine, hot and humid, moderated by trade winds</Climate>
+<Naturalresources>phosphate (production discontinued in 1979)</Naturalresources>
+<Population>91985</Population>
+<Populationgrowthrate>2.34% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 53%, Protestant (Congregational) 41%, Seventh-Day Adventist, Baha'i, Church of God, Mormon 6% (1985 est.)</Religions>
+<Countryname>Kiribati </Countryname>
+<Capital>Tarawa</Capital>
+<Flagdescription>the upper half is red with a yellow frigate bird flying over a yellow rising sun, and the lower half is blue with three horizontal wavy white stripes to represent the ocean</Flagdescription>
+<GDP>purchasing power parity - $74 million (1999 est.), supplemented by a nearly equal amount from external sources</GDP>
+<Industries>fishing, handicrafts</Industries>
+<Exports>$6 million (f.o.b., 1998)</Exports>
+<Imports>$37 million (c.i.f., 1998)</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>21 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Asia, southern half of the Korean Peninsula bordering the Sea of Japan and the Yellow Sea</Location>
+<Geographiccoordinates>37 00 N, 127 30 E</Geographiccoordinates>
+<Area>98480</Area>
+<Climate>temperate, with rainfall heavier in summer than winter</Climate>
+<Naturalresources>coal, tungsten, graphite, molybdenum, lead, hydropower potential</Naturalresources>
+<Population>47470969</Population>
+<Populationgrowthrate>0.93% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.13 male(s)/female
+under 15 years: 1.12 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.63 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 49%, Buddhist 47%, Confucianist 3%, Shamanist, Chondogyo (Religion of the Heavenly Way), and other 1%</Religions>
+<Countryname>South Korea </Countryname>
+<Capital>Seoul</Capital>
+<Flagdescription>white with a red (top) and blue yin-yang symbol in the center; there is a different black trigram from the ancient I Ching (Book of Changes) in each corner of the white field</Flagdescription>
+<GDP>purchasing power parity - $625.7 billion (1999 est.)</GDP>
+<Industries>electronics, automobile production, chemicals, shipbuilding, steel, textiles, clothing, footwear, food processing</Industries>
+<Exports>$144 billion (f.o.b., 1999)</Exports>
+<Imports>$116 billion (c.i.f., 1999)</Imports>
+<Currency>1 South Korean won (W) = 100 chun (theoretical)</Currency>
+<Airports>103 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, island in the Indian Ocean, south of Indonesia</Location>
+<Geographiccoordinates>10 30 S, 105 40 E</Geographiccoordinates>
+<Area>135</Area>
+<Climate>tropical; heat and humidity moderated by trade winds</Climate>
+<Naturalresources>phosphate</Naturalresources>
+<Population>2564</Population>
+<Populationgrowthrate>7.77% (2000 est.)</Populationgrowthrate>
+<Religions>Buddhist 55%, Christian 15%, Muslim 10%, other 20% (1991)</Religions>
+<Countryname>Christmas Island </Countryname>
+<Capital>The Settlement</Capital>
+<Flagdescription>the flag of Australia is used</Flagdescription>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>tourism, phosphate extraction (near depletion)</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, bordering the Persian Gulf, between Iraq and Saudi Arabia</Location>
+<Geographiccoordinates>29 30 N, 45 45 E</Geographiccoordinates>
+<Area>17820</Area>
+<Climate>dry desert; intensely hot summers; short, cool winters</Climate>
+<Naturalresources>petroleum, fish, shrimp, natural gas</Naturalresources>
+<Population>1973572</Population>
+<Populationgrowthrate>3.44% (2000 est.)
+note: this rate reflects a return to pre-Gulf crisis immigration of expatriates</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.76 male(s)/female
+65 years and over: 1.82 male(s)/female
+total population: 1.5 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 85% (Sunni 45%, Shi'a 40%), Christian, Hindu, Parsi, and other 15%</Religions>
+<Countryname>Kuwait </Countryname>
+<Capital>Kuwait</Capital>
+<Flagdescription>three equal horizontal bands of green (top), white, and red with a black trapezoid based on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $44.8 billion (1999 est.)</GDP>
+<Industries>petroleum, petrochemicals, desalination, food processing, construction materials, salt, construction</Industries>
+<Exports>$13.5 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$8.1 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Kuwaiti dinar (KD) = 1,000 fils</Currency>
+<Airports>7 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Asia, northwest of China</Location>
+<Geographiccoordinates>48 00 N, 68 00 E</Geographiccoordinates>
+<Area>2717300</Area>
+<Climate>continental, cold winters and hot summers, arid and semiarid</Climate>
+<Naturalresources>major deposits of petroleum, natural gas, coal, iron ore, manganese, chrome ore, nickel, cobalt, copper, molybdenum, lead, zinc, bauxite, gold, uranium</Naturalresources>
+<Population>16733227</Population>
+<Populationgrowthrate>-0.05% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.94 male(s)/female
+65 years and over: 0.51 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 47%, Russian Orthodox 44%, Protestant 2%, other 7%</Religions>
+<Countryname>Kazakhstan </Countryname>
+<Capital>Astana
+note: the government moved from Almaty to Astana in December 1998</Capital>
+<Flagdescription>sky blue background representing the endless sky and a gold sun with 32 rays soaring above a golden steppe eagle in the center; on the hoist side is a "national ornamentation" in gold</Flagdescription>
+<GDP>purchasing power parity - $54.5 billion (1999 est.)</GDP>
+<Industries>oil, coal, iron ore, manganese, chromite, lead, zinc, copper, titanium, bauxite, gold, silver, phosphates, sulfur, iron and steel, nonferrous metal, tractors and other agricultural machinery, electric motors, construction materials</Industries>
+<Exports>$5.2 billion (1999 est.)</Exports>
+<Imports>$4.8 billion (1999 est.)</Imports>
+<Currency>1 Kazakhstani tenge = 100 tiyn</Currency>
+<Airports>10 (1997 est.)</Airports>
+<Illicitdrugs>significant illicit cultivation of cannabis and limited cultivation of opium poppy and ephedra (for the drug ephedrone); limited government eradication program; cannabis consumed largely in the CIS; used as transshipment point for illicit drugs to Russia, North America, and Western Europe from Southwest Asia</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, northeast of Thailand, west of Vietnam</Location>
+<Geographiccoordinates>18 00 N, 105 00 E</Geographiccoordinates>
+<Area>236800</Area>
+<Climate>tropical monsoon; rainy season (May to November); dry season (December to April)</Climate>
+<Naturalresources>timber, hydropower, gypsum, tin, gold, gemstones</Naturalresources>
+<Population>5497459</Population>
+<Populationgrowthrate>2.5% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.85 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist 60% (in October 1999, the regime proposed a constitutional amendment making Buddhism the state religion; the National Assembly is expected to vote on the amendment sometime in 2000), animist and other 40%</Religions>
+<Countryname>Laos </Countryname>
+<Capital>Vientiane</Capital>
+<Flagdescription>three horizontal bands of red (top), blue (double width), and red with a large white disk centered in the blue band</Flagdescription>
+<GDP>purchasing power parity - $7 billion (1999 est.)</GDP>
+<Industries>tin and gypsum mining, timber, electric power, agricultural processing, construction, garments</Industries>
+<Exports>$271 million (f.o.b., 1999 est.)</Exports>
+<Imports>$497 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 new kip (NK) = 100 at</Currency>
+<Airports>52 (1999 est.)</Airports>
+<Illicitdrugs>world's third-largest illicit opium producer (estimated cultivation in 1999 - 21,800 hectares, a 16% decrease over 1998; estimated potential production in 1999 - 140 metric tons, about the same as in 1998); potential heroin producer; transshipment point for heroin and methamphetamines produced in Burma; illicit producer of cannabis</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Mediterranean Sea, between Israel and Syria</Location>
+<Geographiccoordinates>33 50 N, 35 50 E</Geographiccoordinates>
+<Area>10400</Area>
+<Climate>Mediterranean; mild to cool, wet winters with hot, dry summers; Lebanon mountains experience heavy winter snows</Climate>
+<Naturalresources>limestone, iron ore, salt, water-surplus state in a water-deficit region, arable land</Naturalresources>
+<Population>3578036</Population>
+<Populationgrowthrate>1.38% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 70% (5 legally recognized Islamic groups - Shi'a, Sunni, Druze, Isma'ilite, Alawite or Nusayri), Christian 30% (11 legally recognized Christian groups - 4 Orthodox Christian, 6 Catholic, 1 Protestant), Jewish NEGL%</Religions>
+<Countryname>Lebanon </Countryname>
+<Capital>Beirut</Capital>
+<Flagdescription>three horizontal bands of red (top), white (double width), and red with a green and brown cedar tree centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $16.2 billion (1999 est.)</GDP>
+<Industries>banking; food processing; jewelry; cement; textiles; mineral and chemical products; wood and furniture products; oil refining; metal fabricating</Industries>
+<Exports>$866 million (f.o.b., 1999 est.)</Exports>
+<Imports>$5.7 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Lebanese pound = 100 piasters</Currency>
+<Airports>9 (1999 est.)</Airports>
+<Illicitdrugs>inconsequential producer of hashish; some heroin processing mostly in the Bekaa valley; a Lebanese/Syrian eradication campaign started in the early 1990s has practically eliminated the opium and cannabis crops</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Europe, bordering the Baltic Sea, between Estonia and Lithuania</Location>
+<Geographiccoordinates>57 00 N, 25 00 E</Geographiccoordinates>
+<Area>64589</Area>
+<Climate>maritime; wet, moderate winters</Climate>
+<Naturalresources>minimal; amber, peat, limestone, dolomite, hydropower, arable land</Naturalresources>
+<Population>2404926</Population>
+<Populationgrowthrate>-0.84% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.48 male(s)/female
+total population: 0.85 male(s)/female (2000 est.)</Sexratio>
+<Religions>Lutheran, Roman Catholic, Russian Orthodox</Religions>
+<Countryname>Latvia </Countryname>
+<Capital>Riga</Capital>
+<Flagdescription>three horizontal bands of maroon (top), white (half-width), and maroon</Flagdescription>
+<GDP>purchasing power parity - $9.8 billion (1999 est.)</GDP>
+<Industries>buses, vans, street and railroad cars, synthetic fibers, agricultural machinery, fertilizers, washing machines, radios, electronics, pharmaceuticals, processed foods, textiles; dependent on imports for energy, raw materials, and intermediate products</Industries>
+<Exports>$1.9 billion (f.o.b., 1999)</Exports>
+<Imports>$2.8 billion (f.o.b., 1998)</Imports>
+<Currency>1 Latvian lat (LVL) = 100 santims</Currency>
+<Airports>50 (1994 est.)</Airports>
+<Illicitdrugs>transshipment point for opiates and cannabis from Central and Southwest Asia to Western Europe and Scandinavia and Latin American cocaine and some synthetics from Western Europe to CIS; limited production of illicit amphetamines, ephedrine, and ecstasy for export</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Europe, bordering the Baltic Sea, between Latvia and Russia</Location>
+<Geographiccoordinates>56 00 N, 24 00 E</Geographiccoordinates>
+<Area>65200</Area>
+<Climate>transitional, between maritime and continental; wet, moderate winters and summers</Climate>
+<Naturalresources>peat, arable land</Naturalresources>
+<Population>3620756</Population>
+<Populationgrowthrate>-0.29% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.51 male(s)/female
+total population: 0.88 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic (primarily), Lutheran, Russian Orthodox, Protestant, evangelical Christian Baptist, Muslim, Jewish</Religions>
+<Countryname>Lithuania </Countryname>
+<Capital>Vilnius</Capital>
+<Flagdescription>three equal horizontal bands of yellow (top), green, and red</Flagdescription>
+<GDP>purchasing power parity - $17.3 billion (1999 est.)</GDP>
+<Industries>metal-cutting machine tools, electric motors, television sets, refrigerators and freezers, petroleum refining, shipbuilding (small ships), furniture making, textiles, food processing, fertilizers, agricultural machinery, optical equipment, electronic components, computers, amber</Industries>
+<Exports>$3.3 billion (f.o.b., 1999)</Exports>
+<Imports>$4.5 billion (f.o.b., 1999)</Imports>
+<Currency>1 Lithuanian litas = 100 centas</Currency>
+<Airports>96 (1994 est.)</Airports>
+<Illicitdrugs>transshipment point for opiates and other illicit drugs from Southwest Asia, Latin America, and Western Europe to Western Europe and Scandinavia</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Cote d'Ivoire and Sierra Leone</Location>
+<Geographiccoordinates>6 30 N, 9 30 W</Geographiccoordinates>
+<Area>111370</Area>
+<Climate>tropical; hot, humid; dry winters with hot days and cool to cold nights; wet, cloudy summers with frequent heavy showers</Climate>
+<Naturalresources>iron ore, timber, diamonds, gold, hydropower</Naturalresources>
+<Population>3164156</Population>
+<Populationgrowthrate>1.94% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 1.01 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 40%, Christian 40%, Muslim 20%</Religions>
+<Countryname>Liberia </Countryname>
+<Capital>Monrovia</Capital>
+<Flagdescription>11 equal horizontal stripes of red (top and bottom) alternating with white; there is a white five-pointed star on a blue square in the upper hoist-side corner; the design was based on the US flag</Flagdescription>
+<GDP>purchasing power parity - $2.85 billion (1999 est.)</GDP>
+<Industries>rubber processing, palm oil processing, diamonds</Industries>
+<Exports>$39 million (f.o.b., 1998 est.)</Exports>
+<Imports>$142 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 Liberian dollar (L$) = 100 cents</Currency>
+<Airports>45 (1999 est.)</Airports>
+<Illicitdrugs>increasingly a transshipment point for Southeast and Southwest Asian heroin and South American cocaine for the European and US markets</Illicitdrugs>
+</record>
+<record>
+<Location>Central Europe, south of Poland</Location>
+<Geographiccoordinates>48 40 N, 19 30 E</Geographiccoordinates>
+<Area>48845</Area>
+<Climate>temperate; cool summers; cold, cloudy, humid winters</Climate>
+<Naturalresources>brown coal and lignite; small amounts of iron ore, copper and manganese ore; salt; arable land</Naturalresources>
+<Population>5407956</Population>
+<Populationgrowthrate>0.12% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 60.3%, atheist 9.7%, Protestant 8.4%, Orthodox 4.1%, other 17.5%</Religions>
+<Countryname>Slovakia </Countryname>
+<Capital>Bratislava</Capital>
+<Flagdescription>three equal horizontal bands of white (top), blue, and red superimposed with the Slovak cross in a shield centered on the hoist side; the cross is white centered on a background of red and blue</Flagdescription>
+<GDP>purchasing power parity - $45.9 billion (1999 est.)</GDP>
+<Industries>metal and metal products; food and beverages; electricity, gas, coke, oil, nuclear fuel; chemicals and manmade fibers; machinery; paper and printing; earthenware and ceramics; transport vehicles; textiles; electrical and optical apparatus; rubber products</Industries>
+<Exports>$10.1 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$11.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 koruna (Sk) = 100 halierov</Currency>
+<Airports>36 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for Southwest Asian heroin bound for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, atoll in the North Pacific Ocean, about one-half of the way from Hawaii to American Samoa</Location>
+<Geographiccoordinates>5 52 N, 162 06 W</Geographiccoordinates>
+<Area>11</Area>
+<Climate>equatorial, hot, and very rainy</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Palmyra Atoll </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Europe, between Austria and Switzerland</Location>
+<Geographiccoordinates>47 10 N, 9 32 E</Geographiccoordinates>
+<Area>160</Area>
+<Climate>continental; cold, cloudy winters with frequent snow or rain; cool to moderately warm, cloudy, humid summers</Climate>
+<Naturalresources>hydroelectric potential, arable land</Naturalresources>
+<Population>32207</Population>
+<Populationgrowthrate>1.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 0.99 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.66 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 80%, Protestant 7.4%, unknown 7.7%, other 4.9% (1996)</Religions>
+<Countryname>Liechtenstein </Countryname>
+<Capital>Vaduz</Capital>
+<Flagdescription>two equal horizontal bands of blue (top) and red with a gold crown on the hoist side of the blue band</Flagdescription>
+<GDP>purchasing power parity - $730 million (1998 est.)</GDP>
+<Industries>electronics, metal manufacturing, textiles, ceramics, pharmaceuticals, food products, precision instruments, tourism</Industries>
+<Exports>$2.47 billion (1996)</Exports>
+<Imports>$917.3 million (1996)</Imports>
+<Currency>1 Swiss franc, franken, or franco (SFR) = 100 centimes, rappen, or centesimi</Currency>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Southern Africa, an enclave of South Africa</Location>
+<Geographiccoordinates>29 30 S, 28 30 E</Geographiccoordinates>
+<Area>30355</Area>
+<Climate>temperate; cool to cold, dry winters; hot, wet summers</Climate>
+<Naturalresources>water, agricultural and grazing land, some diamonds and other minerals</Naturalresources>
+<Population>2143141</Population>
+<Populationgrowthrate>1.65% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 80%, indigenous beliefs 20%</Religions>
+<Countryname>Lesotho </Countryname>
+<Capital>Maseru</Capital>
+<Flagdescription>divided diagonally from the lower hoist side corner; the upper half is white, bearing the brown silhouette of a large shield with crossed spear and club; the lower half is a diagonal blue band with a green triangle in the corner</Flagdescription>
+<GDP>purchasing power parity - $4.7 billion (1998 est.)</GDP>
+<Industries>food, beverages, textiles, handicrafts; construction; tourism</Industries>
+<Exports>$235 million (f.o.b., 1998 est.)</Exports>
+<Imports>$700 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 loti (L) = 100 lisente; note - maloti (M) is the plural form of loti</Currency>
+<Airports>29 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Europe, between France and Germany</Location>
+<Geographiccoordinates>49 45 N, 6 10 E</Geographiccoordinates>
+<Area>2586</Area>
+<Climate>modified continental with mild winters, cool summers</Climate>
+<Naturalresources>iron ore (no longer exploited), arable land</Naturalresources>
+<Population>437389</Population>
+<Populationgrowthrate>1.27% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.66 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 97%, Protestant and Jewish 3%</Religions>
+<Countryname>Luxembourg </Countryname>
+<Capital>Luxembourg</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and light blue; similar to the flag of the Netherlands, which uses a darker blue and is shorter; design was based on the flag of France</Flagdescription>
+<GDP>purchasing power parity - $14.7 billion (1999 est.)</GDP>
+<Industries>banking, iron and steel, food processing, chemicals, metal products, engineering, tires, glass, aluminum</Industries>
+<Exports>$7.5 billion (f.o.b., 1998)</Exports>
+<Imports>$9.6 billion (c.i.f., 1998)</Imports>
+<Currency>1 Luxembourg franc (LuxF) = 100 centimes; note - centimes no longer in use</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Africa, bordering the Mediterranean Sea, between Egypt and Tunisia</Location>
+<Geographiccoordinates>25 00 N, 17 00 E</Geographiccoordinates>
+<Area>1759540</Area>
+<Climate>Mediterranean along coast; dry, extreme desert interior</Climate>
+<Naturalresources>petroleum, natural gas, gypsum</Naturalresources>
+<Population>5115450</Population>
+<Populationgrowthrate>2.42% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.07 male(s)/female
+65 years and over: 0.98 male(s)/female
+total population: 1.06 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 97%</Religions>
+<Countryname>Libya </Countryname>
+<Capital>Tripoli</Capital>
+<Flagdescription>plain green; green is the traditional color of Islam (the state religion)</Flagdescription>
+<GDP>purchasing power parity - $39.3 billion (1999 est.)</GDP>
+<Industries>petroleum, food processing, textiles, handicrafts, cement</Industries>
+<Exports>$6.6 billion (f.o.b., 1998 est.)</Exports>
+<Imports>$7 billion (f.o.b., 1998 est.)</Imports>
+<Currency>1 Libyan dinar (LD) = 1,000 dirhams</Currency>
+<Airports>142 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, island in the Indian Ocean, east of Mozambique</Location>
+<Geographiccoordinates>20 00 S, 47 00 E</Geographiccoordinates>
+<Area>587040</Area>
+<Climate>tropical along coast, temperate inland, arid in south</Climate>
+<Naturalresources>graphite, chromite, coal, bauxite, salt, quartz, tar sands, semiprecious stones, mica, fish, hydropower</Naturalresources>
+<Population>15506472</Population>
+<Populationgrowthrate>3.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.89 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 52%, Christian 41%, Muslim 7%</Religions>
+<Countryname>Madagascar </Countryname>
+<Capital>Antananarivo</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and green with a vertical white band of the same width on hoist side</Flagdescription>
+<GDP>purchasing power parity - $11.5 billion (1999 est.)</GDP>
+<Industries>meat processing, soap, breweries, tanneries, sugar, textiles, glassware, cement, automobile assembly plant, paper, petroleum, tourism</Industries>
+<Exports>$600 million (f.o.b., 1998 est.)</Exports>
+<Imports>$881 million (c.i.f., 1998 est.)</Imports>
+<Currency>1 Malagasy franc (FMG) = 100 centimes</Currency>
+<Airports>133 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis (cultivated and wild varieties) used mostly for domestic consumption; transshipment point for heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, north of Trinidad and Tobago</Location>
+<Geographiccoordinates>14 40 N, 61 00 W</Geographiccoordinates>
+<Area>1100</Area>
+<Climate>tropical; moderated by trade winds; rainy season (June to October); vulnerable to devastating cyclones (hurricanes) every eight years on average; average temperature 17.3 degrees C; humid</Climate>
+<Naturalresources>coastal scenery and beaches, cultivable land</Naturalresources>
+<Population>414516</Population>
+<Populationgrowthrate>0.96% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.02 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95%, Hindu and pagan African 5%</Religions>
+<Countryname>Martinique </Countryname>
+<Capital>Fort-de-France</Capital>
+<Flagdescription>a light blue background is divided into four quadrants by a white cross; in the center of each rectangle is a white snake; the flag of France is used for official occasions</Flagdescription>
+<GDP>purchasing power parity - $4.24 billion (1996 est.)</GDP>
+<Industries>construction, rum, cement, oil refining, sugar, tourism</Industries>
+<Exports>$250 million (f.o.b., 1997)</Exports>
+<Imports>$2 billion (c.i.f., 1997)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>2 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine and marijuana bound for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Asia, bordering the South China Sea and China</Location>
+<Geographiccoordinates>22 10 N, 113 33 E</Geographiccoordinates>
+<Area>21</Area>
+<Climate>subtropical; marine with cool winters, warm summers</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>445594</Population>
+<Populationgrowthrate>1.83% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.92 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist 50%, Roman Catholic 15%, none and other 35% (1997 est.)</Religions>
+<Countryname>Macau </Countryname>
+<Flagdescription>light green with a lotus flower above a stylized bridge and water in white, beneath an arc of five gold, five-pointed stars: one large in center of arc and four smaller</Flagdescription>
+<GDP>purchasing power parity - $7.65 billion (1998 est.)</GDP>
+<Industries>clothing, textiles, toys, electronics, footwear, tourism, gambling</Industries>
+<Exports>$1.7 billion (f.o.b., 1999)</Exports>
+<Imports>$1.5 billion (c.i.f., 1999)</Imports>
+<Currency>1 pataca (P) = 100 avos</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Europe, northeast of Romania</Location>
+<Geographiccoordinates>47 00 N, 29 00 E</Geographiccoordinates>
+<Area>33843</Area>
+<Climate>moderate winters, warm summers</Climate>
+<Naturalresources>lignite, phosphorites, gypsum, arable land</Naturalresources>
+<Population>4430654</Population>
+<Populationgrowthrate>-0% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 0.59 male(s)/female
+total population: 0.91 male(s)/female (2000 est.)</Sexratio>
+<Religions>Eastern Orthodox 98.5%, Jewish 1.5%, Baptist (only about 1,000 members) (1991)</Religions>
+<Countryname>Moldova </Countryname>
+<Capital>Chisinau</Capital>
+<Flagdescription>same color scheme as Romania - three equal vertical bands of blue (hoist side), yellow, and red; emblem in center of flag is of a Roman eagle of gold outlined in black with a red beak and talons carrying a yellow cross in its beak and a green olive branch in its right talons and a yellow scepter in its left talons; on its breast is a shield divided horizontally red over blue with a stylized ox head, star, rose, and crescent all in black-outlined yellow</Flagdescription>
+<GDP>purchasing power parity - $9.7 billion (1999 est.)</GDP>
+<Industries>food processing, agricultural machinery, foundry equipment, refrigerators and freezers, washing machines, hosiery, sugar, vegetable oil, shoes, textiles</Industries>
+<Exports>$470 million (f.o.b., 1999)</Exports>
+<Imports>$560 million (f.o.b., 1999)</Imports>
+<Currency>Moldovan leu (MLD) (plural lei)</Currency>
+<Airports>26 (1994 est.)</Airports>
+<Illicitdrugs>limited cultivation of opium poppy and cannabis, mostly for CIS consumption; transshipment point for illicit drugs from Southwest Asia via Central Asia to Russia, Western Europe and possibly the US</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, island in the Mozambique Channel, about one-half of the way from northern Madagascar to northern Mozambique</Location>
+<Geographiccoordinates>12 50 S, 45 10 E</Geographiccoordinates>
+<Area>374</Area>
+<Climate>tropical; marine; hot, humid, rainy season during northeastern monsoon (November to May); dry season is cooler (May to November)</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>155911</Population>
+<Populationgrowthrate>4.76% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1.2 male(s)/female
+65 years and over: 0.98 male(s)/female
+total population: 1.1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 97%, Christian (mostly Roman Catholic)</Religions>
+<Countryname>Mayotte </Countryname>
+<Capital>Mamoutzou</Capital>
+<Flagdescription>the flag of France is used</Flagdescription>
+<GDP>purchasing power parity - $85 million (1998 est.)</GDP>
+<Industries>newly created lobster and shrimp industry, construction</Industries>
+<Exports>$3.44 million (f.o.b., 1997)</Exports>
+<Imports>$141.3 million (f.o.b., 1997)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Asia, between China and Russia</Location>
+<Geographiccoordinates>46 00 N, 105 00 E</Geographiccoordinates>
+<Area>1000000</Area>
+<Climate>desert; continental (large daily and seasonal temperature ranges)</Climate>
+<Naturalresources>oil, coal, copper, molybdenum, tungsten, phosphates, tin, nickel, zinc, wolfram, fluorspar, gold</Naturalresources>
+<Population>2650952</Population>
+<Populationgrowthrate>1.54% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>predominantly Tibetan Buddhist, Muslim 4%
+note: previously limited religious activity because of communist regime</Religions>
+<Countryname>Mongolia </Countryname>
+<Capital>Ulaanbaatar</Capital>
+<Flagdescription>three equal, vertical bands of red (hoist side), blue, and red; centered on the hoist-side red band in yellow is the national emblem ("soyombo" - a columnar arrangement of abstract and geometric representation for fire, sun, moon, earth, water, and the yin-yang symbol)</Flagdescription>
+<GDP>purchasing power parity - $6.1 billion (1999 est.)</GDP>
+<Industries>construction materials, mining (particularly coal and copper); food and beverages, processing of animal products</Industries>
+<Exports>$316.8 million (f.o.b., 1998)</Exports>
+<Imports>$472.4 million (f.o.b., 1998)</Imports>
+<Currency>1 tughrik (Tug) = 100 mongos</Currency>
+<Airports>34 (1994 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, island in the Caribbean Sea, southeast of Puerto Rico</Location>
+<Geographiccoordinates>16 45 N, 62 12 W</Geographiccoordinates>
+<Area>100</Area>
+<Climate>tropical; little daily or seasonal temperature variation</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>6409</Population>
+<Populationgrowthrate>20.53% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 1.15 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican, Methodist, Roman Catholic, Pentecostal, Seventh-Day Adventist, other Christian denominations</Religions>
+<Countryname>Montserrat </Countryname>
+<Capital>Plymouth (abandoned in 1997 due to volcanic activity; interim government buildings have been built at Brades, in the Carr's Bay/Little Bay vicinity at the northwest end of Montserrat)</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and the Montserratian coat of arms centered in the outer half of the flag; the coat of arms features a woman standing beside a yellow harp with her arm around a black cross</Flagdescription>
+<GDP>purchasing power parity - $31 million (1998 est.)</GDP>
+<Industries>tourism, rum, textiles, electronic appliances</Industries>
+<Exports>$1.5 million (1998)</Exports>
+<Imports>$26 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, east of Zambia</Location>
+<Geographiccoordinates>13 30 S, 34 00 E</Geographiccoordinates>
+<Area>118480</Area>
+<Climate>sub-tropical; rainy season (November to May); dry season (May to November)</Climate>
+<Naturalresources>limestone, arable land, hydropower, unexploited deposits of uranium, coal, and bauxite</Naturalresources>
+<Population>10385849</Population>
+<Populationgrowthrate>1.61% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 55%, Roman Catholic 20%, Muslim 20%, indigenous beliefs</Religions>
+<Countryname>Malawi </Countryname>
+<Capital>Lilongwe</Capital>
+<Flagdescription>three equal horizontal bands of black (top), red, and green with a radiant, rising, red sun centered in the black band</Flagdescription>
+<GDP>purchasing power parity - $9.4 billion (1999 est.)</GDP>
+<Industries>tobacco, tea, sugar, sawmill products, cement, consumer goods</Industries>
+<Exports>$510 million (f.o.b., 1999)</Exports>
+<Imports>$512 million (f.o.b., 1999)</Imports>
+<Currency>1 Malawian kwacha (MK) = 100 tambala</Currency>
+<Airports>44 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Europe, north of Greece</Location>
+<Geographiccoordinates>41 50 N, 22 00 E</Geographiccoordinates>
+<Area>25333</Area>
+<Climate>warm, dry summers and autumns and relatively cold winters with heavy snowfall</Climate>
+<Naturalresources>chromium, lead, zinc, manganese, tungsten, nickel, low-grade iron ore, asbestos, sulfur, timber, arable land</Naturalresources>
+<Population>2041467</Population>
+<Populationgrowthrate>0.04% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.08 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Macedonian Orthodox 67%, Muslim 30%, other 3%</Religions>
+<Countryname>The Former Yugoslav Republic of Macedonia </Countryname>
+<Capital>Skopje</Capital>
+<Flagdescription>a rising yellow sun with eight rays extending to the edges of the red field</Flagdescription>
+<GDP>purchasing power parity - $7.6 billion (1999 est.)</GDP>
+<Industries>coal, metallic chromium, lead, zinc, ferronickel, textiles, wood products, tobacco</Industries>
+<Exports>$1.2 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$1.56 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Macedonian denar (MKD) = 100 deni</Currency>
+<Airports>16 (1999 est.)</Airports>
+<Illicitdrugs>increasing transshipment point for Southwest Asian heroin and hashish; minor transit point for South American cocaine destined for Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, southwest of Algeria</Location>
+<Geographiccoordinates>17 00 N, 4 00 W</Geographiccoordinates>
+<Area>1000000</Area>
+<Climate>subtropical to arid; hot and dry February to June; rainy, humid, and mild June to November; cool and dry November to February</Climate>
+<Naturalresources>gold, phosphates, kaolin, salt, limestone, uranium, hydropower
+note: bauxite, iron ore, manganese, tin, and copper deposits are known but not exploited</Naturalresources>
+<Population>10685948</Population>
+<Populationgrowthrate>2.98% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.89 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 90%, indigenous beliefs 9%, Christian 1%</Religions>
+<Countryname>Mali </Countryname>
+<Capital>Bamako</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), yellow, and red; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $8.5 billion (1999 est.)</GDP>
+<Industries>minor local consumer goods production and food processing; construction; phosphate and gold mining</Industries>
+<Exports>$640 million (f.o.b., 1999 est.)</Exports>
+<Imports>$650 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>28 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Europe, bordering the Mediterranean Sea, on the southern coast of France, near the border with Italy</Location>
+<Geographiccoordinates>43 44 N, 7 24 E</Geographiccoordinates>
+<Area>1</Area>
+<Climate>Mediterranean with mild, wet winters and hot, dry summers</Climate>
+<Naturalresources>none</Naturalresources>
+<Population>31693</Population>
+<Populationgrowthrate>0.48% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 0.91 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%</Religions>
+<Countryname>Monaco </Countryname>
+<Capital>Monaco</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and white; similar to the flag of Indonesia which is longer and the flag of Poland which is white (top) and red</Flagdescription>
+<GDP>purchasing power parity - $870 million (1999 est.)</GDP>
+<Industries>tourism, construction, small-scale industrial and consumer products</Industries>
+<Exports>$NA; full customs integration with France, which collects and rebates Monegasque trade duties; also participates in EU market system through customs union with France</Exports>
+<Imports>$NA; full customs integration with France, which collects and rebates Monegasque trade duties; also participates in EU market system through customs union with France</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>linked to airport in Nice, France, by helicopter service</Airports>
+</record>
+<record>
+<Location>Northern Africa, bordering the North Atlantic Ocean and the Mediterranean Sea, between Algeria and Western Sahara</Location>
+<Geographiccoordinates>32 00 N, 5 00 W</Geographiccoordinates>
+<Area>446550</Area>
+<Climate>Mediterranean, becoming more extreme in the interior</Climate>
+<Naturalresources>phosphates, iron ore, manganese, lead, zinc, fish, salt</Naturalresources>
+<Population>30122350</Population>
+<Populationgrowthrate>1.74% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 98.7%, Christian 1.1%, Jewish 0.2%</Religions>
+<Countryname>Morocco </Countryname>
+<Capital>Rabat</Capital>
+<Flagdescription>red with a green pentacle (five-pointed, linear star) known as Solomon's seal in the center of the flag; green is the traditional color of Islam</Flagdescription>
+<GDP>purchasing power parity - $108 billion (1999 est.)</GDP>
+<Industries>phosphate rock mining and processing, food processing, leather goods, textiles, construction, tourism</Industries>
+<Exports>$7.1 billion (f.o.b., 1998)</Exports>
+<Imports>$9.5 billion (f.o.b., 1998)</Imports>
+<Currency>1 Moroccan dirham (DH) = 100 centimes</Currency>
+<Airports>70 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of hashish; trafficking on the increase for both domestic and international drug markets; shipments of hashish mostly directed to Western Europe; transit point for cocaine from South America destined for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, island in the Indian Ocean, east of Madagascar</Location>
+<Geographiccoordinates>20 17 S, 57 33 E</Geographiccoordinates>
+<Area>1860</Area>
+<Climate>tropical, modified by southeast trade winds; warm, dry winter (May to November); hot, wet, humid summer (November to May)</Climate>
+<Naturalresources>arable land, fish</Naturalresources>
+<Population>1179368</Population>
+<Populationgrowthrate>0.89% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.67 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Hindu 52%, Christian 28.3% (Roman Catholic 26%, Protestant 2.3%), Muslim 16.6%, other 3.1%</Religions>
+<Countryname>Mauritius </Countryname>
+<Capital>Port Louis</Capital>
+<Flagdescription>four equal horizontal bands of red (top), blue, yellow, and green</Flagdescription>
+<GDP>purchasing power parity - $12.3 billion (1999 est.)</GDP>
+<Industries>food processing (largely sugar milling), textiles, clothing; chemicals, metal products, transport equipment, nonelectrical machinery; tourism</Industries>
+<Exports>$1.7 billion (f.o.b., 1999)</Exports>
+<Imports>$2.1 billion (f.o.b., 1998)</Imports>
+<Currency>1 Mauritian rupee (MauR) = 100 cents</Currency>
+<Airports>5 (1999 est.)</Airports>
+<Illicitdrugs>minor consumer and transshipment point for heroin from South Asia; small amounts of cannabis produced and consumed locally</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, atoll in the North Pacific Ocean, about one-third of the way from Honolulu to Tokyo</Location>
+<Geographiccoordinates>28 13 N, 177 22 W</Geographiccoordinates>
+<Area>6</Area>
+<Climate>subtropical, but moderated by prevailing easterly winds</Climate>
+<Naturalresources>wildlife, terrestrial and aquatic</Naturalresources>
+<Population></Population>
+<Countryname>Midway Islands </Countryname>
+<Capital>none; administered from Washington, DC</Capital>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Africa, bordering the North Atlantic Ocean, between Senegal and Western Sahara</Location>
+<Geographiccoordinates>20 00 N, 12 00 W</Geographiccoordinates>
+<Area>1030700</Area>
+<Climate>desert; constantly hot, dry, dusty</Climate>
+<Naturalresources>iron ore, gypsum, fish, copper, phosphate</Naturalresources>
+<Population>2667859</Population>
+<Populationgrowthrate>2.94% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 100%</Religions>
+<Countryname>Mauritania </Countryname>
+<Capital>Nouakchott</Capital>
+<Flagdescription>green with a yellow five-pointed star above a yellow, horizontal crescent; the closed side of the crescent is down; the crescent, star, and color green are traditional symbols of Islam</Flagdescription>
+<GDP>purchasing power parity - $4.9 billion (1999 est.)</GDP>
+<Industries>fish processing, mining of iron ore and gypsum</Industries>
+<Exports>$425 million (f.o.b., 1997)</Exports>
+<Imports>$444 million (f.o.b., 1997)</Imports>
+<Currency>1 ouguiya (UM) = 5 khoums</Currency>
+<Airports>26 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Europe, islands in the Mediterranean Sea, south of Sicily (Italy)</Location>
+<Geographiccoordinates>35 50 N, 14 35 E</Geographiccoordinates>
+<Area>316</Area>
+<Climate>Mediterranean with mild, rainy winters and hot, dry summers</Climate>
+<Naturalresources>limestone, salt, arable land</Naturalresources>
+<Population>391670</Population>
+<Populationgrowthrate>0.74% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 91%</Religions>
+<Countryname>Malta </Countryname>
+<Capital>Valletta</Capital>
+<Flagdescription>two equal vertical bands of white (hoist side) and red; in the upper hoist-side corner is a representation of the George Cross, edged in red</Flagdescription>
+<GDP>purchasing power parity - $5.3 billion (1999 est.)</GDP>
+<Industries>tourism; electronics, ship building and repair, construction; food and beverages, textiles, footwear, clothing, tobacco</Industries>
+<Exports>$1.8 billion (f.o.b., 1998)</Exports>
+<Imports>$2.7 billion (f.o.b., 1998)</Imports>
+<Currency>1 Maltese lira (LM) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+<Illicitdrugs>minor transshipment point for hashish from North Africa to Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Arabian Sea, Gulf of Oman, and Persian Gulf, between Yemen and UAE</Location>
+<Geographiccoordinates>21 00 N, 57 00 E</Geographiccoordinates>
+<Area>212460</Area>
+<Climate>dry desert; hot, humid along coast; hot, dry interior; strong southwest summer monsoon (May to September) in far south</Climate>
+<Naturalresources>petroleum, copper, asbestos, some marble, limestone, chromium, gypsum, natural gas</Naturalresources>
+<Population>2533389</Population>
+<Populationgrowthrate>3.46% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.58 male(s)/female
+65 years and over: 1.11 male(s)/female
+total population: 1.31 male(s)/female (2000 est.)</Sexratio>
+<Religions>Ibadhi Muslim 75%, Sunni Muslim, Shi'a Muslim, Hindu</Religions>
+<Countryname>Oman </Countryname>
+<Capital>Muscat</Capital>
+<Flagdescription>three horizontal bands of white, red, and green of equal width with a broad, vertical, red band on the hoist side; the national emblem (a khanjar dagger in its sheath superimposed on two crossed swords in scabbards) in white is centered at the top of the vertical band</Flagdescription>
+<GDP>purchasing power parity - $19.6 billion (1999 est.)</GDP>
+<Industries>crude oil production and refining, natural gas production, construction, cement, copper</Industries>
+<Exports>$7.2 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$5.4 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Omani rial (RO) = 1,000 baiza</Currency>
+<Airports>142 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Asia, group of atolls in the Indian Ocean, south-southwest of India</Location>
+<Geographiccoordinates>3 15 N, 73 00 E</Geographiccoordinates>
+<Area>300</Area>
+<Climate>tropical; hot, humid; dry, northeast monsoon (November to March); rainy, southwest monsoon (June to August)</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>301475</Population>
+<Populationgrowthrate>3.06% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 1.09 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim</Religions>
+<Countryname>Maldives </Countryname>
+<Capital>Male</Capital>
+<Flagdescription>red with a large green rectangle in the center bearing a vertical white crescent; the closed side of the crescent is on the hoist side of the flag</Flagdescription>
+<GDP>purchasing power parity - $540 million (1999 est.)</GDP>
+<Industries>fish processing, tourism, shipping, boat building, coconut processing, garments, woven mats, rope, handicrafts, coral and sand mining</Industries>
+<Exports>$98 million (f.o.b., 1998)</Exports>
+<Imports>$312 million (f.o.b., 1998)</Imports>
+<Currency>1 rufiyaa (Rf) = 100 laari</Currency>
+<Airports>5 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle America, bordering the Caribbean Sea and the Gulf of Mexico, between Belize and the US and bordering the North Pacific Ocean, between Guatemala and the US</Location>
+<Geographiccoordinates>23 00 N, 102 00 W</Geographiccoordinates>
+<Area>1972550</Area>
+<Climate>varies from tropical to desert</Climate>
+<Naturalresources>petroleum, silver, copper, gold, lead, zinc, natural gas, timber</Naturalresources>
+<Population>100349766</Population>
+<Populationgrowthrate>1.53% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>nominally Roman Catholic 89%, Protestant 6%, other 5%</Religions>
+<Countryname>Mexico </Countryname>
+<Capital>Mexico</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), white, and red; the coat of arms (an eagle perched on a cactus with a snake in its beak) is centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $865.5 billion (1999 est.)</GDP>
+<Industries>food and beverages, tobacco, chemicals, iron and steel, petroleum, mining, textiles, clothing, motor vehicles, consumer durables, tourism</Industries>
+<Exports>$136.8 billion (f.o.b., 1999), includes in-bond industries (assembly plant operations with links to US companies)</Exports>
+<Imports>$142.1 billion (f.o.b., 1999), includes in-bond industries (assembly plant operations with links to US companies)</Imports>
+<Currency>1 New Mexican peso (Mex$) = 100 centavos</Currency>
+<Airports>1,806 (1999 est.)</Airports>
+<Illicitdrugs>illicit cultivation of opium poppy (cultivation in 1998 - 5,500 hectares; potential production - 60 metric tons) and cannabis cultivation in 1998 - 4,600 hectares; government eradication efforts have been key in keeping illicit crop levels low; major supplier of heroin and marijuana to the US market; continues as the primary transshipment country for US-bound cocaine from South America; involved in the production and distribution of methamphetamines; upsurge in drug-related violence and official corruption; major drug syndicates growing more powerful</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, peninsula and northern one-third of the island of Borneo, bordering Indonesia and the South China Sea, south of Vietnam</Location>
+<Geographiccoordinates>2 30 N, 112 30 E</Geographiccoordinates>
+<Area>329750</Area>
+<Climate>tropical; annual southwest (April to October) and northeast (October to February) monsoons</Climate>
+<Naturalresources>tin, petroleum, timber, copper, iron ore, natural gas, bauxite</Naturalresources>
+<Population>21793293</Population>
+<Populationgrowthrate>2.01% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Islam, Buddhism, Daoism, Hinduism, Christianity, Sikhism; note - in addition, Shamanism is practiced in East Malaysia</Religions>
+<Countryname>Malaysia </Countryname>
+<Capital>Kuala Lumpur</Capital>
+<Flagdescription>14 equal horizontal stripes of red (top) alternating with white (bottom); there is a blue rectangle in the upper hoist-side corner bearing a yellow crescent and a yellow fourteen-pointed star; the crescent and the star are traditional symbols of Islam; the design was based on the flag of the US</Flagdescription>
+<GDP>purchasing power parity - $229.1 billion (1999 est.)</GDP>
+<Industries>Peninsular Malaysia - rubber and oil palm processing and manufacturing, light manufacturing industry, electronics, tin mining and smelting, logging and processing timber; Sabah - logging, petroleum production; Sarawak - agriculture processing, petroleum production and refining, logging</Industries>
+<Exports>$83.5 billion (1999 est.)</Exports>
+<Imports>$61.5 billion (1999 est.)</Imports>
+<Currency>1 ringgit (M$) = 100 sen</Currency>
+<Airports>115 (1999 est.)</Airports>
+<Illicitdrugs>transit point for some illicit drugs going to Western markets; drug trafficking prosecuted vigorously and carries severe penalties</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, bordering the Mozambique Channel, between South Africa and Tanzania</Location>
+<Geographiccoordinates>18 15 S, 35 00 E</Geographiccoordinates>
+<Area>801590</Area>
+<Climate>tropical to subtropical</Climate>
+<Naturalresources>coal, titanium, natural gas, hydropower</Naturalresources>
+<Population>19104696</Population>
+<Populationgrowthrate>1.47% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 0.99 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 50%, Christian 30%, Muslim 20%</Religions>
+<Countryname>Mozambique </Countryname>
+<Capital>Maputo</Capital>
+<Flagdescription>three equal horizontal bands of green (top), black, and yellow with a red isosceles triangle based on the hoist side; the black band is edged in white; centered in the triangle is a yellow five-pointed star bearing a crossed rifle and hoe in black superimposed on an open white book</Flagdescription>
+<GDP>purchasing power parity - $18.7 billion (1999 est.)</GDP>
+<Industries>food, beverages, chemicals (fertilizer, soap, paints), petroleum products, textiles, cement, glass, asbestos, tobacco</Industries>
+<Exports>$300 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.6 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 metical (Mt) = 100 centavos</Currency>
+<Airports>170 (1999 est.)</Airports>
+<Illicitdrugs>Southern African transit hub for South American cocaine probably destined for the European and US markets; producer of hashish and methaqualone</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, islands in the South Pacific Ocean, east of Australia</Location>
+<Geographiccoordinates>21 30 S, 165 30 E</Geographiccoordinates>
+<Area>19060</Area>
+<Climate>tropical; modified by southeast trade winds; hot, humid</Climate>
+<Naturalresources>nickel, chrome, iron, cobalt, manganese, silver, gold, lead, copper</Naturalresources>
+<Population>201816</Population>
+<Populationgrowthrate>1.52% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.9 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 60%, Protestant 30%, other 10%</Religions>
+<Countryname>New Caledonia </Countryname>
+<Capital>Noumea</Capital>
+<Flagdescription>the flag of France is used</Flagdescription>
+<GDP>purchasing power parity - $3 billion (1998 est.)</GDP>
+<Industries>nickel mining and smelting</Industries>
+<Exports>$381 million (f.o.b., 1998)</Exports>
+<Imports>$922 million (c.i.f., 1998)</Imports>
+<Currency>1 Comptoirs Francais du Pacifique franc (CFPF) = 100 centimes</Currency>
+<Airports>28 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, island in the South Pacific Ocean, east of Tonga</Location>
+<Geographiccoordinates>19 02 S, 169 52 W</Geographiccoordinates>
+<Area>260</Area>
+<Climate>tropical; modified by southeast trade winds</Climate>
+<Naturalresources>fish, arable land</Naturalresources>
+<Population>2113</Population>
+<Populationgrowthrate>0.47% (2000 est.)</Populationgrowthrate>
+<Religions>Ekalesia Niue (Niuean Church - a Protestant church closely related to the London Missionary Society) 75%, Latter-Day Saints 10%, other 15% (mostly Roman Catholic, Jehovah's Witnesses, Seventh-Day Adventist)</Religions>
+<Countryname>Niue </Countryname>
+<Capital>Alofi</Capital>
+<Flagdescription>yellow with the flag of the UK in the upper hoist-side quadrant; the flag of the UK bears five yellow five-pointed stars - a large one on a blue disk in the center and a smaller one on each arm of the bold red cross</Flagdescription>
+<GDP>purchasing power parity - $4.5 million (1994 est.)</GDP>
+<Industries>tourism, handicrafts, food processing</Industries>
+<Exports>$117,500 (f.o.b., 1989)</Exports>
+<Imports>$4.1 million (c.i.f., 1989)</Imports>
+<Currency>1 New Zealand dollar (NZ$) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, island in the South Pacific Ocean, east of Australia</Location>
+<Geographiccoordinates>29 02 S, 167 57 E</Geographiccoordinates>
+<Area>34</Area>
+<Climate>subtropical, mild, little seasonal temperature variation</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>1892</Population>
+<Populationgrowthrate>-0.68% (2000 est.)</Populationgrowthrate>
+<Religions>Anglican 39%, Roman Catholic 11.7%, Uniting Church in Australia 16.4%, Seventh-Day Adventist 4.4%, none 9.2%, unknown 16.9%, other 2.4% (1986)</Religions>
+<Countryname>Norfolk Island </Countryname>
+<Capital>Kingston</Capital>
+<Flagdescription>three vertical bands of green (hoist side), white, and green with a large green Norfolk Island pine tree centered in the slightly wider white band</Flagdescription>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>tourism</Industries>
+<Exports>$1.5 million (f.o.b., FY91/92)</Exports>
+<Imports>$17.9 million (c.i.f., FY91/92)</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, southeast of Algeria</Location>
+<Geographiccoordinates>16 00 N, 8 00 E</Geographiccoordinates>
+<Area>1000000</Area>
+<Climate>desert; mostly hot, dry, dusty; tropical in extreme south</Climate>
+<Naturalresources>uranium, coal, iron ore, tin, phosphates, gold, petroleum</Naturalresources>
+<Population>10075511</Population>
+<Populationgrowthrate>2.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 1.11 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 80%, remainder indigenous beliefs and Christians</Religions>
+<Countryname>Niger </Countryname>
+<Capital>Niamey</Capital>
+<Flagdescription>three equal horizontal bands of orange (top), white, and green with a small orange disk (representing the sun) centered in the white band; similar to the flag of India, which has a blue spoked wheel centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $9.6 billion (1999 est.)</GDP>
+<Industries>uranium mining, cement, brick, textiles, food processing, chemicals, slaughterhouses</Industries>
+<Exports>$269 million (f.o.b., 1997)</Exports>
+<Imports>$295 million (c.i.f., 1997)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>27 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, group of islands in the South Pacific Ocean, about three-quarters of the way from Hawaii to Australia</Location>
+<Geographiccoordinates>16 00 S, 167 00 E</Geographiccoordinates>
+<Area>14760</Area>
+<Climate>tropical; moderated by southeast trade winds</Climate>
+<Naturalresources>manganese, hardwood forests, fish</Naturalresources>
+<Population>189618</Population>
+<Populationgrowthrate>1.74% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 1.18 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Presbyterian 36.7%, Anglican 15%, Roman Catholic 15%, indigenous beliefs 7.6%, Seventh-Day Adventist 6.2%, Church of Christ 3.8%, other 15.7%</Religions>
+<Countryname>Vanuatu </Countryname>
+<Capital>Port-Vila</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and green with a black isosceles triangle (based on the hoist side) all separated by a black-edged yellow stripe in the shape of a horizontal Y (the two points of the Y face the hoist side and enclose the triangle); centered in the triangle is a boar's tusk encircling two crossed namele leaves, all in yellow</Flagdescription>
+<GDP>purchasing power parity - $245 million (1999 est.)</GDP>
+<Industries>food and fish freezing, wood processing, meat canning</Industries>
+<Exports>$33.8 million (f.o.b., 1998)</Exports>
+<Imports>$76.2 million (f.o.b., 1998)</Imports>
+<Currency>1 vatu (VT) = 100 centimes</Currency>
+<Airports>32 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the Gulf of Guinea, between Benin and Cameroon</Location>
+<Geographiccoordinates>10 00 N, 8 00 E</Geographiccoordinates>
+<Area>923768</Area>
+<Climate>varies; equatorial in south, tropical in center, arid in north</Climate>
+<Naturalresources>petroleum, tin, columbite, iron ore, coal, limestone, lead, zinc, natural gas, hydropower, arable land</Naturalresources>
+<Population>123337822</Population>
+<Populationgrowthrate>2.67% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 1 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 50%, Christian 40%, indigenous beliefs 10%</Religions>
+<Countryname>Nigeria </Countryname>
+<Capital>Abuja
+note: on 12 December 1991 the capital was officially moved from Lagos to Abuja; many government offices remain in Lagos pending completion of facilities in Abuja</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), white, and green</Flagdescription>
+<GDP>purchasing power parity - $110.5 billion (1999 est.)</GDP>
+<Industries>crude oil, coal, tin, columbite, palm oil, peanuts, cotton, rubber, wood, hides and skins, textiles, cement and other construction materials, food products, footwear, chemicals, fertilizer, printing, ceramics, steel</Industries>
+<Exports>$13.1 billion (f.o.b., 1999)</Exports>
+<Imports>$10 billion (f.o.b., 1999)</Imports>
+<Currency>1 naira (N) = 100 kobo</Currency>
+<Airports>71 (1999 est.)</Airports>
+<Illicitdrugs>facilitates movement of heroin en route from Southeast and Southwest Asia to Western Europe and North America; increasingly a transit route for cocaine from South America intended for European, East Asian, and North American markets</Illicitdrugs>
+</record>
+<record>
+<Location>Western Europe, bordering the North Sea, between Belgium and Germany</Location>
+<Geographiccoordinates>52 30 N, 5 45 E</Geographiccoordinates>
+<Area>41532</Area>
+<Climate>temperate; marine; cool summers and mild winters</Climate>
+<Naturalresources>natural gas, petroleum, arable land</Naturalresources>
+<Population>15892237</Population>
+<Populationgrowthrate>0.57% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.69 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 34%, Protestant 25%, Muslim 3%, other 2%, unaffiliated 36% (1991)</Religions>
+<Countryname>Netherlands </Countryname>
+<Capital>Amsterdam; The Hague is the seat of government</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and blue; similar to the flag of Luxembourg, which uses a lighter blue and is longer</Flagdescription>
+<GDP>purchasing power parity - $365.1 billion (1999 est.)</GDP>
+<Industries>agroindustries, metal and engineering products, electrical machinery and equipment, chemicals, petroleum, construction, microelectronics, fishing</Industries>
+<Exports>$169 billion (f.o.b., 1998)</Exports>
+<Imports>$152 billion (f.o.b., 1998)</Imports>
+<Currency>1 Netherlands guilder, gulden, or florin (f.) = 100 cents; note - to be replaced by the euro on 1 January 2002</Currency>
+<Airports>28 (1999 est.)</Airports>
+<Illicitdrugs>major European producer of illicit amphetamines and other synthetic drugs; important gateway for cocaine, heroin, and hashish entering Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Europe, bordering the North Sea and the North Atlantic Ocean, west of Sweden</Location>
+<Geographiccoordinates>62 00 N, 10 00 E</Geographiccoordinates>
+<Area>324220</Area>
+<Climate>temperate along coast, modified by North Atlantic Current; colder interior; rainy year-round on west coast</Climate>
+<Naturalresources>petroleum, copper, natural gas, pyrites, nickel, iron ore, zinc, lead, fish, timber, hydropower</Naturalresources>
+<Population>4481162</Population>
+<Populationgrowthrate>0.5% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Evangelical Lutheran 86% (state church), other Protestant and Roman Catholic 3%, other 1%, none and unknown 10% (1997)</Religions>
+<Countryname>Norway </Countryname>
+<Capital>Oslo</Capital>
+<Flagdescription>red with a blue cross outlined in white that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side in the style of the Dannebrog (Danish flag)</Flagdescription>
+<GDP>purchasing power parity - $111.3 billion (1999 est.)</GDP>
+<Industries>petroleum and gas, food processing, shipbuilding, pulp and paper products, metals, chemicals, timber, mining, textiles, fishing</Industries>
+<Exports>$47.3 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$38.6 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Norwegian krone (NKr) = 100 oere</Currency>
+<Airports>103 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Asia, between China and India</Location>
+<Geographiccoordinates>28 00 N, 84 00 E</Geographiccoordinates>
+<Area>140800</Area>
+<Climate>varies from cool summers and severe winters in north to subtropical summers and mild winters in south</Climate>
+<Naturalresources>quartz, water, timber, hydropower, scenic beauty, small deposits of lignite, copper, cobalt, iron ore</Naturalresources>
+<Population>24702119</Population>
+<Populationgrowthrate>2.34% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.99 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Hindu 90%, Buddhist 5%, Muslim 3%, other 2% (1981)
+note: only official Hindu state in the world</Religions>
+<Countryname>Nepal </Countryname>
+<Capital>Kathmandu</Capital>
+<Flagdescription>red with a blue border around the unique shape of two overlapping right triangles; the smaller, upper triangle bears a white stylized moon and the larger, lower triangle bears a white 12-pointed sun</Flagdescription>
+<GDP>purchasing power parity - $27.4 billion (1999 est.)</GDP>
+<Industries>tourism, carpet, textile; small rice, jute, sugar, and oilseed mills; cigarette; cement and brick production</Industries>
+<Exports>$485 million (f.o.b., 1998), but does not include unrecorded border trade with India</Exports>
+<Imports>$1.2 billion (f.o.b., 1998)</Imports>
+<Currency>1 Nepalese rupee (NR) = 100 paisa</Currency>
+<Airports>45 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis for the domestic and international drug markets; transit point for opiates from Southeast Asia to the West</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, island in the South Pacific Ocean, south of the Marshall Islands</Location>
+<Geographiccoordinates>0 32 S, 166 55 E</Geographiccoordinates>
+<Area>21</Area>
+<Climate>tropical; monsoonal; rainy season (November to February)</Climate>
+<Naturalresources>phosphates</Naturalresources>
+<Population>11845</Population>
+<Populationgrowthrate>2.05% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 1 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian (two-thirds Protestant, one-third Roman Catholic)</Religions>
+<Countryname>Nauru </Countryname>
+<Capital>no official capital; government offices in Yaren District</Capital>
+<Flagdescription>blue with a narrow, horizontal, yellow stripe across the center and a large white 12-pointed star below the stripe on the hoist side; the star indicates the country's location in relation to the Equator (the yellow stripe) and the 12 points symbolize the 12 original tribes of Nauru</Flagdescription>
+<GDP>purchasing power parity - $100 million (1993 est.)</GDP>
+<Industries>phosphate mining, financial services, coconut products</Industries>
+<Exports>$25.3 million (f.o.b., 1991)</Exports>
+<Imports>$21.1 million (c.i.f., 1991)</Imports>
+<Currency>1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern South America, bordering the North Atlantic Ocean, between French Guiana and Guyana</Location>
+<Geographiccoordinates>4 00 N, 56 00 W</Geographiccoordinates>
+<Area>163270</Area>
+<Climate>tropical; moderated by trade winds</Climate>
+<Naturalresources>timber, hydropower, fish, kaolin, shrimp, bauxite, gold, and small amounts of nickel, copper, platinum, iron ore</Naturalresources>
+<Population>431303</Population>
+<Populationgrowthrate>0.65% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Hindu 27.4%, Muslim 19.6%, Roman Catholic 22.8%, Protestant 25.2% (predominantly Moravian), indigenous beliefs 5%</Religions>
+<Countryname>Suriname </Countryname>
+<Capital>Paramaribo</Capital>
+<Flagdescription>five horizontal bands of green (top, double width), white, red (quadruple width), white, and green (double width); there is a large, yellow, five-pointed star centered in the red band</Flagdescription>
+<GDP>purchasing power parity - $1.48 billion (1999 est.)</GDP>
+<Industries>bauxite and gold mining, alumina and aluminum production, lumbering, food processing, fishing</Industries>
+<Exports>$406.1 million (f.o.b., 1998)</Exports>
+<Imports>$461.4 million (f.o.b., 1998)</Imports>
+<Currency>1 Surinamese guilder, gulden, or florin (Sf.) = 100 cents</Currency>
+<Airports>46 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American drugs destined mostly for Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, two island groups in the Caribbean Sea - one includes Curacao and Bonaire north of Venezuela and the other is east of the Virgin Islands</Location>
+<Geographiccoordinates>12 15 N, 68 45 W</Geographiccoordinates>
+<Area>960</Area>
+<Climate>tropical; ameliorated by northeast trade winds</Climate>
+<Naturalresources>phosphates (Curacao only), salt (Bonaire only)</Naturalresources>
+<Population>210134</Population>
+<Populationgrowthrate>1.01% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.92 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic, Protestant, Jewish, Seventh-Day Adventist</Religions>
+<Countryname>Netherlands Antilles </Countryname>
+<Capital>Willemstad</Capital>
+<Flagdescription>white, with a horizontal blue stripe in the center superimposed on a vertical red band, also centered; five white, five-pointed stars are arranged in an oval pattern in the center of the blue band; the five stars represent the five main islands of Bonaire, Curacao, Saba, Sint Eustatius, and Sint Maarten</Flagdescription>
+<GDP>purchasing power parity - $2.4 billion (1998 est.)</GDP>
+<Industries>tourism (Curacao, Sint Maarten, and Bonaire), petroleum refining (Curacao), petroleum transshipment facilities (Curacao and Bonaire), light manufacturing (Curacao)</Industries>
+<Exports>$303 million (f.o.b., 1998)</Exports>
+<Imports>$1.3 billion (c.i.f., 1998)</Imports>
+<Currency>1 Netherlands Antillean guilder, gulden, or florin (NAf.) = 100 cents</Currency>
+<Airports>5 (1999 est.)</Airports>
+<Illicitdrugs>money-laundering center; transshipment point for South American drugs bound for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Middle America, bordering both the Caribbean Sea and the North Pacific Ocean, between Costa Rica and Honduras</Location>
+<Geographiccoordinates>13 00 N, 85 00 W</Geographiccoordinates>
+<Area>129494</Area>
+<Climate>tropical in lowlands, cooler in highlands</Climate>
+<Naturalresources>gold, silver, copper, tungsten, lead, zinc, timber, fish</Naturalresources>
+<Population>4812569</Population>
+<Populationgrowthrate>2.2% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.77 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 85%, Protestant</Religions>
+<Countryname>Nicaragua </Countryname>
+<Capital>Managua</Capital>
+<Flagdescription>three equal horizontal bands of blue (top), white, and blue with the national coat of arms centered in the white band; the coat of arms features a triangle encircled by the words REPUBLICA DE NICARAGUA on the top and AMERICA CENTRAL on the bottom; similar to the flag of El Salvador, which features a round emblem encircled by the words REPUBLICA DE EL SALVADOR EN LA AMERICA CENTRAL centered in the white band; also similar to the flag of Honduras, which has five blue stars arranged in an X pattern centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $12.5 billion (1999 est.)</GDP>
+<Industries>food processing, chemicals, machinery and metal products, textiles, clothing, petroleum refining and distribution, beverages, footwear, wood</Industries>
+<Exports>$573 million (f.o.b., 1998 est.)</Exports>
+<Imports>$1.5 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 gold cordoba (C$) = 100 centavos</Currency>
+<Airports>182 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for cocaine destined for the US and transshipment point for arms-for-drugs dealing</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, islands in the South Pacific Ocean, southeast of Australia</Location>
+<Geographiccoordinates>41 00 S, 174 00 E</Geographiccoordinates>
+<Area>268680</Area>
+<Climate>temperate with sharp regional contrasts</Climate>
+<Naturalresources>natural gas, iron ore, sand, coal, timber, hydropower, gold, limestone</Naturalresources>
+<Population>3819762</Population>
+<Populationgrowthrate>1.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.77 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 24%, Presbyterian 18%, Roman Catholic 15%, Methodist 5%, Baptist 2%, other Protestant 3%, unspecified or none 33% (1986)</Religions>
+<Countryname>New Zealand </Countryname>
+<Capital>Wellington</Capital>
+<Flagdescription>blue with the flag of the UK in the upper hoist-side quadrant with four red five-pointed stars edged in white centered in the outer half of the flag; the stars represent the Southern Cross constellation</Flagdescription>
+<GDP>purchasing power parity - $63.8 billion (1999 est.)</GDP>
+<Industries>food processing, wood and paper products, textiles, machinery, transportation equipment, banking and insurance, tourism, mining</Industries>
+<Exports>$12.2 billion (f.o.b., 1998 est.)</Exports>
+<Imports>$11.2 billion (f.o.b., 1998 est.)</Imports>
+<Currency>1 New Zealand dollar (NZ$) = 100 cents</Currency>
+<Airports>111 (1999 est.)</Airports>
+</record>
+<record>
+<Location>body of water between 60 degrees south latitude and Antarctica</Location>
+<Geographiccoordinates>65 00 S, 0 00 E (nominally), but the Southern Ocean has the unique distinction of being a large circumpolar body of water totally encircling the continent of Antarctica; this ring of water lies between 60 degrees south latitude and the coast of Antarctica, and encompasses 360 degrees of longitude</Geographiccoordinates>
+<Area>20000000</Area>
+<Climate>sea temperatures vary from about 10 degrees Centigrade to -2 degrees Centigrade; cyclonic storms travel eastward around the continent and frequently are intense because of the temperature contrast between ice and open ocean; the ocean area from about latitude 40 south to the Antarctic Circle has the strongest average winds found anywhere on Earth; in winter the ocean freezes outward to 65 degrees south latitude in the Pacific sector and 55 degrees south latitude in the Atlantic sector, lowering surface temperatures well below 0 degrees Centigrade; at some coastal points intense persistent drainage winds from the interior keep the shoreline ice-free throughout the winter</Climate>
+<Naturalresources>probable large and possible giant oil and gas fields on the continental margin, manganese nodules, possible placer deposits, sand and gravel, fresh water as icebergs, squid, whales, and seals - none exploited; krill, fishes</Naturalresources>
+</record>
+<record>
+<Location>Central South America, northeast of Argentina</Location>
+<Geographiccoordinates>23 00 S, 58 00 W</Geographiccoordinates>
+<Area>406750</Area>
+<Climate>subtropical to temperate; substantial rainfall in the eastern portions, becoming semiarid in the far west</Climate>
+<Naturalresources>hydropower, timber, iron ore, manganese, limestone</Naturalresources>
+<Population>5585828</Population>
+<Populationgrowthrate>2.64% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.85 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%, Mennonite, and other Protestant</Religions>
+<Countryname>Paraguay </Countryname>
+<Capital>Asuncion</Capital>
+<Flagdescription>three equal, horizontal bands of red (top), white, and blue with an emblem centered in the white band; unusual flag in that the emblem is different on each side; the obverse (hoist side at the left) bears the national coat of arms (a yellow five-pointed star within a green wreath capped by the words REPUBLICA DEL PARAGUAY, all within two circles); the reverse (hoist side at the right) bears the seal of the treasury (a yellow lion below a red Cap of Liberty and the words Paz y Justicia (Peace and Justice) capped by the words REPUBLICA DEL PARAGUAY, all within two circles)</Flagdescription>
+<GDP>purchasing power parity - $19.9 billion (1999 est.)</GDP>
+<Industries>sugar, cement, textiles, beverages, wood products</Industries>
+<Exports>$3.1 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 guarani (G) = 100 centimos</Currency>
+<Airports>937 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of cannabis, most or all of which is consumed in South America; transshipment country for Bolivian cocaine headed for Southern Cone markets and Europe and a limited amount to the US</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, islands in the South Pacific Ocean, about one-half of the way from Peru to New Zealand</Location>
+<Geographiccoordinates>25 04 S, 130 06 W</Geographiccoordinates>
+<Area>47</Area>
+<Climate>tropical, hot, humid; modified by southeast trade winds; rainy season (November to March)</Climate>
+<Naturalresources>miro trees (used for handicrafts), fish
+note: manganese, iron, copper, gold, silver, and zinc have been discovered offshore</Naturalresources>
+<Population>54</Population>
+<Populationgrowthrate>-2.06% (2000 est.)</Populationgrowthrate>
+<Religions>Seventh-Day Adventist 100%</Religions>
+<Countryname>Pitcairn Islands </Countryname>
+<Capital>Adamstown</Capital>
+<Flagdescription>blue with the flag of the UK in the upper hoist-side quadrant and the Pitcairn Islander coat of arms centered on the outer half of the flag; the coat of arms is yellow, green, and light blue with a shield featuring a yellow anchor</Flagdescription>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>postage stamps, handicrafts</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 New Zealand dollar (NZ$) = 100 cents</Currency>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Western South America, bordering the South Pacific Ocean, between Chile and Ecuador</Location>
+<Geographiccoordinates>10 00 S, 76 00 W</Geographiccoordinates>
+<Area>1285220</Area>
+<Climate>varies from tropical in east to dry desert in west; temperate to frigid in Andes</Climate>
+<Naturalresources>copper, silver, gold, petroleum, timber, fish, iron ore, coal, phosphate, potash, hydropower</Naturalresources>
+<Population>27012899</Population>
+<Populationgrowthrate>1.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.85 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%</Religions>
+<Countryname>Peru </Countryname>
+<Capital>Lima</Capital>
+<Flagdescription>three equal, vertical bands of red (hoist side), white, and red with the coat of arms centered in the white band; the coat of arms features a shield bearing a llama, cinchona tree (the source of quinine), and a yellow cornucopia spilling out gold coins, all framed by a green wreath</Flagdescription>
+<GDP>purchasing power parity - $116 billion (1999 est.)</GDP>
+<Industries>mining of metals, petroleum, fishing, textiles, clothing, food processing, cement, auto assembly, steel, shipbuilding, metal fabrication</Industries>
+<Exports>$5.9 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$8.4 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 nuevo sol (S/.) = 100 centimos</Currency>
+<Airports>234 (1999 est.)</Airports>
+<Illicitdrugs>until recently the world's largest coca leaf producer, Peru has reduced the area of coca under cultivation by 24% to 38,700 hectares at the end of 1999; most of cocaine base is shipped to neighboring Colombia, Bolivia, and Brazil for processing into cocaine for the international drug market, but exports of finished cocaine are increasing by maritime conveyance to Mexico, US, and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, group of small islands and reefs in the South China Sea, about one-third of the way from central Vietnam to the northern Philippines</Location>
+<Geographiccoordinates>16 30 N, 112 00 E</Geographiccoordinates>
+<Area></Area>
+<Climate>tropical</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Paracel Islands </Countryname>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, group of reefs and islands in the South China Sea, about two-thirds of the way from southern Vietnam to the southern Philippines</Location>
+<Geographiccoordinates>8 38 N, 111 55 E</Geographiccoordinates>
+<Area></Area>
+<Climate>tropical</Climate>
+<Naturalresources>fish, guano, undetermined oil and natural gas potential</Naturalresources>
+<Population></Population>
+<Countryname>Spratly Islands </Countryname>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Asia, bordering the Arabian Sea, between India on the east and Iran and Afghanistan on the west and China in the north</Location>
+<Geographiccoordinates>30 00 N, 70 00 E</Geographiccoordinates>
+<Area>803940</Area>
+<Climate>mostly hot, dry desert; temperate in northwest; arctic in north</Climate>
+<Naturalresources>land, extensive natural gas reserves, limited petroleum, poor quality coal, iron ore, copper, salt, limestone</Naturalresources>
+<Population>141553775</Population>
+<Populationgrowthrate>2.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.97 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 97% (Sunni 77%, Shi'a 20%), Christian, Hindu, and other 3%</Religions>
+<Countryname>Pakistan </Countryname>
+<Capital>Islamabad</Capital>
+<Flagdescription>green with a vertical white band (symbolizing the role of religious minorities) on the hoist side; a large white crescent and star are centered in the green field; the crescent, star, and color green are traditional symbols of Islam</Flagdescription>
+<GDP>purchasing power parity - $282 billion (1999 est.)</GDP>
+<Industries>textiles, food processing, beverages, construction materials, clothing, paper products, shrimp</Industries>
+<Exports>$8.4 billion (f.o.b., 1999)</Exports>
+<Imports>$9.8 billion (f.o.b., 1999)</Imports>
+<Currency>1 Pakistani rupee (PRe) = 100 paisa</Currency>
+<Airports>118 (1999 est.)</Airports>
+<Illicitdrugs>producer of illicit opium and hashish for the international drug trade (poppy cultivation in 1999 - 1,570 hectares, a 48% drop from 1998 because of eradication and alternative development); key transit area for Southwest Asian heroin moving to Western markets; narcotics still move from Afghanistan into Balochistan Province</Illicitdrugs>
+</record>
+<record>
+<Location>Central Europe, east of Germany</Location>
+<Geographiccoordinates>52 00 N, 20 00 E</Geographiccoordinates>
+<Area>312685</Area>
+<Climate>temperate with cold, cloudy, moderately severe winters with frequent precipitation; mild summers with frequent showers and thundershowers</Climate>
+<Naturalresources>coal, sulfur, copper, natural gas, silver, lead, salt, arable land</Naturalresources>
+<Population>38646023</Population>
+<Populationgrowthrate>-0.04% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 95% (about 75% practicing), Eastern Orthodox, Protestant, and other 5%</Religions>
+<Countryname>Poland </Countryname>
+<Capital>Warsaw</Capital>
+<Flagdescription>two equal horizontal bands of white (top) and red; similar to the flags of Indonesia and Monaco which are red (top) and white</Flagdescription>
+<GDP>purchasing power parity - $276.5 billion (1999 est.)</GDP>
+<Industries>machine building, iron and steel, coal mining, chemicals, shipbuilding, food processing, glass, beverages, textiles</Industries>
+<Exports>$27.8 billion (f.o.b., 1999)</Exports>
+<Imports>$40.8 billion (f.o.b., 1999)</Imports>
+<Currency>1 zloty (Zl) = 100 groszy</Currency>
+<Airports>123 (1999 est.)</Airports>
+<Illicitdrugs>major illicit producer of amphetamines for the international market; minor transshipment point for Asian and Latin American illicit drugs to Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Middle America, bordering both the Caribbean Sea and the North Pacific Ocean, between Colombia and Costa Rica</Location>
+<Geographiccoordinates>9 00 N, 80 00 W</Geographiccoordinates>
+<Area>78200</Area>
+<Climate>tropical maritime; hot, humid, cloudy; prolonged rainy season (May to January), short dry season (January to May)</Climate>
+<Naturalresources>copper, mahogany forests, shrimp, hydropower</Naturalresources>
+<Population>2808268</Population>
+<Populationgrowthrate>1.34% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.92 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 85%, Protestant 15%</Religions>
+<Countryname>Panama </Countryname>
+<Capital>Panama</Capital>
+<Flagdescription>divided into four, equal rectangles; the top quadrants are white (hoist side) with a blue five-pointed star in the center and plain red; the bottom quadrants are plain blue (hoist side) and white with a red five-pointed star in the center</Flagdescription>
+<GDP>purchasing power parity - $21 billion (1999 est.)</GDP>
+<Industries>construction, petroleum refining, brewing, cement and other construction materials, sugar milling</Industries>
+<Exports>$4.7 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$6.4 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 balboa (B) = 100 centesimos</Currency>
+<Airports>105 (1999 est.)</Airports>
+<Illicitdrugs>major cocaine transshipment point and major drug-money-laundering center; no recent signs of coca cultivation; monitoring of financial transactions is improving, yet Panama has failed to prosecute anyone for money laundering - official corruption remains a major problem</Illicitdrugs>
+</record>
+<record>
+<Location>Southwestern Europe, bordering the North Atlantic Ocean, west of Spain</Location>
+<Geographiccoordinates>39 30 N, 8 00 W</Geographiccoordinates>
+<Area>92391</Area>
+<Climate>maritime temperate; cool and rainy in north, warmer and drier in south</Climate>
+<Naturalresources>fish, forests (cork), tungsten, iron ore, uranium ore, marble, arable land, hydro power</Naturalresources>
+<Population>10048232</Population>
+<Populationgrowthrate>0.18% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.92 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 94%, Protestant (1995)</Religions>
+<Countryname>Portugal </Countryname>
+<Capital>Lisbon</Capital>
+<Flagdescription>two vertical bands of green (hoist side, two-fifths) and red (three-fifths) with the Portuguese coat of arms centered on the dividing line</Flagdescription>
+<GDP>purchasing power parity - $151.4 billion (1999 est.)</GDP>
+<Industries>textiles and footwear; wood pulp, paper, and cork; metalworking; oil refining; chemicals; fish canning; wine; tourism</Industries>
+<Exports>$25 billion (f.o.b., 1998)</Exports>
+<Imports>$34.9 billion (f.o.b., 1998)</Imports>
+<Currency>1 Portuguese escudo (Esc) = 100 centavos</Currency>
+<Airports>66 (1999 est.)</Airports>
+<Illicitdrugs>important gateway country for Latin American cocaine entering the European market; transshipment point for hashish from North Africa to Europe; consumer of Southwest Asian heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, group of islands including the eastern half of the island of New Guinea between the Coral Sea and the South Pacific Ocean, east of Indonesia</Location>
+<Geographiccoordinates>6 00 S, 147 00 E</Geographiccoordinates>
+<Area>462840</Area>
+<Climate>tropical; northwest monsoon (December to March), southeast monsoon (May to October); slight seasonal temperature variation</Climate>
+<Naturalresources>gold, copper, silver, natural gas, timber, oil, fisheries</Naturalresources>
+<Population>4926984</Population>
+<Populationgrowthrate>2.47% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.08 male(s)/female
+65 years and over: 0.9 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 22%, Lutheran 16%, Presbyterian/Methodist/London Missionary Society 8%, Anglican 5%, Evangelical Alliance 4%, Seventh-Day Adventist 1%, other Protestant 10%, indigenous beliefs 34%</Religions>
+<Countryname>Papua New Guinea </Countryname>
+<Capital>Port Moresby</Capital>
+<Flagdescription>divided diagonally from upper hoist-side corner; the upper triangle is red with a soaring yellow bird of paradise centered; the lower triangle is black with five white five-pointed stars of the Southern Cross constellation centered</Flagdescription>
+<GDP>purchasing power parity - $11.6 billion (1999 est.)</GDP>
+<Industries>copra crushing, palm oil processing, plywood production, wood chip production; mining of gold, silver, and copper; crude oil production; construction, tourism</Industries>
+<Exports>$1.9 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$1 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 kina (K) = 100 toea</Currency>
+<Airports>492 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, group of islands in the North Pacific Ocean, southeast of the Philippines</Location>
+<Geographiccoordinates>7 30 N, 134 30 E</Geographiccoordinates>
+<Area>458</Area>
+<Climate>wet season May to November; hot and humid</Climate>
+<Naturalresources>forests, minerals (especially gold), marine products, deep-seabed minerals</Naturalresources>
+<Population>18766</Population>
+<Populationgrowthrate>1.75% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.21 male(s)/female
+65 years and over: 0.89 male(s)/female
+total population: 1.15 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian (Catholics, Seventh-Day Adventists, Jehovah's Witnesses, the Assembly of God, the Liebenzell Mission, and Latter-Day Saints), Modekngei religion (one-third of the population observes this religion which is indigenous to Palau)</Religions>
+<Countryname>Palau </Countryname>
+<Capital>Koror
+note: a new capital is being built about 20 km northeast of Koror</Capital>
+<Flagdescription>light blue with a large yellow disk (representing the moon) shifted slightly to the hoist side</Flagdescription>
+<GDP>purchasing power parity - $160 million (1997 est.)
+note: GDP numbers reflect US spending</GDP>
+<Industries>tourism, craft items (from shell, wood, pearls), construction, garment making</Industries>
+<Exports>$14.3 million (f.o.b., 1996)</Exports>
+<Imports>$72.4 million (f.o.b., 1996)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Guinea and Senegal</Location>
+<Geographiccoordinates>12 00 N, 15 00 W</Geographiccoordinates>
+<Area>36120</Area>
+<Climate>tropical; generally hot and humid; monsoonal-type rainy season (June to November) with southwesterly winds; dry season (December to May) with northeasterly harmattan winds</Climate>
+<Naturalresources>fish, timber, phosphates, bauxite, unexploited deposits of petroleum</Naturalresources>
+<Population>1285715</Population>
+<Populationgrowthrate>2.4% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 0.9 male(s)/female
+65 years and over: 0.83 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 50%, Muslim 45%, Christian 5%</Religions>
+<Countryname>Guinea-Bissau </Countryname>
+<Capital>Bissau</Capital>
+<Flagdescription>two equal horizontal bands of yellow (top) and green with a vertical red band on the hoist side; there is a black five-pointed star centered in the red band; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $1.1 billion (1999 est.)</GDP>
+<Industries>agricultural products processing, beer, soft drinks</Industries>
+<Exports>$26.8 million (f.o.b., 1998)</Exports>
+<Imports>$22.9 million (f.o.b., 1998)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>30 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, peninsula bordering the Persian Gulf and Saudi Arabia</Location>
+<Geographiccoordinates>25 30 N, 51 15 E</Geographiccoordinates>
+<Area>11437</Area>
+<Climate>desert; hot, dry; humid and sultry in summer</Climate>
+<Naturalresources>petroleum, natural gas, fish</Naturalresources>
+<Population>744483</Population>
+<Populationgrowthrate>3.35% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 2.48 male(s)/female
+65 years and over: 2.43 male(s)/female
+total population: 1.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 95%</Religions>
+<Countryname>Qatar </Countryname>
+<Capital>Doha</Capital>
+<Flagdescription>maroon with a broad white serrated band (nine white points) on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $12.3 billion (1999 est.)</GDP>
+<Industries>crude oil production and refining, fertilizers, petrochemicals, steel reinforcing bars, cement</Industries>
+<Exports>$6.7 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$4.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Qatari riyal (QR) = 100 dirhams</Currency>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, island in the Indian Ocean, east of Madagascar</Location>
+<Geographiccoordinates>21 06 S, 55 36 E</Geographiccoordinates>
+<Area>2512</Area>
+<Climate>tropical, but temperature moderates with elevation; cool and dry from May to November, hot and rainy from November to April</Climate>
+<Naturalresources>fish, arable land, hydropower</Naturalresources>
+<Population>720934</Population>
+<Populationgrowthrate>1.63% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 86%, Hindu, Muslim, Buddhist (1995)</Religions>
+<Countryname>Reunion </Countryname>
+<Capital>Saint-Denis</Capital>
+<Flagdescription>the flag of France is used</Flagdescription>
+<GDP>purchasing power parity - $3.4 billion (1998 est.)</GDP>
+<Industries>sugar, rum, cigarettes, handicraft items, flower oil extraction</Industries>
+<Exports>$214.162 million (f.o.b., 1997)</Exports>
+<Imports>$2.5 billion (c.i.f., 1997)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, group of atolls and reefs in the North Pacific Ocean, about one-half of the way from Hawaii to Papua New Guinea</Location>
+<Geographiccoordinates>9 00 N, 168 00 E</Geographiccoordinates>
+<Area>181</Area>
+<Climate>wet season from May to November; hot and humid; islands border typhoon belt</Climate>
+<Naturalresources>phosphate deposits, marine products, deep seabed minerals</Naturalresources>
+<Population>68126</Population>
+<Populationgrowthrate>3.88% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.9 male(s)/female
+total population: 1.04 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian (mostly Protestant)</Religions>
+<Countryname>Marshall Islands </Countryname>
+<Capital>Majuro</Capital>
+<Flagdescription>blue with two stripes radiating from the lower hoist-side corner - orange (top) and white; there is a white star with four large rays and 20 small rays on the hoist side above the two stripes</Flagdescription>
+<GDP>purchasing power parity - $105 million (1998 est.), supplemented by approximately $65 million annual US aid</GDP>
+<Industries>copra, fish, tourism, craft items from shell, wood, and pearls, offshore banking (embryonic)</Industries>
+<Exports>$28 million (f.o.b., 1997 est.)</Exports>
+<Imports>$58 million (f.o.b., 1997 est.)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>16 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Black Sea, between Bulgaria and Ukraine</Location>
+<Geographiccoordinates>46 00 N, 25 00 E</Geographiccoordinates>
+<Area>237500</Area>
+<Climate>temperate; cold, cloudy winters with frequent snow and fog; sunny summers with frequent showers and thunderstorms</Climate>
+<Naturalresources>petroleum (reserves declining), timber, natural gas, coal, iron ore, salt, arable land, hydro power</Naturalresources>
+<Population>22411121</Population>
+<Populationgrowthrate>-0.21% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Romanian Orthodox 70%, Roman Catholic 6% (of which 3% are Uniate), Protestant 6%, unaffiliated 18%</Religions>
+<Countryname>Romania </Countryname>
+<Capital>Bucharest</Capital>
+<Flagdescription>three equal vertical bands of blue (hoist side), yellow, and red; the national coat of arms that used to be centered in the yellow band has been removed; now similar to the flag of Chad, also resembles the flags of Andorra and Moldova</Flagdescription>
+<GDP>purchasing power parity - $87.4 billion (1999 est.)</GDP>
+<Industries>mining, timber, construction materials, metallurgy, chemicals, machine building, food processing, petroleum production and refining</Industries>
+<Exports>$8.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$9.6 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 leu (L) = 100 bani</Currency>
+<Airports>62 (1999 est.)</Airports>
+<Illicitdrugs>important transshipment point for Southwest Asian heroin transiting the Balkan route and small amounts of Latin American cocaine bound for Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Asia, archipelago between the Philippine Sea and the South China Sea, east of Vietnam</Location>
+<Geographiccoordinates>13 00 N, 122 00 E</Geographiccoordinates>
+<Area>300000</Area>
+<Climate>tropical marine; northeast monsoon (November to April); southwest monsoon (May to October)</Climate>
+<Naturalresources>timber, petroleum, nickel, cobalt, silver, gold, salt, copper</Naturalresources>
+<Population>81159644</Population>
+<Populationgrowthrate>2.07% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 83%, Protestant 9%, Muslim 5%, Buddhist and other 3%</Religions>
+<Countryname>Philippines </Countryname>
+<Capital>Manila</Capital>
+<Flagdescription>two equal horizontal bands of blue (top) and red with a white equilateral triangle based on the hoist side; in the center of the triangle is a yellow sun with eight primary rays (each containing three individual rays) and in each corner of the triangle is a small yellow five-pointed star</Flagdescription>
+<GDP>purchasing power parity - $282 billion (1999 est.)</GDP>
+<Industries>textiles, pharmaceuticals, chemicals, wood products, food processing, electronics assembly, petroleum refining, fishing</Industries>
+<Exports>$34.8 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$30.7 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Philippine peso (P) = 100 centavos</Currency>
+<Airports>266 (1999 est.)</Airports>
+<Illicitdrugs>exports locally produced marijuana and hashish to East Asia, the US, and other Western markets; serves as a transit point for heroin and crystal methamphetamine</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and the North Atlantic Ocean, east of the Dominican Republic</Location>
+<Geographiccoordinates>18 15 N, 66 30 W</Geographiccoordinates>
+<Area>9104</Area>
+<Climate>tropical marine, mild; little seasonal temperature variation</Climate>
+<Naturalresources>some copper and nickel; potential for onshore and offshore oil</Naturalresources>
+<Population>3915798</Population>
+<Populationgrowthrate>0.56% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 85%, Protestant and other 15%</Religions>
+<Countryname>Puerto Rico </Countryname>
+<Capital>San Juan</Capital>
+<Flagdescription>five equal horizontal bands of red (top and bottom) alternating with white; a blue isosceles triangle based on the hoist side bears a large, white, five-pointed star in the center; design based on the US flag</Flagdescription>
+<GDP>purchasing power parity - $38.1 billion (1999 est.)</GDP>
+<Industries>pharmaceuticals, electronics, apparel, food products; tourism</Industries>
+<Exports>$34.9 billion (f.o.b., 1999)</Exports>
+<Imports>$25.3 billion (c.i.f., 1999)</Imports>
+<Currency>1 US dollar (US$) = 100 cents</Currency>
+<Airports>30 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Asia (that part west of the Urals is sometimes included with Europe), bordering the Arctic Ocean, between Europe and the North Pacific Ocean</Location>
+<Geographiccoordinates>60 00 N, 100 00 E</Geographiccoordinates>
+<Area>17075200</Area>
+<Climate>ranges from steppes in the south through humid continental in much of European Russia; subarctic in Siberia to tundra climate in the polar north; winters vary from cool along Black Sea coast to frigid in Siberia; summers vary from warm in the steppes to cool along Arctic coast</Climate>
+<Naturalresources>wide natural resource base including major deposits of oil, natural gas, coal, and many strategic minerals, timber
+note: formidable obstacles of climate, terrain, and distance hinder exploitation of natural resources</Naturalresources>
+<Population>146001176</Population>
+<Populationgrowthrate>-0.38% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.94 male(s)/female
+65 years and over: 0.46 male(s)/female
+total population: 0.88 male(s)/female (2000 est.)</Sexratio>
+<Religions>Russian Orthodox, Muslim, other</Religions>
+<Countryname>Russia </Countryname>
+<Capital>Moscow</Capital>
+<Flagdescription>three equal horizontal bands of white (top), blue, and red</Flagdescription>
+<GDP>purchasing power parity - $620.3 billion (1999 est.)</GDP>
+<Industries>complete range of mining and extractive industries producing coal, oil, gas, chemicals, and metals; all forms of machine building from rolling mills to high-performance aircraft and space vehicles; shipbuilding; road and rail transportation equipment; communications equipment; agricultural machinery, tractors, and construction equipment; electric power generating and transmitting equipment; medical and scientific instruments; consumer durables, textiles, foodstuffs, handicrafts</Industries>
+<Exports>$75.4 billion (1999 est.)</Exports>
+<Imports>$48.2 billion (1999 est.)</Imports>
+<Currency>1 ruble (R) = 100 kopeks</Currency>
+<Airports>2,517 (1994 est.)</Airports>
+<Illicitdrugs>limited cultivation of illicit cannabis and opium poppy and producer of amphetamines, mostly for domestic consumption; government has active eradication program; increasingly used as transshipment point for Southwest and Southeast Asian opiates and cannabis and Latin American cocaine to Western Europe, possibly to the US, and growing domestic market; major source of heroin precursor chemicals</Illicitdrugs>
+</record>
+<record>
+<Location>Central Africa, east of Democratic Republic of the Congo</Location>
+<Geographiccoordinates>2 00 S, 30 00 E</Geographiccoordinates>
+<Area>26338</Area>
+<Climate>temperate; two rainy seasons (February to April, November to January); mild in mountains with frost and snow possible</Climate>
+<Naturalresources>gold, cassiterite (tin ore), wolframite (tungsten ore), methane, hydropower, arable land</Naturalresources>
+<Population>7229129</Population>
+<Populationgrowthrate>1.14% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 65%, Protestant 9%, Muslim 1%, indigenous beliefs and other 25%</Religions>
+<Countryname>Rwanda </Countryname>
+<Capital>Kigali</Capital>
+<Flagdescription>three equal vertical bands of red (hoist side), yellow, and green with a large black letter R centered in the yellow band; uses the popular pan-African colors of Ethiopia; similar to the flag of Guinea, which has a plain yellow band</Flagdescription>
+<GDP>purchasing power parity - $5.9 billion (1999 est.)</GDP>
+<Industries>cement, agricultural products, small-scale beverages, soap, furniture, shoes, plastic goods, textiles, cigarettes</Industries>
+<Exports>$70.8 million (f.o.b., 1999 est.)</Exports>
+<Imports>$242 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 Rwandan franc (RF) = 100 centimes</Currency>
+<Airports>8 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, bordering the Persian Gulf and the Red Sea, north of Yemen</Location>
+<Geographiccoordinates>25 00 N, 45 00 E</Geographiccoordinates>
+<Area>1960582</Area>
+<Climate>harsh, dry desert with great extremes of temperature</Climate>
+<Naturalresources>petroleum, natural gas, iron ore, gold, copper</Naturalresources>
+<Population>22023506</Population>
+<Populationgrowthrate>3.28% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.43 male(s)/female
+65 years and over: 1.18 male(s)/female
+total population: 1.24 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 100%</Religions>
+<Countryname>Saudi Arabia </Countryname>
+<Capital>Riyadh</Capital>
+<Flagdescription>green with large white Arabic script (that may be translated as There is no God but God; Muhammad is the Messenger of God) above a white horizontal saber (the tip points to the hoist side); green is the traditional color of Islam</Flagdescription>
+<GDP>purchasing power parity - $191 billion (1999 est.)</GDP>
+<Industries>crude oil production, petroleum refining, basic petrochemicals, cement, construction, fertilizer, plastics</Industries>
+<Exports>$48 billion (f.o.b., 1999)</Exports>
+<Imports>$28 billion (f.o.b., 1999)</Imports>
+<Currency>1 Saudi riyal (SR) = 100 halalah</Currency>
+<Airports>205 (1999 est.)</Airports>
+<Illicitdrugs>death penalty for traffickers; increasing consumption of heroin and cocaine</Illicitdrugs>
+</record>
+<record>
+<Location>Northern North America, islands in the North Atlantic Ocean, south of Newfoundland (Canada)</Location>
+<Geographiccoordinates>46 50 N, 56 20 W</Geographiccoordinates>
+<Area>242</Area>
+<Climate>cold and wet, with much mist and fog; spring and autumn are windy</Climate>
+<Naturalresources>fish, deepwater ports</Naturalresources>
+<Population>6896</Population>
+<Populationgrowthrate>0.49% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.04 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 99%</Religions>
+<Countryname>Saint Pierre and Miquelon </Countryname>
+<Capital>Saint-Pierre</Capital>
+<Flagdescription>a yellow sailing ship facing the hoist side rides on a dark blue background with a black wave line under the ship; on the hoist side, a vertical band is divided into three parts: the top part is red with a green diagonal cross extending to the corners overlaid by a white cross dividing the square into four sections; the middle part has a white background with an ermine pattern; the third part has a red background with two stylized yellow lions outlined in black, one on top of the other; the flag of France is used for official occasions</Flagdescription>
+<GDP>purchasing power parity - $74 million (1996 est.); supplemented by annual payments from France of about $65 million</GDP>
+<Industries>fish processing and supply base for fishing fleets; tourism</Industries>
+<Exports>$5 million (f.o.b., 1997)</Exports>
+<Imports>$66 million (c.i.f., 1997 est.)</Imports>
+<Currency>1 French franc (F) = 100 centimes</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Caribbean, islands in the Caribbean Sea, about one-third of the way from Puerto Rico to Trinidad and Tobago</Location>
+<Geographiccoordinates>17 20 N, 62 45 W</Geographiccoordinates>
+<Area>261</Area>
+<Climate>tropical tempered by constant sea breezes; little seasonal temperature variation; rainy season (May to November)</Climate>
+<Naturalresources>arable land</Naturalresources>
+<Population>38819</Population>
+<Populationgrowthrate>-0.22% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican, other Protestant, Roman Catholic</Religions>
+<Countryname>Saint Kitts and Nevis </Countryname>
+<Capital>Basseterre</Capital>
+<Flagdescription>divided diagonally from the lower hoist side by a broad black band bearing two white, five-pointed stars; the black band is edged in yellow; the upper triangle is green, the lower triangle is red</Flagdescription>
+<GDP>purchasing power parity - $244 million (1998 est.)</GDP>
+<Industries>sugar processing, tourism, cotton, salt, copra, clothing, footwear, beverages</Industries>
+<Exports>$42 million (1998)</Exports>
+<Imports>$160 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>2 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American drugs destined for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, group of islands in the Indian Ocean, northeast of Madagascar</Location>
+<Geographiccoordinates>4 35 S, 55 40 E</Geographiccoordinates>
+<Area>455</Area>
+<Climate>tropical marine; humid; cooler season during southeast monsoon (late May to September); warmer season during northwest monsoon (March to May)</Climate>
+<Naturalresources>fish, copra, cinnamon trees</Naturalresources>
+<Population>79326</Population>
+<Populationgrowthrate>0.49% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.51 male(s)/female
+total population: 0.93 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%, Anglican 8%, other 2%</Religions>
+<Countryname>Seychelles </Countryname>
+<Capital>Victoria</Capital>
+<Flagdescription>five oblique bands of blue (hoist side), yellow, red, white, and green (bottom) radiating from the bottom of the hoist side</Flagdescription>
+<GDP>purchasing power parity - $590 million (1999 est.)</GDP>
+<Industries>fishing; tourism; processing of coconuts and vanilla, coir (coconut fiber) rope, boat building, printing, furniture; beverages</Industries>
+<Exports>$91 million (f.o.b., 1998)</Exports>
+<Imports>$403 million (c.i.f., 1998)</Imports>
+<Currency>1 Seychelles rupee (SRe) = 100 cents</Currency>
+<Airports>14 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, at the southern tip of the continent of Africa</Location>
+<Geographiccoordinates>29 00 S, 24 00 E</Geographiccoordinates>
+<Area>1219912</Area>
+<Climate>mostly semiarid; subtropical along east coast; sunny days, cool nights</Climate>
+<Naturalresources>gold, chromium, antimony, coal, iron ore, manganese, nickel, phosphates, tin, uranium, gem diamonds, platinum, copper, vanadium, salt, natural gas</Naturalresources>
+<Population>43421021</Population>
+<Populationgrowthrate>0.5% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.02 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.61 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 68% (includes most whites and Coloreds, about 60% of blacks and about 40% of Indians), Muslim 2%, Hindu 1.5% (60% of Indians), indigenous beliefs and animist 28.5%</Religions>
+<Countryname>South Africa </Countryname>
+<Capital>Pretoria; note - Cape Town is the legislative center and Bloemfontein the judicial center</Capital>
+<Flagdescription>two equal width horizontal bands of red (top) and blue separated by a central green band which splits into a horizontal Y, the arms of which end at the corners of the hoist side; the Y embraces a black isosceles triangle from which the arms are separated by narrow yellow bands; the red and blue bands are separated from the green band and its arms by narrow white stripes
+note: prior to 26 April 1994, the flag was actually four flags in one - three miniature flags reproduced in the center of the white band of the former flag of the Netherlands, which has three equal horizontal bands of orange (top), white, and blue; the miniature flags are a vertically hanging flag of the old Orange Free State with a horizontal flag of the UK adjoining on the hoist side and a horizontal flag of the old Transvaal Republic adjoining on the other side</Flagdescription>
+<GDP>purchasing power parity - $296.1 billion (1999 est.)</GDP>
+<Industries>mining (world's largest producer of platinum, gold, chromium), automobile assembly, metalworking, machinery, textile, iron and steel, chemicals, fertilizer, foodstuffs</Industries>
+<Exports>$28 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$26 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 rand (R) = 100 cents</Currency>
+<Airports>744 (1999 est.)</Airports>
+<Illicitdrugs>transshipment center for heroin and cocaine; cocaine consumption on the rise; world's largest market for illicit methaqualone, usually imported illegally from India through various east African countries; illicit cultivation of marijuana</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Guinea-Bissau and Mauritania</Location>
+<Geographiccoordinates>14 00 N, 14 00 W</Geographiccoordinates>
+<Area>196190</Area>
+<Climate>tropical; hot, humid; rainy season (May to November) has strong southeast winds; dry season (December to April) dominated by hot, dry, harmattan wind</Climate>
+<Naturalresources>fish, phosphates, iron ore</Naturalresources>
+<Population>9987494</Population>
+<Populationgrowthrate>2.94% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 1 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 92%, indigenous beliefs 6%, Christian 2% (mostly Roman Catholic)</Religions>
+<Countryname>Senegal </Countryname>
+<Capital>Dakar</Capital>
+<Flagdescription>three equal vertical bands of green (hoist side), yellow, and red with a small green five-pointed star centered in the yellow band; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $16.6 billion (1999 est.)</GDP>
+<Industries>agricultural and fish processing, phosphate mining, fertilizer production, petroleum refining, construction materials</Industries>
+<Exports>$925 million (f.o.b., 1998)</Exports>
+<Imports>$1.2 billion (f.o.b., 1998)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>20 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for Southwest and Southeast Asian heroin moving to Europe and North America; illicit cultivator of cannabis</Illicitdrugs>
+</record>
+<record>
+<Location>islands in the South Atlantic Ocean, about mid-way between South America and Africa</Location>
+<Geographiccoordinates>15 56 S, 5 42 W</Geographiccoordinates>
+<Area>410</Area>
+<Climate>Saint Helena - tropical; marine; mild, tempered by trade winds; Tristan da Cunha - temperate; marine, mild, tempered by trade winds (tends to be cooler than Saint Helena)</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>7212</Population>
+<Populationgrowthrate>0.76% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.09 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 1.04 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican (majority), Baptist, Seventh-Day Adventist, Roman Catholic</Religions>
+<Countryname>Saint Helena </Countryname>
+<Capital>Jamestown</Capital>
+<Flagdescription>blue with the flag of the UK in the upper hoist-side quadrant and the Saint Helenian shield centered on the outer half of the flag; the shield features a rocky coastline and three-masted sailing ship</Flagdescription>
+<GDP>purchasing power parity - $13.9 million (FY94/95 est.)</GDP>
+<Industries>construction, crafts (furniture, lacework, fancy woodwork), fishing</Industries>
+<Exports>$704,000 (f.o.b., 1995)</Exports>
+<Imports>$14.434 million (c.i.f., 1995)</Imports>
+<Currency>1 Saint Helenian pound = 100 pence</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Europe, eastern Alps bordering the Adriatic Sea, between Austria and Croatia</Location>
+<Geographiccoordinates>46 00 N, 15 00 E</Geographiccoordinates>
+<Area>20253</Area>
+<Climate>Mediterranean climate on the coast, continental climate with mild to hot summers and cold winters in the plateaus and valleys to the east</Climate>
+<Naturalresources>lignite coal, lead, zinc, mercury, uranium, silver, hydropower</Naturalresources>
+<Population>1927593</Population>
+<Populationgrowthrate>0.12% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.57 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 70.8% (including Uniate 2%), Lutheran 1%, Muslim 1%, atheist 4.3%, other 22.9%</Religions>
+<Countryname>Slovenia </Countryname>
+<Capital>Ljubljana</Capital>
+<Flagdescription>three equal horizontal bands of white (top), blue, and red, with the Slovenian seal (a shield with the image of Triglav, Slovenia's highest peak, in white against a blue background at the center; beneath it are two wavy blue lines depicting seas and rivers, and above it are three six-pointed stars arranged in an inverted triangle which are taken from the coat of arms of the Counts of Celje, the great Slovene dynastic house of the late 14th and early 15th centuries); the seal is located in the upper hoist side of the flag centered in the white and blue bands</Flagdescription>
+<GDP>purchasing power parity - $21.4 billion (1999 est.)</GDP>
+<Industries>ferrous metallurgy and rolling mill products, aluminum reduction and rolled products, lead and zinc smelting, electronics (including military electronics), trucks, electric power equipment, wood products, textiles, chemicals, machine tools</Industries>
+<Exports>$8.4 billion (f.o.b., 1999)</Exports>
+<Imports>$9.7 billion (f.o.b., 1999)</Imports>
+<Currency>1 tolar (SlT) = 100 stotins</Currency>
+<Airports>14 (1999 est.)</Airports>
+<Illicitdrugs>minor transit point for Southwest Asian heroin bound for Western Europe, and for precursor chemicals</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, bordering the North Atlantic Ocean, between Guinea and Liberia</Location>
+<Geographiccoordinates>8 30 N, 11 30 W</Geographiccoordinates>
+<Area>71740</Area>
+<Climate>tropical; hot, humid; summer rainy season (May to December); winter dry season (December to April)</Climate>
+<Naturalresources>diamonds, titanium ore, bauxite, iron ore, gold, chromite</Naturalresources>
+<Population>5232624</Population>
+<Populationgrowthrate>3.67% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 0.96 male(s)/female
+15-64 years: 0.92 male(s)/female
+65 years and over: 1 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 60%, indigenous beliefs 30%, Christian 10%</Religions>
+<Countryname>Sierra Leone </Countryname>
+<Capital>Freetown</Capital>
+<Flagdescription>three equal horizontal bands of light green (top), white, and light blue</Flagdescription>
+<GDP>purchasing power parity - $2.5 billion (1999 est.)</GDP>
+<Industries>mining (diamonds); small-scale manufacturing (beverages, textiles, cigarettes, footwear); petroleum refining</Industries>
+<Exports>$41 million (f.o.b., 1998)</Exports>
+<Imports>$166 million (f.o.b., 1998)</Imports>
+<Currency>1 leone (Le) = 100 cents</Currency>
+<Airports>10 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Europe, an enclave in central Italy</Location>
+<Geographiccoordinates>43 46 N, 12 25 E</Geographiccoordinates>
+<Area>60</Area>
+<Climate>Mediterranean; mild to cool winters; warm, sunny summers</Climate>
+<Naturalresources>building stone</Naturalresources>
+<Population>26937</Population>
+<Populationgrowthrate>1.49% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic</Religions>
+<Countryname>San Marino </Countryname>
+<Capital>San Marino</Capital>
+<Flagdescription>two equal horizontal bands of white (top) and light blue with the national coat of arms superimposed in the center; the coat of arms has a shield (featuring three towers on three peaks) flanked by a wreath, below a crown and above a scroll bearing the word LIBERTAS (Liberty)</Flagdescription>
+<GDP>purchasing power parity - $500 million (1997 est.)</GDP>
+<Industries>tourism, banking, textiles, electronics, ceramics, cement, wine</Industries>
+<Exports>trade data are included with the statistics for Italy</Exports>
+<Imports>trade data are included with the statistics for Italy</Imports>
+<Currency>1 Italian lira (Lit) = 100 centesimi; note - also mints its own coins</Currency>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, islands between Malaysia and Indonesia</Location>
+<Geographiccoordinates>1 22 N, 103 48 E</Geographiccoordinates>
+<Area>647</Area>
+<Climate>tropical; hot, humid, rainy; no pronounced rainy or dry seasons; thunderstorms occur on 40% of all days (67% of days in April)</Climate>
+<Naturalresources>fish, deepwater ports</Naturalresources>
+<Population>4151264</Population>
+<Populationgrowthrate>3.54% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist (Chinese), Muslim (Malays), Christian, Hindu, Sikh, Taoist, Confucianist</Religions>
+<Countryname>Singapore </Countryname>
+<Capital>Singapore</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and white; near the hoist side of the red band, there is a vertical, white crescent (closed portion is toward the hoist side) partially enclosing five white five-pointed stars arranged in a circle</Flagdescription>
+<GDP>purchasing power parity - $98 billion (1999 est.)</GDP>
+<Industries>electronics, financial services, oil drilling equipment, petroleum refining, rubber processing and rubber products, processed food and beverages, ship repair, entrepot trade, biotechnology</Industries>
+<Exports>$114 billion (1999)</Exports>
+<Imports>$111 billion (1999)</Imports>
+<Currency>1 Singapore dollar (S$) = 100 cents</Currency>
+<Airports>9 (1999 est.)</Airports>
+<Illicitdrugs>transit point for Golden Triangle heroin going to North America, Western Europe, and the Third World; also a money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, bordering the Gulf of Aden and the Indian Ocean, east of Ethiopia</Location>
+<Geographiccoordinates>10 00 N, 49 00 E</Geographiccoordinates>
+<Area>637657</Area>
+<Climate>principally desert; December to February - northeast monsoon, moderate temperatures in north and very hot in south; May to October - southwest monsoon, torrid in the north and hot in the south, irregular rainfall, hot and humid periods (tangambili) between monsoons</Climate>
+<Naturalresources>uranium and largely unexploited reserves of iron ore, tin, gypsum, bauxite, copper, salt</Naturalresources>
+<Population>7253137</Population>
+<Populationgrowthrate>2.9% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1.01 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim</Religions>
+<Countryname>Somalia </Countryname>
+<Capital>Mogadishu</Capital>
+<Flagdescription>light blue with a large white five-pointed star in the center; design based on the flag of the UN (Italian Somaliland was a UN trust territory)</Flagdescription>
+<GDP>purchasing power parity - $4.3 billion (1999 est.)</GDP>
+<Industries>a few small industries, including sugar refining, textiles, petroleum refining (mostly shut down)</Industries>
+<Exports>$187 million (f.o.b., 1998 est.)</Exports>
+<Imports>$327 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 Somali shilling (So. Sh.) = 100 cents</Currency>
+<Airports>61 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southwestern Europe, bordering the Bay of Biscay, Mediterranean Sea, North Atlantic Ocean, and Pyrenees Mountains, southwest of France</Location>
+<Geographiccoordinates>40 00 N, 4 00 W</Geographiccoordinates>
+<Area>504782</Area>
+<Climate>temperate; clear, hot summers in interior, more moderate and cloudy along coast; cloudy, cold winters in interior, partly cloudy and cool along coast</Climate>
+<Naturalresources>coal, lignite, iron ore, uranium, mercury, pyrites, fluorspar, gypsum, zinc, lead, tungsten, copper, kaolin, potash, hydropower, arable land</Naturalresources>
+<Population>39996671</Population>
+<Populationgrowthrate>0.11% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.72 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 99%, other 1%</Religions>
+<Countryname>Spain </Countryname>
+<Capital>Madrid</Capital>
+<Flagdescription>three horizontal bands of red (top), yellow (double width), and red with the national coat of arms on the hoist side of the yellow band; the coat of arms includes the royal seal framed by the Pillars of Hercules, which are the two promontories (Gibraltar and Ceuta) on either side of the eastern end of the Strait of Gibraltar</Flagdescription>
+<GDP>purchasing power parity - $677.5 billion (1999 est.)</GDP>
+<Industries>textiles and apparel (including footwear), food and beverages, metals and metal manufactures, chemicals, shipbuilding, automobiles, machine tools, tourism</Industries>
+<Exports>$112.3 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$137.5 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 peseta (Pta) = 100 centimos</Currency>
+<Airports>105 (1999 est.)</Airports>
+<Illicitdrugs>key European gateway country for Latin American cocaine and North African hashish entering the European market; transshipment point for and consumer of Southwest Asian heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Southeastern Europe, bordering the Adriatic Sea, between Albania and Bosnia and Herzegovina</Location>
+<Geographiccoordinates>44 00 N, 21 00 E</Geographiccoordinates>
+<Area>102350</Area>
+<Climate>in the north, continental climate (cold winters and hot, humid summers with well distributed rainfall); central portion, continental and Mediterranean climate; to the south, Adriatic climate along the coast, hot, dry summers and autumns and relatively cold winters with heavy snowfall inland</Climate>
+<Naturalresources>oil, gas, coal, antimony, copper, lead, zinc, nickel, gold, pyrite, chrome, hydro power</Naturalresources>
+<Population>10662087</Population>
+<Populationgrowthrate>Serbia - 0.739%; Montenegro - -12.22% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: Serbia - 1.08 male(s)/female; Montenegro - 1.09 male(s)/female
+under 15 years: Serbia - 1.07 male(s)/female; Montenegro - 1.07 male(s)/female
+15-64 years: Serbia - 0.96 male(s)/female; Montenegro - 0.97 male(s)/female
+65 years and over: Serbia - 0.76 male(s)/female; Montenegro - 0.68 male(s)/female
+total population: Serbia - 0.95 male(s)/female; Montenegro - 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Orthodox 65%, Muslim 19%, Roman Catholic 4%, Protestant 1%, other 11%</Religions>
+<Countryname>Serbia and Montenegro </Countryname>
+<Capital>Belgrade (Serbia), Podgorica (Montenegro)</Capital>
+<GDP>purchasing power parity - $20.6 billion (1999 est.)</GDP>
+<Industries>machine building (aircraft, trucks, and automobiles; tanks and weapons; electrical equipment; agricultural machinery); metallurgy (steel, aluminum, copper, lead, zinc, chromium, antimony, bismuth, cadmium); mining (coal, bauxite, nonferrous ore, iron ore, limestone); consumer goods (textiles, footwear, foodstuffs, appliances); electronics, petroleum products, chemicals, and pharmaceuticals</Industries>
+<Exports>$1.5 billion (1999)</Exports>
+<Imports>$3.3 billion (1999)</Imports>
+<Currency>1 Yugoslav New Dinar (YD) = 100 paras; Montenegro made the German deutsche mark (1 deutsche mark (DM) = 100 pfennige) legal tender alongside the Yugoslav dinar (1999)</Currency>
+<Airports>48 (Serbia 43, Montenegro 5) (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for Southwest Asian heroin moving to Western Europe on the Balkan route</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, island between the Caribbean Sea and North Atlantic Ocean, north of Trinidad and Tobago</Location>
+<Geographiccoordinates>13 53 N, 60 68 W</Geographiccoordinates>
+<Area>620</Area>
+<Climate>tropical, moderated by northeast trade winds; dry season from January to April, rainy season from May to August</Climate>
+<Naturalresources>forests, sandy beaches, minerals (pumice), mineral springs, geothermal potential</Naturalresources>
+<Population>156260</Population>
+<Populationgrowthrate>1.21% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.07 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.96 male(s)/female
+65 years and over: 0.6 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 90%, Protestant 7%, Anglican 3%</Religions>
+<Countryname>Saint Lucia </Countryname>
+<Capital>Castries</Capital>
+<Flagdescription>blue, with a gold isosceles triangle below a black arrowhead; the upper edges of the arrowhead have a white border</Flagdescription>
+<GDP>purchasing power parity - $656 million (1998 est.)</GDP>
+<Industries>clothing, assembly of electronic components, beverages, corrugated cardboard boxes, tourism, lime processing, coconut processing</Industries>
+<Exports>$75 million (1998)</Exports>
+<Imports>$290 million (1998)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>2 (1999 est.)</Airports>
+<Illicitdrugs>transit point for South American drugs destined for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Northern Africa, bordering the Red Sea, between Egypt and Eritrea</Location>
+<Geographiccoordinates>15 00 N, 30 00 E</Geographiccoordinates>
+<Area>2505810</Area>
+<Climate>tropical in south; arid desert in north; rainy season (April to October)</Climate>
+<Naturalresources>petroleum; small reserves of iron ore, copper, chromium ore, zinc, tungsten, mica, silver, gold, hydropower</Naturalresources>
+<Population>35079814</Population>
+<Populationgrowthrate>2.84% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 1.33 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 70% (in north), indigenous beliefs 25%, Christian 5% (mostly in south and Khartoum)</Religions>
+<Countryname>Sudan </Countryname>
+<Capital>Khartoum</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and black with a green isosceles triangle based on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $32.6 billion (1999 est.)</GDP>
+<Industries>cotton ginning, textiles, cement, edible oils, sugar, soap distilling, shoes, petroleum refining</Industries>
+<Exports>$580 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.4 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Sudanese dinar (SD) = 100 piastres; note - in July 1999 the Sudanese Central Bank made the formal declaration that all dealings with the Sudanese pound should stop</Currency>
+<Airports>61 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Europe, islands between the Arctic Ocean, Barents Sea, Greenland Sea, and Norwegian Sea, north of Norway</Location>
+<Geographiccoordinates>78 00 N, 20 00 E</Geographiccoordinates>
+<Area>62049</Area>
+<Climate>arctic, tempered by warm North Atlantic Current; cool summers, cold winters; North Atlantic Current flows along west and north coasts of Spitsbergen, keeping water open and navigable most of the year</Climate>
+<Naturalresources>coal, copper, iron ore, phosphate, zinc, wildlife, fish</Naturalresources>
+<Population>2416</Population>
+<Populationgrowthrate>-3.55% (2000 est.)</Populationgrowthrate>
+<Countryname>Svalbard (sometimes referred to as Spitzbergen) </Countryname>
+<Capital>Longyearbyen</Capital>
+<Flagdescription>the flag of Norway is used</Flagdescription>
+<GDP>$NA</GDP>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Norwegian krone (NKr) = 100 oere</Currency>
+<Airports>4 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Europe, bordering the Baltic Sea, Gulf of Bothnia, Kattegat, and Skagerrak, between Finland and Norway</Location>
+<Geographiccoordinates>62 00 N, 15 00 E</Geographiccoordinates>
+<Area>449964</Area>
+<Climate>temperate in south with cold, cloudy winters and cool, partly cloudy summers; subarctic in north</Climate>
+<Naturalresources>zinc, iron ore, lead, copper, silver, timber, uranium, hydropower</Naturalresources>
+<Population>8873052</Population>
+<Populationgrowthrate>0.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.73 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Lutheran 87%, Roman Catholic, Orthodox, Baptist, Muslim, Jewish, Buddhist</Religions>
+<Countryname>Sweden </Countryname>
+<Capital>Stockholm</Capital>
+<Flagdescription>blue with a yellow cross that extends to the edges of the flag; the vertical part of the cross is shifted to the hoist side in the style of the Dannebrog (Danish flag)</Flagdescription>
+<GDP>purchasing power parity - $184 billion (1999 est.)</GDP>
+<Industries>iron and steel, precision equipment (bearings, radio and telephone parts, armaments), wood pulp and paper products, processed foods, motor vehicles</Industries>
+<Exports>$85.7 billion (f.o.b., 1999)</Exports>
+<Imports>$67.9 billion (f.o.b., 1999)</Imports>
+<Currency>1 Swedish krona (SKr) = 100 oere</Currency>
+<Airports>256 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern South America, islands in the South Atlantic Ocean, east of the tip of South America</Location>
+<Geographiccoordinates>54 30 S, 37 00 W</Geographiccoordinates>
+<Area>4066</Area>
+<Climate>variable, with mostly westerly winds throughout the year interspersed with periods of calm; nearly all precipitation falls as snow</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population></Population>
+<Countryname>South Georgia and the South Sandwich Islands </Countryname>
+<Capital>none; Grytviken on South Georgia is the garrison town</Capital>
+<Flagdescription>the flag of the UK is used</Flagdescription>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Middle East, bordering the Mediterranean Sea, between Lebanon and Turkey</Location>
+<Geographiccoordinates>35 00 N, 38 00 E</Geographiccoordinates>
+<Area>185180</Area>
+<Climate>mostly desert; hot, dry, sunny summers (June to August) and mild, rainy winters (December to February) along coast; cold weather with snow or sleet periodically hitting Damascus</Climate>
+<Naturalresources>petroleum, phosphates, chrome and manganese ores, asphalt, iron ore, rock salt, marble, gypsum, hydropower</Naturalresources>
+<Population>16305659</Population>
+<Populationgrowthrate>2.58% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.96 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 74%, Alawite, Druze, and other Muslim sects 16%, Christian (various sects) 10%, Jewish (tiny communities in Damascus, Al Qamishli, and Aleppo)</Religions>
+<Countryname>Syria </Countryname>
+<Capital>Damascus</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and black, with two small green five-pointed stars in a horizontal line centered in the white band; similar to the flag of Yemen, which has a plain white band, and of Iraq, which has three green stars (plus an Arabic inscription) in a horizontal line centered in the white band; also similar to the flag of Egypt, which has a heraldic eagle centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $42.2 billion (1999 est.)</GDP>
+<Industries>petroleum, textiles, food processing, beverages, tobacco, phosphate rock mining</Industries>
+<Exports>$3.3 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.2 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Syrian pound = 100 piastres</Currency>
+<Airports>104 (1999 est.)</Airports>
+<Illicitdrugs>a transit point for opiates and hashish bound for regional and Western markets</Illicitdrugs>
+</record>
+<record>
+<Location>Central Europe, east of France, north of Italy</Location>
+<Geographiccoordinates>47 00 N, 8 00 E</Geographiccoordinates>
+<Area>41290</Area>
+<Climate>temperate, but varies with altitude; cold, cloudy, rainy/snowy winters; cool to warm, cloudy, humid summers with occasional showers</Climate>
+<Naturalresources>hydropower potential, timber, salt</Naturalresources>
+<Population>7262372</Population>
+<Populationgrowthrate>0.3% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.68 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 46.1%, Protestant 40%, other 5%, none 8.9% (1990)</Religions>
+<Countryname>Switzerland </Countryname>
+<Capital>Bern</Capital>
+<Flagdescription>red square with a bold, equilateral white cross in the center that does not extend to the edges of the flag</Flagdescription>
+<GDP>purchasing power parity - $197 billion (1999 est.)</GDP>
+<Industries>machinery, chemicals, watches, textiles, precision instruments</Industries>
+<Exports>$98.5 billion (f.o.b., 1999)</Exports>
+<Imports>$99 billion (f.o.b., 1999)</Imports>
+<Currency>1 Swiss franc, franken, or franco (SFR) = 100 centimes, rappen, or centesimi</Currency>
+<Airports>67 (1999 est.)</Airports>
+<Illicitdrugs>because of more stringent government regulations, used significantly less as a money-laundering center; transit country for and consumer of South American cocaine and Southwest Asian heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Middle East, bordering the Gulf of Oman and the Persian Gulf, between Oman and Saudi Arabia</Location>
+<Geographiccoordinates>24 00 N, 54 00 E</Geographiccoordinates>
+<Area>82880</Area>
+<Climate>desert; cooler in eastern mountains</Climate>
+<Naturalresources>petroleum, natural gas</Naturalresources>
+<Population>2369153</Population>
+<Populationgrowthrate>1.61% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.77 male(s)/female
+65 years and over: 2.26 male(s)/female
+total population: 1.51 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 96% (Shi'a 16%), Christian, Hindu, and other 4%</Religions>
+<Countryname>United Arab Emirates </Countryname>
+<Capital>Abu Dhabi</Capital>
+<Flagdescription>three equal horizontal bands of green (top), white, and black with a thicker vertical red band on the hoist side</Flagdescription>
+<GDP>purchasing power parity - $41.5 billion (1999 est.)</GDP>
+<Industries>petroleum, fishing, petrochemicals, construction materials, some boat building, handicrafts, pearling</Industries>
+<Exports>$34 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$27.5 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Emirian dirham (Dh) = 100 fils</Currency>
+<Airports>40 (1999 est.)</Airports>
+<Illicitdrugs>growing role as heroin transshipment and money-laundering center due to its proximity to southwest Asian producing countries and the bustling free trade zone in Dubai</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, islands between the Caribbean Sea and the North Atlantic Ocean, northeast of Venezuela</Location>
+<Geographiccoordinates>11 00 N, 61 00 W</Geographiccoordinates>
+<Area>5128</Area>
+<Climate>tropical; rainy season (June to December)</Climate>
+<Naturalresources>petroleum, natural gas, asphalt</Naturalresources>
+<Population>1175523</Population>
+<Populationgrowthrate>-0.49% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.8 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 29.4%, Hindu 23.8%, Anglican 10.9%, Muslim 5.8%, Presbyterian 3.4%, other 26.7%</Religions>
+<Countryname>Trinidad and Tobago </Countryname>
+<Capital>Port-of-Spain</Capital>
+<Flagdescription>red with a white-edged black diagonal band from the upper hoist side</Flagdescription>
+<GDP>purchasing power parity - $9.41 billion (1999 est.)</GDP>
+<Industries>petroleum, chemicals, tourism, food processing, cement, beverage, cotton textiles</Industries>
+<Exports>$2.4 billion (f.o.b., 1998)</Exports>
+<Imports>$3 billion (c.i.f., 1998)</Imports>
+<Currency>1 Trinidad and Tobago dollar (TT$) = 100 cents</Currency>
+<Airports>6 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American drugs destined for the US and Europe; producer of cannabis</Illicitdrugs>
+</record>
+<record>
+<Location>Southern Africa, island in the Indian Ocean, east of Madagascar</Location>
+<Geographiccoordinates>15 52 S, 54 25 E</Geographiccoordinates>
+<Area>1</Area>
+<Climate>tropical</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population></Population>
+<Countryname>Tromelin Island </Countryname>
+<Flagdescription>the flag of France is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, bordering the Andaman Sea and the Gulf of Thailand, southeast of Burma</Location>
+<Geographiccoordinates>15 00 N, 100 00 E</Geographiccoordinates>
+<Area>514000</Area>
+<Climate>tropical; rainy, warm, cloudy southwest monsoon (mid-May to September); dry, cool northeast monsoon (November to mid-March); southern isthmus always hot and humid</Climate>
+<Naturalresources>tin, rubber, natural gas, tungsten, tantalum, timber, lead, fish, gypsum, lignite, fluorite, arable land</Naturalresources>
+<Population>61230874</Population>
+<Populationgrowthrate>0.93% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.79 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhism 95%, Muslim 3.8%, Christianity 0.5%, Hinduism 0.1%, other 0.6% (1991)</Religions>
+<Countryname>Thailand </Countryname>
+<Capital>Bangkok</Capital>
+<Flagdescription>five horizontal bands of red (top), white, blue (double width), white, and red</Flagdescription>
+<GDP>purchasing power parity - $388.7 billion (1999 est.)</GDP>
+<Industries>tourism; textiles and garments, agricultural processing, beverages, tobacco, cement, light manufacturing, such as jewelry; electric appliances and components, computers and parts, integrated circuits, furniture, plastics; world's second-largest tungsten producer and third-largest tin producer</Industries>
+<Exports>$58.5 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$45 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 baht (B) = 100 satang</Currency>
+<Airports>106 (1999 est.)</Airports>
+<Illicitdrugs>a minor producer of opium, heroin, and marijuana; major illicit transit point for heroin en route to the international drug market from Burma and Laos; eradication efforts have reduced the area of cannabis cultivation and shifted some production to neighboring countries; opium poppy cultivation has been reduced by eradication efforts; also a drug money-laundering center; minor role in amphetamine production for regional consumption; increasing indigenous abuse of methamphetamines and heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Central Asia, west of China</Location>
+<Geographiccoordinates>39 00 N, 71 00 E</Geographiccoordinates>
+<Area>143100</Area>
+<Climate>midlatitude continental, hot summers, mild winters; semiarid to polar in Pamir Mountains</Climate>
+<Naturalresources>hydropower, some petroleum, uranium, mercury, brown coal, lead, zinc, antimony, tungsten</Naturalresources>
+<Population>6440732</Population>
+<Populationgrowthrate>2.12% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Sunni Muslim 80%, Shi'a Muslim 5%</Religions>
+<Countryname>Tajikistan </Countryname>
+<Capital>Dushanbe</Capital>
+<Flagdescription>three horizontal stripes of red (top), a wider stripe of white, and green; a gold crown surmounted by seven gold, five-pointed stars is located in the center of the white stripe</Flagdescription>
+<GDP>purchasing power parity - $6.2 billion (1999 est.)</GDP>
+<Industries>aluminum, zinc, lead, chemicals and fertilizers, cement, vegetable oil, metal-cutting machine tools, refrigerators and freezers</Industries>
+<Exports>$634 million (1999 est.)</Exports>
+<Imports>$770 million (1999 est.)</Imports>
+<Currency>Tajikistani ruble (TJR) = 100 tanga</Currency>
+<Airports>59 (1994 est.)</Airports>
+<Illicitdrugs>limited illicit cultivation of cannabis, mostly for domestic consumption; opium poppy cultivation negligible in 1998 because of government eradication program; major transshipment point for illicit drugs from Southwest Asia to Russia and Western Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, two island groups in the North Atlantic Ocean, southeast of The Bahamas</Location>
+<Geographiccoordinates>21 45 N, 71 35 W</Geographiccoordinates>
+<Area>430</Area>
+<Climate>tropical; marine; moderated by trade winds; sunny and relatively dry</Climate>
+<Naturalresources>spiny lobster, conch</Naturalresources>
+<Population>17502</Population>
+<Populationgrowthrate>3.55% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.11 male(s)/female
+65 years and over: 0.81 male(s)/female
+total population: 1.07 male(s)/female (2000 est.)</Sexratio>
+<Religions>Baptist 41.2%, Methodist 18.9%, Anglican 18.3%, Seventh-Day Adventist 1.7%, other 19.9% (1980)</Religions>
+<Countryname>Turks and Caicos Islands </Countryname>
+<Capital>Cockburn Town (on Grand Turk)</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and the colonial shield centered on the outer half of the flag; the shield is yellow and contains a conch shell, lobster, and cactus</Flagdescription>
+<GDP>purchasing power parity - $117 million (1997 est.)</GDP>
+<Industries>tourism, offshore financial services</Industries>
+<Exports>$4.7 million (1993)</Exports>
+<Imports>$46.6 million (1993)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>7 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American narcotics destined for the US</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, group of three islands in the South Pacific Ocean, about one-half of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>9 00 S, 172 00 W</Geographiccoordinates>
+<Area>10</Area>
+<Climate>tropical; moderated by trade winds (April to November)</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>1458</Population>
+<Populationgrowthrate>-0.89% (2000 est.)</Populationgrowthrate>
+<Religions>Congregational Christian Church 70%, Roman Catholic 28%, other 2%
+note: on Atafu, all Congregational Christian Church of Samoa; on Nukunonu, all Roman Catholic; on Fakaofo, both denominations, with the Congregational Christian Church predominant</Religions>
+<Countryname>Tokelau </Countryname>
+<Capital>none; each atoll has its own administrative center</Capital>
+<Flagdescription>the flag of New Zealand is used</Flagdescription>
+<GDP>purchasing power parity - $1.5 million (1993 est.)</GDP>
+<Industries>small-scale enterprises for copra production, wood work, plaited craft goods; stamps, coins; fishing</Industries>
+<Exports>$98,000 (f.o.b., 1983)</Exports>
+<Imports>$323,400 (c.i.f., 1983)</Imports>
+<Currency>1 New Zealand dollar (NZ$) = 100 cents</Currency>
+<Airports>none; lagoon landings by amphibious aircraft from Samoa</Airports>
+</record>
+<record>
+<Location>Oceania, archipelago in the South Pacific Ocean, about two-thirds of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>20 00 S, 175 00 W</Geographiccoordinates>
+<Area>748</Area>
+<Climate>tropical; modified by trade winds; warm season (December to May), cool season (May to December)</Climate>
+<Naturalresources>fish, fertile soil</Naturalresources>
+<Population>102321</Population>
+<Populationgrowthrate>1.91% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.83 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian (Free Wesleyan Church claims over 30,000 adherents)</Religions>
+<Countryname>Tonga </Countryname>
+<Capital>Nuku'alofa</Capital>
+<Flagdescription>red with a bold red cross on a white rectangle in the upper hoist-side corner</Flagdescription>
+<GDP>purchasing power parity - $238 million (1998 est.)</GDP>
+<Industries>tourism, fishing</Industries>
+<Exports>$8 million (f.o.b., 1998)</Exports>
+<Imports>$69 million (f.o.b., 1998)</Imports>
+<Currency>1 pa'anga (T$) = 100 seniti</Currency>
+<Airports>6 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Africa, bordering the Bight of Benin, between Benin and Ghana</Location>
+<Geographiccoordinates>8 00 N, 1 10 E</Geographiccoordinates>
+<Area>56785</Area>
+<Climate>tropical; hot, humid in south; semiarid in north</Climate>
+<Naturalresources>phosphates, limestone, marble, arable land</Naturalresources>
+<Population>5018502</Population>
+<Populationgrowthrate>2.7% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 70%, Christian 20%, Muslim 10%</Religions>
+<Countryname>Togo </Countryname>
+<Capital>Lome</Capital>
+<Flagdescription>five equal horizontal bands of green (top and bottom) alternating with yellow; there is a white five-pointed star on a red square in the upper hoist-side corner; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $8.6 billion (1999 est.)</GDP>
+<Industries>phosphate mining, agricultural processing, cement; handicrafts, textiles, beverages</Industries>
+<Exports>$400 million (f.o.b., 1999)</Exports>
+<Imports>$450 million (f.o.b., 1999)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>9 (1999 est.)</Airports>
+<Illicitdrugs>transit hub for Nigerian heroin and cocaine traffickers</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, islands in the Gulf of Guinea, straddling the Equator, west of Gabon</Location>
+<Geographiccoordinates>1 00 N, 7 00 E</Geographiccoordinates>
+<Area>1001</Area>
+<Climate>tropical; hot, humid; one rainy season (October to May)</Climate>
+<Naturalresources>fish, hydropower</Naturalresources>
+<Population>159883</Population>
+<Populationgrowthrate>3.16% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 80% (Roman Catholic, Evangelical Protestant, Seventh-Day Adventist)</Religions>
+<Countryname>Sao Tome and Principe </Countryname>
+<Capital>Sao Tome</Capital>
+<Flagdescription>three horizontal bands of green (top), yellow (double width), and green with two black five-pointed stars placed side by side in the center of the yellow band and a red isosceles triangle based on the hoist side; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $169 million (1999 est.)</GDP>
+<Industries>light construction, textiles, soap, beer; fish processing; timber</Industries>
+<Exports>$4.9 million (f.o.b., 1999 est.)</Exports>
+<Imports>$19.5 million (f.o.b., 1999 est.)</Imports>
+<Currency>1 dobra (Db) = 100 centimos</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Africa, bordering the Mediterranean Sea, between Algeria and Libya</Location>
+<Geographiccoordinates>34 00 N, 9 00 E</Geographiccoordinates>
+<Area>163610</Area>
+<Climate>temperate in north with mild, rainy winters and hot, dry summers; desert in south</Climate>
+<Naturalresources>petroleum, phosphates, iron ore, lead, zinc, salt, arable land</Naturalresources>
+<Population>9593402</Population>
+<Populationgrowthrate>1.17% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 1.01 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 98%, Christian 1%, Jewish and other 1%</Religions>
+<Countryname>Tunisia </Countryname>
+<Capital>Tunis</Capital>
+<Flagdescription>red with a white disk in the center bearing a red crescent nearly encircling a red five-pointed star; the crescent and star are traditional symbols of Islam</Flagdescription>
+<GDP>purchasing power parity - $52.6 billion (1999 est.)</GDP>
+<Industries>petroleum, mining (particularly phosphate and iron ore), tourism, textiles, footwear, food, beverages</Industries>
+<Exports>$5.8 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$8.3 billion (c.i.f., 1999 est.)</Imports>
+<Currency>1 Tunisian dinar (TD) = 1,000 millimes</Currency>
+<Airports>32 (1999 est.)</Airports>
+</record>
+<record>
+<Geographiccoordinates>39 00 N, 35 00 E</Geographiccoordinates>
+<Area>780580</Area>
+<Climate>temperate; hot, dry summers with mild, wet winters; harsher in interior</Climate>
+<Naturalresources>antimony, coal, chromium, mercury, copper, borate, sulfur, iron ore, arable land, hydropower</Naturalresources>
+<Population>65666677</Population>
+<Populationgrowthrate>1.27% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 0.85 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 99.8% (mostly Sunni), other 0.2% (Christian and Jews)</Religions>
+<Countryname>Turkey </Countryname>
+<Capital>Ankara</Capital>
+<Flagdescription>red with a vertical white crescent (the closed portion is toward the hoist side) and white five-pointed star centered just outside the crescent opening</Flagdescription>
+<GDP>purchasing power parity - $409.4 billion (1999 est.)</GDP>
+<Industries>textiles, food processing, autos, mining (coal, chromite, copper, boron), steel, petroleum, construction, lumber, paper</Industries>
+<Exports>$26 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$40 billion (c.i.f., 1999 est.)</Imports>
+<Currency>Turkish lira (TL) = 100 kurus (theoretical)</Currency>
+<Airports>118 (1999 est.)</Airports>
+<Illicitdrugs>key transit route for Southwest Asian heroin to Western Europe and - to a far lesser extent the US - via air, land, and sea routes; major Turkish, Iranian, and other international trafficking organizations operate out of Istanbul; laboratories to convert imported morphine base into heroin are in remote regions of Turkey as well as near Istanbul; government maintains strict controls over areas of legal opium poppy cultivation and output of poppy straw concentrate</Illicitdrugs>
+</record>
+<record>
+<Location>Oceania, island group consisting of nine coral atolls in the South Pacific Ocean, about one-half of the way from Hawaii to Australia</Location>
+<Geographiccoordinates>8 00 S, 178 00 E</Geographiccoordinates>
+<Area>26</Area>
+<Climate>tropical; moderated by easterly trade winds (March to November); westerly gales and heavy rain (November to March)</Climate>
+<Naturalresources>fish</Naturalresources>
+<Population>10838</Population>
+<Populationgrowthrate>1.41% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 0.94 male(s)/female (2000 est.)</Sexratio>
+<Religions>Church of Tuvalu (Congregationalist) 97%, Seventh-Day Adventist 1.4%, Baha'i 1%, other 0.6%</Religions>
+<Countryname>Tuvalu </Countryname>
+<Capital>Funafuti</Capital>
+<Flagdescription>light blue with the flag of the UK in the upper hoist-side quadrant; the outer half of the flag represents a map of the country with nine yellow five-pointed stars symbolizing the nine islands</Flagdescription>
+<GDP>purchasing power parity - $7.8 million (1995 est.)</GDP>
+<Industries>fishing, tourism, copra</Industries>
+<Exports>$165,000 (f.o.b., 1989)</Exports>
+<Imports>$4.4 million (c.i.f., 1989)</Imports>
+<Currency>1 Tuvaluan dollar ($T) or 1 Australian dollar ($A) = 100 cents</Currency>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Eastern Asia, islands bordering the East China Sea, Philippine Sea, South China Sea, and Taiwan Strait, north of the Philippines, off the southeastern coast of China</Location>
+<Geographiccoordinates>23 30 N, 121 00 E</Geographiccoordinates>
+<Area>35980</Area>
+<Climate>tropical; marine; rainy season during southwest monsoon (June to August); cloudiness is persistent and extensive all year</Climate>
+<Naturalresources>small deposits of coal, natural gas, limestone, marble, and asbestos</Naturalresources>
+<Population>22191087</Population>
+<Populationgrowthrate>0.81% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.08 male(s)/female
+15-64 years: 1.03 male(s)/female
+65 years and over: 1.12 male(s)/female
+total population: 1.05 male(s)/female (2000 est.)</Sexratio>
+<Religions>mixture of Buddhist, Confucian, and Taoist 93%, Christian 4.5%, other 2.5%</Religions>
+<Countryname>Taiwan </Countryname>
+<Capital>Taipei</Capital>
+<Flagdescription>red with a dark blue rectangle in the upper hoist-side corner bearing a white sun with 12 triangular rays</Flagdescription>
+<GDP>purchasing power parity - $357 billion (1999 est.)</GDP>
+<Industries>electronics, petroleum refining, chemicals, textiles, iron and steel, machinery, cement, food processing</Industries>
+<Exports>$121.6 billion (f.o.b., 1999)</Exports>
+<Imports>$101.7 billion (c.i.f., 1999)</Imports>
+<Currency>1 New Taiwan dollar (NT$) = 100 cents</Currency>
+<Airports>38 (1999 est.)</Airports>
+<Illicitdrugs>considered an important heroin transit point; major problem with domestic consumption of methamphetamines and heroin</Illicitdrugs>
+</record>
+<record>
+<Location>Central Asia, bordering the Caspian Sea, between Iran and Kazakhstan</Location>
+<Geographiccoordinates>40 00 N, 60 00 E</Geographiccoordinates>
+<Area>488100</Area>
+<Climate>subtropical desert</Climate>
+<Naturalresources>petroleum, natural gas, coal, sulfur, salt</Naturalresources>
+<Population>4518268</Population>
+<Populationgrowthrate>1.87% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.62 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 89%, Eastern Orthodox 9%, unknown 2%</Religions>
+<Countryname>Turkmenistan </Countryname>
+<Capital>Ashgabat</Capital>
+<Flagdescription>green field with a vertical red stripe near the hoist side, containing five carpet guls (designs used in producing rugs) stacked above two crossed olive branches similar to the olive branches on the UN flag; a white crescent moon and five white stars appear in the upper corner of the field just to the fly side of the red stripe</Flagdescription>
+<GDP>purchasing power parity - $7.7 billion (1999 est.)</GDP>
+<Industries>natural gas, oil, petroleum products, textiles, food processing</Industries>
+<Exports>$1.1 billion (1999 est.)</Exports>
+<Imports>$1.25 billion (1999 est.)</Imports>
+<Currency>1 Turkmen manat (TMM) = 100 tenesi</Currency>
+<Airports>64 (1994 est.)</Airports>
+<Illicitdrugs>limited illicit cultivator of opium poppy, mostly for domestic consumption; limited government eradication program; increasingly used as transshipment point for illicit drugs from Southwest Asia to Russia and Western Europe; also a transshipment point for acetic anhydride destined for Afghanistan</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, bordering the Indian Ocean, between Kenya and Mozambique</Location>
+<Geographiccoordinates>6 00 S, 35 00 E</Geographiccoordinates>
+<Area>945087</Area>
+<Climate>varies from tropical along coast to temperate in highlands</Climate>
+<Naturalresources>hydropower, tin, phosphates, iron ore, coal, diamonds, gemstones, gold, natural gas, nickel</Naturalresources>
+<Population>35306126</Population>
+<Populationgrowthrate>2.57% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>mainland - Christian 45%, Muslim 35%, indigenous beliefs 20%; Zanzibar - more than 99% Muslim</Religions>
+<Countryname>Tanzania </Countryname>
+<Capital>Dar es Salaam
+note: some government offices have been transferred to Dodoma, which is planned as the new national capital; the National Assembly now meets there on regular basis</Capital>
+<Flagdescription>divided diagonally by a yellow-edged black band from the lower hoist-side corner; the upper triangle (hoist side) is green and the lower triangle is blue</Flagdescription>
+<GDP>purchasing power parity - $23.3 billion (1999 est.)</GDP>
+<Industries>primarily agricultural processing (sugar, beer, cigarettes, sisal twine), diamond and gold mining, oil refining, shoes, cement, textiles, wood products, fertilizer, salt</Industries>
+<Exports>$828 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.44 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Tanzanian shilling (TSh) = 100 cents</Currency>
+<Airports>129 (1999 est.)</Airports>
+<Illicitdrugs>growing role in transshipment of Southwest and Southeast Asian heroin and South American cocaine destined for European and US markets and of South Asian methaqualone bound for Southern Africa</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Africa, west of Kenya</Location>
+<Geographiccoordinates>1 00 N, 32 00 E</Geographiccoordinates>
+<Area>236040</Area>
+<Climate>tropical; generally rainy with two dry seasons (December to February, June to August); semiarid in northeast</Climate>
+<Naturalresources>copper, cobalt, hydropower, limestone, salt, arable land</Naturalresources>
+<Population>23317560</Population>
+<Populationgrowthrate>2.72% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 1 male(s)/female
+65 years and over: 0.92 male(s)/female
+total population: 1 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 33%, Protestant 33%, Muslim 16%, indigenous beliefs 18%</Religions>
+<Countryname>Uganda </Countryname>
+<Capital>Kampala</Capital>
+<Flagdescription>six equal horizontal bands of black (top), yellow, red, black, yellow, and red; a white disk is superimposed at the center and depicts a red-crested crane (the national symbol) facing the hoist side</Flagdescription>
+<GDP>purchasing power parity - $24.2 billion (1999 est.)</GDP>
+<Industries>sugar, brewing, tobacco, cotton textiles, cement</Industries>
+<Exports>$471 million (f.o.b., 1999)</Exports>
+<Imports>$1.1 billion (f.o.b., 1999)</Imports>
+<Currency>1 Ugandan shilling (USh) = 100 cents</Currency>
+<Airports>26 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Western Europe, islands including the northern one-sixth of the island of Ireland between the North Atlantic Ocean and the North Sea, northwest of France</Location>
+<Geographiccoordinates>54 00 N, 2 00 W</Geographiccoordinates>
+<Area>244820</Area>
+<Climate>temperate; moderated by prevailing southwest winds over the North Atlantic Current; more than one-half of the days are overcast</Climate>
+<Naturalresources>coal, petroleum, natural gas, tin, limestone, iron ore, salt, clay, chalk, gypsum, lead, silica, arable land</Naturalresources>
+<Population>59511464</Population>
+<Populationgrowthrate>0.25% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 27 million, Roman Catholic 9 million, Muslim 1 million, Presbyterian 800,000, Methodist 760,000, Sikh 400,000, Hindu 350,000, Jewish 300,000 (1991 est.)</Religions>
+<Countryname>United Kingdom </Countryname>
+<Capital>London</Capital>
+<Flagdescription>blue with the red cross of Saint George (patron saint of England) edged in white superimposed on the diagonal red cross of Saint Patrick (patron saint of Ireland) and which is superimposed on the diagonal white cross of Saint Andrew (patron saint of Scotland); known as the Union Flag or Union Jack; the design and colors (especially the Blue Ensign) have been the basis for a number of other flags including other Commonwealth countries and their constituent states or provinces, as well as British overseas territories</Flagdescription>
+<GDP>purchasing power parity - $1.29 trillion (1999 est.)</GDP>
+<Industries>production machinery including machine tools, electric power equipment, automation equipment, railroad equipment, shipbuilding, aircraft, motor vehicles and parts, electronics and communications equipment, metals, chemicals, coal, petroleum, paper and paper products, food processing, textiles, clothing, and other consumer goods</Industries>
+<Exports>$271 billion (f.o.b., 1998)</Exports>
+<Imports>$305.9 billion (f.o.b., 1998)</Imports>
+<Currency>1 British pound = 100 pence</Currency>
+<Airports>498 (1999 est.)</Airports>
+<Illicitdrugs>gateway country for Latin American cocaine entering the European market; producer and major consumer of synthetic drugs, synthetic precursor chemicals; major consumer of Southwest Asian heroin; money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>Eastern Europe, bordering the Black Sea, between Poland and Russia</Location>
+<Geographiccoordinates>49 00 N, 32 00 E</Geographiccoordinates>
+<Area>603700</Area>
+<Climate>temperate continental; Mediterranean only on the southern Crimean coast; precipitation disproportionately distributed, highest in west and north, lesser in east and southeast; winters vary from cool along the Black Sea to cold farther inland; summers are warm across the greater part of the country, hot in the south</Climate>
+<Naturalresources>iron ore, coal, manganese, natural gas, oil, salt, sulfur, graphite, titanium, magnesium, kaolin, nickel, mercury, timber, arable land</Naturalresources>
+<Population>49153027</Population>
+<Populationgrowthrate>-0.83% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.49 male(s)/female
+total population: 0.86 male(s)/female (2000 est.)</Sexratio>
+<Religions>Ukrainian Orthodox - Moscow Patriarchate, Ukrainian Orthodox - Kiev Patriarchate, Ukrainian Autocephalous Orthodox, Ukrainian Catholic (Uniate), Protestant, Jewish</Religions>
+<Countryname>Ukraine </Countryname>
+<Capital>Kiev (Kyyiv)</Capital>
+<Flagdescription>two equal horizontal bands of azure (top) and golden yellow represent grainfields under a blue sky</Flagdescription>
+<GDP>purchasing power parity - $109.5 billion (1999 est.)</GDP>
+<Industries>coal, electric power, ferrous and nonferrous metals, machinery and transport equipment, chemicals, food-processing (especially sugar)</Industries>
+<Exports>$11.6 billion (1999 est.)</Exports>
+<Imports>$11.8 billion (1999 est.)</Imports>
+<Currency>1 hryvna = 100 kopiykas</Currency>
+<Airports>706 (1994 est.)</Airports>
+<Illicitdrugs>limited cultivation of cannabis and opium poppy, mostly for CIS consumption; some synthetic drug production for export to West; limited government eradication program; used as transshipment point for opiates and other illicit drugs from Africa, Latin America, and Turkey, and to Europe and Russia; drug-related money laundering a minor, but growing, problem</Illicitdrugs>
+</record>
+<record>
+<Location>North America, bordering both the North Atlantic Ocean and the North Pacific Ocean, between Canada and Mexico</Location>
+<Geographiccoordinates>38 00 N, 97 00 W</Geographiccoordinates>
+<Area>9629091</Area>
+<Climate>mostly temperate, but tropical in Hawaii and Florida, arctic in Alaska, semiarid in the great plains west of the Mississippi River, and arid in the Great Basin of the southwest; low winter temperatures in the northwest are ameliorated occasionally in January and February by warm chinook winds from the eastern slopes of the Rocky Mountains</Climate>
+<Naturalresources>coal, copper, lead, molybdenum, phosphates, uranium, bauxite, gold, iron, mercury, nickel, potash, silver, tungsten, zinc, petroleum, natural gas, timber</Naturalresources>
+<Population>275562673</Population>
+<Populationgrowthrate>0.91% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.71 male(s)/female
+total population: 0.96 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 56%, Roman Catholic 28%, Jewish 2%, other 4%, none 10% (1989)</Religions>
+<Countryname>United States </Countryname>
+<Capital>Washington, DC</Capital>
+<Flagdescription>thirteen equal horizontal stripes of red (top and bottom) alternating with white; there is a blue rectangle in the upper hoist-side corner bearing 50 small, white, five-pointed stars arranged in nine offset horizontal rows of six stars (top and bottom) alternating with rows of five stars; the 50 stars represent the 50 states, the 13 stripes represent the 13 original colonies; known as Old Glory; the design and colors have been the basis for a number of other flags, including Chile, Liberia, Malaysia, and Puerto Rico</Flagdescription>
+<GDP>purchasing power parity - $9.255 trillion (1999 est.)</GDP>
+<Industries>leading industrial power in the world, highly diversified and technologically advanced; petroleum, steel, motor vehicles, aerospace, telecommunications, chemicals, electronics, food processing, consumer goods, lumber, mining</Industries>
+<Exports>$663 billion (f.o.b., 1998 est.)</Exports>
+<Imports>$912 billion (c.i.f., 1998 est.)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>14,572 (1999 est.)</Airports>
+<Illicitdrugs>consumer of cocaine shipped from Colombia through Mexico and the Caribbean; consumer of heroin, marijuana, and increasingly methamphetamines from Mexico; consumer of high-quality Southeast Asian heroin; illicit producer of cannabis, marijuana, depressants, stimulants, hallucinogens, and methamphetamines; drug-money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>Western Africa, north of Ghana</Location>
+<Geographiccoordinates>13 00 N, 2 00 W</Geographiccoordinates>
+<Area>274200</Area>
+<Climate>tropical; warm, dry winters; hot, wet summers</Climate>
+<Naturalresources>manganese, limestone, marble; small deposits of gold, antimony, copper, nickel, bauxite, lead, phosphates, zinc, silver</Naturalresources>
+<Population>11946065</Population>
+<Populationgrowthrate>2.71% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 0.91 male(s)/female
+65 years and over: 0.74 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>indigenous beliefs 40%, Muslim 50%, Christian (mainly Roman Catholic) 10%</Religions>
+<Countryname>Burkina Faso </Countryname>
+<Capital>Ouagadougou</Capital>
+<Flagdescription>two equal horizontal bands of red (top) and green with a yellow five-pointed star in the center; uses the popular pan-African colors of Ethiopia</Flagdescription>
+<GDP>purchasing power parity - $12.4 billion (1999 est.)</GDP>
+<Industries>cotton lint, beverages, agricultural processing, soap, cigarettes, textiles, gold</Industries>
+<Exports>$311 million (f.o.b., 1998 est.)</Exports>
+<Imports>$572 million (f.o.b., 1998 est.)</Imports>
+<Currency>1 Communaute Financiere Africaine franc (CFAF) = 100 centimes</Currency>
+<Airports>33 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern South America, bordering the South Atlantic Ocean, between Argentina and Brazil</Location>
+<Geographiccoordinates>33 00 S, 56 00 W</Geographiccoordinates>
+<Area>176220</Area>
+<Climate>warm temperate; freezing temperatures almost unknown</Climate>
+<Naturalresources>arable land, hydropower, minor minerals, fisheries</Naturalresources>
+<Population>3334074</Population>
+<Populationgrowthrate>0.77% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 0.97 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Roman Catholic 66% (less than one-half of the adult population attends church regularly), Protestant 2%, Jewish 2%, nonprofessing or other 30%</Religions>
+<Countryname>Uruguay </Countryname>
+<Capital>Montevideo</Capital>
+<Flagdescription>nine equal horizontal stripes of white (top and bottom) alternating with blue; there is a white square in the upper hoist-side corner with a yellow sun bearing a human face known as the Sun of May and 16 rays alternately triangular and wavy</Flagdescription>
+<GDP>purchasing power parity - $28 billion (1999 est.)</GDP>
+<Industries>food processing, electrical machinery, transportation equipment, petroleum products, textiles, chemicals, beverages</Industries>
+<Exports>$2.1 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$3.4 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Uruguayan peso ($Ur) = 100 centesimos</Currency>
+<Airports>65 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Central Asia, north of Afghanistan</Location>
+<Geographiccoordinates>41 00 N, 64 00 E</Geographiccoordinates>
+<Area>447400</Area>
+<Climate>mostly midlatitude desert, long, hot summers, mild winters; semiarid grassland in east</Climate>
+<Naturalresources>natural gas, petroleum, coal, gold, uranium, silver, copper, lead and zinc, tungsten, molybdenum</Naturalresources>
+<Population>24755519</Population>
+<Populationgrowthrate>1.6% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.66 male(s)/female
+total population: 0.98 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 88% (mostly Sunnis), Eastern Orthodox 9%, other 3%</Religions>
+<Countryname>Uzbekistan </Countryname>
+<Capital>Tashkent (Toshkent)</Capital>
+<Flagdescription>three equal horizontal bands of blue (top), white, and green separated by red fimbriations with a white crescent moon and 12 white stars in the upper hoist-side quadrant</Flagdescription>
+<GDP>purchasing power parity - $59.3 billion (1999 est.)</GDP>
+<Industries>textiles, food processing, machine building, metallurgy, natural gas</Industries>
+<Exports>$2.9 billion (1999 est.)</Exports>
+<Imports>$3.1 billion (1999 est.)</Imports>
+<Currency>Uzbekistani som (UKS)</Currency>
+<Airports>3 (1997 est.)</Airports>
+<Illicitdrugs>limited illicit cultivation of cannabis and very small amounts of opium poppy, mostly for domestic consumption, almost entirely eradicated by an effective government eradication program; increasingly used as transshipment point for illicit drugs from Afghanistan to Russia and Western Europe and for acetic anhydride destined for Afghanistan</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, islands in the Caribbean Sea, north of Trinidad and Tobago</Location>
+<Geographiccoordinates>13 15 N, 61 12 W</Geographiccoordinates>
+<Area>389</Area>
+<Climate>tropical; little seasonal temperature variation; rainy season (May to November)</Climate>
+<Naturalresources>hydropower, cropland</Naturalresources>
+<Population>115461</Population>
+<Populationgrowthrate>0.43% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 0.75 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>Anglican 47%, Methodist 28%, Roman Catholic 13%, Seventh-Day Adventist, Hindu, other Protestant</Religions>
+<Countryname>Saint Vincent and the Grenadines </Countryname>
+<Capital>Kingstown</Capital>
+<Flagdescription>three vertical bands of blue (hoist side), gold (double width), and green; the gold band bears three green diamonds arranged in a V pattern</Flagdescription>
+<GDP>purchasing power parity - $309 million (1999 est.)</GDP>
+<Industries>food processing, cement, furniture, clothing, starch</Industries>
+<Exports>$47.8 million (1998 est.)</Exports>
+<Imports>$180 million (1998 est.)</Imports>
+<Currency>1 East Caribbean dollar (EC$) = 100 cents</Currency>
+<Airports>6 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for South American drugs destined for the US and Europe</Illicitdrugs>
+</record>
+<record>
+<Location>Northern South America, bordering the Caribbean Sea and the North Atlantic Ocean, between Colombia and Guyana</Location>
+<Geographiccoordinates>8 00 N, 66 00 W</Geographiccoordinates>
+<Area>912050</Area>
+<Climate>tropical; hot, humid; more moderate in highlands</Climate>
+<Naturalresources>petroleum, natural gas, iron ore, gold, bauxite, other minerals, hydropower, diamonds</Naturalresources>
+<Population>23542649</Population>
+<Populationgrowthrate>1.6% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.08 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 1.01 male(s)/female
+65 years and over: 0.84 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>nominally Roman Catholic 96%, Protestant 2%</Religions>
+<Countryname>Venezuela </Countryname>
+<Capital>Caracas</Capital>
+<Flagdescription>three equal horizontal bands of yellow (top), blue, and red with the coat of arms on the hoist side of the yellow band and an arc of seven white five-pointed stars centered in the blue band</Flagdescription>
+<GDP>purchasing power parity - $182.8 billion (1999 est.)</GDP>
+<Industries>petroleum, iron ore mining, construction materials, food processing, textiles, steel, aluminum, motor vehicle assembly</Industries>
+<Exports>$20.9 billion (f.o.b., 1999)</Exports>
+<Imports>$11.8 billion (f.o.b., 1999)</Imports>
+<Currency>1 bolivar (Bs) = 100 centimos</Currency>
+<Airports>366 (1999 est.)</Airports>
+<Illicitdrugs>illicit producer of opium for the international drug trade on a small scale; however, large quantities of cocaine and heroin transit the country from Colombia bound for US and Europe; important money-laundering hub; active eradication program primarily targeting opium; increasing signs of drug-related activities by Colombian insurgents on border</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, between the Caribbean Sea and the North Atlantic Ocean, east of Puerto Rico</Location>
+<Geographiccoordinates>18 30 N, 64 30 W</Geographiccoordinates>
+<Area>150</Area>
+<Climate>subtropical; humid; temperatures moderated by trade winds</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>19615</Population>
+<Populationgrowthrate>2.34% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.06 male(s)/female
+65 years and over: 1.2 male(s)/female
+total population: 1.06 male(s)/female (2000 est.)</Sexratio>
+<Religions>Protestant 86% (Methodist 45%, Anglican 21%, Church of God 7%, Seventh-Day Adventist 5%, Baptist 4%, Jehovah's Witnesses 2%, other 2%), Roman Catholic 6%, none 2%, other 6% (1981)</Religions>
+<Countryname>British Virgin Islands </Countryname>
+<Capital>Road Town</Capital>
+<Flagdescription>blue, with the flag of the UK in the upper hoist-side quadrant and the Virgin Islander coat of arms centered in the outer half of the flag; the coat of arms depicts a woman flanked on either side by a vertical column of six oil lamps above a scroll bearing the Latin word VIGILATE (Be Watchful)</Flagdescription>
+<GDP>purchasing power parity - $287 million (1999 est.)</GDP>
+<Industries>tourism, light industry, construction, rum, concrete block, offshore financial center</Industries>
+<Exports>$6 million (1998)</Exports>
+<Imports>$175 million (1998)</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southeastern Asia, bordering the Gulf of Thailand, Gulf of Tonkin, and South China Sea, alongside China, Laos, and Cambodia</Location>
+<Geographiccoordinates>16 00 N, 106 00 E</Geographiccoordinates>
+<Area>329560</Area>
+<Climate>tropical in south; monsoonal in north with hot, rainy season (mid-May to mid-September) and warm, dry season (mid-October to mid-March)</Climate>
+<Naturalresources>phosphates, coal, manganese, bauxite, chromate, offshore oil and gas deposits, forests, hydropower</Naturalresources>
+<Population>78773873</Population>
+<Populationgrowthrate>1.49% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.07 male(s)/female
+15-64 years: 0.95 male(s)/female
+65 years and over: 0.66 male(s)/female
+total population: 0.97 male(s)/female (2000 est.)</Sexratio>
+<Religions>Buddhist, Taoist, Roman Catholic, indigenous beliefs, Muslim, Protestant, Cao Dai, Hoa Hao</Religions>
+<Countryname>Vietnam </Countryname>
+<Capital>Hanoi</Capital>
+<Flagdescription>red with a large yellow five-pointed star in the center</Flagdescription>
+<GDP>purchasing power parity - $143.1 billion (1999 est.)</GDP>
+<Industries>food processing, garments, shoes, machine building, mining, cement, chemical fertilizer, glass, tires, oil, coal, steel, paper</Industries>
+<Exports>$11.5 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$11.6 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 new dong (D) = 100 xu</Currency>
+<Airports>48 (1999 est.)</Airports>
+<Illicitdrugs>minor producer of opium poppy with 2,100 hectares cultivated in 1999, capable of producing 11 metric tons of opium; probably minor transit point for Southeast Asian heroin destined for the US and Europe; growing opium/heroin addiction; possible small-scale heroin production</Illicitdrugs>
+</record>
+<record>
+<Location>Caribbean, islands between the Caribbean Sea and the North Atlantic Ocean, east of Puerto Rico</Location>
+<Geographiccoordinates>18 20 N, 64 50 W</Geographiccoordinates>
+<Area>352</Area>
+<Climate>subtropical, tempered by easterly trade winds, relatively low humidity, little seasonal temperature variation; rainy season May to November</Climate>
+<Naturalresources>sun, sand, sea, surf</Naturalresources>
+<Population>120917</Population>
+<Populationgrowthrate>1.07% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.06 male(s)/female
+under 15 years: 1.06 male(s)/female
+15-64 years: 0.83 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.88 male(s)/female (2000 est.)</Sexratio>
+<Religions>Baptist 42%, Roman Catholic 34%, Episcopalian 17%, other 7%</Religions>
+<Countryname>Virgin Islands </Countryname>
+<Capital>Charlotte Amalie</Capital>
+<Flagdescription>white, with a modified US coat of arms in the center between the large blue initials V and I; the coat of arms shows a yellow eagle holding an olive branch in one talon and three arrows in the other with a superimposed shield of vertical red and white stripes below a blue panel</Flagdescription>
+<GDP>purchasing power parity - $1.8 billion (1999 est.)</GDP>
+<Industries>tourism, petroleum refining, watch assembly, rum distilling, construction, pharmaceuticals, textiles, electronics</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 United States dollar (US$) = 100 cents</Currency>
+<Airports>2
+note: international airports on Saint Thomas and Saint Croix (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Europe, an enclave of Rome (Italy)</Location>
+<Geographiccoordinates>41 54 N, 12 27 E</Geographiccoordinates>
+<Area>0</Area>
+<Climate>temperate; mild, rainy winters (September to mid-May) with hot, dry summers (May to September)</Climate>
+<Naturalresources>none</Naturalresources>
+<Population>880</Population>
+<Populationgrowthrate>1.15% (2000 est.)</Populationgrowthrate>
+<Religions>Roman Catholic</Religions>
+<Countryname>Holy See (Vatican City) </Countryname>
+<Capital>Vatican City</Capital>
+<Flagdescription>two vertical bands of yellow (hoist side) and white with the crossed keys of Saint Peter and the papal miter centered in the white band</Flagdescription>
+<Industries>printing and production of a small amount of mosaics and staff uniforms; worldwide banking and financial activities</Industries>
+<Currency>1 Vatican lira (VLit) = 100 centesimi</Currency>
+<Airports>none</Airports>
+</record>
+<record>
+<Location>Southern Africa, bordering the South Atlantic Ocean, between Angola and South Africa</Location>
+<Geographiccoordinates>22 00 S, 17 00 E</Geographiccoordinates>
+<Area>825418</Area>
+<Climate>desert; hot, dry; rainfall sparse and erratic</Climate>
+<Naturalresources>diamonds, copper, uranium, gold, lead, tin, lithium, cadmium, zinc, salt, vanadium, natural gas, hydropower, fish
+note: suspected deposits of oil, coal, and iron ore</Naturalresources>
+<Population>1771327</Population>
+<Populationgrowthrate>1.57% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 0.99 male(s)/female
+65 years and over: 0.76 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 80% to 90% (Lutheran 50% at least), indigenous beliefs 10% to 20%</Religions>
+<Countryname>Namibia </Countryname>
+<Capital>Windhoek</Capital>
+<Flagdescription>a large blue triangle with a yellow sunburst fills the upper left section and an equal green triangle (solid) fills the lower right section; the triangles are separated by a red stripe that is contrasted by two narrow white-edge borders</Flagdescription>
+<GDP>purchasing power parity - $7.1 billion (1999 est.)</GDP>
+<Industries>meat packing, fish processing, dairy products; mining (diamond, lead, zinc, tin, silver, tungsten, uranium, copper)</Industries>
+<Exports>$1.4 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$1.5 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Namibian dollar (N$) = 100 cents</Currency>
+<Airports>135 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Middle East, west of Jordan</Location>
+<Geographiccoordinates>32 00 N, 35 15 E</Geographiccoordinates>
+<Area>5860</Area>
+<Climate>temperate, temperature and precipitation vary with altitude, warm to hot summers, cool to mild winters</Climate>
+<Naturalresources>arable land</Naturalresources>
+<Population>2020298</Population>
+<Populationgrowthrate>3.38% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.05 male(s)/female
+15-64 years: 1.04 male(s)/female
+65 years and over: 0.78 male(s)/female
+total population: 1.03 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim 75% (predominantly Sunni), Jewish 17%, Christian and other 8%</Religions>
+<Countryname>West Bank </Countryname>
+<GDP>purchasing power parity - $3.3 billion (1999 est.)</GDP>
+<Industries>generally small family businesses that produce cement, textiles, soap, olive-wood carvings, and mother-of-pearl souvenirs; the Israelis have established some small-scale, modern industries in the settlements and industrial centers</Industries>
+<Exports>$682 million (includes Gaza Strip) (f.o.b., 1998 est.)</Exports>
+<Imports>$2.5 billion (includes Gaza Strip) (c.i.f., 1998 est.)</Imports>
+<Currency>1 new Israeli shekel (NIS) = 100 new agorot; 1 Jordanian dinar (JD) = 1,000 fils</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, islands in the South Pacific Ocean, about two-thirds of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>13 18 S, 176 12 W</Geographiccoordinates>
+<Area>274</Area>
+<Climate>tropical; hot, rainy season (November to April); cool, dry season (May to October); rains 2,500-3,000 mm per year (80% humidity); average temperature 26.6 degrees C</Climate>
+<Naturalresources>NEGL</Naturalresources>
+<Population>15283</Population>
+<Populationgrowthrate>NA%</Populationgrowthrate>
+<Religions>Roman Catholic 100%</Religions>
+<Countryname>Wallis and Futuna </Countryname>
+<Capital>Mata-Utu (on Ile Uvea)</Capital>
+<Flagdescription>a large white modified Maltese cross centered on a red background; the flag of France outlined in white on two sides is in the upper hoist quadrant; the flag of France is used for official occasions</Flagdescription>
+<GDP>purchasing power parity - $28.7 million (1995 est.)</GDP>
+<Industries>copra, handicrafts, fishing, lumber</Industries>
+<Exports>$370,000 (f.o.b., 1995 est.)</Exports>
+<Imports>$13.5 million (c.i.f., 1995 est.)</Imports>
+<Currency>1 Comptoirs Francais du Pacifique franc (CFPF) = 100 centimes</Currency>
+<Airports>2 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Northern Africa, bordering the North Atlantic Ocean, between Mauritania and Morocco</Location>
+<Geographiccoordinates>24 30 N, 13 00 W</Geographiccoordinates>
+<Area>266000</Area>
+<Climate>hot, dry desert; rain is rare; cold offshore air currents produce fog and heavy dew</Climate>
+<Naturalresources>phosphates, iron ore</Naturalresources>
+<Population>244943</Population>
+<Populationgrowthrate>2.29% (2000 est.)</Populationgrowthrate>
+<Religions>Muslim</Religions>
+<Countryname>Western Sahara </Countryname>
+<Capital>none</Capital>
+<GDP>purchasing power parity - $NA</GDP>
+<Industries>phosphate mining, handicrafts</Industries>
+<Exports>$NA</Exports>
+<Imports>$NA</Imports>
+<Currency>1 Moroccan dirham (DH) = 100 centimes</Currency>
+<Airports>12 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, atoll in the North Pacific Ocean, about two-thirds of the way from Hawaii to the Northern Mariana Islands</Location>
+<Geographiccoordinates>19 17 N, 166 36 E</Geographiccoordinates>
+<Area>6</Area>
+<Climate>tropical</Climate>
+<Naturalresources>none</Naturalresources>
+<Population></Population>
+<Countryname>Wake Island </Countryname>
+<Flagdescription>the flag of the US is used</Flagdescription>
+<Airports>1 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Oceania, group of islands in the South Pacific Ocean, about one-half of the way from Hawaii to New Zealand</Location>
+<Geographiccoordinates>13 35 S, 172 20 W</Geographiccoordinates>
+<Area>2860</Area>
+<Climate>tropical; rainy season (October to March), dry season (May to October)</Climate>
+<Naturalresources>hardwood forests, fish, hydropower</Naturalresources>
+<Population>179466</Population>
+<Populationgrowthrate>-0.22% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.03 male(s)/female
+15-64 years: 1.72 male(s)/female
+65 years and over: 0.88 male(s)/female
+total population: 1.39 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 99.7% (about one-half of population associated with the London Missionary Society; includes Congregational, Roman Catholic, Methodist, Latter-Day Saints, Seventh-Day Adventist)</Religions>
+<Countryname>Samoa </Countryname>
+<Capital>Apia</Capital>
+<Flagdescription>red with a blue rectangle in the upper hoist-side quadrant bearing five white five-pointed stars representing the Southern Cross constellation</Flagdescription>
+<GDP>purchasing power parity - $485 million (1998 est.)</GDP>
+<Industries>timber, tourism, food processing, fishing</Industries>
+<Exports>$20.3 million (f.o.b., 1998)</Exports>
+<Imports>$96.6 million (f.o.b., 1998)</Imports>
+<Currency>1 tala (WS$) = 100 sene</Currency>
+<Airports>3 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, between Mozambique and South Africa</Location>
+<Geographiccoordinates>26 30 S, 31 30 E</Geographiccoordinates>
+<Area>17363</Area>
+<Climate>varies from tropical to near temperate</Climate>
+<Naturalresources>asbestos, coal, clay, cassiterite, hydropower, forests, small gold and diamond deposits, quarry stone, and talc</Naturalresources>
+<Population>1083289</Population>
+<Populationgrowthrate>2.02% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 0.99 male(s)/female
+15-64 years: 0.93 male(s)/female
+65 years and over: 0.7 male(s)/female
+total population: 0.95 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 60%, indigenous beliefs 40%</Religions>
+<Countryname>Swaziland </Countryname>
+<Capital>Mbabane; note - Lobamba is the royal and legislative capital</Capital>
+<Flagdescription>three horizontal bands of blue (top), red (triple width), and blue; the red band is edged in yellow; centered in the red band is a large black and white shield covering two spears and a staff decorated with feather tassels, all placed horizontally</Flagdescription>
+<GDP>purchasing power parity - $4.2 billion (1999 est.)</GDP>
+<Industries>mining (coal and asbestos), wood pulp, sugar, soft drink concentrates</Industries>
+<Exports>$825 million (f.o.b., 1999)</Exports>
+<Imports>$1.05 billion (f.o.b., 1999)</Imports>
+<Currency>1 lilangeni (E) = 100 cents</Currency>
+<Airports>18 (1999 est.)</Airports>
+</record>
+<record>
+<Location>body of water between Africa, the Southern Ocean, Asia, and Australia</Location>
+<Geographiccoordinates>20 00 S, 80 00 E</Geographiccoordinates>
+<Area>68000000</Area>
+<Climate>northeast monsoon (December to April), southwest monsoon (June to October); tropical cyclones occur during May/June and October/November in the northern Indian Ocean and January/February in the southern Indian Ocean</Climate>
+<Naturalresources>oil and gas fields, fish, shrimp, sand and gravel aggregates, placer deposits, polymetallic nodules</Naturalresources>
+</record>
+<record>
+<Location>body of water mostly north of the Arctic Circle</Location>
+<Geographiccoordinates>90 00 N, 0 00 E</Geographiccoordinates>
+<Area>14000000</Area>
+<Climate>polar climate characterized by persistent cold and relatively narrow annual temperature ranges; winters characterized by continuous darkness, cold and stable weather conditions, and clear skies; summers characterized by continuous daylight, damp and foggy weather, and weak cyclones with rain or snow</Climate>
+<Naturalresources>sand and gravel aggregates, placer deposits, polymetallic nodules, oil and gas fields, fish, marine mammals (seals and whales)</Naturalresources>
+</record>
+<record>
+<Location>Middle East, bordering the Arabian Sea, Gulf of Aden, and Red Sea, between Oman and Saudi Arabia</Location>
+<Geographiccoordinates>15 00 N, 48 00 E</Geographiccoordinates>
+<Area>527970</Area>
+<Climate>mostly desert; hot and humid along west coast; temperate in western mountains affected by seasonal monsoon; extraordinarily hot, dry, harsh desert in east</Climate>
+<Naturalresources>petroleum, fish, rock salt, marble, small deposits of coal, gold, lead, nickel, and copper, fertile soil in west</Naturalresources>
+<Population>17479206</Population>
+<Populationgrowthrate>3.36% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.05 male(s)/female
+under 15 years: 1.04 male(s)/female
+15-64 years: 1.05 male(s)/female
+65 years and over: 1.04 male(s)/female
+total population: 1.04 male(s)/female (2000 est.)</Sexratio>
+<Religions>Muslim including Shaf'i (Sunni) and Zaydi (Shi'a), small numbers of Jewish, Christian, and Hindu</Religions>
+<Countryname>Yemen </Countryname>
+<Capital>Sanaa</Capital>
+<Flagdescription>three equal horizontal bands of red (top), white, and black; similar to the flag of Syria which has two green stars and of Iraq which has three green stars (plus an Arabic inscription) in a horizontal line centered in the white band; also similar to the flag of Egypt which has a heraldic eagle centered in the white band</Flagdescription>
+<GDP>purchasing power parity - $12.7 billion (1999 est.)</GDP>
+<Industries>crude oil production and petroleum refining; small-scale production of cotton textiles and leather goods; food processing; handicrafts; small aluminum products factory; cement</Industries>
+<Exports>$2 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2.3 billion (f.o.b., 1999 est.)</Imports>
+<Currency>Yemeni rial (YER) = 100 fils</Currency>
+<Airports>50 (1999 est.)</Airports>
+</record>
+<record>
+<Location>Southern Africa, east of Angola</Location>
+<Geographiccoordinates>15 00 S, 30 00 E</Geographiccoordinates>
+<Area>752614</Area>
+<Climate>tropical; modified by altitude; rainy season (October to April)</Climate>
+<Naturalresources>copper, cobalt, zinc, lead, coal, emeralds, gold, silver, uranium, hydropower</Naturalresources>
+<Population>9582418</Population>
+<Populationgrowthrate>1.95% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.01 male(s)/female
+15-64 years: 0.98 male(s)/female
+65 years and over: 0.79 male(s)/female
+total population: 0.99 male(s)/female (2000 est.)</Sexratio>
+<Religions>Christian 50%-75%, Muslim and Hindu 24%-49%, indigenous beliefs 1%</Religions>
+<Countryname>Zambia </Countryname>
+<Capital>Lusaka</Capital>
+<Flagdescription>green with a panel of three vertical bands of red (hoist side), black, and orange below a soaring orange eagle, on the outer edge of the flag</Flagdescription>
+<GDP>purchasing power parity - $8.5 billion (1999 est.)</GDP>
+<Industries>copper mining and processing, construction, foodstuffs, beverages, chemicals, textiles, fertilizer</Industries>
+<Exports>$900 million (f.o.b., 1999 est.)</Exports>
+<Imports>$1.15 billion (f.o.b., 1999 est.)</Imports>
+<Currency>1 Zambian kwacha (ZK) = 100 ngwee</Currency>
+<Airports>112 (1999 est.)</Airports>
+<Illicitdrugs>transshipment point for methaqualone, heroin, and cocaine bound for Southern Africa and Europe; regional money-laundering center</Illicitdrugs>
+</record>
+<record>
+<Location>body of water between Africa, Europe, the Southern Ocean, and the Western Hemisphere</Location>
+<Geographiccoordinates>0 00 N, 25 00 W</Geographiccoordinates>
+<Area>76000000</Area>
+<Climate>tropical cyclones (hurricanes) develop off the coast of Africa near Cape Verde and move westward into the Caribbean Sea; hurricanes can occur from May to December, but are most frequent from August to November</Climate>
+<Naturalresources>oil and gas fields, fish, marine mammals (seals and whales), sand and gravel aggregates, placer deposits, polymetallic nodules, precious stones</Naturalresources>
+</record>
+<record>
+<Location>Southern Africa, between South Africa and Zambia</Location>
+<Geographiccoordinates>20 00 S, 30 00 E</Geographiccoordinates>
+<Area>390580</Area>
+<Climate>tropical; moderated by altitude; rainy season (November to March)</Climate>
+<Naturalresources>coal, chromium ore, asbestos, gold, nickel, copper, iron ore, vanadium, lithium, tin, platinum group metals</Naturalresources>
+<Population>11342521</Population>
+<Populationgrowthrate>0.26% (2000 est.)</Populationgrowthrate>
+<Sexratio>
+at birth: 1.03 male(s)/female
+under 15 years: 1.02 male(s)/female
+15-64 years: 1.02 male(s)/female
+65 years and over: 1.03 male(s)/female
+total population: 1.02 male(s)/female (2000 est.)</Sexratio>
+<Religions>syncretic (part Christian, part indigenous beliefs) 50%, Christian 25%, indigenous beliefs 24%, Muslim and other 1%</Religions>
+<Countryname>Zimbabwe </Countryname>
+<Capital>Harare</Capital>
+<Flagdescription>seven equal horizontal bands of green, yellow, red, black, red, yellow, and green with a white isosceles triangle edged in black with its base on the hoist side; a yellow Zimbabwe bird is superimposed on a red five-pointed star in the center of the triangle</Flagdescription>
+<GDP>purchasing power parity - $26.5 billion (1999 est.)</GDP>
+<Industries>mining (coal, gold, copper, nickel, tin, clay, numerous metallic and nonmetallic ores), steel, wood products, cement, chemicals, fertilizer, clothing and footwear, foodstuffs, beverages</Industries>
+<Exports>$2 billion (f.o.b., 1999 est.)</Exports>
+<Imports>$2 billion (f.o.b., 1998 est.)</Imports>
+<Currency>1 Zimbabwean dollar (Z$) = 100 cents</Currency>
+<Airports>459 (1999 est.)</Airports>
+<Illicitdrugs>significant transit point for African cannabis and South Asian heroin, mandrax, and methamphetamines destined for the South African and European markets</Illicitdrugs>
+</record>
+<record>
+<Location>body of water between the Southern Ocean, Asia, Australia, and the Western Hemisphere</Location>
+<Geographiccoordinates>0 00 N, 160 00 W</Geographiccoordinates>
+<Area>155000000</Area>
+<Climate>planetary air pressure systems and resultant wind patterns exhibit remarkable uniformity in the south and east; trade winds and westerly winds are well-developed patterns, modified by seasonal fluctuations; tropical cyclones (hurricanes) may form south of Mexico from June to October and affect Mexico and Central America; continental influences cause climatic uniformity to be much less pronounced in the eastern and western regions at the same latitude in the North Pacific Ocean; the western Pacific is monsoonal - a rainy season occurs during the summer months, when moisture-laden winds blow from the ocean over the land, and a dry season during the winter months, when dry winds blow from the Asian landmass back to the ocean; tropical cyclones (typhoons) may strike southeast and east Asia from May to December</Climate>
+<Naturalresources>oil and gas fields, polymetallic nodules, sand and gravel aggregates, placer deposits, fish</Naturalresources>
+</record>
+</database>
diff --git a/noncore/apps/tableviewer/db/.cvsignore b/noncore/apps/tableviewer/db/.cvsignore
new file mode 100644
index 0000000..a433295
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+Makefile
+
diff --git a/noncore/apps/tableviewer/db/common.cpp b/noncore/apps/tableviewer/db/common.cpp
new file mode 100644
index 0000000..4c70e54
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/common.cpp
@@ -0,0 +1,1470 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdlib.h>
+#include <qstring.h>
+#include <qheader.h>
+#include <qvector.h>
+#include <qdatetime.h>
+#include <timestring.h>
+#include "common.h"
+#include "datacache.h"
+#include <assert.h>
+
+static const int del_flag = 0x1;
+static const int new_flag = 0x2;
+
+/* Helper function */
+
+int parseNextNumber(QString *q) {
+ QChar c;
+ uint i;
+ int result = 0;
+
+ bool found_digits = FALSE;
+ for(i = 0; i < q->length(); i++) {
+ c = q->at(i);
+ if (c.isDigit()) {
+ if (found_digits)
+ result *= 10;
+ found_digits = TRUE;
+ result += c.digitValue();
+ } else {
+ if (found_digits)
+ break;
+ /* just skip this char */
+ }
+ }
+ /* now truncate q */
+ if (found_digits)
+ q->remove(0, i);
+ return result;
+}
+
+/*!
+ \class QStringVector
+ \brief A Vector of QStrings that can be sorted and searched
+
+ Implmented in order to allow reverse lookup on the string name
+
+*/
+
+/*!
+ This function implements the compare function in order to allow the
+ searching and sorting of the QStringVector to occur
+
+ \returns an int which is either
+ <UL>
+ <LI> < 0 if the first string is smaller than the second,</LI>
+ <LI> > 0 if the first string is bigger then the second,</LI>
+ <LI> == 0 if the first string is equal to the second.</LI>
+ </UL>
+*/
+int QStringVector::compareItems(Item a, Item b)
+{
+ QString *qa = (QString *)a;
+ QString *qb = (QString *)b;
+
+ return QString::compare(*qa, *qb);
+}
+
+/*!
+ \class TVVariant
+ A way of abstracting void * and keeping information on
+ the keytypes and behaviours in one place
+*/
+
+TVVariantPrivate::TVVariantPrivate()
+{
+ typ = TVVariant::Invalid;
+}
+
+TVVariantPrivate::TVVariantPrivate( TVVariantPrivate *d)
+{
+ switch(d->typ)
+ {
+ case TVVariant::Invalid:
+ break;
+ case TVVariant::String:
+ value.ptr = new QString(*((QString *)d->value.ptr));
+ break;
+ case TVVariant::Date:
+ value.ptr = new QDate(*((QDate *)d->value.ptr));
+ break;
+ case TVVariant::Time:
+ value.ptr = new QTime(*((QTime *)d->value.ptr));
+ break;
+ case TVVariant::Int:
+ value.i = d->value.i;
+ break;
+ default:
+ ASSERT( 0 );
+ }
+
+ typ = d->typ;
+}
+
+TVVariantPrivate::~TVVariantPrivate()
+{
+ clear();
+}
+
+void TVVariantPrivate::clear()
+{
+ switch( typ )
+ {
+ case TVVariant::String:
+ delete (QString *)value.ptr;
+ break;
+ case TVVariant::Date:
+ delete (QDate *)value.ptr;
+ break;
+ case TVVariant::Time:
+ delete (QTime *)value.ptr;
+ break;
+ case TVVariant::Invalid:
+ case TVVariant::Int:
+ break;
+ }
+
+ typ = TVVariant::Invalid;
+}
+
+/*!
+ \class TVVariant
+ blah
+*/
+
+TVVariant::TVVariant()
+{
+ d = new TVVariantPrivate;
+}
+
+TVVariant::~TVVariant()
+{
+ if (d->deref())
+ delete d;
+}
+
+TVVariant::TVVariant(const TVVariant& p)
+{
+ d = new TVVariantPrivate;
+ *this = p;
+}
+
+TVVariant::TVVariant(QDataStream& s)
+{
+ d = new TVVariantPrivate;
+ s >> *this;
+}
+
+TVVariant::TVVariant(const QString &val)
+{
+ d = new TVVariantPrivate;
+ d->typ = String;
+ d->value.ptr = new QString(val);
+}
+
+TVVariant::TVVariant(const QDate &val)
+{
+ d = new TVVariantPrivate;
+ d->typ = Date;
+ d->value.ptr = new QDate(val);
+}
+
+TVVariant::TVVariant(const QTime &val)
+{
+ d = new TVVariantPrivate;
+ d->typ = Time;
+ d->value.ptr = new QTime(val);
+}
+
+TVVariant::TVVariant( int val )
+{
+ d = new TVVariantPrivate;
+ d->typ = Int;
+ d->value.i = val;
+}
+
+TVVariant& TVVariant::operator=(const TVVariant& variant )
+{
+ TVVariant& other = (TVVariant&) variant;
+
+ other.d->ref();
+ if ( d->deref() )
+ delete d;
+
+ d = other.d;
+
+ return *this;
+}
+
+void TVVariant::detach()
+{
+ if (d->count == 1)
+ return;
+
+ d->deref();
+ d = new TVVariantPrivate(d);
+}
+
+const QString TVVariant::typeName() const
+{
+ return typeToName(d->typ);
+}
+
+void TVVariant::clear()
+{
+ if (d->count > 1)
+ {
+ d->deref();
+ d = new TVVariantPrivate;
+ return;
+ }
+
+ d->clear();
+}
+
+const QString TVVariant::typeToName(KeyType typ)
+{
+ switch(typ) {
+ case String:
+ return QString("String");
+ case Date:
+ return QString("Date");
+ case Time:
+ return QString("Time");
+ case Int:
+ return QString("Int");
+ case Invalid:
+ default:
+ return QString("Invalid");
+ }
+ return QString("Invalid");
+}
+
+TVVariant::KeyType TVVariant::nameToType(const QString &name)
+{
+ if(!qstrcmp("String", name))
+ return String;
+ if(!qstrcmp("Date", name))
+ return Date;
+ if(!qstrcmp("Time", name))
+ return Time;
+ if(!qstrcmp("Int", name))
+ return Int;
+
+ return Invalid;
+}
+
+void TVVariant::load(QDataStream &s )
+{
+ KeyType t;
+ s >> t;
+
+ d->typ = t;
+ switch(t) {
+ case Invalid:
+ d->typ = t;
+ break;
+ case String:
+ {
+ QString *x = new QString;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Time:
+ {
+ QTime *x = new QTime;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Date:
+ {
+ QDate *x = new QDate;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Int:
+ {
+ int x;
+ s >> x;
+ d->value.i = x;
+ }
+ break;
+ default:
+ qFatal("Unrecognized data type");
+ }
+}
+
+void TVVariant::save( QDataStream &s ) const
+{
+ s << type();
+
+ switch( d->typ ) {
+ case String:
+ s << *((QString *)d->value.ptr);
+ break;
+ case Date:
+ s << *((QDate *)d->value.ptr);
+ break;
+ case Time:
+ s << *((QTime *)d->value.ptr);
+ break;
+ case Int:
+ s << d->value.i;
+ break;
+ case Invalid:
+ break;
+ }
+}
+
+QDataStream& operator>>(QDataStream& s, TVVariant& p)
+{
+ p.load( s );
+ return s;
+}
+
+QDataStream& operator<<(QDataStream &s, const TVVariant& p)
+{
+ p.save( s );
+ return s;
+}
+
+QDataStream& operator>> (QDataStream &s, TVVariant::KeyType& p)
+{
+ Q_UINT8 u = 0;
+ s >> u;
+ p = (TVVariant::KeyType) u;
+
+ return s;
+}
+
+QDataStream& operator<< (QDataStream& s, const TVVariant::KeyType& p)
+{
+ s << (Q_UINT8)p;
+ return s;
+}
+
+const QString TVVariant::toString() const
+{
+ switch(d->typ) {
+ case String:
+ return *((QString*)d->value.ptr);
+ case Date:
+ return ((QDate*)d->value.ptr)->toString();
+ case Time:
+ return ((QTime*)d->value.ptr)->toString();
+ case Int:
+ return QString::number(d->value.i);
+ case Invalid:
+ default:
+ return QString::null;
+ }
+ return QString::null;
+}
+
+// TODO DO, this properly, */
+int TVVariant::toInt() const
+{
+ if(d->typ == Int)
+ return d->value.i;
+
+ if(d->typ == String) {
+ QString tmpq(*(QString *)d->value.ptr);
+ return parseNextNumber(&tmpq);
+ }
+
+ return 0;
+}
+
+const QDate TVVariant::toDate() const
+{
+ if(d->typ == Date)
+ return *((QDate *)d->value.ptr);
+
+ if(d->typ == String) {
+ QString q = toString();
+
+ /* date format is day mon d yyyy */
+ /* ignore the first three letters, read the next
+ three for month.. etc */
+
+ int day = parseNextNumber(&q);
+ int month = parseNextNumber(&q);
+ int year = parseNextNumber(&q);
+ if (!QDate::isValid(year, month, day))
+ return QDate();
+ return QDate(year, month, day);
+ }
+
+
+ return QDate();
+}
+
+const QTime TVVariant::toTime() const
+{
+ if(d->typ == Time)
+ return *((QTime *)d->value.ptr);
+
+ if(d->typ == String) {
+ QString q = toString();
+ int hour = parseNextNumber(&q);
+ int minute = parseNextNumber(&q);
+ int second = parseNextNumber(&q);
+ int msecond = parseNextNumber(&q);
+ if (!QTime::isValid(hour, minute, second, msecond))
+ return QTime();
+ return QTime(hour, minute, second, msecond);
+ }
+
+ return QTime();
+}
+
+#define TV_VARIANT_AS( f ) Q##f& TVVariant::as##f() { \
+ if ( d->typ != f ) \
+ *this = TVVariant( to##f() ); \
+ else \
+ detach(); \
+ return *((Q##f*)d->value.ptr); }
+
+TV_VARIANT_AS(String)
+TV_VARIANT_AS(Date)
+TV_VARIANT_AS(Time)
+
+#undef TV_VARIANT_AS
+
+int& TVVariant::asInt()
+{
+ detach();
+ if (d->typ != Int) {
+ d->value.i = toInt();
+ d->typ = Int;
+ }
+ return d->value.i;
+}
+
+/*!
+ valid cast is
+ anything to String
+ same to same
+*/
+bool TVVariant::canCast(KeyType t) const
+{
+ if(d->typ == t)
+ return TRUE;
+
+ if(t == String)
+ return TRUE;
+
+ if(t == Int) {
+ if (d->typ == Date)
+ return TRUE;
+ if (d->typ == Time)
+ return TRUE;
+ if (d->typ == String)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool TVVariant::operator==( const TVVariant &v ) const
+{
+ switch(d->typ) {
+ case String:
+ return v.toString() == toString();
+ case Date:
+ return v.toDate() == toDate();
+ case Time:
+ return v.toTime() == toTime();
+ case Int:
+ return v.toInt() == toInt();
+ case Invalid:
+ break;
+ }
+
+ return FALSE;
+}
+
+bool TVVariant::operator!=( const TVVariant &v ) const
+{
+ return !( v == *this);
+}
+
+bool TVVariant::operator<( const TVVariant &v ) const
+{
+ switch(d->typ) {
+ case String:
+ return toString().lower() < v.toString().lower();
+ case Date:
+ return toDate() < v.toDate();
+ case Time:
+ return toTime() < v.toTime();
+ case Int:
+ return toInt() < v.toInt();
+ case Invalid:
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool TVVariant::operator>( const TVVariant &v ) const
+{
+ switch(d->typ) {
+ case String:
+ return toString().lower() > v.toString().lower();
+ case Date:
+ return toDate() > v.toDate();
+ case Time:
+ return toTime() > v.toTime();
+ case Int:
+ return toInt() > v.toInt();
+ case Invalid:
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*! True if n is closer to this than o */
+bool TVVariant::closer(TVVariant n, TVVariant o)
+{
+ /* Nothing is close to an invalid, so nothing can be closer */
+ if(d->typ == Invalid)
+ return FALSE;
+
+ /* can't be closer if of different type */
+ if(n.type() != type())
+ return FALSE;
+
+ /* if new shares type, and old doesn't, then new is closer */
+ if(o.type() != type())
+ return TRUE;
+
+ switch(type()){
+ case String: {
+ /* case for strings is close is a substring.. closer is
+ * earlier alphabetically */
+ QString qs1 = n.toString().lower();
+ QString qs2 = o.toString().lower();
+ QString qsv = toString().lower();
+
+ if (!qs1.startsWith(qsv))
+ return FALSE;
+
+ /* contains sub-str, if later than is not closer */
+ if(QString::compare(qs1, qs2) > 0)
+ return FALSE;
+ return TRUE;
+ }
+ case Int: {
+ /* case for int is smallest absolute difference */
+ int i1 = n.toInt();
+ int i2 = o.toInt();
+ int iv = toInt();
+
+ int diff1 = (i1 - iv);
+ if (diff1 < 0)
+ diff1 = -diff1;
+ int diff2 = (i2 - iv);
+ if (diff2 < 0)
+ diff2 = -diff2;
+
+ if (diff1 < diff2)
+ return TRUE;
+ return FALSE;
+ }
+ case Date: {
+ QDate i1 = n.toDate();
+ QDate i2 = o.toDate();
+ QDate iv = toDate();
+
+ /* definition of closer is the least difference in days */
+ int diff1 = i1.daysTo(iv);
+ if (diff1 < 0)
+ diff1 = -diff1;
+ int diff2 = i2.daysTo(iv);
+ if (diff2 < 0)
+ diff2 = -diff2;
+
+ if (diff1 < diff2)
+ return TRUE;
+ return FALSE;
+ }
+ case Time: {
+ QTime i1 = n.toTime();
+ QTime i2 = o.toTime();
+ QTime iv = toTime();
+
+ /* definition of closer is the least difference in days */
+ int diff1 = i1.msecsTo(iv);
+ if (diff1 < 0)
+ diff1 = -diff1;
+ int diff2 = i2.msecsTo(iv);
+ if (diff2 < 0)
+ diff2 = -diff2;
+ if (diff1 < diff2)
+ return TRUE;
+ return FALSE;
+ }
+ default:
+ /* don't know how to do 'closer' on this type, hence never closer
+ * or even close */
+ break;
+ }
+ return FALSE;
+}
+
+/*! True if n is close to this */
+bool TVVariant::close(TVVariant n)
+{
+ /* Nothing is close to an invalid, so nothing can be closer */
+ if(type() == Invalid)
+ return FALSE;
+
+ /* can't be close if of different type */
+ if(n.type() != type())
+ return FALSE;
+
+ switch(type()){
+ case String: {
+ /* case for strings is close is a substring.. closer is
+ * earlier alphabetically */
+ QString qs1 = n.toString().lower();
+ QString qsv = toString().lower();
+
+ if (!qs1.startsWith(qsv))
+ return FALSE;
+ return TRUE;
+ }
+ case Int:
+ case Date:
+ case Time:
+ return TRUE;
+ default:
+ /* don't know how to do 'closer' on this type, hence never closer
+ * or even close */
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ \class Key
+ \brief document me!
+
+ document me!
+*/
+
+Key::Key() : kname(), kexample(), kflags(0) { }
+
+Key::Key(QString name, TVVariant example, int flags = 0) :
+ kname(name), kexample(example), kflags(flags) { }
+
+Key::Key(const Key &other)
+{
+ kname = other.kname;
+ kexample = other.kexample;
+ kflags = other.kflags;
+}
+
+Key& Key::operator=(const Key& key)
+{
+ kname = key.kname;
+ kexample = key.kexample;
+ kflags = key.kflags;
+ return *this;
+}
+
+QString Key::name() const
+{
+ return QString(kname);
+}
+
+TVVariant Key::example() const
+{
+ return TVVariant(kexample);
+}
+
+TVVariant::KeyType Key::type() const
+{
+ return kexample.type();
+}
+
+void Key::setName(const QString &name)
+{
+ kname = QString(name);
+}
+
+void Key::setExample(const TVVariant &e)
+{
+ kexample = TVVariant(e);
+}
+
+int Key::flags() const
+{
+ return kflags;
+}
+
+void Key::setFlags(int fl)
+{
+ kflags = fl;
+}
+
+bool Key::delFlag() const
+{
+ if(kflags & del_flag)
+ return TRUE;
+ return FALSE;
+}
+
+bool Key::newFlag() const
+{
+ if(kflags & new_flag)
+ return TRUE;
+ return FALSE;
+}
+
+void Key::setDelFlag(bool v)
+{
+ if(delFlag() != v)
+ kflags = kflags ^ del_flag;
+}
+
+void Key::setNewFlag(bool v)
+{
+ if(newFlag() != v)
+ kflags = kflags ^ new_flag;
+}
+
+/*!
+ \class KeyList
+ \brief A represntation of keys used for a table.
+
+ The KeyList class is used to store the representation of keys used in table
+ headings by DBStore. It stores the names and types of the keys
+*/
+
+/*!
+ Constructs a KeyList
+*/
+KeyList::KeyList() : QIntDict<Key>(20)
+{
+ setAutoDelete(TRUE);
+}
+
+/* Should be deep copy, but isn't */
+KeyList::KeyList(const KeyList &k) : QIntDict<Key>(k)
+{
+ KeyListIterator it(k);
+ while(it.current()) {
+ replace(it.currentKey(), new Key(*it.current()));
+ ++it;
+ }
+
+ setAutoDelete(TRUE);
+}
+
+/*!
+ Destroys a KeyList
+*/
+KeyList::~KeyList() {
+}
+
+/* Do a comparision base on Keys */
+bool KeyList::operator!=(const KeyList &other)
+{
+ KeyListIterator it(*this);
+
+ if (other.getNumFields() != getNumFields())
+ return TRUE;
+
+ while(it.current()) {
+ //it.currentKey(), it.current();
+ if (other.getKeyName(it.currentKey()) != getKeyName(it.currentKey()))
+ return TRUE;
+ if (other.getKeyType(it.currentKey()) != getKeyType(it.currentKey()))
+ return TRUE;
+ ++it;
+ }
+ return FALSE;
+}
+
+/*!
+ Returns the number of keys stored in the KeyList
+*/
+int KeyList::getNumFields() const
+{
+ return count();
+}
+
+/*!
+ Adds a new key to the KeyList
+
+ \param name the name of the new key
+ \param type the type of the new key
+*/
+int KeyList::addKey(QString name, TVVariant example)
+{
+ int i = count();
+ while(find(i) && (i > -1))
+ i--;
+ replace(i, new Key(name, example, 0));
+ return i;
+}
+
+int KeyList::addKey(QString name, TVVariant::KeyType type)
+{
+ /* generate a valid type for the example? */
+ TVVariant e = TVVariant("0");
+ switch(type) {
+ case TVVariant::String:
+ return addKey(name, TVVariant("<undefined>").asString());
+ break;
+ case TVVariant::Date:
+ return addKey(name, TVVariant(QDate::currentDate()).asDate());
+ break;
+ case TVVariant::Time:
+ return addKey(name, TVVariant(QTime(0,0,0)).toTime());
+ break;
+ case TVVariant::Int:
+ return addKey(name, TVVariant(0).toInt());
+ break;
+ default:
+ qWarning(QObject::tr("KeyList::addKey() Cannot make default "
+ "value for type %1, Key not added.").arg(type));
+ break;
+ }
+ return -1;
+}
+
+void KeyList::setKeyFlags(int i, int flag)
+{
+ if(find(i))
+ find(i)->setFlags(flag);
+}
+
+int KeyList::getKeyFlags(int i) const
+{
+ if(find(i))
+ return find(i)->flags();
+ return 0;
+}
+
+bool KeyList::checkNewFlag(int i) const
+{
+ if (find(i))
+ return find(i)->newFlag();
+ return false;
+}
+
+void KeyList::setNewFlag(int i, bool f)
+{
+ if(!find(i))
+ return;
+ find(i)->setNewFlag(f);
+}
+
+bool KeyList::checkDeleteFlag(int i) const
+{
+ if (find(i))
+ return find(i)->delFlag();
+ return false;
+}
+
+void KeyList::setDeleteFlag(int i, bool f)
+{
+ if(!find(i))
+ return;
+ find(i)->setDelFlag(f);
+}
+
+/*!
+ Returns the name of the key at index i
+*/
+QString KeyList::getKeyName(int i) const
+{
+ if (find (i))
+ return find(i)->name();
+ return QString();
+}
+
+void KeyList::setKeyName(int i, const QString &n)
+{
+ if(find(i))
+ find(i)->setName(n);
+}
+
+/*!
+ Returns the type of the key at index i
+*/
+TVVariant::KeyType KeyList::getKeyType(int i) const
+{
+ if(find(i))
+ return find(i)->type();
+ return TVVariant::Invalid;
+}
+
+void KeyList::setKeyType(int i, TVVariant::KeyType t)
+{
+ if(!find(i))
+ return;
+ switch(t) {
+ case TVVariant::String:
+ find(i)->setExample(TVVariant(QString("default")));
+ return;
+ case TVVariant::Int:
+ find(i)->setExample(TVVariant(int(0)));
+ return;
+ case TVVariant::Date:
+ find(i)->setExample(TVVariant(QDate::currentDate()));
+ return;
+ case TVVariant::Time:
+ find(i)->setExample(TVVariant(QTime(0,0,0,0)));
+ return;
+ default:
+ break;
+ }
+ return;
+}
+
+TVVariant KeyList::getKeyExample(int i) const
+{
+ if(find(i))
+ return find(i)->example();
+ return TVVariant();
+}
+
+void KeyList::setKeyExample(int i, TVVariant example)
+{
+ if(find(i))
+ find(i)->setExample(example);
+}
+
+/*!
+ Returns the index of the key with name q
+*/
+int KeyList::getKeyIndex(QString q) const
+{
+ KeyListIterator it(*this);
+
+ while(it.current()) {
+ if(it.current()->name() == q)
+ return it.currentKey();
+ ++it;
+ }
+ return -1;
+}
+
+bool KeyList::validIndex(int i) const
+{
+ if(!find(i))
+ return FALSE;
+ if(find(i)->delFlag())
+ return FALSE;
+ return TRUE;
+}
+
+QDataStream &operator<<( QDataStream &s, const KeyList &k)
+{
+ s << k.getNumFields();
+
+ KeyListIterator it(k);
+
+ while(it.current()) {
+ s << (Q_UINT16)it.currentKey();
+ s << it.current()->name();
+ s << it.current()->example();
+ s << (Q_UINT16)it.current()->flags();
+ ++it;
+ }
+ return s;
+}
+
+QDataStream &operator>>( QDataStream &s, KeyList &k)
+{
+ int i;
+ int size;
+ int index = 0;
+ int flags = 0;
+ TVVariant type = TVVariant();
+ QString name;
+
+ s >> size;
+
+ for (i=0; i < size; i++) {
+ s >> (Q_UINT16 &)index;
+ s >> name;
+ s >> type;
+ s >> (Q_UINT16 &)flags;
+ k.replace(index, new Key(name, type, flags));
+ }
+ return s;
+}
+
+/*!
+ \class DataElem
+ \brief A class representing a single row or element of a table in a DBStore
+
+ This class holds the data of a row in a table.
+*/
+
+
+/*!
+ Constructs a DataElem. This function needs a container because the
+ size, types of keys and primary key are all defined by the containing
+ database
+*/
+DataElem::DataElem(DBStore *c) : values(20)
+{
+ int size;
+ contained = c;
+ size = c->getNumFields();
+ values.setAutoDelete(TRUE);
+}
+
+/*!
+ Destroys a DataElem and frees memory used by the DataElem
+*/
+DataElem::~DataElem() {
+}
+
+
+
+QDataStream &operator<<( QDataStream &s, const DataElem &d)
+{
+ int size = d.getNumFields();
+
+ s << size; /* redundent data but makes streaming easier */
+ KeyList k = d.getKeys();
+
+ KeyListIterator it(k);
+
+ while(it.current()) {
+ s << (Q_UINT16)it.currentKey();
+ s << d.getField(it.currentKey());
+ ++it;
+ }
+ return s;
+}
+
+QDataStream &operator>>( QDataStream &s, DataElem &d)
+{
+ int i;
+ int size;
+ TVVariant t;
+ int index = 0;
+
+ s >> size; /* redundent data but makes streaming easier */
+ if (size != d.getNumFields()) {
+ qWarning("DataSize mis-match");
+ return s; /* sanity check failed.. don't load */
+ }
+
+ for(i = 0; i < size; i++) {
+ s >> (Q_UINT16)index;
+ s >> t;
+ d.setField(index, t);
+ }
+ return s;
+}
+
+/*! Returns the number of possible (not valid) fields in the data element */
+int DataElem::getNumFields() const
+{
+ return contained->getNumFields();
+}
+
+KeyList DataElem::getKeys() const
+{
+ return *(contained->getKeys());
+}
+
+/*!
+ This function determines whether field index i of the element has been
+ set yet.
+
+ \return A boolean value that is TRUE if the specfied field of this
+ element has been set and FALSE if the field has not yet been set
+*/
+bool DataElem::hasValidValue(int i) const
+{
+ if(!values.find(i))
+ return FALSE;
+ if(!contained->getKeys()->validIndex(i))
+ return FALSE;
+ return values.find(i)->isValid();
+}
+
+/*!
+ This function determines whether field name qs of the element has been
+ set yet.
+
+ \return A boolean value that is TRUE if the specfied field of this
+ element has been set and FALSE if the field has not yet been set
+*/
+bool DataElem::hasValidValue(QString qs) const
+{
+ int i = contained->getKeyIndex(qs);
+ return hasValidValue(i);
+}
+
+/*! returns the type of the field specified by index i */
+TVVariant::KeyType DataElem::getFieldType(int i) const
+{
+ return contained->getKeyType(i);
+}
+
+/*! returns the type of the field specified by name qs */
+TVVariant::KeyType DataElem::getFieldType(QString qs) const
+{
+ int i = contained->getKeyIndex(qs);
+ return contained->getKeyType(i);
+}
+
+/*!
+ returns a pointer to the data stored in field index i for this
+ data element, (value may not be valid)
+*/
+TVVariant DataElem::getField(int i) const
+{
+ if(hasValidValue(i))
+ return TVVariant(*values.find(i));
+ return TVVariant();
+}
+
+/*!
+ returns a pointer to the data stored in field name qs for this
+ data element, (value may not be valid)
+*/
+TVVariant DataElem::getField(QString qs) const
+{
+ int i = contained->getKeyIndex(qs);
+ return getField(i);
+}
+
+/*!
+ Sets the value of the elements field index i to the value represented in
+ the QString q.
+
+ \param i index of the field to set
+ \param q a string that can be parsed to get the value to be set
+*/
+void DataElem::setField(int i, QString q)
+{
+ /* from the type of the field, parse q and store */
+ TVVariant::KeyType kt = contained->getKeyType(i);
+
+ TVVariant t = TVVariant(q);
+
+ switch(kt) {
+ case TVVariant::Int: {
+ t.asInt();
+ setField(i, t);
+ return;
+ }
+ case TVVariant::String: {
+ t.asString();
+ setField(i, t);
+ return;
+ }
+ case TVVariant::Date: {
+ t.asDate();
+ setField(i, t);
+ return;
+ }
+ case TVVariant::Time: {
+ t.asTime();
+ setField(i, t);
+ return;
+ }
+ default:
+ qWarning(
+ QObject::tr("DataElem::setField(%1, %2) No valid type found").arg(i).arg(q)
+ );
+ }
+}
+
+/*!
+ Sets the value of the elements field index i to the value at the pointer
+ value.
+
+ \param i index of the field to set
+ \param value a pointer to the (already allocated) value to set
+*/
+void DataElem::setField(int i, TVVariant value)
+{
+ if (value.isValid()) {
+ values.remove(i);
+ values.replace(i, new TVVariant(value));
+ }
+}
+
+/*!
+ Sets the value of the elements field name qs to the value represented in
+ the QString q.
+
+ \param qs name of the field to set
+ \param q a string that can be parsed to get the value to be set
+*/
+void DataElem::setField(QString qs, QString q)
+{
+ /* from the type of the field, parse q and store */
+ int i = contained->getKeyIndex(qs);
+ setField(i, qs);
+}
+
+/*!
+ Sets the value of the elements field name qs to the value at the pointer
+ value.
+
+ \param qs name of the field to set
+ \param value a pointer to the (already allocated) value to set
+*/
+void DataElem::setField(QString qs, TVVariant value)
+{
+ int i = contained->getKeyIndex(qs);
+ setField(i, value);
+}
+
+void DataElem::unsetField(int i) {
+ values.remove(i);
+}
+
+void DataElem::unsetField(QString qs)
+{
+ int i = contained->getKeyIndex(qs);
+ unsetField(i);
+}
+
+/*!
+ Converts the data element to a Rich Text QString
+*/
+QString DataElem::toQString() const
+{
+ /* lets make an attempt at this function */
+ int i;
+ QString scratch = "";
+
+ QIntDictIterator<TVVariant> it(values);
+
+ while (it.current()) {
+ i = it.currentKey();
+ if(hasValidValue(i)) {
+ scratch += "<B>" + contained->getKeyName(i) + ":</B> ";
+ scratch += getField(i).toString();
+ scratch += "<br>";
+ }
+ ++it;
+ }
+ return scratch;
+}
+
+/*! formats individual fields to strings so can be displayed */
+QString DataElem::toQString(int i) const
+{
+ if(hasValidValue(i)) {
+ return getField(i).toString();
+ }
+ return "";
+}
+/*! formats individual fields to strings so can be sorted by QListView */
+QString DataElem::toSortableQString(int i) const
+{
+ QString scratch = "";
+ if(hasValidValue(i)) {
+ switch (contained->getKeyType(i)) {
+ case TVVariant::String: {
+ scratch += getField(i).toString();
+ break;
+ }
+ case TVVariant::Int: {
+ scratch.sprintf("%08d", getField(i).toInt());
+ break;
+ }
+ case TVVariant::Date: {
+ static QDate epochD(1800, 1, 1);
+ scratch.sprintf("%08d",
+ epochD.daysTo(getField(i).toDate()));
+ break;
+ }
+ case TVVariant::Time: {
+ static QTime epochT(0, 0, 0);
+ scratch.sprintf("%08d",
+ epochT.msecsTo(getField(i).toTime()));
+ break;
+ }
+ default:
+ scratch += "Unknown type";
+ break;
+ }
+ }
+ return scratch;
+}
+
+/* compare functions */
+
+bool DataElem::lessThan(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ return (getField(i) < v);
+}
+
+bool DataElem::moreThan(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ return (getField(i) > v);
+}
+
+bool DataElem::equalTo(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ return (getField(i) == v);
+}
+
+bool DataElem::contains(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ switch(getField(i).type()) {
+ case TVVariant::String: {
+ QString qs1 = getField(i).toString().lower();
+ QString qs2 = v.toString().lower();
+ if (qs1.contains(qs2) > 0) return TRUE;
+ break;
+ }
+ /* meaningless for ints */
+ /* meaningless for time */
+ /* meaningless for dates */
+ case TVVariant::Int:
+ case TVVariant::Time:
+ case TVVariant::Date:
+ break;
+ default:
+ qWarning("Tried to compare unknown data type");
+ }
+ return FALSE;
+}
+
+bool DataElem::startsWith(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ switch(getField(i).type()) {
+ case TVVariant::String: {
+ QString qs1 = getField(i).toString().lower();
+ QString qs2 = v.toString().lower();
+ return qs1.startsWith(qs2);
+ }
+ /* meaningless for ints */
+ /* meaningless for time */
+ /* meaningless for dates */
+ case TVVariant::Int:
+ case TVVariant::Time:
+ case TVVariant::Date:
+ return FALSE;
+ default:
+ qWarning("Tried to compare unknown data type");
+ }
+ return FALSE;
+}
+
+bool DataElem::endsWith(int i, TVVariant v) const
+{
+ if (!hasValidValue(i)) return FALSE;
+
+ if (getField(i).type() != v.type())
+ return FALSE;
+
+ switch(getField(i).type()) {
+ case TVVariant::String: {
+ QString qs1 = getField(i).toString().lower();
+ QString qs2 = v.toString().lower();
+ return qs1.startsWith(qs2);
+ }
+ /* meaningless for ints */
+ /* meaningless for time */
+ /* meaningless for dates */
+ case TVVariant::Int:
+ case TVVariant::Time:
+ case TVVariant::Date:
+ return FALSE;
+ default:
+ qWarning("Tried to compare unknown data type");
+ }
+ return FALSE;
+}
+
+/*!
+ Determins which of the first to parameters are closer to the third, target
+ parameter.
+
+ \return
+ <UL>
+ <LI>TRUE if the first element is a closer match to the target than the
+ second element</LI>
+ <LI>FALSE if the first element is not a closer match to the target than
+ the second element</LI>
+ </UL>
+*/
+bool DataElem::closer(DataElem*d1, DataElem *d2, TVVariant target, int column)
+{
+ int type;
+
+ if(!d1) return FALSE;
+
+ if (!d1->hasValidValue(column)) return FALSE;
+
+ if(!target.isValid()) return FALSE;
+
+ type = d1->getField(column).type();
+
+ if(d2) {
+ if (type != d2->getField(column).type()) {
+ /* can't do compare */
+ qWarning("Tried to compare two incompatable types");
+ return FALSE;
+ }
+ return target.closer(d1->getField(column), d2->getField(column));
+ }
+ return target.close(d1->getField(column));
+}
diff --git a/noncore/apps/tableviewer/db/common.h b/noncore/apps/tableviewer/db/common.h
new file mode 100644
index 0000000..bb0a953
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/common.h
@@ -0,0 +1,285 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/* This file represents shared data structures that will be passed
+ * around often.
+ */
+#ifndef __SHAREDDATA_H__
+#define __SHAREDDATA_H__
+
+// TODO rename this to a sensable class name
+
+#include <qvector.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qcstring.h>
+#include <qdatastream.h>
+#include <qintdict.h>
+
+class DBStore;
+
+/* helper classes to common classes */
+class QStringVector : public QVector<QString>
+{
+public:
+ int compareItems(Item a, Item b);
+};
+
+/* in QT 2.3, dates and times not supported int QVariant. So.....
+ * for now use my special Variant type which is basically identical
+ * except that does it for my types. TODO replace with QVariant when
+ * qvariant supports all the types we require */
+
+class TVVariantPrivate;
+
+class TVVariant
+{
+public:
+ enum KeyType {
+ Invalid = 0,
+ Int,
+ String,
+ Date,
+ Time,
+ };
+
+ TVVariant();
+ ~TVVariant();
+
+ TVVariant(const TVVariant&);
+ TVVariant(QDataStream&);
+
+ TVVariant(const QString &);
+ TVVariant(const int);
+ TVVariant(const QDate &);
+ TVVariant(const QTime &);
+
+ TVVariant& operator=(const TVVariant& );
+ bool operator==(const TVVariant&) const;
+ bool operator!=(const TVVariant&) const;
+ bool operator<(const TVVariant&) const;
+ bool operator>(const TVVariant&) const;
+
+ bool closer(TVVariant, TVVariant);
+ bool close(TVVariant);
+
+ KeyType type() const;
+ const QString typeName() const;
+ int numTypes() const;
+
+ const QString typeName(KeyType) const;
+ bool canCast(KeyType) const;
+ bool isValid() const;
+ void clear();
+
+ const QString toString() const;
+ const QDate toDate() const;
+ const QTime toTime() const;
+ int toInt() const;
+
+ QString& asString();
+ QDate& asDate();
+ QTime& asTime();
+ int& asInt();
+
+ void load(QDataStream&);
+ void save(QDataStream&) const;
+
+ static const QString typeToName(KeyType typ);
+ static KeyType nameToType(const QString &);
+private:
+ void detach();
+
+ TVVariantPrivate *d;
+};
+
+class TVVariantPrivate : public QShared
+{
+ public:
+ TVVariantPrivate();
+ TVVariantPrivate(TVVariantPrivate *);
+
+ ~TVVariantPrivate();
+
+ void clear();
+
+ TVVariant::KeyType typ;
+
+ union {
+ int i;
+ void *ptr;
+ } value;
+};
+
+inline TVVariant::KeyType TVVariant::type() const
+{
+ return d->typ;
+}
+
+inline bool TVVariant::isValid() const
+{
+ return (d->typ != Invalid);
+}
+
+inline int TVVariant::numTypes() const
+{
+ return 4;
+}
+
+class Key {
+public:
+ Key();
+ Key(QString name, TVVariant example, int flags = 0);
+ Key(const Key &);
+ Key& operator=(const Key& );
+
+ QString name() const;
+ TVVariant example() const;
+ TVVariant::KeyType type() const;
+ int flags() const;
+
+ void setName(const QString &);
+ void setExample(const TVVariant &);
+ void setFlags(int);
+
+ bool delFlag() const;
+ bool newFlag() const;
+
+ void setDelFlag(bool);
+ void setNewFlag(bool);
+
+private:
+ QString kname;
+ TVVariant kexample;
+ int kflags;
+};
+
+class KeyList : public QIntDict<Key> {
+public:
+ KeyList();
+ KeyList(const KeyList&);
+
+ ~KeyList();
+
+ bool operator!=(const KeyList &);
+
+ int getNumFields() const;
+
+ int addKey(QString KeyName, TVVariant example);
+ int addKey(QString KeyName, TVVariant::KeyType type);
+
+ TVVariant getKeyExample(int ) const;
+ void setKeyExample(int, TVVariant e);
+
+ QString getKeyName(int i) const;
+ void setKeyName(int i, const QString &n);
+
+ TVVariant::KeyType getKeyType(int i) const;
+ void setKeyType(int i, TVVariant::KeyType);
+
+ int getKeyIndex(QString q) const;
+
+ int getKeyFlags(int i) const;
+ void setKeyFlags(int i, int flag);
+
+ /* Below should be abstracted a bit more */
+ bool checkNewFlag(int i) const;
+ void setNewFlag(int i, bool f);
+ bool checkDeleteFlag(int i) const;
+ void setDeleteFlag(int i, bool f);
+
+ bool validIndex(int) const;
+};
+
+class KeyListIterator : public QIntDictIterator<Key>
+{
+public:
+ KeyListIterator(const KeyList &k) : QIntDictIterator<Key>(k) {};
+};
+
+/* TODO start using this */
+class DataElem {
+public:
+ DataElem(DBStore *container);
+ ~DataElem();
+
+ int getNumFields() const;
+ KeyList getKeys() const;
+
+ bool hasValidValue(int) const;
+ bool hasValidValue(QString) const;
+ TVVariant::KeyType getFieldType(int) const;
+ TVVariant::KeyType getFieldType(QString) const;
+ TVVariant getField(int) const;
+ TVVariant getField(QString) const;
+
+ void setField(int, QString);
+ void setField(int, TVVariant);
+ void setField(QString, QString);
+ void setField(QString, TVVariant);
+ void unsetField(int);
+ void unsetField(QString);
+
+ QString toQString() const;
+ QString toQString(int i) const;
+ QString toSortableQString(int i) const;
+
+ /* compare functions */
+ bool lessThan(int i, TVVariant) const;
+ bool moreThan(int i, TVVariant) const;
+ bool equalTo(int i, TVVariant) const;
+ bool contains(int i, TVVariant) const;
+ bool startsWith(int i, TVVariant) const;
+ bool endsWith(int i, TVVariant) const;
+
+ /* class functions... Compare is based of the primary key, which
+ is determined by the containing DBStores of each element. */
+ static int compare(const TVVariant, const TVVariant, int i);
+
+ /* False, second element's primary key is closer to target.
+ * True, first element's primary key is a closer match to target */
+ static bool closer(DataElem*, DataElem *, TVVariant, int column);
+private:
+ QIntDict<TVVariant> values;
+ DBStore *contained;
+};
+
+typedef struct _TableState {
+ int current_column;
+ KeyList *kRep;
+ DataElem *current_elem;
+} TableState;
+
+/* Stream functions */
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const KeyList & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const DataElem & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, KeyList & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, DataElem & );
+
+
+Q_EXPORT QDataStream &operator>>( QDataStream &, TVVariant & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const TVVariant & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, TVVariant::KeyType& );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const TVVariant::KeyType& );
+#endif
+
+#endif
diff --git a/noncore/apps/tableviewer/db/csvsource.cpp b/noncore/apps/tableviewer/db/csvsource.cpp
new file mode 100644
index 0000000..2561b4b
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/csvsource.cpp
@@ -0,0 +1,207 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "csvsource.h"
+#include "common.h"
+#include "datacache.h"
+#include <qtextstream.h>
+#include <qstringlist.h>
+#include <qmap.h>
+#include <qregexp.h>
+
+DBCsv::DBCsv(DBStore *d)
+{
+ dstore = d;
+}
+
+DBCsv::~DBCsv()
+{
+}
+
+QString DBCsv::type()
+{
+ return "csv";
+}
+
+QStringList readElem(QString in)
+{
+ QStringList out;
+
+ if (in.isEmpty())
+ return out;
+
+ bool firstChar = TRUE;
+ bool quotedElem = FALSE;
+ uint index = 0;
+ while(index < in.length()) {
+ if(firstChar) {
+ /* skip whitespace */
+ while(index < in.length() && in[index] == ' ')
+ index++;
+ if(in[index] == '"') {
+ quotedElem = TRUE;
+ index++;
+ }
+ }
+ /* real first char */
+ QString elem;
+ if(quotedElem) {
+ while(index < in.length() && in[index] != '"') {
+ /* check for escape character */
+ if (in[index] == '\\') {
+ if (index++ < in.length()) {
+ elem.append(in[index]);
+ index++;
+ }
+ } else {
+ elem.append(in[index]);
+ index++;
+ }
+ }
+ } else {
+ while(index < in.length() && in[index] != ',') {
+ if (in[index] == '\\') {
+ if (index++ < in.length()) {
+ elem.append(in[index]);
+ index++;
+ }
+ } else {
+ elem.append(in[index]);
+ index++;
+ }
+ }
+ }
+ /* we have our current elem */
+ out << elem.stripWhiteSpace();
+ firstChar = TRUE;
+ quotedElem = FALSE;
+ /* skip till a , or end of line */
+ while (index < in.length() && in[index] != ',') index++;
+ if(index == in.length())
+ return out;
+ else
+ index++;
+ }
+}
+
+bool DBCsv::openSource(QIODevice *inDev)
+{
+ QTextStream tsIn(inDev);
+ QString in = tsIn.readLine().stripWhiteSpace();
+ QStringList keys;
+
+ keys = readElem(in);
+
+ QMap<int,int> keyIndexes;
+
+ KeyList *keyR = new KeyList();
+ QStringList::Iterator i = keys.begin();
+
+ uint fileIndex = 0;
+ while(i != keys.end()) {
+ if ((*i).isEmpty())
+ keyIndexes.insert(fileIndex, keyR->addKey("Unamed", TVVariant::String));
+ else
+ keyIndexes.insert(fileIndex, keyR->addKey(*i, TVVariant::String));
+ i++;
+ fileIndex++;
+ }
+ dstore->setKeys(keyR);
+
+ in = tsIn.readLine().stripWhiteSpace();
+ while(!in.isNull()) {
+ QStringList elems = readElem(in);
+
+ i = elems.begin();
+ fileIndex = 0;
+ DataElem *current_data = new DataElem(dstore);
+ while(i != elems.end()) {
+ if(!(*i).isEmpty()) {
+ current_data->setField(keyIndexes[fileIndex], *i);
+ }
+ fileIndex++;
+ i++;
+ }
+ dstore->addItem(current_data);
+ in = tsIn.readLine().stripWhiteSpace();
+ }
+
+ return TRUE;
+}
+
+bool DBCsv::saveSource(QIODevice *outDev)
+{
+ /* try not to use the escape character when possible. */
+ int i;
+ DataElem *elem;
+ KeyList *k;
+ QTextStream outstream(outDev);
+
+ k = dstore->getKeys();
+ KeyListIterator it(*k);
+ while(it.current()) {
+ if(!it.current()->delFlag()) {
+ QString name = it.current()->name();
+
+ name.replace(QRegExp("\\"), "\\\\");
+ name.replace(QRegExp("\""), "\\\"");
+ if(name.find(',') != -1) {
+ name.prepend('\"');
+ name.append('\"');
+ }
+
+ outstream << name;
+ }
+ ++it;
+ if(it.current())
+ outstream << ", ";
+ }
+ outstream << "\n";
+
+ dstore->first();
+
+ do {
+ elem = dstore->getCurrentData();
+ if(!elem)
+ break;
+ it.toFirst();
+ while(it.current()) {
+ i = it.currentKey();
+ if (elem->hasValidValue(i)) {
+ QString name = elem->toQString(i);
+
+ name.replace(QRegExp("\\"), "\\\\");
+ name.replace(QRegExp("\""), "\\\"");
+ if(name.find(',') != -1) {
+ name.prepend('\"');
+ name.append('\"');
+ }
+
+ outstream << name;
+ }
+ ++it;
+ if(it.current())
+ outstream << ", ";
+ }
+ outstream << "\n";
+ } while (dstore->next());
+
+ return TRUE;
+}
+
diff --git a/noncore/apps/tableviewer/db/csvsource.h b/noncore/apps/tableviewer/db/csvsource.h
new file mode 100644
index 0000000..691234c
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/csvsource.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/* A Class to parse an comma seperated values docment of the form
+
+"Displayed Name", key2name, key 3 name, key name 4
+value1, , value 3, "value 4"
+value1, , value 3, "value 4"
+
+ * '\' is the escape character. Basically \", \' and \\ escape the ", ' or \
+ * into the actual value of the field.
+ * Before any other character will have the effect of dropping the '\'.
+ *
+ * Currently there is no support for comments. */
+
+#ifndef __CSVSOURCE_H__
+#define __CSVSOURCE_H__
+
+#include <qstring.h>
+#include "datacache.h"
+#include "common.h"
+
+
+class DBCsv : public DBAccess
+{
+public:
+ /* create connection and either open or initialize */
+ DBCsv(DBStore *d);
+ QString type();
+ bool openSource(QIODevice *);
+ bool saveSource(QIODevice *);
+ /* does a db write */
+ ~DBCsv();
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/db/datacache.cpp b/noncore/apps/tableviewer/db/datacache.cpp
new file mode 100644
index 0000000..7c14eef
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/datacache.cpp
@@ -0,0 +1,293 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+/*
+ * This file is used to load the xml files that represent the database.
+ * The main requirment for said file is each data entry must contain a key,
+ * otherwise any other data headings are allowed.
+ */
+
+#include "datacache.h"
+#include "xmlsource.h"
+#include "csvsource.h"
+#include <stdlib.h>
+#include <qheader.h>
+
+#define INIT_TABLE_SIZE 128
+
+/*!
+ \class DBStore datastore.h
+
+ \brief The DBStore class is the class responsible for storing, sorting and
+ searching the data loaded by the application
+
+*/
+
+/*!
+ Constructs a DBStore item
+*/
+DBStore::DBStore()
+{
+ name = "";
+ number_elems = 0;
+ full = false;
+ kRep = new KeyList();
+ master_table.resize(INIT_TABLE_SIZE);
+ table_size = INIT_TABLE_SIZE;
+
+ current_elem = 0;
+ archive = 0;
+}
+
+//TODO
+/*!
+ Reinitializes the table to empty (include a resize of the master table,
+ which should free some memory)
+*/
+void DBStore::freeTable()
+{
+ name = "";
+ if(archive) {
+ delete archive;
+ archive = 0;
+ }
+ kRep->clear(); /* clear the current key list */
+
+ number_elems = 0;
+ table_size = INIT_TABLE_SIZE;
+ master_table.resize(table_size);
+ full = false;
+ current_elem = 0;
+}
+
+/*!
+ Removes all items from the DBStore and destroys the DBStore
+*/
+DBStore::~DBStore()
+{
+ freeTable();
+}
+
+/*!
+ This function opens the given xml file, loads it and sets up the
+ appropriate data structures.
+
+ \param file_name A string representing the name of the file to be opened
+ \return true if successful, false otherwise.
+*/
+bool DBStore::openSource(QIODevice *inDev, const QString &source) {
+
+ /* first check if db is already open, if contains data.. then clear */
+ if(number_elems > 0) {
+ freeTable();
+ }
+
+ if (source == "text/x-xml-tableviewer") {
+ archive = new DBXml(this);
+ } else if (source == "text/csv") {
+ archive = new DBCsv(this);
+ } else
+ return false;
+
+ return (archive->openSource(inDev));
+}
+
+bool DBStore::saveSource(QIODevice *outDev, const QString &source)
+{
+ /* saving a new file */
+ if(!archive) {
+ if (source == "text/x-xml-tableviewer") {
+ archive = new DBXml(this);
+ } else if (source == "text/x-xml-tableviewer") {
+ archive = new DBCsv(this);
+ } else
+ return false;
+ }
+
+ /* changing file type */
+ if(archive->type() != source) {
+ delete archive;
+ if (source == "text/x-xml-tableviewer") {
+ archive = new DBXml(this);
+ } else if (source == "text/x-xml-tableviewer") {
+ archive = new DBCsv(this);
+ } else
+ return false;
+ }
+
+ return (archive->saveSource(outDev));
+}
+
+/*!
+ This function is used to add new elements to the database. If the database
+ has already reached the maximum allowable size this function does not alter
+ the database.
+
+ \param delm An already allocated and initialized data element to be added
+*/
+void DBStore::addItem(DataElem *delem)
+{
+ addItemInternal(delem);
+}
+
+void DBStore::addItemInternal(DataElem *delem)
+{
+ /* if already full, don't over fill, do a qWarning though */
+ if (full) {
+ qWarning("Attempted to add items to already full table");
+ return;
+ }
+
+ master_table.insert(number_elems, delem);
+
+ current_elem = number_elems;
+ number_elems++;
+
+ if(number_elems >= table_size) {
+ /* filled current table, double if we can */
+ table_size = table_size << 1;
+
+ /* check that the new table size is still valid, i.e. that we didn't
+ just shift the 1 bit of the end of the int. */
+ if (!table_size) {
+ full = true;
+ /* no point in doing antying else. */
+ return;
+ }
+ master_table.resize(table_size);
+ }
+}
+
+void DBStore::removeItem(DataElem *r)
+{
+ int position = master_table.findRef(r);
+ if(position != -1) {
+ /* there is at least one item, this is it */
+ /* replace this with the last element, decrease the element count */
+ master_table.insert(position, master_table.at(--number_elems));
+ master_table.remove(number_elems);
+ delete r;
+ }
+}
+
+/*!
+ Sets the name of the database
+
+ \param n A string representing the new name of the database.
+*/
+void DBStore::setName(const QString &n)
+{
+ name = n;
+}
+
+/*!
+ Gets the name of the database
+
+ \return A string representing the name of the database.
+*/
+QString DBStore::getName()
+{
+ return name;
+}
+
+/*!
+ Retrieves a pointer to the key representation of the database for
+ other classes to use as reference.
+
+ \return a pointer to the databases key representaion
+*/
+KeyList *DBStore::getKeys()
+{
+ return kRep;
+}
+
+/*!
+ sets the database's key representation the passed pointer
+ \param a pointer to a key representaton
+*/
+void DBStore::setKeys(KeyList *k)
+{
+ kRep = k;
+}
+
+/*!
+ Sets the current element to the first element of the database
+*/
+void DBStore::first()
+{
+ current_elem = 0;
+}
+
+/*!
+ Sets the current element to the last element of the database
+*/
+void DBStore::last()
+{
+ current_elem = number_elems - 1;
+}
+
+/*!
+ Sets the current element to the next element of the database if
+ there exists an element after the current one.
+*/
+bool DBStore::next()
+{
+ unsigned int new_current_elem = current_elem + 1;
+ if (current_elem < number_elems)
+ /* was valid before inc (it is possible but unlikely that inc current
+ elem will change it from invalid to valid) */
+ if (new_current_elem < number_elems) {
+ /* is valid after inc */
+ current_elem = new_current_elem;
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Sets the current element to the previous element of the database if
+ there exists an element before the current one.
+*/
+bool DBStore::previous()
+{
+ unsigned int new_current_elem = current_elem -1;
+ if (current_elem < number_elems)
+ /* was valid */
+ if (new_current_elem < number_elems) {
+ /* still is (if was 0, then now -1, but as is unsigned will wrap
+ and hence be invalid */
+ current_elem = new_current_elem;
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns the current data element in the database. Which element is current
+ is affected by newly added items, findItem, next, previous, first and
+ last functions
+
+ \return a pointer to the current data element
+*/
+DataElem *DBStore::getCurrentData()
+{
+ if (current_elem >= number_elems)
+ return NULL;
+ return master_table[current_elem];
+}
diff --git a/noncore/apps/tableviewer/db/datacache.h b/noncore/apps/tableviewer/db/datacache.h
new file mode 100644
index 0000000..c5dc637
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/datacache.h
@@ -0,0 +1,130 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/*
+ * This file is used to load the xml files that represent the database.
+ * The main requirment for said file is each data entry must contain a key,
+ * otherwise any other data headings are allowed.
+ */
+
+#ifndef __DATACACHE_H__
+#define __DATACACHE_H__
+
+#include <qstring.h>
+#include <qvector.h>
+#include "common.h"
+
+class DBStore;
+
+/*! Abstract class that defines how database stuff can be accessed */
+class DBAccess {
+public:
+
+// DBAccess(DBStore *d) { dstore = d; }
+ virtual ~DBAccess() {}
+
+ virtual QString type() {
+ return QString();
+ }
+
+ virtual bool openSource(QIODevice *) {
+ qWarning("DBAccess::openSource not yet implemented");
+ return false;
+ }
+
+ virtual bool saveSource(QIODevice *) {
+ qWarning("DBAccess::saveSource(QString) not yet implemented");
+ return false;
+ }
+
+protected:
+ DBStore *dstore;
+ QString source_name;
+};
+
+class DBStore {
+public:
+ DBStore();
+ ~DBStore();
+
+ bool openSource(QIODevice *, const QString &source);
+ bool saveSource(QIODevice *, const QString &source);
+
+ // Add an item
+ void addItem(DataElem *);
+ void addItemInternal(DataElem *);
+ void removeItem(DataElem *);
+
+ // Set the name of the database
+ void setName(const QString &name);
+
+ // Get the name of the database
+ QString getName();
+
+ KeyList *getKeys();
+ void setKeys(KeyList *);
+
+ /*! gets the number of fields defined in the database */
+ inline int getNumFields() {
+ return kRep->getNumFields();
+ }
+
+ /*! gets the index of a key given its name */
+ inline int getKeyIndex(QString qs) {
+ return kRep->getKeyIndex(qs);
+ }
+
+ /*! gets the type of a key given its index */
+ inline TVVariant::KeyType getKeyType(int i) {
+ return kRep->getKeyType(i);
+ }
+
+ /*! gets the name of a key given its index */
+ inline QString getKeyName(int i) {
+ return kRep->getKeyName(i);
+ }
+
+// Access functions.. iterator type stuff
+
+ void first();
+ void last();
+
+ bool next();
+ bool previous();
+
+ DataElem* getCurrentData();
+
+private:
+ /* does the work of freeing used memory */
+ void freeTable();
+ QString name;
+
+ QVector<DataElem> master_table;
+ DBAccess *archive;
+
+ KeyList *kRep;
+
+ unsigned int number_elems;
+ unsigned int table_size; /* should always be a power of 2 */
+ bool full; /* since because we are using an int for indexing there is
+ an upper limit on the number of items we can store. */
+ unsigned int current_elem;
+};
+#endif
diff --git a/noncore/apps/tableviewer/db/xmlsource.cpp b/noncore/apps/tableviewer/db/xmlsource.cpp
new file mode 100644
index 0000000..7418a85
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/xmlsource.cpp
@@ -0,0 +1,295 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "xmlsource.h"
+#include <qdict.h>
+#include <stdlib.h>
+#include <qtextstream.h>
+
+
+DBXml::DBXml(DBStore *d)
+{
+ dstore = d;
+}
+
+QString DBXml::type()
+{
+ return "xml";
+}
+
+bool DBXml::openSource(QIODevice *inDev)
+{
+ bool ok;
+
+ DBXmlHandler h(dstore);
+
+ QTextStream tsIn(inDev);
+ QXmlInputSource source(tsIn);
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&h);
+ reader.setErrorHandler(&h);
+ ok = reader.parse(source);
+
+ return ok;
+}
+
+bool DBXml::saveSource(QIODevice *outDev)
+{
+ int i;
+ DataElem *elem;
+ KeyList *k;
+
+ QTextStream outstream(outDev);
+
+ outstream << "<database name=\"" << dstore->getName() << "\">" << endl;
+ outstream << "<header>" << endl;
+
+ k = dstore->getKeys();
+ KeyListIterator it(*k);
+ while(it.current()) {
+ if (!it.current()->delFlag()) {
+ outstream << "<key name=\"KEYID" << it.currentKey() << "\" ";
+ outstream << "type=\""
+ << TVVariant::typeToName(it.current()->type())
+ << "\">";
+ outstream << it.current()->name() << "</key>" << endl;
+ }
+ ++it;
+ }
+
+ outstream << "</header>" << endl;
+
+ dstore->first();
+
+ do {
+ elem = dstore->getCurrentData();
+ if (!elem)
+ break;
+ outstream << "<record>" << endl;
+ it.toFirst();
+ while (it.current()) {
+ i = it.currentKey();
+ if (elem->hasValidValue(i)) {
+ outstream << "<KEYID" << i << ">";
+ if (dstore->getKeyType(i) == TVVariant::Date) {
+ // dates in files are different from displayed dates
+ QDate date = elem->getField(i).toDate();
+ outstream << date.day() << "/"
+ << date.month() << "/"
+ << date.year();
+ } else {
+ outstream << elem->toQString(i);
+ }
+ outstream << "</KEYID" << i << ">" << endl;
+ }
+ ++it;
+ }
+ outstream << "</record>" << endl;
+ } while(dstore->next());
+
+ outstream << "</database>" << endl;
+ return TRUE;
+}
+
+DBXml::~DBXml() {}
+
+/*!
+ \class DBXmlHandler
+ \brief An Xml parser for flat tables.
+
+ An xml parser for parsing the files used by the table viewer application.
+
+ The format of the xml files can be found at the front of the file
+ dataparser.h
+*/
+
+/*!
+ Constructs a new DBXmlHandler, and sets that the table should be
+ constructed in the DBStore pointed to by ds.
+*/
+DBXmlHandler::DBXmlHandler(DBStore *ds)
+{
+ data_store = ds;
+ current_keyrep = 0;
+}
+
+/*!
+ Destroys the DBXmlHandler
+*/
+DBXmlHandler::~DBXmlHandler()
+{
+}
+
+QString DBXmlHandler::errorProtocol()
+{
+ qWarning("Error reading file");
+ return errorProt;
+}
+
+bool DBXmlHandler::startDocument()
+{
+ errorProt = "";
+ state = StateInit;
+ return TRUE;
+}
+
+bool DBXmlHandler::startElement(const QString&, const QString&,
+ const QString& qName, const QXmlAttributes& atts)
+{
+ if (state == StateInit && qName == "database") {
+ // First thing it expects is a <document name="..."> tag
+ state = StateDocument;
+ data_store->setName(atts.value("name"));
+ return TRUE;
+ }
+ if (state == StateDocument && qName == "header") {
+ state = StateHeader;
+ if (current_keyrep) delete current_keyrep;
+ current_keyrep = new KeyList();
+ return TRUE;
+ }
+ if (state == StateHeader && qName == "key") {
+ /* Ok, adding a new key to our KeyList TODO */
+ state = StateKey;
+ last_key_type = TVVariant::String;
+ key = atts.value("name");
+ if (key.isEmpty()) {
+ qWarning("empty key name");
+ return FALSE;
+ }
+ if(!atts.value("type").isEmpty())
+ last_key_type = TVVariant::nameToType(atts.value("type"));
+ return TRUE;
+ }
+ if (state == StateDocument && qName == "record") {
+ state = StateRecord;
+ current_data = new DataElem(data_store);
+ // Now expecting a <record> tag
+ return TRUE;
+ }
+ if (state == StateRecord) {
+ state = StateField;
+ /* the qName is the name of a key */
+ if (!keyIndexList[qName]) {
+ /* invalid key, we failed */
+ qWarning("Invalid key in record");
+ return FALSE;
+ }
+ keyIndex = *keyIndexList[qName];
+ return TRUE;
+ }
+ qWarning("Unable to determine tag type");
+ return FALSE;
+}
+
+bool DBXmlHandler::endElement(const QString&, const QString&,
+ const QString& qName)
+{
+ switch(state) {
+ case StateField:
+ // TODO checks 'could' be done of the popped value
+ state = StateRecord;
+ break;
+ case StateKey:
+ // TODO checks 'could' be done of the popped value
+ state = StateHeader;
+ break;
+ case StateHeader:
+ data_store->setKeys(current_keyrep);
+ state = StateDocument;
+ break;
+ case StateRecord:
+ data_store->addItem(current_data);
+ state = StateDocument;
+ break;
+ case StateDocument:
+ // we are done...
+ break;
+ default:
+ // should only get a 'endElement' from one of the above states.
+ qWarning("Invalid end tag");
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool DBXmlHandler::characters(const QString& ch)
+{
+ // this is where the 'between tag' stuff happens.
+ // e.g. the stuff between tags.
+ QString ch_simplified = ch.simplifyWhiteSpace();
+
+ if (ch_simplified.isEmpty())
+ return TRUE;
+
+ if (state == StateKey) {
+ int *tmp_val = new int;
+ /* We just grabbed the display name of a key */
+ *tmp_val = current_keyrep->addKey(ch_simplified, last_key_type);
+ keyIndexList.insert(key, tmp_val);
+ return TRUE;
+ }
+ if (state == StateField) {
+ /* Ok, need to add data here */
+ current_data->setField(keyIndex, ch_simplified);
+ return TRUE;
+ }
+
+ qWarning("Junk characters found... ignored");
+ return TRUE;
+}
+
+QString DBXmlHandler::errorString()
+{
+ return "the document is not in the expected file format";
+}
+
+bool DBXmlHandler::warning(const QXmlParseException& exception)
+{
+ errorProt += QString("warning parsing error: %1 in line %2, column %3\n" )
+ .arg(exception.message())
+ .arg(exception.lineNumber())
+ .arg(exception.columnNumber());
+
+ qWarning(errorProt);
+ return QXmlDefaultHandler::fatalError(exception);
+}
+
+bool DBXmlHandler::error(const QXmlParseException& exception)
+{
+ errorProt += QString("error parsing error: %1 in line %2, column %3\n" )
+ .arg(exception.message())
+ .arg(exception.lineNumber())
+ .arg(exception.columnNumber());
+
+ qWarning(errorProt);
+ return QXmlDefaultHandler::fatalError(exception);
+}
+
+bool DBXmlHandler::fatalError(const QXmlParseException& exception)
+{
+ errorProt += QString("fatal parsing error: %1 in line %2, column %3\n" )
+ .arg(exception.message())
+ .arg(exception.lineNumber())
+ .arg(exception.columnNumber());
+
+ qWarning(errorProt);
+ return QXmlDefaultHandler::fatalError(exception);
+}
diff --git a/noncore/apps/tableviewer/db/xmlsource.h b/noncore/apps/tableviewer/db/xmlsource.h
new file mode 100644
index 0000000..ec267a6
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/xmlsource.h
@@ -0,0 +1,119 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/* A Class to parse an xml docment of the form
+ * <database name="...">
+ * <header>
+ * <key name=key_name type=String>Displayed Name</key>
+ * <key name=key2name>key2name</key>
+ * <key name=key3name type=Date>Key 3</key>
+ * <key name=key4name type=Int>key 4</key>
+ * </header>
+ * <record>
+ * <key_name>string</key_name>
+ * <key4name>int</key4name>
+ * <key2name>string</key2name>
+ * </record>
+ * <record>
+ * ....
+ * </record>
+ * ....
+ * </database>
+ *
+ * There is some room for improvment mostly around using better checking
+ * and the use of more advanced xml features.
+ */
+
+#ifndef __XMLSOURCE_H__
+#define __XMLSOURCE_H__
+
+#include <qxml.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qstack.h>
+#include <qdict.h>
+#include "datacache.h"
+#include "common.h"
+
+
+class DBXml : public DBAccess
+{
+public:
+ /* create connection and either open or initialize */
+ DBXml(DBStore *d);
+ QString type();
+ bool openSource(QIODevice *);
+ bool saveSource(QIODevice *);
+ /* does a db write */
+ ~DBXml();
+};
+
+
+class DBXmlHandler : public QXmlDefaultHandler
+{
+
+public:
+ DBXmlHandler(DBStore *ds);
+ virtual ~DBXmlHandler();
+
+ // return the error protocol if parsing failed
+ QString errorProtocol();
+
+ // overloaded handler functions
+ bool startDocument();
+ bool startElement(const QString& namespaceURI, const QString& localName,
+ const QString& qName, const QXmlAttributes& atts);
+ bool endElement(const QString& namespaceURI, const QString& localName,
+ const QString& qName);
+ bool characters(const QString& ch);
+
+ QString errorString();
+
+ bool warning(const QXmlParseException& exception);
+ bool error(const QXmlParseException& exception);
+ bool fatalError(const QXmlParseException& exception);
+
+private:
+
+ QStack<QString> stack;
+ KeyList *current_keyrep;
+ DataElem *current_data;
+ TVVariant::KeyType last_key_type;
+
+ QString errorProt;
+ DBStore *data_store;
+
+ enum State {
+ StateInit,
+ StateHeader,
+ StateKey,
+ StateDocument,
+ StateRecord,
+ StateField
+ };
+
+ State state;
+
+ QDict<int> keyIndexList;
+ int keyIndex;
+ QString key;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/keyentry.cw b/noncore/apps/tableviewer/keyentry.cw
new file mode 100644
index 0000000..e46da90
--- a/dev/null
+++ b/noncore/apps/tableviewer/keyentry.cw
@@ -0,0 +1,55 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>TVBrowseKeyEntry</class>
+ <header location="local">browsekeyentry.h</header>
+ <sizehint>
+ <width>6</width>
+ <height>4</height>
+ </sizehint>
+ <container>1</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>TVListViewPrivate</class>
+ <header location="local">tvlistview.h</header>
+ <sizehint>
+ <width>10</width>
+ <height>10</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753</data>
+ </pixmap>
+ <signal>sortChanged(int)</signal>
+ <signal>currentChanged(QListViewItem *)</signal>
+ </customwidget>
+ <customwidget>
+ <class>TVFilterKeyEntry</class>
+ <header location="local">filterkeyentry.h</header>
+ <sizehint>
+ <width>10</width>
+ <height>10</height>
+ </sizehint>
+ <container>1</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753</data>
+ </pixmap>
+ <signal>valueChanged()</signal>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/noncore/apps/tableviewer/main.cpp b/noncore/apps/tableviewer/main.cpp
new file mode 100644
index 0000000..736e1cf
--- a/dev/null
+++ b/noncore/apps/tableviewer/main.cpp
@@ -0,0 +1,32 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "tableviewer.h"
+#include <qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ TableViewerWindow * mw = new TableViewerWindow;
+ mw->setCaption( TableViewerWindow::tr("Table Viewer") );
+ a.showMainWidget(mw);
+
+ return a.exec();
+}
diff --git a/noncore/apps/tableviewer/qpe-tableviewer.control b/noncore/apps/tableviewer/qpe-tableviewer.control
new file mode 100644
index 0000000..86d0342
--- a/dev/null
+++ b/noncore/apps/tableviewer/qpe-tableviewer.control
@@ -0,0 +1,10 @@
+Files: EXCLUDED bin/tableviewer apps/Applications/tableviewer.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: XML database browsers
+ A table/database viewer for the Qtopia environment.
diff --git a/noncore/apps/tableviewer/tableviewer.cpp b/noncore/apps/tableviewer/tableviewer.cpp
new file mode 100644
index 0000000..0d4a412
--- a/dev/null
+++ b/noncore/apps/tableviewer/tableviewer.cpp
@@ -0,0 +1,455 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+/* local includes */
+#include "tableviewer.h"
+#include "ui/tvbrowseview.h"
+#include "ui/tvfilterview.h"
+#include "ui/tvlistview.h"
+#include "ui/tveditview.h"
+#include "ui/tvkeyedit.h"
+#include "db/datacache.h"
+
+/* QPE includes */
+#include "fileselector.h"
+#include "resource.h"
+
+/* QTE includes */
+#include <qpe/qpemenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qwidgetstack.h>
+#include <qlayout.h>
+#include <qbuffer.h>
+
+/*!
+ \class TableViewerWindow
+ \brief The main window widget of the application
+
+ This is the main widget of the table viewer application.
+ It is the co-ordination point.
+*/
+
+/*!
+ Constructs a new TableViewerWindow
+*/
+TableViewerWindow::TableViewerWindow(QWidget *parent, const char *name, WFlags f)
+ : QMainWindow(parent, name, f)
+{
+ setCaption(tr("Table Viewer"));
+
+/* Build data */
+ ds = new DBStore();
+ doc.setType("text/x-xml-tableviewer");
+ doc.setName("table");
+
+ dirty = FALSE;
+ ts.current_column = 0;
+ ts.kRep = ds->getKeys();
+
+/* build menus */
+ menu = new QPEMenuBar(this, 0);
+
+ QPopupMenu *file_menu = new QPopupMenu;
+ file_menu->insertItem("New", this, SLOT(newDocument()));
+
+ file_menu->insertItem("Open", this, SLOT(selectDocument()));
+ file_menu->insertSeparator();
+ file_menu->insertItem("Properties");
+
+ /* later will want to set this up to clean up first via this, SLOT(quit) */
+ menu->insertItem("Document", file_menu);
+
+ QPopupMenu *edit_menu = new QPopupMenu;
+ edit_menu->insertItem("Edit Item", this, SLOT(editItemSlot()));
+ edit_menu->insertItem("Edit Keys", this, SLOT(editKeysSlot()));
+ edit_menu->insertItem("Edit filters", this, SLOT(filterViewSlot()));
+ menu->insertItem("Edit", edit_menu);
+
+ QPopupMenu *view_menu = new QPopupMenu;
+ view_menu->insertItem("Browse View", this, SLOT(browseViewSlot()));
+ view_menu->insertItem("List View", this, SLOT(listViewSlot()));
+ menu->insertItem("View", view_menu);
+
+ QVBoxLayout *main_layout = new QVBoxLayout;
+
+ /* Build tool bar */
+ navigation = new QPEToolBar(this, "navigation");
+ QToolButton *newItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("new")), "New Item", QString::null,
+ this, SLOT(newItemSlot()), navigation, "New Item");
+ QToolButton *editItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("edit")), "Edit Item", QString::null,
+ this, SLOT(editItemSlot()), navigation, "Edit Item");
+ QToolButton *deleteItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("trash")), "Delete Item",
+ QString::null, this,
+ SLOT(deleteItemSlot()), navigation, "Delete Item");
+
+ navigation->addSeparator();
+
+ QToolButton *firstItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("fastback")), "First Item",
+ QString::null, this,
+ SLOT(firstItem()), navigation, "First Item");
+ QToolButton *previousItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("back")), "Previous Item",
+ QString::null, this,
+ SLOT(previousItem()), navigation, "Previous Item");
+ QToolButton *nextItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("forward")), "Next Item",
+ QString::null, this,
+ SLOT(nextItem()), navigation, "Next Item");
+ QToolButton *lastItemButton = new QToolButton(
+ QIconSet(Resource::loadImage("fastforward")), "Last Item",
+ QString::null, this,
+ SLOT(lastItem()), navigation, "Last Item");
+
+ navigation->addSeparator();
+ QToolButton *browseButton = new QToolButton(
+ QIconSet(Resource::loadImage("day")), "View Single Item",
+ QString::null, this,
+ SLOT(browseViewSlot()), navigation, "View Single Item");
+ QToolButton *listButton = new QToolButton(
+ QIconSet(Resource::loadImage("month")), "View Multiple Items",
+ QString::null, this,
+ SLOT(listViewSlot()), navigation, "View Multiple Items");
+
+ setToolBarsMovable(FALSE);
+ setToolBarsMovable(FALSE);
+ setToolBarsMovable(FALSE);
+
+/* Build widgets */
+ browseView = new TVBrowseView(&ts, this, 0);
+ listView = new TVListView(&ts, this, 0);
+ filterView = new TVFilterView(&ts, this, 0);
+ fileSelector = new FileSelector("text/csv;text/x-xml-tableviewer",
+ this, "fileselector");
+ fileSelector->setNewVisible(FALSE);
+ fileSelector->setCloseVisible(FALSE);
+
+ cw = new QWidgetStack(this, 0);
+ cw->addWidget(listView, ListState);
+ cw->addWidget(browseView, BrowseState);
+ cw->addWidget(filterView, FilterState);
+ cw->addWidget(fileSelector, FileState);
+
+ current_view = FileState;
+ cw->raiseWidget(current_view);
+ fileSelector->reread();
+
+ connect(browseView, SIGNAL(searchOnKey(int, TVVariant)),
+ this, SLOT(searchOnKey(int, TVVariant)));
+ connect(browseView, SIGNAL(sortChanged(int)),
+ this, SLOT(setPrimaryKey(int)));
+
+ connect(fileSelector, SIGNAL(closeMe()), this, SLOT(browseViewSlot()));
+ connect(fileSelector, SIGNAL(fileSelected(const DocLnk &)),
+ this, SLOT(openDocument(const DocLnk &)));
+
+ main_layout->addWidget(menu);
+ main_layout->addWidget(cw);
+
+ setCentralWidget(cw);
+
+}
+
+/*!
+ Destroys the TableViewerWindow
+*/
+TableViewerWindow::~TableViewerWindow()
+{
+ if(dirty)
+ saveDocument();
+}
+
+/*!
+ Opens a file dialog and loads the file specified by the dialog
+*/
+void TableViewerWindow::selectDocument()
+{
+ if(dirty)
+ saveDocument();
+ current_view = FileState;
+ cw->raiseWidget(current_view);
+ fileSelector->reread();
+}
+
+void TableViewerWindow::saveDocument()
+{
+ if(!dirty)
+ return;
+
+ FileManager fm;
+ QIODevice *dev = fm.saveFile(doc);
+
+ if(!ds->saveSource(dev, doc.type())){
+ qWarning("Save unsuccessful");
+ return;
+ }
+ dev->close();
+ dirty = FALSE;
+}
+
+void TableViewerWindow::newDocument()
+{
+ DocLnk nf;
+ nf.setType("text/x-xml-tableviewer");
+ nf.setName("table");
+
+ delete ds;
+ ds = new DBStore();
+
+ ts.current_column = 0;
+ ts.kRep = ds->getKeys();
+ browseView->reset();
+ listView->reset();
+ filterView->reset();
+
+ doc = nf;
+ dirty = FALSE;
+
+ current_view = BrowseState;
+ cw->raiseWidget(current_view);
+
+ /* now set up for editing the keys */
+ ts.kRep->addKey("key", TVVariant::String);
+ editKeysSlot();
+}
+
+void TableViewerWindow::openDocument(const DocLnk &f)
+{
+
+ if (!f.isValid())
+ return;
+
+ FileManager fm;
+ QIODevice *dev = fm.openFile(f);
+ doc = f;
+
+ if(ds->openSource(dev, doc.type())) {
+ DataElem *d;
+
+ browseView->reset();
+ listView->reset();
+ filterView->reset();
+
+ current_view = BrowseState;
+ cw->raiseWidget(current_view);
+
+ /* set up new table state and ensure sub widgets have a reference */
+ ts.current_column = 0;
+ ts.kRep = ds->getKeys();
+ browseView->rebuildKeys();
+ listView->rebuildKeys();
+ filterView->rebuildKeys();
+
+ ds->first();
+ /* set up the list view */
+ listView->clearItems();
+ do {
+ d = ds->getCurrentData();
+ if(d)
+ listView->addItem(d);
+ } while(ds->next());
+
+ /* Set up browse view, Will be based of structure of listView */
+ listView->first();
+ ts.current_elem = listView->getCurrentData();
+ browseView->rebuildData();
+ listView->rebuildData();
+
+ QString scratch = "Table Viewer";/* later take from constant */
+ scratch += " - ";
+ scratch += ds->getName();
+ setCaption(tr(scratch));
+
+ dirty = FALSE;
+ } else {
+ qWarning(tr("could not load Document"));
+ }
+ dev->close();
+}
+
+/*!
+ Moves to the next item of the current table
+*/
+void TableViewerWindow::nextItem()
+{
+ listView->next();
+ ts.current_elem = listView->getCurrentData();
+ browseView->rebuildData();
+}
+
+/*!
+ Moves to the previous item of the current table
+*/
+void TableViewerWindow::previousItem()
+{
+ listView->previous();
+ ts.current_elem = listView->getCurrentData();
+ browseView->rebuildData();
+}
+
+/*!
+ Raises the List View. This is a mode change for the application.
+*/
+void TableViewerWindow::listViewSlot()
+{
+ if(current_view == FilterState)
+ applyFilter();
+ current_view = ListState;
+ cw->raiseWidget(current_view);
+}
+
+void TableViewerWindow::applyFilter()
+{
+ DataElem *d;
+
+ listView->clearItems();
+ ds->first();
+ do {
+ d = ds->getCurrentData();
+ if(d)
+ if(filterView->passesFilter(d))
+ listView->addItem(d);
+ } while(ds->next());
+ listView->first();
+ listView->rebuildData();
+}
+
+/*!
+ Raises the Browse View. This is a mode change for the application.
+*/
+void TableViewerWindow::browseViewSlot()
+{
+ if(current_view == FilterState)
+ applyFilter();
+
+ ts.current_elem = listView->getCurrentData();
+ browseView->rebuildData();
+
+ current_view = BrowseState;
+ cw->raiseWidget(current_view);
+}
+
+/*!
+ Raises the List View. This is a mode change for the application.
+*/
+void TableViewerWindow::filterViewSlot()
+{
+ current_view = FilterState;
+ cw->raiseWidget(current_view);
+}
+
+
+
+
+void TableViewerWindow::editItemSlot()
+{
+ if(TVEditView::openEditItemDialog(&ts, ts.current_elem, this)) {
+ listView->rebuildData();
+ browseView->rebuildData();
+ dirty = TRUE;
+ }
+}
+
+void TableViewerWindow::newItemSlot()
+{
+ DataElem *d = new DataElem(ds);
+ if (TVEditView::openEditItemDialog(&ts, d, this)) {
+
+ ds->addItem(d);
+ ts.current_elem = d;
+ applyFilter();
+ listView->rebuildData();
+ browseView->rebuildData();
+ dirty = TRUE;
+ }
+}
+
+void TableViewerWindow::deleteItemSlot()
+{
+ /* delete the actual item, then do a 'filter' */
+ DataElem *to_remove = ts.current_elem;
+
+ if(!to_remove)
+ return;
+
+ listView->removeItem();
+ ds->removeItem(to_remove);
+
+ applyFilter();
+ listView->rebuildData();
+ browseView->rebuildData();
+ dirty = TRUE;
+}
+
+void TableViewerWindow::editKeysSlot()
+{
+ DataElem *d;
+ KeyList *k = TVKeyEdit::openEditKeysDialog(&ts, this);
+
+ if(k) {
+ /* set as new keys */
+ ds->setKeys(k);
+
+ ts.current_column = 0;
+ ts.kRep = k;
+
+ browseView->reset();
+ listView->reset();
+ filterView->reset();
+
+ browseView->rebuildKeys();
+ listView->rebuildKeys();
+ filterView->rebuildKeys();
+
+ ds->first();
+ /* set up the list view */
+ listView->clearItems();
+ do {
+ d = ds->getCurrentData();
+ if(d)
+ listView->addItem(d);
+ } while(ds->next());
+
+ /* Set up browse view, Will be based of structure of listView */
+ dirty = TRUE;
+ }
+}
+
+/*!
+ A Slot that allows for widgets above to indicate a search should be
+ done on a specified key index for a specified value
+*/
+void TableViewerWindow::searchOnKey(int i, TVVariant v)
+{
+ listView->findItem(i, v);
+ ts.current_elem = listView->getCurrentData();
+ browseView->rebuildData();
+}
+
+void TableViewerWindow::setPrimaryKey(int i)
+{
+ ts.current_column = i;
+ listView->rebuildData();
+ browseView->rebuildData();
+}
diff --git a/noncore/apps/tableviewer/tableviewer.h b/noncore/apps/tableviewer/tableviewer.h
new file mode 100644
index 0000000..2d4686a
--- a/dev/null
+++ b/noncore/apps/tableviewer/tableviewer.h
@@ -0,0 +1,109 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Tableviewer_H
+#define Tableviewer_H
+
+#include <qmainwindow.h>
+#include "db/common.h"
+#include "fileselector.h"
+
+/* Forward class declarations */
+class QWidgetStack;
+class QDialog;
+class QMenuBar;
+
+class TVListView;
+class TVBrowseView;
+class TVFilterView;
+class TVEditView;
+
+class DBStore;
+
+class TableViewerWindow: public QMainWindow
+{
+ Q_OBJECT
+public:
+ TableViewerWindow( QWidget *parent = 0,
+ const char *name = 0, WFlags f = 0 );
+ ~TableViewerWindow();
+
+public slots:
+ void selectDocument();
+
+ void newDocument();
+ void saveDocument();
+ void openDocument(const DocLnk &);
+
+ void nextItem();
+ void previousItem();
+
+ void listViewSlot();
+ void browseViewSlot();
+ void filterViewSlot();
+
+ void editItemSlot();
+ void newItemSlot();
+ void deleteItemSlot();
+
+ void editKeysSlot();
+
+ /* reveiw the sig. for this function TODO */
+ void searchOnKey(int, TVVariant);
+ void setPrimaryKey(int);
+
+/* TODO add new event */
+protected:
+
+/* TODO add new slots */
+private slots:
+
+/* TODO add other widgets used here */
+private:
+ bool dirty;
+
+ QMenuBar *menu;
+ QToolBar *navigation;
+
+ TVListView *listView;
+ TVBrowseView *browseView;
+ TVFilterView *filterView;
+ TVEditView *editView;
+ FileSelector *fileSelector;
+
+ DocLnk doc;
+
+ QWidgetStack *cw;
+ DBStore *ds;
+ TableState ts; /* not a pointer.. this class keeps the state */
+
+ enum UserState {
+ BrowseState = 0,
+ ListState,
+ FilterState,
+ EditState,
+ FileState,
+ };
+
+ UserState current_view;
+
+ void applyFilter();
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/tableviewer.pro b/noncore/apps/tableviewer/tableviewer.pro
new file mode 100644
index 0000000..edd41c5
--- a/dev/null
+++ b/noncore/apps/tableviewer/tableviewer.pro
@@ -0,0 +1,36 @@
+TEMPLATE = app
+CONFIG = qt warn_on debug
+DESTDIR = ../bin
+SUBDIRS = db ui
+HEADERS = tableviewer.h \
+ ui/commonwidgets.h \
+ ui/tvbrowseview.h \
+ ui/tvlistview.h \
+ ui/tvfilterview.h \
+ ui/tveditview.h \
+ ui/browsekeyentry.h \
+ ui/filterkeyentry.h \
+ ui/tvkeyedit.h \
+ db/datacache.h \
+ db/common.h \
+ db/xmlsource.h \
+ db/csvsource.h
+SOURCES = main.cpp \
+ tableviewer.cpp \
+ ui/commonwidgets.cpp \
+ ui/tvbrowseview.cpp \
+ ui/tvfilterview.cpp \
+ ui/browsekeyentry.cpp \
+ ui/filterkeyentry.cpp \
+ ui/tvlistview.cpp \
+ ui/tveditview.cpp \
+ ui/tvkeyedit.cpp \
+ db/datacache.cpp \
+ db/xmlsource.cpp \
+ db/csvsource.cpp \
+ db/common.cpp
+INTERFACES = ui/tvkeyedit_gen.ui
+TARGET = tableviewer
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
diff --git a/noncore/apps/tableviewer/ui/.cvsignore b/noncore/apps/tableviewer/ui/.cvsignore
new file mode 100644
index 0000000..183c939
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/.cvsignore
@@ -0,0 +1,8 @@
+moc_*
+Makefile
+tvbrowseview_gen.h
+tvfilterview_gen.h
+tvkeyedit_gen.h
+tvbrowseview_gen.cpp
+tvfilterview_gen.cpp
+tvkeyedit_gen.cpp
diff --git a/noncore/apps/tableviewer/ui/browsekeyentry.cpp b/noncore/apps/tableviewer/ui/browsekeyentry.cpp
new file mode 100644
index 0000000..42e24dd
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/browsekeyentry.cpp
@@ -0,0 +1,206 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "browsekeyentry.h"
+#include "commonwidgets.h"
+
+#include <qtoolbutton.h>
+#include <qwidgetstack.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qpopupmenu.h>
+#include <qhbox.h>
+#include <qdatetime.h>
+
+#include <qheader.h>
+// For qWarning(const char *)
+
+/*!
+ \class TVBrowseKeyEntry
+ \brief a Widget used enter keys into the TVBrowseViewWidget
+
+ The TVBrowseKeyEntry Widget provides the facility to enter
+ various key types to be search on in the table. The key can be changed
+ and the entry field will update to the correct sort of widget appropriately
+*/
+
+/*!
+ Constructs the widget
+*/
+TVBrowseKeyEntry::TVBrowseKeyEntry(QWidget *parent, const char *name, WFlags f)
+ : QWidget(parent, name, f)
+{
+ QHBoxLayout *h_layout = new QHBoxLayout(this);
+
+ textKey = new QLineEdit(this, 0);
+ intKey = new IntEdit(this, 0);
+ dateKey = new DateEdit(this, 0);
+ timeKey = new TimeEdit(this, 0);
+
+ resetButton = new QPushButton(this, "reset");
+ resetButton->setMinimumSize(QSize(50, 0));
+ resetButton->setText(tr("Reset"));
+
+ changeKeyButton = new QToolButton(this, "changekey");
+ // TODO The icon stuff.
+ changeKeyButton->setText(tr("key"));
+
+ totalKeys = 0;
+ ts = 0;
+ keyMenu = new QPopupMenu(this, "keymenu");
+
+ ws = new QWidgetStack(this, 0);
+ ws->addWidget(textKey, TVVariant::String);
+ ws->addWidget(intKey, TVVariant::Int);
+ ws->addWidget(timeKey, TVVariant::Time);
+ ws->addWidget(dateKey, TVVariant::Date);
+
+ ws->raiseWidget(TVVariant::String);
+
+ // TODO connect slots and signals....
+ connect(changeKeyButton, SIGNAL(clicked()),
+ this, SLOT(changeKeyMenuSlot()));
+
+ connect(resetButton, SIGNAL(clicked()),
+ textKey, SLOT(clear()));
+ connect(resetButton, SIGNAL(clicked()),
+ intKey, SLOT(clear()));
+ connect(resetButton, SIGNAL(clicked()),
+ dateKey, SLOT(clear()));
+ connect(resetButton, SIGNAL(clicked()),
+ timeKey, SLOT(clear()));
+
+ h_layout->addWidget(ws);
+ h_layout->addWidget(resetButton);
+ h_layout->addWidget(changeKeyButton);
+
+ connect(textKey, SIGNAL(textChanged(const QString&)),
+ this, SLOT(searchOnText()));
+ connect(intKey, SIGNAL(valueChanged(int)),
+ this, SLOT(searchOnText()));
+ connect(dateKey, SIGNAL(valueChanged(const QDate&)),
+ this, SLOT(searchOnText()));
+ connect(timeKey, SIGNAL(valueChanged(const QTime&)),
+ this, SLOT(searchOnText()));
+}
+
+/*!
+ Destructs the widget
+*/
+TVBrowseKeyEntry::~TVBrowseKeyEntry()
+{
+}
+
+/*!
+ Changes which key the user intends to search on
+
+ \param id_param the index of the key future searches should be base on
+*/
+void TVBrowseKeyEntry::changeKeySlot(int id_param)
+{
+ if(ts) {
+ emit sortChanged(id_param);
+ ws->raiseWidget(ts->kRep->getKeyType(ts->current_column));
+ }
+}
+
+/*!
+ Opens the change key menu
+*/
+void TVBrowseKeyEntry::changeKeyMenuSlot()
+{
+ if(ts)
+ keyMenu->exec(changeKeyButton->mapToGlobal(QPoint(0,0)));
+}
+
+
+void TVBrowseKeyEntry::setTableState(TableState *t) {
+ ts = t;
+}
+
+void TVBrowseKeyEntry::rebuildKeys() {
+ int i;
+ if (!ts) return;
+ if (!ts->kRep) return;
+
+ /* clear the old */
+ keyMenu->clear();
+
+ KeyListIterator it(*ts->kRep);
+
+ for (i = 0; i < ts->kRep->getNumFields(); i++) {
+ keyMenu->insertItem(it.current()->name(), this,
+ SLOT(changeKeySlot(int)), 0, i);
+ keyMenu->setItemParameter(i, it.currentKey());
+ ++it;
+ }
+}
+
+void TVBrowseKeyEntry::reset()
+{
+ textKey->clear();
+ intKey->clear();
+ dateKey->clear();
+ timeKey->clear();
+
+ keyMenu->clear();
+}
+/*!
+ Searches on the current value of the key entry provided that the
+ current key is of type text WARNING, TODO fix memory leaks
+*/
+void TVBrowseKeyEntry::searchOnText()
+{
+ TVVariant sendkey;
+
+ if (!ts)
+ return;
+
+ switch(ts->kRep->getKeyType(ts->current_column)) {
+ case TVVariant::String:
+ sendkey = TVVariant(QString(textKey->text()));
+ break;
+ case TVVariant::Int: {
+ sendkey = TVVariant(intKey->value());
+ break;
+ }
+ case TVVariant::Time: {
+ sendkey = TVVariant(QTime(timeKey->time()));
+ break;
+ }
+ case TVVariant::Date: {
+ sendkey = TVVariant(QDate(dateKey->date()));
+ break;
+ }
+ case TVVariant::Invalid:
+ break;
+ default:
+ qWarning("TVBrowseKeyEntry::searchOnText() "
+ "cannot work out data type");
+ return;
+ }
+ emit searchOnKey(ts->current_column, sendkey);
+}
+
+/*! \fn void TVBrowseKeyEntry::searchOnKey(int currentKeyId, TVVariant)
+
+ This signal indicates that a search on key index currentKeyId should be
+ done searching for the value v.
+*/
diff --git a/noncore/apps/tableviewer/ui/browsekeyentry.h b/noncore/apps/tableviewer/ui/browsekeyentry.h
new file mode 100644
index 0000000..220bf6a
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/browsekeyentry.h
@@ -0,0 +1,75 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef BrowseKeyEntry_H
+#define BrowseKeyEntry_H
+
+#include <qwidget.h>
+#include "../db/common.h"
+
+/* Forward class declarations */
+class QWidgetStack;
+class QToolButton;
+class QPushButton;
+class QLineEdit;
+class DateEdit;
+class TimeEdit;
+class IntEdit;
+class QPopupMenu;
+class QHBox;
+
+class TVBrowseKeyEntry: public QWidget
+{
+ Q_OBJECT
+public:
+ TVBrowseKeyEntry( QWidget *parent = 0,
+ const char *name = 0, WFlags f = 0 );
+ ~TVBrowseKeyEntry();
+
+ void setTableState(TableState *t);
+ void rebuildKeys();
+ void reset();
+
+signals:
+ void searchOnKey(int keyIndex, TVVariant keyData);
+ void sortChanged(int i);
+
+private slots:
+ void changeKeySlot(int);
+ void changeKeyMenuSlot();
+ void searchOnText();
+
+private:
+ QPushButton *resetButton;
+ QToolButton *changeKeyButton;
+ QPopupMenu *keyMenu;
+ int totalKeys;
+ TableState *ts;
+
+ /* each type of possible data entry will be put on the stack */
+ QWidgetStack *ws;
+
+ /* include widgets for each type of data entry you need here. */
+ QLineEdit *textKey;
+ IntEdit *intKey;
+ DateEdit *dateKey;
+ TimeEdit *timeKey;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/commonwidgets.cpp b/noncore/apps/tableviewer/ui/commonwidgets.cpp
new file mode 100644
index 0000000..0b4f3c2
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/commonwidgets.cpp
@@ -0,0 +1,209 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <datebookmonth.h>
+#include <qpopupmenu.h>
+#include <qspinbox.h>
+#include "commonwidgets.h"
+
+DateEdit::DateEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 )
+ : QToolButton(parent, name)
+{
+ QPopupMenu *m1 = new QPopupMenu(this);
+ dateSelector = new DateBookMonth(m1, 0, TRUE);
+ m1->insertItem(dateSelector);
+ setPopup(m1);
+ setPopupDelay(0);
+
+ connect(dateSelector, SIGNAL(dateClicked(int, int, int)),
+ this, SLOT(subValueChanged()));
+
+ setText(dateSelector->selectedDate().toString());
+}
+
+
+DateEdit::~DateEdit() {}
+
+QDate DateEdit::date() const
+{
+ return dateSelector->selectedDate();
+}
+
+void DateEdit::setDate(QDate d)
+{
+ dateSelector->setDate(d.year(), d.month(), d.day());
+ setText(d.toString());
+}
+
+QSizePolicy DateEdit::sizePolicy() const
+{
+ QSizePolicy sp;
+ sp.setHorData(QToolButton::sizePolicy().horData());
+ sp.setVerData(QSizePolicy::Fixed);
+
+ return sp;
+}
+
+void DateEdit::clear()
+{
+ QDate today = QDate::currentDate();
+
+ dateSelector->setDate(today.year(), today.month(), today.day());
+ setText(today.toString());
+}
+
+void DateEdit::subValueChanged()
+{
+ QDate current = dateSelector->selectedDate();
+
+ setText(current.toString());
+ emit valueChanged(current);
+}
+
+TimeEdit::TimeEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 )
+ : QWidget(parent, name, f)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this, 0);
+
+ layout->addWidget(hourKey = new QSpinBox(1, 12, 1, this));
+ hourKey->setWrapping(true);
+ hourKey->setMinimumWidth(30);
+ hourKey->setMaximumWidth(35);
+
+ layout->addWidget(new QLabel(" : ", this));
+ layout->addWidget(minuteKey = new QSpinBox(0, 59, 1, this));
+ minuteKey->setWrapping(true);
+ minuteKey->setMinimumWidth(30);
+ minuteKey->setMaximumWidth(35);
+
+ layout->addWidget(new QLabel(" : ", this));
+ layout->addWidget(secondKey = new QSpinBox(0, 59, 1, this, 0));
+ secondKey->setWrapping(true);
+ secondKey->setMinimumWidth(30);
+ secondKey->setMaximumWidth(35);
+
+ layout->addWidget(ampm = new QComboBox(this));
+ ampm->insertItem("AM");
+ ampm->insertItem("PM");
+
+ layout->addStretch(-1);
+
+ clear();
+
+ connect(secondKey, SIGNAL(valueChanged(const QString&)),
+ this, SLOT(subValueChanged()));
+ connect(minuteKey, SIGNAL(valueChanged(const QString&)),
+ this, SLOT(subValueChanged()));
+ connect(hourKey, SIGNAL(valueChanged(const QString&)),
+ this, SLOT(subValueChanged()));
+ connect(ampm, SIGNAL(activated(int)),
+ this, SLOT(subValueChanged()));
+}
+
+
+TimeEdit::~TimeEdit() {}
+
+QTime TimeEdit::time() const
+{
+ int s,m,h;
+
+ s = secondKey->text().toInt();
+ m = minuteKey->text().toInt();
+ h = hourKey->text().toInt();
+
+ if(ampm->currentItem() == 1) {
+ /* pm */
+ h = h + 12;
+ }
+ /* hour now ranges 1->24 */
+
+ if (h == 12)
+ h = 0;
+ if (h == 24)
+ h = 12;
+
+ if(QTime::isValid(h, m, s))
+ return QTime(h, m, s);
+ return QTime(0, 0, 0);
+}
+
+void TimeEdit::setTime(QTime t)
+{
+ int h = t.hour();
+ secondKey->setValue(t.second());
+ minuteKey->setValue(t.minute());
+
+ /* h 0..23 */
+ if (h > 11) {
+ h -= 12;
+ ampm->setCurrentItem(1);
+ } else {
+ ampm->setCurrentItem(0);
+ }
+
+ if (h == 0) h = 12;
+ hourKey->setValue(h);
+}
+
+QSizePolicy TimeEdit::sizePolicy() const
+{
+ QSizePolicy sp;
+ sp.setHorData(QSizePolicy::Preferred);
+ sp.setVerData(QSizePolicy::Fixed);
+
+ return sp;
+}
+
+void TimeEdit::clear()
+{
+ secondKey->setValue(0);
+ minuteKey->setValue(0);
+ hourKey->setValue(12);
+
+ ampm->setCurrentItem(0);
+}
+
+void TimeEdit::subValueChanged()
+{
+ emit valueChanged(time());
+}
+
+IntEdit::IntEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 )
+ : QSpinBox(INT_MIN, INT_MAX, 1, parent, name)
+{
+ setValue(0);
+}
+
+
+IntEdit::~IntEdit() {}
+
+int IntEdit::value()
+{
+ return cleanText().toInt();
+}
+
+void IntEdit::clear()
+{
+ setValue(0);
+}
diff --git a/noncore/apps/tableviewer/ui/commonwidgets.h b/noncore/apps/tableviewer/ui/commonwidgets.h
new file mode 100644
index 0000000..2a9691f
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/commonwidgets.h
@@ -0,0 +1,98 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Dateedit_H
+#define Dateedit_H
+
+#include <qwidget.h>
+#include <qdatetime.h>
+
+/* inherited classes */
+#include <qtoolbutton.h>
+#include <qspinbox.h>
+
+class DateBookMonth;
+class QComboBox;
+
+class DateEdit : public QToolButton
+{
+ Q_OBJECT
+
+public:
+ DateEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~DateEdit();
+
+ QDate date() const;
+ void setDate(QDate);
+
+ QSizePolicy sizePolicy() const;
+signals:
+ void valueChanged(const QDate &);
+
+public slots:
+ void clear();
+private slots:
+ void subValueChanged();
+
+private:
+ DateBookMonth *dateSelector;
+};
+
+class TimeEdit : public QWidget
+{
+ Q_OBJECT
+
+public:
+ TimeEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~TimeEdit();
+
+ QTime time() const;
+ void setTime(QTime);
+
+ QSizePolicy sizePolicy() const;
+signals:
+ void valueChanged(const QTime &);
+
+public slots:
+ void clear();
+private slots:
+ void subValueChanged();
+
+private:
+ QSpinBox *secondKey;
+ QSpinBox *minuteKey;
+ QSpinBox *hourKey;
+ QComboBox *ampm;
+};
+
+/* more for consistency than need */
+class IntEdit : public QSpinBox
+{
+ Q_OBJECT
+
+public:
+ IntEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~IntEdit();
+
+ int value();
+
+public slots:
+ void clear();
+};
+#endif
diff --git a/noncore/apps/tableviewer/ui/filterkeyentry.cpp b/noncore/apps/tableviewer/ui/filterkeyentry.cpp
new file mode 100644
index 0000000..d108fbd
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/filterkeyentry.cpp
@@ -0,0 +1,208 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "filterkeyentry.h"
+#include "commonwidgets.h"
+
+#include <qwidgetstack.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qsizepolicy.h>
+#include <qdatetime.h>
+#include <qhbox.h>
+
+TVFilterKeyEntry::TVFilterKeyEntry(QWidget *parent, const char *name, WFlags f)
+ : QWidget(parent, name, f)
+{
+ int stack_elem = 0;
+
+ layout = new QHBoxLayout(this, 0);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ textEntry = new QHBox(this, 0);
+ textEntry->setSpacing(0);
+ textEntry->setMargin(0);
+
+ intEntry = new QHBox(this, 0);
+ intEntry->setSpacing(0);
+ intEntry->setMargin(0);
+
+ timeEntry = new QHBox(this, 0);
+ timeEntry->setSpacing(0);
+ timeEntry->setMargin(0);
+
+ dateEntry = new QHBox(this, 0);
+ dateEntry->setSpacing(0);
+ dateEntry->setMargin(0);
+
+ textCombo = new QComboBox(textEntry, 0);
+ textKey = new QLineEdit(textEntry, 0);
+
+ /* Build the text combo list */
+ textCombo->insertItem("less than");
+ textCombo->insertItem("more than");
+ textCombo->insertItem("equal to");
+ textCombo->insertItem("containing");
+ textCombo->insertItem("starting with");
+ textCombo->insertItem("ending with");
+
+ intCombo = new QComboBox(intEntry, 0);
+ intKey = new IntEdit(intEntry, 0);
+
+ /* Build the int combo list */
+ intCombo->insertItem("less than");
+ intCombo->insertItem("more than");
+ intCombo->insertItem("equal to");
+
+ timeCombo = new QComboBox(timeEntry, 0);
+ timeKey = new TimeEdit(timeEntry, 0);
+
+ /* Build the time combo list */
+ timeCombo->insertItem("less than");
+ timeCombo->insertItem("more than");
+ timeCombo->insertItem("equal to");
+
+ dateCombo = new QComboBox(dateEntry, 0);
+ dateKey = new DateEdit(dateEntry, 0);
+
+ /* Build the date combo list */
+ dateCombo->insertItem("less than");
+ dateCombo->insertItem("more than");
+ dateCombo->insertItem("equal to");
+
+ ts = 0;
+
+ ws = new QWidgetStack(this, 0);
+ ws->setMargin(0);
+ ws->addWidget(textEntry, TVVariant::String);
+ ws->addWidget(intEntry, TVVariant::Int);
+ ws->addWidget(timeEntry, TVVariant::Time);
+ ws->addWidget(dateEntry, TVVariant::Date);
+
+ /* connect the signals down */
+ connect(textKey, SIGNAL(textChanged(const QString&)),
+ this, SIGNAL(valueChanged()));
+ connect(intKey, SIGNAL(valueChanged(int)),
+ this, SIGNAL(valueChanged()));
+ connect(dateKey, SIGNAL(valueChanged(const QDate&)),
+ this, SIGNAL(valueChanged()));
+ connect(timeKey, SIGNAL(valueChanged(const QTime&)),
+ this, SIGNAL(valueChanged()));
+
+ connect(intCombo, SIGNAL(activated(int)), this, SIGNAL(valueChanged()));
+ connect(textCombo, SIGNAL(activated(int)), this, SIGNAL(valueChanged()));
+ connect(timeCombo, SIGNAL(activated(int)), this, SIGNAL(valueChanged()));
+ connect(dateCombo, SIGNAL(activated(int)), this, SIGNAL(valueChanged()));
+
+ ws->raiseWidget(TVVariant::String);
+ layout->addWidget(ws);
+
+ current_type = TVVariant::String;
+}
+
+/*!
+ Destructs the widget
+*/
+TVFilterKeyEntry::~TVFilterKeyEntry()
+{
+}
+
+void TVFilterKeyEntry::setKey(int i)
+{
+
+ if (!ts) return;
+ if (!ts->kRep) return;
+
+ /* set up to raise appropriate widget set */
+ if (current_type != ts->kRep->getKeyType(i)) {
+ current_type = ts->kRep->getKeyType(i);
+ ws->raiseWidget(current_type);
+ }
+}
+
+void TVFilterKeyEntry::setTableState(TableState *t) {
+ int i;
+ ts = t;
+ if(!t) return;
+ if (!t->kRep)
+ return;
+ if (t->kRep->getNumFields() < 1)
+ return;
+ setKey(0);
+ /* set up the the menu stuff.. */
+}
+
+CmpType TVFilterKeyEntry::getCompareType()
+{
+
+ switch(current_type) {
+ case TVVariant::String: {
+ CmpType k = (CmpType) textCombo->currentItem();
+ return k;
+ }
+ case TVVariant::Int: {
+ CmpType k = (CmpType) intCombo->currentItem();
+ return k;
+ }
+ case TVVariant::Time: {
+ CmpType k = (CmpType) timeCombo->currentItem();
+ return k;
+ }
+ case TVVariant::Date: {
+ CmpType k = (CmpType) dateCombo->currentItem();
+ return k;
+ }
+ default:
+ break;
+ }
+ return ct_equal;
+}
+
+/* MUST return a valid pointer */
+TVVariant TVFilterKeyEntry::getCompareValue()
+{
+ TVVariant sendkey;
+ int tmp;
+
+ switch(current_type) {
+ case TVVariant::String:
+ sendkey = TVVariant(QString(textKey->text()));
+ break;
+ case TVVariant::Int: {
+ sendkey = TVVariant(intKey->value());
+ break;
+ }
+ case TVVariant::Time: {
+ sendkey = TVVariant(QTime(timeKey->time()));
+ break;
+ }
+ case TVVariant::Date: {
+ sendkey = TVVariant(QDate(dateKey->date()));
+ break;
+ }
+ default: {
+ sendkey = TVVariant(0);
+ qWarning("TVFilterKeyEntry::getCompareValue() "
+ "cannot work out data type");
+ }
+ }
+ return sendkey;
+}
diff --git a/noncore/apps/tableviewer/ui/filterkeyentry.h b/noncore/apps/tableviewer/ui/filterkeyentry.h
new file mode 100644
index 0000000..260e250
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/filterkeyentry.h
@@ -0,0 +1,96 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef FilterKeyEntry_H
+#define FilterKeyEntry_H
+
+#include <qwidget.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include "../db/common.h"
+
+/* Forward class declarations */
+class QWidgetStack;
+class QToolButton;
+class QLineEdit;
+class DateEdit;
+class TimeEdit;
+class IntEdit;
+class QPopupMenu;
+class QComboBox;
+
+typedef enum _CmpType {
+ ct_less = 0,
+ ct_more,
+ ct_equal,
+ ct_contains,
+ ct_startswith,
+ ct_endswith
+} CmpType;
+
+
+class TVFilterKeyEntry: public QWidget
+{
+ Q_OBJECT
+public:
+ TVFilterKeyEntry( QWidget *parent = 0,
+ const char *name = 0, WFlags f = 0 );
+ ~TVFilterKeyEntry();
+
+ void setTableState(TableState *t);
+ void setKey(int i);
+
+ CmpType getCompareType();
+ TVVariant getCompareValue();
+
+signals:
+ void valueChanged();
+
+private:
+ /* include widgets for each type of data entry you need here. */
+ QLineEdit *textKey;
+ QComboBox *textCombo;
+ QHBox *textEntry;
+
+ IntEdit *intKey;
+ QComboBox *intCombo;
+ QHBox *intEntry;
+
+ TimeEdit *timeKey;
+ QComboBox *timeCombo;
+ QHBox *timeEntry;
+
+ DateEdit *dateKey;
+ QComboBox *dateCombo;
+ QHBox *dateEntry;
+
+ TableState *ts;
+
+ /* each type of possible data entry will be put on the stack */
+ QWidgetStack *ws;
+
+ /* This allows for the inherited functions dealing with prefered size
+ * etc to simply get the information from the layout.
+ */
+ QHBoxLayout *layout;
+
+ TVVariant::KeyType current_type;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/tvbrowseview.cpp b/noncore/apps/tableviewer/ui/tvbrowseview.cpp
new file mode 100644
index 0000000..f6da7b1
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvbrowseview.cpp
@@ -0,0 +1,122 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "tvbrowseview.h"
+#include "browsekeyentry.h"
+#include <qtoolbutton.h>
+#include <qtextview.h>
+#include <qtextbrowser.h>
+#include <qlayout.h>
+
+/*!
+ \class TVBrowseView
+ \brief The widget describing how to draw the browse view user interface
+
+ This widget allows for the user to browse through the table, one element
+ at a time, or search on a single key. Its main goal is to show a
+ single element in a readable format and make it easy for the user to
+ rapidly find specific elements in the table.
+*/
+
+/*!
+ Constructs a new TVBrowseView widget
+*/
+TVBrowseView::TVBrowseView(TableState *t, QWidget* parent = 0, const char *name = 0,
+ WFlags fl =0)
+{
+ if (!name)
+ setName("BrowseView");
+
+ setSizePolicy(QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding, 0, 0, sizePolicy().hasHeightForWidth() ) );
+ QVBoxLayout *vlayout = new QVBoxLayout(this);
+ textViewDisplay = new QTextBrowser(this, "textViewDisplay");
+ vlayout->addWidget( textViewDisplay );
+
+ keyEntry = new TVBrowseKeyEntry(this, "keyEntry");
+ vlayout->addWidget( keyEntry );
+
+ /* connect the signals down */
+
+ connect(keyEntry, SIGNAL(searchOnKey(int, TVVariant)),
+ this, SIGNAL(searchOnKey(int, TVVariant)));
+ connect(keyEntry, SIGNAL(sortChanged(int)),
+ this, SIGNAL(sortChanged(int)));
+
+ ts = t;
+ keyEntry->setTableState(t);
+}
+
+/*!
+ Destroys the TVBrowseView widget
+*/
+TVBrowseView::~TVBrowseView()
+{
+}
+
+void TVBrowseView::rebuildData()
+{
+ if(!ts)
+ return;
+ if(!ts->current_elem) {
+ /* also disable buttons */
+ textViewDisplay->setText("");
+ return;
+ }
+
+ setDisplayText(ts->current_elem);
+}
+
+/* Reset to initial state */
+void TVBrowseView::reset()
+{
+ textViewDisplay->setText("");
+ keyEntry->reset();
+}
+
+/*!
+ sets the data element to be displayed to element
+*/
+void TVBrowseView::setDisplayText(const DataElem *element)
+{
+ QString rep = "";
+
+ KeyListIterator it(*ts->kRep);
+
+ while (it.current()) {
+ if (element->hasValidValue(it.currentKey())) {
+ if(it.currentKey() == ts->current_column) {
+ rep += "<A name=\"ckey\"></A><B><FONT COLOR=#FF0000>"
+ + it.current()->name()
+ + ":</FONT></B> ";
+ } else {
+ rep += "<B>" + it.current()->name() + ":</B> ";
+ }
+ rep += element->toQString(it.currentKey()) + "<BR>";
+ }
+ ++it;
+ }
+
+ textViewDisplay->setText(rep);
+ textViewDisplay->scrollToAnchor("ckey");
+}
+
+void TVBrowseView::rebuildKeys()
+{
+ keyEntry->rebuildKeys();
+}
diff --git a/noncore/apps/tableviewer/ui/tvbrowseview.h b/noncore/apps/tableviewer/ui/tvbrowseview.h
new file mode 100644
index 0000000..1daff1c
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvbrowseview.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Tvbrowseview_H
+#define Tvbrowseview_H
+
+#include "../db/common.h"
+#include <qwidget.h>
+
+class QTextBrowser;
+class TVBrowseKeyEntry;
+
+class TVBrowseView : public QWidget
+{
+ Q_OBJECT
+
+signals:
+ void searchOnKey(int keyIndex, TVVariant keyValue);
+ void sortChanged(int);
+
+public:
+ TVBrowseView(TableState *t, QWidget* parent = 0,
+ const char* name = 0, WFlags fl = 0);
+ ~TVBrowseView();
+
+ /* Access Methods */
+ void setDisplayText(const DataElem *);
+ void rebuildKeys();
+ void rebuildData();
+ void reset();
+
+private:
+ TableState *ts;
+
+ QTextBrowser* textViewDisplay;
+ TVBrowseKeyEntry *keyEntry;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/tveditview.cpp b/noncore/apps/tableviewer/ui/tveditview.cpp
new file mode 100644
index 0000000..ba2bd06
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tveditview.cpp
@@ -0,0 +1,235 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+/* The edit view widget. For each key in the DB display an
+ * appropriate edit box, and a 'key' button to change that particular
+ * key information (delete or edit).
+ *
+ * Bottem line should be a 'new key' button. Should be able to scroll
+ * in both directions.
+ */
+
+#include "tveditview.h"
+#include "commonwidgets.h"
+
+#include <qlayout.h>
+#include <qgrid.h>
+#include <qvbox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qlist.h>
+#include <qlabel.h>
+#include <qscrollview.h>
+#include <qsignalmapper.h>
+
+TVEditView::TVEditView(TableState *s, DataElem *d, QWidget* parent = 0,
+ const char *name = 0, WFlags fl =0) : QDialog(parent, name, true, fl)
+{
+ if (!name)
+ setName("TVEditView");
+
+ QVBoxLayout *layout = new QVBoxLayout(this, 0); /* only so that will resize
+ correctly in other
+ widgets */
+
+ toggles = new QSignalMapper(this);
+ QScrollView *sv = new QScrollView(this, 0);
+ sv->setResizePolicy(QScrollView::AutoOneFit);
+
+ layout->addWidget(sv);
+
+ editDisplay = new QGrid(3, sv, 0);
+ editDisplay->setSpacing(3);
+ sv->addChild(editDisplay);
+
+ connect(toggles, SIGNAL(mapped(int)), this, SLOT(toggleEnabled(int)));
+
+ setData(s, d);
+#ifdef Q_WS_QWS
+ showMaximized();
+#endif
+}
+
+TVEditView::~TVEditView()
+{
+}
+
+/*! set up the widgets in the grid, Set up initial values */
+void TVEditView::setData(TableState *t, DataElem *d)
+{
+
+ /* TODO need to somehow clear old children... a delete of each
+ * child? */
+ keyIds.clear();
+
+ KeyListIterator it(*t->kRep);
+
+ int i = 0;
+ while(it.current()) {
+ if (t->kRep->validIndex(it.currentKey())) {
+ new QLabel(it.current()->name(), editDisplay);
+ keyIds.insert(i, it.currentKey());
+ if (d->hasValidValue(it.currentKey())) {
+ switch(it.current()->type()) {
+ case TVVariant::String: {
+ QLineEdit *edit = new QLineEdit(editDisplay, 0);
+ edit->setText(d->getField(it.currentKey()).toString());
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Int: {
+ IntEdit *edit = new IntEdit(editDisplay, 0);
+ edit->setValue(d->getField(it.currentKey()).toInt());
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Time: {
+ TimeEdit *edit = new TimeEdit(editDisplay, 0);
+ edit->setTime(d->getField(it.currentKey()).toTime());
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Date: {
+ DateEdit *edit = new DateEdit(editDisplay, 0);
+ edit->setDate(d->getField(it.currentKey()).toDate());
+ edits.append(edit);
+ break;
+ }
+ default:
+ edits.append(new QLabel("<B><I>Uknown key type</I></B>", editDisplay));
+ }
+ QCheckBox *tb = new QCheckBox(editDisplay);
+ tb->setChecked(TRUE);
+ toggles->setMapping(tb, i);
+ connect(tb, SIGNAL(clicked()), toggles, SLOT(map()));
+ buttons.append(tb);
+ } else {
+ /* No valid value.. set to null */
+ switch(it.current()->type()) {
+ case TVVariant::String: {
+ QLineEdit *edit = new QLineEdit(editDisplay, 0);
+ edit->setEnabled(false);
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Int: {
+ IntEdit *edit = new IntEdit(editDisplay, 0);
+ edit->setEnabled(false);
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Time: {
+ TimeEdit *edit = new TimeEdit(editDisplay, 0);
+ edit->setEnabled(false);
+ edits.append(edit);
+ break;
+ }
+ case TVVariant::Date: {
+ DateEdit *edit = new DateEdit(editDisplay, 0);
+ edit->setEnabled(false);
+ edits.append(edit);
+ break;
+ }
+ default:
+ edits.append(new QLabel("<B><I>Uknown key type</I></B>", editDisplay));
+ }
+ QCheckBox *tb = new QCheckBox(editDisplay);
+ tb->setChecked(FALSE);
+ toggles->setMapping(tb, i);
+ connect(tb, SIGNAL(clicked()), toggles, SLOT(map()));
+ buttons.append(tb);
+ }
+ i++;
+ }
+ ++it;
+ }
+ num_edits = i;
+}
+
+void TVEditView::toggleEnabled(int i) {
+
+ if(edits.at(i)->isEnabled()) {
+ edits.at(i)->setEnabled(false);
+ buttons.at(i)->setChecked(FALSE);
+ } else {
+ edits.at(i)->setEnabled(true);
+ buttons.at(i)->setChecked(TRUE);
+ }
+}
+
+bool TVEditView::openEditItemDialog(TableState *ts, DataElem *d,
+ QWidget *parent)
+{
+ int i;
+ int keyId;
+
+ if(!ts) return 0;
+ if(!d) return 0;
+ if(!ts->kRep) return 0;
+
+ TVEditView *dlg = new TVEditView(ts, d, parent);
+
+ if (dlg->exec() == QDialog::Accepted ) {
+ /* update the element, basically for each
+ edits, if isEnabled, set Value, else unsetField */
+
+ for(i = 0; i < dlg->num_edits; i++) {
+ keyId = dlg->keyIds[i];
+ if(dlg->edits.at(i)->isEnabled()) {
+ switch(d->getFieldType(keyId)) {
+ case TVVariant::String: {
+ TVVariant value = TVVariant(
+ ((QLineEdit *)dlg->edits.at(i))->text());
+ d->setField(keyId, value);
+ break;
+ }
+ case TVVariant::Int: {
+ TVVariant value = TVVariant(
+ ((IntEdit *)dlg->edits.at(i))->value());
+ d->setField(keyId, value);
+ break;
+ }
+ case TVVariant::Time: {
+ TVVariant value = TVVariant(
+ ((TimeEdit *)dlg->edits.at(i))->time());
+ d->setField(keyId, value);
+ break;
+ }
+ case TVVariant::Date: {
+ TVVariant value = TVVariant(
+ ((DateEdit *)dlg->edits.at(i))->date());
+ d->setField(keyId, value);
+ break;
+ }
+ default:
+ break;
+ }
+ } else {
+ /* unset the field */
+ d->unsetField(keyId);
+ }
+ }
+ delete dlg;
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/noncore/apps/tableviewer/ui/tveditview.h b/noncore/apps/tableviewer/ui/tveditview.h
new file mode 100644
index 0000000..94c51d9
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tveditview.h
@@ -0,0 +1,62 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef Tveditview_H
+#define Tveditview_H
+
+#include <qwidget.h>
+#include <qlist.h>
+#include <qdialog.h>
+#include <qmap.h>
+#include "../db/common.h"
+
+class QGrid;
+class QSignalMapper;
+class QCheckBox;
+
+class TVEditView : public QDialog
+{
+ Q_OBJECT
+
+public:
+ TVEditView(TableState *s, DataElem *d, QWidget* parent = 0,
+ const char* name = 0, WFlags fl = 0);
+ ~TVEditView();
+
+ static bool openEditItemDialog(TableState *s, DataElem *d, QWidget *parent);
+
+protected slots:
+ void toggleEnabled(int);
+
+protected:
+
+ void setData(TableState *s, DataElem *d);
+
+ QGrid *editDisplay;
+ QList<QWidget> edits;
+ QList<QCheckBox> buttons;
+ QSignalMapper *toggles;
+
+ QMap<int,int> keyIds;
+
+ int num_edits;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/tvfilterview.cpp b/noncore/apps/tableviewer/ui/tvfilterview.cpp
new file mode 100644
index 0000000..72d39d6
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvfilterview.cpp
@@ -0,0 +1,304 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "tvfilterview.h"
+#include <qtoolbutton.h>
+#include <qcombobox.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qheader.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+
+TVFilterView::TVFilterView(TableState *t, QWidget* parent = 0,
+ const char *name = 0, WFlags fl =0) : QDialog(parent, name, TRUE, fl)
+{
+ if ( !name )
+ setName( "Filter View" );
+
+ QVBoxLayout *vlayout = new QVBoxLayout(this);
+
+ display = new QListView(this, "display");
+ display->addColumn("Key");
+ display->addColumn("Constraint");
+ display->addColumn("Value");
+ display->header()->setClickEnabled(FALSE);
+ display->header()->setResizeEnabled(FALSE);
+
+ vlayout->addWidget(display);
+
+ QHBoxLayout *hlayout = new QHBoxLayout;
+ hlayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ newFilterButton = new QPushButton(this, "new Filter");
+ newFilterButton->setMaximumSize(QSize(50, 32767));
+ newFilterButton->setText("New");
+ hlayout->addWidget(newFilterButton);
+
+ deleteFilterButton = new QPushButton(this, "delete Filter");
+ deleteFilterButton->setMaximumSize(QSize(50, 32767));
+ deleteFilterButton->setText("Delete");
+ hlayout->addWidget(deleteFilterButton);
+
+ clearFilterButton = new QPushButton(this, "delete Filter");
+ clearFilterButton->setMaximumSize(QSize(60, 32767));
+ clearFilterButton->setText("Clear All");
+ hlayout->addWidget(clearFilterButton);
+
+ vlayout->addLayout(hlayout);
+
+ QHBoxLayout *hlayout2 = new QHBoxLayout;
+
+ keyNameCombo = new QComboBox(FALSE, this, "key name");
+ keyNameCombo->setEnabled(FALSE);
+ hlayout2->addWidget(keyNameCombo);
+
+ QLabel *label = new QLabel(this);
+ label->setText("has value");
+ hlayout2->addWidget(label);
+
+ keyEntry = new TVFilterKeyEntry(this, "key entry");
+ keyEntry->setEnabled(FALSE);
+
+ vlayout->addLayout(hlayout2);
+ vlayout->addWidget(keyEntry);
+
+ connect(newFilterButton, SIGNAL( clicked() ), this, SLOT( newTerm() ));
+ connect(deleteFilterButton, SIGNAL( clicked() ), this, SLOT( deleteTerm()));
+ connect(clearFilterButton, SIGNAL( clicked() ), this, SLOT( clearTerms()));
+
+ connect(keyEntry, SIGNAL(valueChanged()), this, SLOT( updateTerm() ));
+ connect(keyNameCombo, SIGNAL(activated(int)), this, SLOT( updateTerm() ));
+
+ connect(display, SIGNAL(selectionChanged(QListViewItem*)), this,
+ SLOT(setTerm(QListViewItem *)));
+
+ ts = t;
+ current = 0;
+ terms.setAutoDelete(true);
+ do_filter = false;
+
+#ifdef Q_WS_QWS
+ showMaximized();
+#endif
+}
+
+/*!
+ Destroys the TVFilterView widget
+*/
+TVFilterView::~TVFilterView()
+{
+}
+
+void TVFilterView::rebuildData()
+{
+}
+
+void TVFilterView::reset()
+{
+ keyNameCombo->clear();
+ keyIds.clear();
+}
+
+void TVFilterView::rebuildKeys()
+{
+ int i;
+
+ if (!ts) return;
+ if(!ts->kRep) return;
+ keyEntry->setTableState(ts);
+
+ /* set up the list of keys that can be compared on */
+ keyNameCombo->clear();
+ KeyListIterator it(*ts->kRep);
+
+ i = 0;
+ while(it.current()) {
+ if(ts->kRep->validIndex(it.currentKey())) {
+ keyNameCombo->insertItem(it.current()->name());
+ keyIds.insert(i, it.currentKey());
+ ++i;
+ }
+ ++it;
+ }
+}
+
+bool TVFilterView::passesFilter(DataElem *d) {
+ if (!filterActive()) return true;
+
+
+ FilterTerm *t;
+
+ for (t = terms.first(); t != 0; t = terms.next() ) {
+ /* check against filter */
+ switch(t->ct) {
+ case ct_less:
+ if (!d->lessThan(t->keyIndex, t->value))
+ return false;
+ break;
+ case ct_more:
+ if (!d->moreThan(t->keyIndex, t->value))
+ return false;
+ break;
+ case ct_equal:
+ if (!d->equalTo(t->keyIndex, t->value))
+ return false;
+ break;
+ case ct_contains:
+ if (!d->contains(t->keyIndex, t->value))
+ return false;
+ break;
+ case ct_startswith:
+ if (!d->startsWith(t->keyIndex, t->value))
+ return false;
+ break;
+ case ct_endswith:
+ if (!d->endsWith(t->keyIndex, t->value))
+ return false;
+ break;
+ default:
+ qWarning("TVFilterView::passesFilter() "
+ "unrecognized filter type");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TVFilterView::filterActive() const
+{
+ /* when button operated, also check the do_filter value
+ return do_filter;
+ */
+ if (terms.isEmpty())
+ return false;
+ return true;
+}
+
+/* SLOTS */
+void TVFilterView::newTerm()
+{
+ if (!ts) return;
+
+ FilterTerm *term = new FilterTerm;
+ current = term;
+
+ term->view = 0;
+
+ updateTerm();
+
+ display->setSelected(term->view, true);
+ terms.append(term);
+
+ keyEntry->setEnabled(true);
+ keyNameCombo->setEnabled(true);
+}
+
+void TVFilterView::updateTerm()
+{
+ FilterTerm *term;
+ /* Read the widget values (keyname, compare type, value)
+ * and build the lists */
+ if (!ts) return;
+ if (!current) return;
+
+ QString keyString;
+ QString cmpString;
+ QString vString;
+
+ term = current;
+
+ /* create new list item, set initial values, enable widgets */
+ term->keyIndex = keyIds[keyNameCombo->currentItem()];
+ keyEntry->setKey(term->keyIndex); /* so the next two items make sense */
+ term->ct = keyEntry->getCompareType(),
+ term->value = keyEntry->getCompareValue();
+
+ keyString = keyNameCombo->currentText();
+
+ switch(term->ct) {
+ case ct_less:
+ cmpString = " less than ";
+ break;
+ case ct_more:
+ cmpString = " more than ";
+ break;
+ case ct_equal:
+ cmpString = " equal to ";
+ break;
+ case ct_contains:
+ cmpString = " containing ";
+ break;
+ case ct_startswith:
+ cmpString = " starting with ";
+ break;
+ case ct_endswith:
+ cmpString = " ending with ";
+ break;
+ default:
+ cmpString = " ERROR ";
+ }
+
+ vString = term->value.toString();
+
+ /* remove old view */
+ if (term->view)
+ delete(term->view);
+ term->view = new QListViewItem(display, 0, keyString, cmpString, vString);
+ display->setSelected(term->view, true);
+}
+
+/* deletes current term */
+void TVFilterView::deleteTerm()
+{
+ if(!current) return;
+ if (current->view)
+ delete(current->view);
+
+ terms.removeRef(current);
+
+ current = terms.first();
+
+ if(terms.isEmpty()) {
+ keyEntry->setEnabled(false);
+ keyNameCombo->setEnabled(false);
+ }
+}
+
+/* clears all terminations */
+void TVFilterView::clearTerms()
+{
+ while(current)
+ deleteTerm();
+}
+
+void TVFilterView::setTerm(QListViewItem *target)
+{
+ /* Iterate through the list to find item with view=target..
+ * set as current, delete */
+ FilterTerm *term = current;
+
+ for (current = terms.first(); current != 0; current = terms.next() )
+ if (current->view == target)
+ break;
+
+ if (!current) {
+ current = term;
+ }
+}
diff --git a/noncore/apps/tableviewer/ui/tvfilterview.h b/noncore/apps/tableviewer/ui/tvfilterview.h
new file mode 100644
index 0000000..5de87b9
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvfilterview.h
@@ -0,0 +1,88 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Tvfilterview_H
+#define Tvfilterview_H
+
+#include "filterkeyentry.h"
+#include "../db/common.h"
+#include <qlist.h>
+#include <qmap.h>
+#include <qdialog.h>
+
+class QListViewItem;
+class QPushButton;
+class QListView;
+class TVFilterKeyEntry;
+
+class TVFilterView : public QDialog
+{
+ Q_OBJECT
+
+signals:
+ void editView();
+ void listView();
+ void browseView();
+ void loadFile();
+
+protected slots:
+ void newTerm();
+ void deleteTerm();
+ void clearTerms();
+ void updateTerm();
+ void setTerm(QListViewItem *);
+
+public:
+ TVFilterView(TableState *t, QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
+ ~TVFilterView();
+
+ /* Access Methods */
+ void rebuildKeys();
+ void rebuildData();
+ void reset();
+
+ bool passesFilter(DataElem *d);
+ bool filterActive() const; /* return true if and only if filtering is on */
+
+ QListView* display;
+ QPushButton* newFilterButton;
+ QPushButton* deleteFilterButton;
+ QPushButton* clearFilterButton;
+ QComboBox* keyNameCombo;
+
+ TVFilterKeyEntry* keyEntry;
+private:
+
+ typedef struct _FilterTerm {
+ int keyIndex;
+ CmpType ct;
+ TVVariant value;
+ QListViewItem *view;
+ } FilterTerm;
+
+ QList<FilterTerm> terms;
+ FilterTerm *current;
+ bool do_filter;
+
+ TableState *ts;
+
+ QMap<int, int> keyIds;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/tvkeyedit.cpp b/noncore/apps/tableviewer/ui/tvkeyedit.cpp
new file mode 100644
index 0000000..fb7b7fe
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvkeyedit.cpp
@@ -0,0 +1,254 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "tvkeyedit.h"
+#include <qtoolbutton.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qlistview.h>
+#include <qmessagebox.h>
+#include <stdlib.h>
+#include <qpushbutton.h>
+
+/* QList view item... ?? that can store and update the values that I will
+ * be changing */
+
+class TVKEListViewItem : public QListViewItem
+{
+public:
+ TVKEListViewItem(QString n, TVVariant::KeyType kt, int p, QListView *parent) :
+ QListViewItem(parent)
+ {
+ name = n;
+ keyType = kt;
+ position = p;
+ }
+
+ QString text(int i) const
+ {
+ if(i) {
+ return TVVariant::typeToName(keyType);
+ }
+ return name;
+ }
+
+ /* always sort by key index, ignore i */
+ QString key(int, bool) const
+ {
+ return QString().sprintf("%08d", position);
+ }
+
+ void setText(int i, const QString &)
+ {
+ ;
+ }
+
+ QString getName() const
+ {
+ return name;
+ }
+
+ void setName(QString n)
+ {
+ name = n;
+ repaint();
+ }
+
+ TVVariant::KeyType getKeyType() const
+ {
+ return keyType;
+ }
+
+ void setKeyType(TVVariant::KeyType k)
+ {
+ keyType = k;
+ repaint();
+ }
+
+ inline int getPos() const
+ {
+ return position;
+ }
+
+private:
+ QString name;
+ TVVariant::KeyType keyType;
+ int position;
+};
+
+TVKeyEdit::TVKeyEdit(TableState *t, QWidget* parent = 0, const char *name = 0,
+ WFlags fl = 0) : TVKeyEdit_gen(parent, name, true, fl)
+{
+ int i;
+ ts = t;
+
+ if(!ts) return;
+ if(!ts->kRep) return;
+
+ working_state = *ts->kRep;
+
+ i = 1;
+ keyTypeEdit->insertItem(TVVariant::typeToName((TVVariant::KeyType)i));
+ i++;
+ keyTypeEdit->insertItem(TVVariant::typeToName((TVVariant::KeyType)i));
+ i++;
+ keyTypeEdit->insertItem(TVVariant::typeToName((TVVariant::KeyType)i));
+ i++;
+ keyTypeEdit->insertItem(TVVariant::typeToName((TVVariant::KeyType)i));
+
+ KeyListIterator it(*ts->kRep);
+ while(it.current()) {
+ if(t->kRep->validIndex(it.currentKey())) {
+ new TVKEListViewItem(it.current()->name(),
+ it.current()->type(),
+ it.currentKey(),
+ display);
+ }
+ ++it;
+ }
+ num_keys = ts->kRep->getNumFields();
+ if(display->childCount() > 0) {
+ display->setCurrentItem(display->firstChild());
+ setTerm(display->currentItem());
+ } else {
+ deleteKeyButton->setEnabled(FALSE);
+ clearKeysButton->setEnabled(FALSE);
+ keyNameEdit->setEnabled(FALSE);
+ keyTypeEdit->setEnabled(FALSE);
+ }
+
+ display->setSorting(0);
+#ifdef Q_WS_QWS
+ showMaximized();
+#endif
+}
+
+/*!
+ Destroys the TVKeyEdit widget
+*/
+TVKeyEdit::~TVKeyEdit()
+{
+}
+
+/* SLOTS */
+void TVKeyEdit::newTerm()
+{
+ /* new item, make current Item */
+ int i;
+
+ i = working_state.addKey("<New Key>", TVVariant::String);
+ //working_state.setNewFlag(i, TRUE);
+ TVKEListViewItem *nItem = new TVKEListViewItem("<New Key>",
+ TVVariant::String,
+ i,
+ display);
+ display->setCurrentItem(nItem);
+ setTerm(nItem);
+
+ num_keys++;
+ if(display->childCount() == 1) {
+ deleteKeyButton->setEnabled(TRUE);
+ clearKeysButton->setEnabled(TRUE);
+ keyNameEdit->setEnabled(TRUE);
+ keyTypeEdit->setEnabled(TRUE);
+ }
+}
+
+void TVKeyEdit::updateTerm(const QString &newName)
+{
+ /* TODO if name matches a deleted term, prompt for
+ renewing old data instead */
+ TVKEListViewItem *i = (TVKEListViewItem *)display->currentItem();
+ if(i) {
+ i->setName(newName);
+ working_state.setKeyName(i->getPos(), newName);
+ }
+}
+
+void TVKeyEdit::updateTerm(int t)
+{
+ /* t is an index to a combo in a menu, NOT a type */
+ t++; /* menu counts from 0, types count from 1 */
+ TVKEListViewItem *i = (TVKEListViewItem *)display->currentItem();
+ if (i) {
+ i->setKeyType((TVVariant::KeyType)t);
+ working_state.setKeyType(i->getPos(), (TVVariant::KeyType)t);
+ }
+}
+
+/* deletes current term
+ * really just marks key as deleted so is now invalid.
+ * the actual delete will happen when data is 'cleaned'
+ * or when file is saved.
+ */
+
+void TVKeyEdit::deleteTerm()
+{
+ TVKEListViewItem *i = (TVKEListViewItem *)display->currentItem();
+ if (i) {
+ working_state.setDeleteFlag(i->getPos(), TRUE);
+ delete i;
+ }
+ if(!display->childCount()) {
+ /* disable the delete and clear buttons, etc */
+ deleteKeyButton->setEnabled(FALSE);
+ clearKeysButton->setEnabled(FALSE);
+ keyNameEdit->setEnabled(FALSE);
+ keyTypeEdit->setEnabled(FALSE);
+ }
+}
+
+/* clears all terminations */
+void TVKeyEdit::clearTerms()
+{
+ /* should pop up a warning */
+ if (QMessageBox::warning(this, "Delete all keys",
+ "Are you sure you want to\ndelete all the keys?",
+ "Yes", "No") == 0)
+ {
+ while(display->currentItem())
+ deleteTerm();
+ }
+}
+
+void TVKeyEdit::setTerm(QListViewItem *target)
+{
+ /* need to update the widgets to show keys values */
+ keyNameEdit->setText(((TVKEListViewItem *)target)->getName());
+ int t = (int)(((TVKEListViewItem *)target)->getKeyType());
+ t--;
+ keyTypeEdit->setCurrentItem(t);
+}
+
+KeyList* TVKeyEdit::openEditKeysDialog(TableState *t, QWidget *parent = 0)
+{
+ if(!t)
+ return 0;
+ if(!t->kRep)
+ return 0;
+
+ TVKeyEdit *dlg = new TVKeyEdit(t, parent);
+
+ if ((dlg->exec() == QDialog::Accepted) &&
+ (dlg->working_state != *t->kRep))
+ {
+ return (new KeyList(dlg->working_state));
+ }
+ return 0;
+}
diff --git a/noncore/apps/tableviewer/ui/tvkeyedit.h b/noncore/apps/tableviewer/ui/tvkeyedit.h
new file mode 100644
index 0000000..5e80b66
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvkeyedit.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Tvkeyedit_H
+#define Tvkeyedit_H
+
+#include "tvkeyedit_gen.h"
+#include "../db/common.h"
+
+class TVKeyEdit : public TVKeyEdit_gen
+{
+ Q_OBJECT
+
+signals:
+ void listView();
+ void browseView();
+
+protected slots:
+ void newTerm();
+ void deleteTerm();
+ void clearTerms();
+ void updateTerm(int);
+ void updateTerm(const QString &);
+ void setTerm(QListViewItem *);
+
+public:
+ TVKeyEdit(TableState *ts, QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
+ ~TVKeyEdit();
+
+
+ static KeyList *openEditKeysDialog(TableState *ts, QWidget *parent);
+
+private:
+
+ TableState *ts;
+ int num_keys;
+ KeyList working_state;
+};
+
+#endif
diff --git a/noncore/apps/tableviewer/ui/tvkeyedit_gen.ui b/noncore/apps/tableviewer/ui/tvkeyedit_gen.ui
new file mode 100644
index 0000000..5c19d06
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvkeyedit_gen.ui
@@ -0,0 +1,239 @@
+<!DOCTYPE UI><UI>
+<class>TVKeyEdit_gen</class>
+<comment>Dialog for editing the keys and key types</comment>
+<author>Ian Walters</author>
+<forward>class QListViewItem;</forward>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TVKeyEdit_gen</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>194</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>TableViewer - Edit Keys</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Key Name</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>false</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Key Type</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>false</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>false</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>display</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>newKeyButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>50</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>New</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>deleteKeyButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>50</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Delete</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>clearKeysButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>60</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Clear All</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>keyNameEdit</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>keyTypeEdit</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>newKeyButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>newTerm()</slot>
+ </connection>
+ <connection>
+ <sender>deleteKeyButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>deleteTerm()</slot>
+ </connection>
+ <connection>
+ <sender>clearKeysButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>clearTerms()</slot>
+ </connection>
+ <connection>
+ <sender>display</sender>
+ <signal>selectionChanged(QListViewItem*)</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>setTerm(QListViewItem *)</slot>
+ </connection>
+ <connection>
+ <sender>keyNameEdit</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>updateTerm(const QString &amp;)</slot>
+ </connection>
+ <connection>
+ <sender>keyTypeEdit</sender>
+ <signal>activated(int)</signal>
+ <receiver>TVKeyEdit_gen</receiver>
+ <slot>updateTerm(int)</slot>
+ </connection>
+ <slot access="protected">clearTerms()</slot>
+ <slot access="protected">deleteTerm()</slot>
+ <slot access="protected">newTerm()</slot>
+ <slot access="public">new_slot()</slot>
+ <slot access="protected">setTerm(QListViewItem *)</slot>
+ <slot access="protected">updateTerm(int)</slot>
+ <slot access="protected">updateTerm(const QString &amp;)</slot>
+</connections>
+</UI>
diff --git a/noncore/apps/tableviewer/ui/tvlistview.cpp b/noncore/apps/tableviewer/ui/tvlistview.cpp
new file mode 100644
index 0000000..82d67c6
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvlistview.cpp
@@ -0,0 +1,315 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "tvlistview.h"
+#include "../db/common.h"
+#include <qtoolbutton.h>
+#include <qlistview.h>
+#include <qlayout.h>
+
+void TVListViewPrivate::setColumnWidth(int column, int width)
+{
+ if(width > 70) width = 70;
+ QListView::setColumnWidth(column, width);
+}
+
+void TVListViewPrivate::setSorting(int column, bool increasing)
+{
+ emit sortChanged(column);
+ QListView::setSorting(column, increasing);
+}
+
+TVListViewPrivate::TVListViewPrivate(QWidget *parent, const char* name,
+ WFlags fl) : QListView(parent, name, fl) {
+ ;
+}
+
+class TVListViewItem : public QListViewItem
+{
+public:
+
+ TVListViewItem(QListView *parent, DataElem *d);
+ ~TVListViewItem();
+
+ QString text(int i) const
+ {
+ return data_reference->toQString(i);
+ }
+
+ /* Do nothing... all data for this item should be generated */
+ void setText(int i, const QString &)
+ {
+ ;
+ }
+ QString key(int i, bool a) const
+ {
+ return data_reference->toSortableQString(i);
+ }
+
+ void setDataElem(DataElem *d)
+ {
+ data_reference = d;
+ }
+
+ DataElem *getDataElem() {
+ return data_reference;
+ }
+private:
+ DataElem *data_reference;
+};
+
+TVListViewItem::TVListViewItem(QListView *parent, DataElem *d)
+ : QListViewItem(parent)
+{
+ data_reference = d;
+}
+
+TVListViewItem::~TVListViewItem()
+{
+ data_reference = 0;
+}
+
+TVListView::TVListView(TableState *t, QWidget* parent = 0,
+ const char *name = 0, WFlags fl =0) : QWidget(parent, name, fl)
+{
+ if (!name)
+ setName("TVListView");
+
+ // the next two lines need to be rationalized.
+ resize(318,457);
+ setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
+ (QSizePolicy::SizeType)7, sizePolicy().hasHeightForWidth()));
+ setCaption(tr("List View"));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ listViewDisplay = new TVListViewPrivate(this, "listViewDisplay");
+ layout->addWidget(listViewDisplay);
+
+ connect(listViewDisplay, SIGNAL(currentChanged(QListViewItem *)), this,
+ SLOT(setCurrent(QListViewItem *)));
+ connect(listViewDisplay, SIGNAL(sortChanged(int)), this,
+ SLOT(setSorting(int)));
+
+ listViewDisplay->setShowSortIndicator(true);
+
+ it = new QListViewItemIterator(listViewDisplay);
+ ts = t;
+}
+
+TVListView::~TVListView()
+{
+}
+
+void TVListView::addItem(DataElem *d)
+{
+ TVListViewItem *i = new TVListViewItem(listViewDisplay, d);
+
+ delete it;
+ it = new QListViewItemIterator(i);
+}
+
+/* remove current (it) item */
+void TVListView::removeItem()
+{
+ QListViewItemIterator other(*it);
+
+ QListViewItemIterator tmp = *it;
+ (*it)++;
+ if (!it->current()) {
+ *it = tmp;
+ (*it)--;
+ if (!it->current()) {
+ delete it;
+ it = 0;
+ }
+ }
+
+ delete other.current();
+}
+
+void TVListView::clearItems()
+{
+ /* This is ok since the destructor for TVListItem does not know about
+ the data_reference pointer.. and hence will leave it alone */
+ listViewDisplay->clear();
+ delete it;
+ it = new QListViewItemIterator(listViewDisplay);
+}
+
+void TVListView::first()
+{
+ delete it;
+ it = new QListViewItemIterator(listViewDisplay);
+}
+
+void TVListView::last()
+{
+ qWarning("TVListView::last not yet implemented");
+}
+
+void TVListView::next()
+{
+ QListViewItemIterator tmp = *it;
+ (*it)++;
+ if (!it->current()) {
+ *it = tmp;
+ }
+}
+
+void TVListView::previous()
+{
+ QListViewItemIterator tmp = *it;
+ (*it)--;
+ if (!it->current()) {
+ *it = tmp;
+ }
+}
+
+DataElem *TVListView::getCurrentData() {
+ if (it->current()) {
+ return ((TVListViewItem *)it->current())->getDataElem();
+ }
+ return NULL;
+}
+
+/*! Now to implement the closest match function */
+void TVListView::findItem(int keyId, TVVariant value)
+{
+ QListViewItem *i;
+ TVListViewItem *best_so_far = NULL;
+ /* start at the beginning... go through till find the closest elem */
+ i = listViewDisplay->firstChild();
+ while (i) {
+ /* search stuff */
+ if(best_so_far) {
+ if (DataElem::closer(
+ ((TVListViewItem *)i)->getDataElem(),
+ best_so_far->getDataElem(), value, keyId))
+ best_so_far = (TVListViewItem *)i;
+ } else {
+ if (DataElem::closer(
+ ((TVListViewItem *)i)->getDataElem(),
+ NULL, value, keyId))
+ best_so_far = (TVListViewItem *)i;
+ }
+
+ i = i->itemBelow();
+ }
+ if (best_so_far) {
+ /* set best_so_far to current element */
+ delete it;
+ it = new QListViewItemIterator(best_so_far);
+ }
+}
+
+void TVListView::rebuildKeys()
+{
+ int i;
+ if(!ts) return;
+ if(!ts->kRep) return;
+
+ i = listViewDisplay->columns();
+
+ while(i > 0)
+ listViewDisplay->removeColumn(--i);
+
+ KeyListIterator kit(*ts->kRep);
+ i = 0;
+ while(kit.current()) {
+ if(!kit.current()->delFlag()) {
+ listViewDisplay->addColumn(kit.current()->name());
+ keyIds.insert(i, kit.currentKey());
+ ++i;
+ }
+ ++kit;
+ }
+}
+
+
+void TVListView::setSorting(int column)
+{
+ /* Without table state can't do anything */
+ if (ts == 0)
+ return;
+ if (keyIds[column] != ts->current_column) {
+ ts->current_column = keyIds[column];
+ }
+}
+
+void TVListView::rebuildData() {
+ int i;
+ QMap<int, int>::Iterator kit;
+ /* Need to set sort order */
+ if(!ts)
+ return;
+
+ /* revers lookup the column */
+ i = -1;
+ for(kit = keyIds.begin(); kit != keyIds.end(); ++kit) {
+ if (kit.data() == ts->current_column) {
+ i = kit.key();
+ break;
+ }
+ }
+ if (i == -1)
+ return;
+
+ listViewDisplay->setSorting(i);
+ listViewDisplay->sort();
+
+ /* reset current element */
+ listViewDisplay->setCurrentItem(it->current());
+ listViewDisplay->setSelected(it->current(), true);
+ listViewDisplay->ensureItemVisible(it->current());
+}
+
+void TVListView::reset()
+{
+ int i;
+ listViewDisplay->clear();
+
+ i = listViewDisplay->columns();
+ while (i > 0)
+ listViewDisplay->removeColumn(--i);
+
+ keyIds.clear();
+}
+
+void TVListView::setCurrent(QListViewItem *i)
+{
+ /* cast */
+ TVListViewItem *t = (TVListViewItem *)i;
+
+ if(!t) {
+ /* set current to null */
+ ts->current_elem = 0;
+ return;
+ }
+
+ ts->current_elem = t->getDataElem();
+ /* now also set up the iterator */
+
+ delete it;
+ it = new QListViewItemIterator(i);
+
+ //emit browseView();
+}
diff --git a/noncore/apps/tableviewer/ui/tvlistview.h b/noncore/apps/tableviewer/ui/tvlistview.h
new file mode 100644
index 0000000..26bc299
--- a/dev/null
+++ b/noncore/apps/tableviewer/ui/tvlistview.h
@@ -0,0 +1,92 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef Tvlistview_H
+#define Tvlistview_H
+
+#include "../db/common.h"
+#include <qlistview.h>
+#include <qmap.h>
+
+class QListViewItemIterator;
+
+class TVListViewPrivate : public QListView
+{
+ Q_OBJECT
+
+signals:
+ void sortChanged(int i);
+
+public:
+ TVListViewPrivate( QWidget *parent = 0, const char *name = 0, WFlags fl = 0);
+
+ void setColumnWidth(int c, int w);
+ void setSorting(int i, bool increasing=true);
+};
+
+class TVListView : public QWidget
+{
+ Q_OBJECT
+
+signals:
+ void loadFile();
+ void browseView();
+ void filterView();
+ void editView();
+
+protected slots:
+ void setSorting(int);
+ void setCurrent(QListViewItem *);
+
+public:
+ TVListView(TableState *t, QWidget* parent = 0,
+ const char* name = 0, WFlags fl = 0);
+ ~TVListView();
+
+ /* to be used for setting up the list */
+ void addItem(DataElem *);
+ void removeItem(); // remove from list, not from program
+ void clearItems();
+
+ /* DBStore clone functions */
+ void first();
+ void last();
+ void next();
+ void previous();
+
+ void rebuildKeys();
+ void rebuildData();
+ void reset();
+
+ DataElem *getCurrentData();
+
+ void findItem(int i, TVVariant v);
+
+protected:
+ QListViewItemIterator *it;
+ TableState *ts;
+
+ TVListViewPrivate *listViewDisplay;
+
+ QMap<int, int> keyIds;
+
+};
+
+#endif
diff --git a/noncore/comm/keypebble/.cvsignore b/noncore/comm/keypebble/.cvsignore
new file mode 100644
index 0000000..c4782a1
--- a/dev/null
+++ b/noncore/comm/keypebble/.cvsignore
@@ -0,0 +1,5 @@
+moc_*
+*.moc
+Makefile
+vncoptionsbase.cpp
+vncoptionsbase.h
diff --git a/noncore/comm/keypebble/LICENSE.GPL b/noncore/comm/keypebble/LICENSE.GPL
new file mode 100644
index 0000000..ec5dad8
--- a/dev/null
+++ b/noncore/comm/keypebble/LICENSE.GPL
@@ -0,0 +1,286 @@
+NOTE! The GPL below is copyrighted by the Free Software Foundation, but
+the instance of code that it refers to (the kde programs) are copyrighted
+by the authors who actually wrote it.
+
+---------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/noncore/comm/keypebble/Makefile.in b/noncore/comm/keypebble/Makefile.in
new file mode 100644
index 0000000..1dbd5d2
--- a/dev/null
+++ b/noncore/comm/keypebble/Makefile.in
@@ -0,0 +1,286 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = keypebble
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = d3des.h \
+ krfbbuffer.h \
+ krfbcanvas.h \
+ krfbconnection.h \
+ krfbdecoder.h \
+ krfblogin.h \
+ krfboptions.h \
+ krfbserverinfo.h \
+ kvnc.h \
+ kvncconnectdlg.h \
+ kvncoptionsdlg.h \
+ version.h \
+ vncauth.h
+SOURCES = d3des.c \
+ vncauth.c \
+ krfbbuffer.cpp \
+ krfbcanvas.cpp \
+ krfbconnection.cpp \
+ krfbdecoder.cpp \
+ krfblogin.cpp \
+ krfboptions.cpp \
+ kvnc.cpp \
+ kvncconnectdlg.cpp \
+ kvncoptionsdlg.cpp \
+ main.cpp
+OBJECTS = d3des.o \
+ vncauth.o \
+ krfbbuffer.o \
+ krfbcanvas.o \
+ krfbconnection.o \
+ krfbdecoder.o \
+ krfblogin.o \
+ krfboptions.o \
+ kvnc.o \
+ kvncconnectdlg.o \
+ kvncoptionsdlg.o \
+ main.o \
+ vncoptionsbase.o
+INTERFACES = vncoptionsbase.ui
+UICDECLS = vncoptionsbase.h
+UICIMPLS = vncoptionsbase.cpp
+SRCMOC = moc_krfbbuffer.cpp \
+ moc_krfbcanvas.cpp \
+ moc_krfbconnection.cpp \
+ moc_krfbdecoder.cpp \
+ moc_krfblogin.cpp \
+ moc_kvnc.cpp \
+ moc_kvncconnectdlg.cpp \
+ moc_kvncoptionsdlg.cpp \
+ moc_vncoptionsbase.cpp
+OBJMOC = moc_krfbbuffer.o \
+ moc_krfbcanvas.o \
+ moc_krfbconnection.o \
+ moc_krfbdecoder.o \
+ moc_krfblogin.o \
+ moc_kvnc.o \
+ moc_kvncconnectdlg.o \
+ moc_kvncoptionsdlg.o \
+ moc_vncoptionsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake keypebble.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+d3des.o: d3des.c \
+ d3des.h
+
+vncauth.o: vncauth.c \
+ vncauth.h \
+ d3des.h
+
+krfbbuffer.o: krfbbuffer.cpp \
+ krfbdecoder.h \
+ krfbbuffer.h \
+ krfbserverinfo.h
+
+krfbcanvas.o: krfbcanvas.cpp \
+ kvncconnectdlg.h \
+ krfbconnection.h \
+ krfbcanvas.h \
+ krfboptions.h \
+ krfbbuffer.h \
+ $(QPEDIR)/include/qpe/config.h
+
+krfbconnection.o: krfbconnection.cpp \
+ krfbconnection.h \
+ krfblogin.h \
+ krfboptions.h \
+ krfbdecoder.h \
+ krfbbuffer.h
+
+krfbdecoder.o: krfbdecoder.cpp \
+ krfbconnection.h \
+ krfboptions.h \
+ krfbserverinfo.h \
+ krfbdecoder.h \
+ krfbbuffer.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+krfblogin.o: krfblogin.cpp \
+ vncauth.h \
+ krfblogin.h \
+ krfbconnection.h
+
+krfboptions.o: krfboptions.cpp \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ krfboptions.h
+
+kvnc.o: kvnc.cpp \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/global.h \
+ kvnc.h \
+ krfbcanvas.h \
+ kvncoptionsdlg.h \
+ vncoptionsbase.h \
+ krfbconnection.h
+
+kvncconnectdlg.o: kvncconnectdlg.cpp \
+ krfbconnection.h \
+ kvncoptionsdlg.h \
+ vncoptionsbase.h \
+ kvncconnectdlg.h
+
+kvncoptionsdlg.o: kvncoptionsdlg.cpp \
+ krfboptions.h \
+ kvncoptionsdlg.h \
+ vncoptionsbase.h
+
+main.o: main.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ kvnc.h
+
+vncoptionsbase.h: vncoptionsbase.ui
+ $(UIC) vncoptionsbase.ui -o $(INTERFACE_DECL_PATH)/vncoptionsbase.h
+
+vncoptionsbase.cpp: vncoptionsbase.ui
+ $(UIC) vncoptionsbase.ui -i vncoptionsbase.h -o vncoptionsbase.cpp
+
+vncoptionsbase.o: vncoptionsbase.cpp \
+ vncoptionsbase.h \
+ vncoptionsbase.ui
+
+moc_krfbbuffer.o: moc_krfbbuffer.cpp \
+ krfbbuffer.h
+
+moc_krfbcanvas.o: moc_krfbcanvas.cpp \
+ krfbcanvas.h
+
+moc_krfbconnection.o: moc_krfbconnection.cpp \
+ krfbconnection.h
+
+moc_krfbdecoder.o: moc_krfbdecoder.cpp \
+ krfbdecoder.h
+
+moc_krfblogin.o: moc_krfblogin.cpp \
+ krfblogin.h
+
+moc_kvnc.o: moc_kvnc.cpp \
+ kvnc.h
+
+moc_kvncconnectdlg.o: moc_kvncconnectdlg.cpp \
+ kvncconnectdlg.h
+
+moc_kvncoptionsdlg.o: moc_kvncoptionsdlg.cpp \
+ kvncoptionsdlg.h \
+ vncoptionsbase.h
+
+moc_vncoptionsbase.o: moc_vncoptionsbase.cpp \
+ vncoptionsbase.h
+
+moc_krfbbuffer.cpp: krfbbuffer.h
+ $(MOC) krfbbuffer.h -o moc_krfbbuffer.cpp
+
+moc_krfbcanvas.cpp: krfbcanvas.h
+ $(MOC) krfbcanvas.h -o moc_krfbcanvas.cpp
+
+moc_krfbconnection.cpp: krfbconnection.h
+ $(MOC) krfbconnection.h -o moc_krfbconnection.cpp
+
+moc_krfbdecoder.cpp: krfbdecoder.h
+ $(MOC) krfbdecoder.h -o moc_krfbdecoder.cpp
+
+moc_krfblogin.cpp: krfblogin.h
+ $(MOC) krfblogin.h -o moc_krfblogin.cpp
+
+moc_kvnc.cpp: kvnc.h
+ $(MOC) kvnc.h -o moc_kvnc.cpp
+
+moc_kvncconnectdlg.cpp: kvncconnectdlg.h
+ $(MOC) kvncconnectdlg.h -o moc_kvncconnectdlg.cpp
+
+moc_kvncoptionsdlg.cpp: kvncoptionsdlg.h
+ $(MOC) kvncoptionsdlg.h -o moc_kvncoptionsdlg.cpp
+
+moc_vncoptionsbase.cpp: vncoptionsbase.h
+ $(MOC) vncoptionsbase.h -o moc_vncoptionsbase.cpp
+
+
diff --git a/noncore/comm/keypebble/README.html b/noncore/comm/keypebble/README.html
new file mode 100644
index 0000000..def766b
--- a/dev/null
+++ b/noncore/comm/keypebble/README.html
@@ -0,0 +1,206 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>Keystone README</title>
+ </head>
+
+ <body>
+ <h1>Keystone README</h1>
+ <div align="justify"> <!-- #BeginEditable "Body" -->
+ <h3>Contents</h3>
+ <ul>
+ <li><a href="#whatisvnc">What is Keystone?</a></li>
+ <li><a href="#servers">Servers</a></li>
+ <li><a href="#status">Status</a></li>
+ <li><a href="#bugs">Bugs</a></li>
+ <li><a href="#download">Download</a></li>
+ <li><a href="#faq">FAQs</a></li>
+ <li><a href="#todo">Todo</a></li>
+ <li><a href="#credits">Credits</a></li>
+ <li><a href="#references">References</a></li>
+ </ul>
+ <h3><a name="whatiskvnc">What is Keystone?</a></h3>
+ <p>Keystone is a tool for <a href="http://www.kde.org/">KDE</a> that
+ allows you to remotely access the desktops of machines using the cross-platform
+ VNC system. Keystone can access machines running a variety of operating
+ systems (including most UNIX systems and Windows 95/98/NT/2000) providing
+ they are running a VNC server. Note that Keystone is only a client
+ program, you will need to download a server separately in order to
+ use it.</p>
+ <p>The protocol used by Keystone (called RFB) was developed, and released
+ as GPL by ORL (now the UK branch of AT&amp;T research), they also
+ wrote and maintain GPL servers for several platforms. You can find
+ both information about the protocol and links to servers for a range
+ of platforms on their <a href="http://www.uk.research.att.com/vnc/">website</a>.</p>
+ <p>Keystone started life as a port of Markus Wuebben's kvncviewer program
+ to KDE 2, but in the course porting the code, I have rewritten and
+ redesigned most of the system. The new implementation builds on several
+ new facilities that were not available in KDE 1, such as KPixmapIO
+ and QSocket. There is so little of the original code left that I have
+ decided on a name change, and to put the version number back to 0.1.</p>
+ <p>You can see a few screenshots of <a href="http://www.ipso-facto.demon.co.uk/keystone/screenshots.html">Keystone
+ in action</a> on my screenshots page. The screenshots may or may not
+ reflect the look of the current version as I have some look and feel
+ improvements planned.</p>
+ <h3><a name="servers">Servers</a></h3>
+ <p>Most Linux distributions include the standard Xvnc server (usually
+ run via the <i>vncserver</i> script), you can also download this and
+ servers for other platforms such as MS Windows from the <a href="http://www.uk.research.att.com/vnc/">VNC
+ website</a>. If you have a problem with setting up a server then you
+ should read the <a href="http://www.uk.research.att.com/vnc/faq.html">VNC
+ FAQ</a>, and if that does not help join the VNC mailing list. Do not
+ mail me on this topic - I can't help and won't even reply.</p>
+ <p>I may in future write a server that operates in the same manner as
+ the Win32 server for KDE. The Win32 server differs from the X11 server
+ in that it does not virtualise the entire desktop. This has both advantages
+ and disadvatages, it means that you can make an existing session available
+ over the network, but only allows you to run a single server. I may
+ also put a GUI together that makes it easy to configure the ORL server.</p>
+ <h3><a name="status">Status</a></h3>
+ <p><font color="#000000">The current version is 0.4, and the following
+ are now working:</font></p>
+ <p>
+ <ul>
+ <li><b>0.1</b>
+ <ul>
+ <li>Non-blocking socket handling</li>
+ <li>Authentication and logon</li>
+ <li>KDE 2 user interface</li>
+ <li>Raw and CopyRect encodings</li>
+ <li>Full screen mode</li>
+ <li>Grab keyboard mode</li>
+ <li>Graphics</li>
+ <li>Taking screenshots of the remote desktop</li>
+ <li>Event dispatching</li>
+ <li>Konqueror helper application support (you can run Keystone
+ by entering a vnc: URL anywhere in KDE).</li>
+ <li>Options, login, password and about dialogs</li>
+ </ul>
+ </li>
+ <li><b>0.2</b>
+ <ul>
+ <li>XSHM support using KPixmapIO</li>
+ <li>Now uses KXMLGUI (thanks to Kurt)</li>
+ <li>Tru64 patch from Tom Leitner</li>
+ <li>Status reporting improvements</li>
+ <li>Config handling fixed</li>
+ <li>Recent connections list implemented</li>
+ <li>Update frequency respected</li>
+ </ul>
+ </li>
+ <li><b>0.3 [KDE 2.0]</b>
+ <ul>
+ <li>Portability fixes for FreeBSD (and maybe others)</li>
+ </ul>
+ </li>
+ <li><b>0.4</b>
+ <ul>
+ <li>Icons for the full screen mode now reflect the current state</li>
+ <li>Added a toolbar (optional of course)</li>
+ <li>Added support for the clipboard (you can cut and paste between the
+ local and remote machines)</li>
+ <li>Added some what's this help to the options dialog</li>
+ </ul>
+ </li>
+ </ul>
+ <h3><a name="bugs">Bugs</a></h3>
+ <p>Version 0.4 contains the following known bugs:
+ <ul>
+ <li><b>Custom about dialog is not shown</b><br>
+ I can't see a clean way to fix this without creating a complete custom
+ help menu. For now I've left the standard about dialog in place.
+ </li>
+ <li><b>Crash when you connect to a non-existant server</b><br>
+ I can reproduce this every time, but I can't figure out what's wrong
+ other developers have reported similar problems and they seem to be
+ down to QSocket. The only known fix so far is to use KSocket instead.
+ I'd prefer to fix the problem at the source, but I'm having no luck and
+ I suspect QSocket may also be causing some other weird network issues
+ I've seen, so if I can't track down the bug soon I'll give in and switch
+ to KSocket like everyone else.
+ </li>
+ </ul>
+ </p>
+ <h3><a name="download"></a>Download</h3>
+ <p>Keystone is available in the kdenetwork module of the
+ <a href="http://www.kde.org/anoncvs.html">KDE CVS</a>, and
+ is included in the KDE 2.0 release. The current version is 0.4.
+ Note that Keystone <b>requires KDE 2</b>, you cannot use KDE 1.x.</p>
+ <h3><a name="faq"></a>FAQs</h3>
+ <p>
+ <ul>
+ <li><b>Why don't the shortcut keys work in full screen mode?</b><br>
+ When you're in full screen mode Keystone grabs the keyboard to send
+ every key press to the remote screen. This means that you can send key
+ combinations that are used by Keystone or KDE to the remote screen. If
+ you really hate it, then you can add -nograb to the command line
+ arguments to disable all keyboard grabs. I will add an option to allow
+ this behaviour to be overridden in a future release.
+ </li>
+ <li><b>Why is Keystone so slow?</b><br>
+ Currently only the simplest of the RFB encodings are supported, this
+ means that Keystone is only useful on fairly fast networks. This is
+ a serious bug and is being addressed.
+ </ul>
+ </p>
+ <h3><a name="todo">Todo</a></h3>
+ These are the things I'm hoping to add to future versions of Keystone.
+ They're vaguely sorted in order of importance.
+ <p>
+ <ul>
+ <li>RRE encoding.<br>
+ I've started this, but the implementation has some
+ bugs so it did not make the cut for Keystone 0.3.</li>
+ <li>CoRRE and Hextile encodings</li>
+ <li>Session management</li>
+ <li>Support for Windows Terminal Server.<br>
+ There is now a GPL implementation
+ of the protocol, and the author is happy for me to use the code. If someone
+ can offer me an account to test it on then this is possible.</li>
+ <li>Zoom support.<br>
+ This will be handled using the same protocol extension
+ as is used in the Palm client, this will allow you to make use of
+ server side scaling to reduce the amount of network traffic. You
+ will also be able to do client side zooms, but in this case the
+ full screen needs to transmitted over the network.</li>
+ <li>Macros</li>
+ <li>Monitor mode (thumbnails of several machines)</li>
+ <li>ZLib extension support</li>
+ <li>Bookmarks</li>
+ <li>URL specific settings</li>
+ <li>Possibly a DnD extension using a mechanism based on mulitpart
+ MIME attachments.</li>
+ </ul>
+ <h3>Credits<a name="credits"></a></h3>
+ <p>Keystone owes a lot to Markus Wuebben's kvncviewer which some of
+ the code is derived from. Thanks are also due to Espen Sand the author
+ of khexedit from which I borrowed some code for the about dialog.
+ Alison Burch drew the bridge image used in the background of this
+ page (and in future versions of Keystone too of course). Finally thanks
+ go to ORL for making the RFB protocol and servers GPL.</p>
+ <h3><a name="references">References</a><br>
+ </h3>
+ <p>
+ <ul>
+ <li>The Keystone homepage<br>
+ <a href="http://www.ipso-facto.demon.co.uk/keystone/">http://www.ipso-facto.demon.co.uk/keystone/</a></li>
+ <li>The VNC Homepage<br>
+ <a href="http://www.uk.research.att.com/vnc/">http://www.uk.research.att.com/vnc/</a></li>
+ <li>The VNC FAQ<br>
+ <a href="http://www.uk.research.att.com/vnc/faq.html">http://www.uk.research.att.com/vnc/faq.html</a></li>
+ <li>The KDE Homepage<br>
+ <a href="http://www.kde.org/">http://www.kde.org/</a> </li>
+ </ul>
+ <p></p>
+ <!-- #EndEditable --> </div>
+
+
+
+ <hr>
+ <address><a href="mailto:rich@kde.org">Richard Moore</a></address>
+<!-- Created: Tue Dec 5 01:35:56 GMT 2000 -->
+<!-- hhmts start -->
+Last modified: Tue Dec 5 01:37:17 GMT 2000
+<!-- hhmts end -->
+ </body>
+</html>
diff --git a/noncore/comm/keypebble/d3des.c b/noncore/comm/keypebble/d3des.c
new file mode 100644
index 0000000..b0f065e
--- a/dev/null
+++ b/noncore/comm/keypebble/d3des.c
@@ -0,0 +1,439 @@
+/*
+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
+ * triple-length support removed for use in VNC. Also the bytebit[] array
+ * has been reversed so that the most significant bit in each byte of the
+ * key is ignored, not the least significant.
+ *
+ * These changes are Copyright (C) 1998 Olivetti & Oracle Research Laboratory
+ *
+ * This software 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.
+ */
+
+/* D3DES (V5.09) -
+ *
+ * A portable, public domain, version of the Data Encryption Standard.
+ *
+ * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
+ * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
+ * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
+ * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
+ * for humouring me on.
+ *
+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
+ * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
+ */
+
+#include "d3des.h"
+
+static void scrunch(unsigned char *, unsigned long *);
+static void unscrun(unsigned long *, unsigned char *);
+static void desfunc(unsigned long *, unsigned long *);
+static void cookey(unsigned long *);
+
+static unsigned long KnL[32] = { 0L };
+static unsigned long KnR[32] = { 0L };
+static unsigned long Kn3[32] = { 0L };
+static unsigned char Df_Key[24] = {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+ 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
+
+static unsigned short bytebit[8] = {
+ 01, 02, 04, 010, 020, 040, 0100, 0200 };
+
+static unsigned long bigbyte[24] = {
+ 0x800000L, 0x400000L, 0x200000L, 0x100000L,
+ 0x80000L, 0x40000L, 0x20000L, 0x10000L,
+ 0x8000L, 0x4000L, 0x2000L, 0x1000L,
+ 0x800L, 0x400L, 0x200L, 0x100L,
+ 0x80L, 0x40L, 0x20L, 0x10L,
+ 0x8L, 0x4L, 0x2L, 0x1L };
+
+/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
+
+static unsigned char pc1[56] = {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
+
+static unsigned char totrot[16] = {
+ 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
+
+static unsigned char pc2[48] = {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
+
+void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
+unsigned char *key;
+short edf;
+{
+ register int i, j, l, m, n;
+ unsigned char pc1m[56], pcr[56];
+ unsigned long kn[32];
+
+ for ( j = 0; j < 56; j++ ) {
+ l = pc1[j];
+ m = l & 07;
+ pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
+ }
+ for( i = 0; i < 16; i++ ) {
+ if( edf == DE1 ) m = (15 - i) << 1;
+ else m = i << 1;
+ n = m + 1;
+ kn[m] = kn[n] = 0L;
+ for( j = 0; j < 28; j++ ) {
+ l = j + totrot[i];
+ if( l < 28 ) pcr[j] = pc1m[l];
+ else pcr[j] = pc1m[l - 28];
+ }
+ for( j = 28; j < 56; j++ ) {
+ l = j + totrot[i];
+ if( l < 56 ) pcr[j] = pc1m[l];
+ else pcr[j] = pc1m[l - 28];
+ }
+ for( j = 0; j < 24; j++ ) {
+ if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
+ if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
+ }
+ }
+ cookey(kn);
+ return;
+ }
+
+static void cookey(raw1)
+register unsigned long *raw1;
+{
+ register unsigned long *cook, *raw0;
+ unsigned long dough[32];
+ register int i;
+
+ cook = dough;
+ for( i = 0; i < 16; i++, raw1++ ) {
+ raw0 = raw1++;
+ *cook = (*raw0 & 0x00fc0000L) << 6;
+ *cook |= (*raw0 & 0x00000fc0L) << 10;
+ *cook |= (*raw1 & 0x00fc0000L) >> 10;
+ *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
+ *cook = (*raw0 & 0x0003f000L) << 12;
+ *cook |= (*raw0 & 0x0000003fL) << 16;
+ *cook |= (*raw1 & 0x0003f000L) >> 4;
+ *cook++ |= (*raw1 & 0x0000003fL);
+ }
+ usekey(dough);
+ return;
+ }
+
+void cpkey(into)
+register unsigned long *into;
+{
+ register unsigned long *from, *endp;
+
+ from = KnL, endp = &KnL[32];
+ while( from < endp ) *into++ = *from++;
+ return;
+ }
+
+void usekey(from)
+register unsigned long *from;
+{
+ register unsigned long *to, *endp;
+
+ to = KnL, endp = &KnL[32];
+ while( to < endp ) *to++ = *from++;
+ return;
+ }
+
+void des(inblock, outblock)
+unsigned char *inblock, *outblock;
+{
+ unsigned long work[2];
+
+ scrunch(inblock, work);
+ desfunc(work, KnL);
+ unscrun(work, outblock);
+ return;
+ }
+
+static void scrunch(outof, into)
+register unsigned char *outof;
+register unsigned long *into;
+{
+ *into = (*outof++ & 0xffL) << 24;
+ *into |= (*outof++ & 0xffL) << 16;
+ *into |= (*outof++ & 0xffL) << 8;
+ *into++ |= (*outof++ & 0xffL);
+ *into = (*outof++ & 0xffL) << 24;
+ *into |= (*outof++ & 0xffL) << 16;
+ *into |= (*outof++ & 0xffL) << 8;
+ *into |= (*outof & 0xffL);
+ return;
+ }
+
+static void unscrun(outof, into)
+register unsigned long *outof;
+register unsigned char *into;
+{
+ *into++ = (*outof >> 24) & 0xffL;
+ *into++ = (*outof >> 16) & 0xffL;
+ *into++ = (*outof >> 8) & 0xffL;
+ *into++ = *outof++ & 0xffL;
+ *into++ = (*outof >> 24) & 0xffL;
+ *into++ = (*outof >> 16) & 0xffL;
+ *into++ = (*outof >> 8) & 0xffL;
+ *into = *outof & 0xffL;
+ return;
+ }
+
+static unsigned long SP1[64] = {
+ 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
+ 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
+ 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
+ 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
+ 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
+ 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
+ 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
+ 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
+ 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
+ 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
+ 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
+ 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
+ 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
+ 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
+
+static unsigned long SP2[64] = {
+ 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
+ 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
+ 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
+ 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
+ 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
+ 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
+ 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
+ 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
+ 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
+ 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
+ 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
+ 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
+ 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
+ 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
+ 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
+ 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
+
+static unsigned long SP3[64] = {
+ 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
+ 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
+ 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
+ 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
+ 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
+ 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
+ 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
+ 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
+ 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
+ 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
+ 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
+ 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
+ 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
+ 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
+ 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
+ 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
+
+static unsigned long SP4[64] = {
+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+ 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
+ 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
+ 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
+ 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
+ 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
+ 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
+ 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
+ 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
+ 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
+ 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+ 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
+ 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
+ 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
+ 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
+
+static unsigned long SP5[64] = {
+ 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
+ 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
+ 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
+ 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
+ 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
+ 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
+ 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
+ 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
+ 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
+ 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
+ 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
+ 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
+ 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
+ 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
+ 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
+ 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
+
+static unsigned long SP6[64] = {
+ 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
+ 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
+ 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
+ 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
+ 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
+ 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
+ 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
+ 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
+ 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
+ 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
+ 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
+ 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
+ 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
+ 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
+ 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
+ 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
+
+static unsigned long SP7[64] = {
+ 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
+ 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
+ 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
+ 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
+ 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
+ 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
+ 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
+ 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
+ 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
+ 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
+ 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
+ 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
+ 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
+ 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
+ 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
+ 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
+
+static unsigned long SP8[64] = {
+ 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
+ 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
+ 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
+ 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
+ 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
+ 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
+ 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
+ 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
+ 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
+ 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
+ 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
+ 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
+ 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
+ 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
+ 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
+ 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
+
+static void desfunc(block, keys)
+register unsigned long *block, *keys;
+{
+ register unsigned long fval, work, right, leftt;
+ register int round;
+
+ leftt = block[0];
+ right = block[1];
+ work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
+ right ^= work;
+ leftt ^= (work << 4);
+ work = ((leftt >> 16) ^ right) & 0x0000ffffL;
+ right ^= work;
+ leftt ^= (work << 16);
+ work = ((right >> 2) ^ leftt) & 0x33333333L;
+ leftt ^= work;
+ right ^= (work << 2);
+ work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
+ leftt ^= work;
+ right ^= (work << 8);
+ right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
+ work = (leftt ^ right) & 0xaaaaaaaaL;
+ leftt ^= work;
+ right ^= work;
+ leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
+
+ for( round = 0; round < 8; round++ ) {
+ work = (right << 28) | (right >> 4);
+ work ^= *keys++;
+ fval = SP7[ work & 0x3fL];
+ fval |= SP5[(work >> 8) & 0x3fL];
+ fval |= SP3[(work >> 16) & 0x3fL];
+ fval |= SP1[(work >> 24) & 0x3fL];
+ work = right ^ *keys++;
+ fval |= SP8[ work & 0x3fL];
+ fval |= SP6[(work >> 8) & 0x3fL];
+ fval |= SP4[(work >> 16) & 0x3fL];
+ fval |= SP2[(work >> 24) & 0x3fL];
+ leftt ^= fval;
+ work = (leftt << 28) | (leftt >> 4);
+ work ^= *keys++;
+ fval = SP7[ work & 0x3fL];
+ fval |= SP5[(work >> 8) & 0x3fL];
+ fval |= SP3[(work >> 16) & 0x3fL];
+ fval |= SP1[(work >> 24) & 0x3fL];
+ work = leftt ^ *keys++;
+ fval |= SP8[ work & 0x3fL];
+ fval |= SP6[(work >> 8) & 0x3fL];
+ fval |= SP4[(work >> 16) & 0x3fL];
+ fval |= SP2[(work >> 24) & 0x3fL];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >> 1);
+ work = (leftt ^ right) & 0xaaaaaaaaL;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 31) | (leftt >> 1);
+ work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
+ right ^= work;
+ leftt ^= (work << 8);
+ work = ((leftt >> 2) ^ right) & 0x33333333L;
+ right ^= work;
+ leftt ^= (work << 2);
+ work = ((right >> 16) ^ leftt) & 0x0000ffffL;
+ leftt ^= work;
+ right ^= (work << 16);
+ work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
+ leftt ^= work;
+ right ^= (work << 4);
+ *block++ = right;
+ *block = leftt;
+ return;
+ }
+
+/* Validation sets:
+ *
+ * Single-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : c957 4425 6a5e d31d
+ *
+ * Double-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : 7f1d 0a77 826b 8aff
+ *
+ * Double-length key, double-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
+ * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
+ *
+ * Triple-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : de0b 7c06 ae5e 0ed5
+ *
+ * Triple-length key, double-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
+ * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
+ *
+ * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
+ **********************************************************************/
diff --git a/noncore/comm/keypebble/d3des.h b/noncore/comm/keypebble/d3des.h
new file mode 100644
index 0000000..5da6013
--- a/dev/null
+++ b/noncore/comm/keypebble/d3des.h
@@ -0,0 +1,50 @@
+/*
+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
+ * triple-length support removed for use in VNC.
+ *
+ * These changes are Copyright (C) 1998 Olivetti & Oracle Research Laboratory
+ *
+ * This software 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.
+ */
+
+/* d3des.h -
+ *
+ * Headers and defines for d3des.c
+ * Graven Imagery, 1992.
+ *
+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
+ * (GEnie : OUTER; CIS : [71755,204])
+ */
+
+#define EN0 0 /* MODE == encrypt */
+#define DE1 1 /* MODE == decrypt */
+
+extern void deskey(unsigned char *, short);
+/* hexkey[8] MODE
+ * Sets the internal key register according to the hexadecimal
+ * key contained in the 8 bytes of hexkey, according to the DES,
+ * for encryption or decryption according to MODE.
+ */
+
+extern void usekey(unsigned long *);
+/* cookedkey[32]
+ * Loads the internal key register with the data in cookedkey.
+ */
+
+extern void cpkey(unsigned long *);
+/* cookedkey[32]
+ * Copies the contents of the internal key register into the storage
+ * located at &cookedkey[0].
+ */
+
+extern void des(unsigned char *, unsigned char *);
+/* from[8] to[8]
+ * Encrypts/Decrypts (according to the key currently loaded in the
+ * internal key register) one block of eight bytes at address 'from'
+ * into the block at address 'to'. They can be the same.
+ */
+
+/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
+ ********************************************************************/
diff --git a/noncore/comm/keypebble/keypebble.pro b/noncore/comm/keypebble/keypebble.pro
new file mode 100644
index 0000000..6b11801
--- a/dev/null
+++ b/noncore/comm/keypebble/keypebble.pro
@@ -0,0 +1,38 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+DESTDIR = ../bin
+
+HEADERS = d3des.h \
+ krfbbuffer.h \
+ krfbcanvas.h \
+ krfbconnection.h \
+ krfbdecoder.h \
+ krfblogin.h \
+ krfboptions.h \
+ krfbserverinfo.h \
+ kvnc.h \
+ kvncconnectdlg.h \
+ kvncoptionsdlg.h \
+ version.h \
+ vncauth.h
+
+SOURCES = d3des.c \
+ vncauth.c \
+ krfbbuffer.cpp \
+ krfbcanvas.cpp \
+ krfbconnection.cpp \
+ krfbdecoder.cpp \
+ krfblogin.cpp \
+ krfboptions.cpp \
+ kvnc.cpp \
+ kvncconnectdlg.cpp \
+ kvncoptionsdlg.cpp \
+ main.cpp
+INTERFACES = vncoptionsbase.ui
+TARGET = keypebble
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
diff --git a/noncore/comm/keypebble/krfbbuffer.cpp b/noncore/comm/keypebble/krfbbuffer.cpp
new file mode 100644
index 0000000..4885261
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbbuffer.cpp
@@ -0,0 +1,163 @@
+#include <assert.h>
+#include <qpixmap.h>
+#include <qbrush.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include "krfbdecoder.h"
+#include "krfbbuffer.h"
+#include "krfbserverinfo.h"
+
+//
+// Endian stuff
+//
+#ifndef KDE_USE_FINAL
+const int endianTest = 1;
+#endif
+
+#define Swap16IfLE(s) \
+ (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
+
+#define Swap32IfLE(l) \
+ (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
+ (((l) & 0x00ff0000) >> 8) | \
+ (((l) & 0x0000ff00) << 8) | \
+ (((l) & 0x000000ff) << 24)) : (l))
+
+KRFBBuffer::KRFBBuffer( KRFBDecoder *decoder,
+ QObject *parent, const char *name )
+ : QObject( parent, name )
+{
+ assert( decoder );
+ this->decoder = decoder;
+ pix = new QPixmap();
+}
+
+KRFBBuffer::~KRFBBuffer()
+{
+ delete pix;
+}
+
+void KRFBBuffer::resize( int w, int h )
+{
+ qWarning( "Resizing buffer" );
+
+ pix->resize( w, h );
+
+ QPalette pal = qApp->palette();
+ pix->fill( pal.active().base() );
+
+ emit sizeChanged( w, h );
+}
+
+void KRFBBuffer::soundBell()
+{
+ emit bell();
+}
+
+void KRFBBuffer::mouseEvent( QMouseEvent *e )
+{
+ decoder->sendMouseEvent( e );
+}
+
+void KRFBBuffer::keyPressEvent( QKeyEvent *e )
+{
+ qWarning( "Buffer got a key" );
+
+ decoder->sendKeyPressEvent( e );
+}
+
+void KRFBBuffer::keyReleaseEvent( QKeyEvent *e )
+{
+ decoder->sendKeyReleaseEvent( e );
+}
+
+void KRFBBuffer::copyRect( int srcX, int srcY,
+ int destX, int destY, int w, int h )
+{
+// qWarning( "Got copy rect" );
+ bitBlt( pix, destX, destY, pix, srcX, srcY, w, h, CopyROP );
+
+ emit updated( destX, destY, w, h );
+}
+
+void KRFBBuffer::drawRawRectChunk( void *data,
+ int x, int y, int w, int h )
+{
+ QImage img( w, h, 32 );
+
+ int redMax = Swap16IfLE( decoder->format->redMax );
+ int greenMax = Swap16IfLE( decoder->format->greenMax );
+ int blueMax = Swap16IfLE( decoder->format->blueMax );
+
+ QPainter p( pix );
+
+ if ( decoder->format->bpp == 8 ) {
+ uchar *d = (unsigned char *) data;
+
+ uint r,g,b;
+
+ for ( int j = 0; j < h; j++ ) {
+ for ( int i = 0; i < w ; i++ ) {
+ r = d[ j * w + i ];
+ r = r >> decoder->format->redShift;
+ r = r & redMax;
+
+ g = d[ j * w + i ];
+ g = g >> decoder->format->greenShift;
+ g = g & greenMax;
+
+ b = d[ j * w + i ];
+ b = b >> decoder->format->blueShift;
+ b = b & blueMax;
+
+ r = ( r * 255 ) / redMax;
+ g = ( g * 255 ) / greenMax;
+ b = ( b * 255 ) / blueMax;
+
+ uint *p = ( uint * ) img.scanLine( j ) + i;
+ *p = qRgb( r,g,b );
+ }
+ }
+ }
+ else if ( decoder->format->bpp == 32 ) {
+ ulong *d = (ulong *) data;
+
+ ulong r,g,b;
+
+ for ( int j = 0; j < h; j++ ) {
+ for ( int i = 0; i < w ; i++ ) {
+ ulong pixel = d[ j * w + i ];
+ pixel = Swap32IfLE( pixel );
+
+ r = pixel;
+ r = r >> decoder->format->redShift;
+ r = r & redMax;
+
+ g = pixel;
+ g = g >> decoder->format->greenShift;
+ g = g & greenMax;
+
+ b = pixel;
+ b = b >> decoder->format->blueShift;
+ b = b & blueMax;
+
+ r = ( r * 255 ) / redMax;
+ g = ( g * 255 ) / greenMax;
+ b = ( b * 255 ) / blueMax;
+
+ uint *p = ( uint * ) img.scanLine( j ) + i;
+ *p = qRgb( r,g,b );
+ }
+ }
+ }
+ else {
+ p.setBrush( QBrush( Qt::black ) );
+ p.drawRect( x, y, w, h );
+ }
+
+ p.drawImage( x, y, img );
+
+ emit updated( x, y, w, h );
+}
+
diff --git a/noncore/comm/keypebble/krfbbuffer.h b/noncore/comm/keypebble/krfbbuffer.h
new file mode 100644
index 0000000..1116d00
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbbuffer.h
@@ -0,0 +1,62 @@
+// -*- c++ -*-
+
+#ifndef KRFBBUFFER_H
+#define KRFBBUFFER_H
+
+#include <qobject.h>
+
+class QPixmap;
+class KRFBDecoder;
+class QMouseEvent;
+class QKeyEvent;
+
+/**
+ * A wrapper around QPixmap that knows how to implement the RFB
+ * drawing primitives. If possible it makes use of the MIT XSHM
+ * extension to optimise the drawing operations.
+ */
+class KRFBBuffer : public QObject
+{
+ Q_OBJECT
+
+public:
+ KRFBBuffer( KRFBDecoder *decoder, QObject *parent, const char *name=0 );
+ ~KRFBBuffer();
+
+ QPixmap *pixmap() const { return pix; };
+
+ /**
+ * Draw a chunk of a raw encoded rectangle.
+ */
+ void drawRawRectChunk( void *data, int x, int y, int w, int h );
+
+ void copyRect( int srcX, int srcY,
+ int destX, int destY, int w, int h );
+
+ void fillRect( int ,int , int , int , unsigned long ) {};
+
+ void resize( int w, int h );
+
+ void mouseEvent( QMouseEvent *e );
+
+ void keyPressEvent( QKeyEvent *e );
+ void keyReleaseEvent( QKeyEvent *e );
+
+ void soundBell();
+
+signals:
+ /**
+ * Emitted when the size of the buffer changes.
+ */
+ void sizeChanged( int w, int h );
+
+ void updated( int x, int y, int w, int h );
+
+ void bell();
+
+private:
+ KRFBDecoder *decoder;
+ QPixmap *pix;
+};
+
+#endif // KRFBBUFFER_H
diff --git a/noncore/comm/keypebble/krfbcanvas.cpp b/noncore/comm/keypebble/krfbcanvas.cpp
new file mode 100644
index 0000000..f74ab7b
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbcanvas.cpp
@@ -0,0 +1,169 @@
+#include "kvncconnectdlg.h"
+#include "krfbconnection.h"
+#include "krfbcanvas.h"
+#include "krfboptions.h"
+#include "krfbbuffer.h"
+
+#include <qpe/config.h>
+
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qaction.h>
+#include <qpixmap.h>
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qiconset.h>
+
+KRFBCanvas::KRFBCanvas( QWidget *parent, const char *name )
+ : QScrollView( parent, name )
+{
+ connection_ = new KRFBConnection();
+ connect( connection_, SIGNAL( passwordRequired( KRFBConnection * ) ),
+ this, SLOT( passwordRequired( KRFBConnection * ) ) );
+ connect( connection_, SIGNAL( loggedIn() ),
+ this, SLOT( loggedIn() ) );
+
+ loggedIn_ = false;
+
+ viewport()->setFocusPolicy( QWidget::StrongFocus );
+ viewport()->setFocus();
+}
+
+KRFBCanvas::~KRFBCanvas()
+{
+}
+
+void KRFBCanvas::openConnection()
+{
+ KVNCConnectDlg dlg( connection_, this, "connect dialog" );
+ if ( dlg.exec() ) {
+ QCString host = dlg.hostname().latin1();
+ password = dlg.password();
+ connection_->connectTo( host, dlg.display() );
+ }
+}
+
+void KRFBCanvas::openURL( const QUrl &url )
+{
+ if ( loggedIn_ ) {
+ qWarning( "openURL invoked when logged in\n" );
+ return;
+ }
+
+ QCString host = url.host().latin1();
+ int display = url.port();
+ if ( url.hasPassword() )
+ connection_->setPassword( url.password().latin1() );
+
+ connection_->connectTo( host, display );
+}
+
+void KRFBCanvas::closeConnection()
+{
+ loggedIn_ = false;
+ connection_->disconnect();
+
+ viewport()->setMouseTracking( false );
+ viewport()->setBackgroundMode( PaletteDark );
+ setBackgroundMode( PaletteDark );
+ update();
+}
+
+void KRFBCanvas::passwordRequired( KRFBConnection *con )
+{
+ con->setPassword( password.latin1() );
+}
+
+void KRFBCanvas::bell()
+{
+ if ( connection_->options()->deIconify ) {
+ topLevelWidget()->raise();
+ topLevelWidget()->show();
+ }
+}
+
+void KRFBCanvas::loggedIn()
+{
+ qWarning( "Ok, we're logged in" );
+
+ //
+ // Get ready for action
+ //
+ loggedIn_ = true;
+ viewport()->setMouseTracking( true );
+ viewport()->setBackgroundMode( NoBackground );
+ setBackgroundMode( NoBackground );
+
+ // Start using the buffer
+ connect( connection_->buffer(), SIGNAL( sizeChanged( int, int ) ),
+ this, SLOT( resizeContents(int,int) ) );
+ connect( connection_->buffer(), SIGNAL( updated( int, int, int, int ) ),
+ this, SLOT( viewportUpdate(int,int,int,int) ) );
+ connect( connection_->buffer(), SIGNAL( bell() ),
+ this, SLOT( bell() ) );
+ connect( qApp->clipboard(), SIGNAL( dataChanged() ),
+ this, SLOT( clipboardChanged() ) );
+}
+
+void KRFBCanvas::viewportPaintEvent( QPaintEvent *e )
+{
+ QRect r = e->rect();
+
+ if ( loggedIn_ ) {
+ bitBlt( viewport(), r.x(), r.y(),
+ connection_->buffer()->pixmap(),
+ r.x() + contentsX(), r.y() + contentsY(),
+ r.width(), r.height() );
+ }
+ else {
+ QScrollView::viewportPaintEvent( e );
+ }
+}
+
+void KRFBCanvas::viewportUpdate( int x, int y, int w, int h )
+{
+ updateContents( x, y, w, h );
+}
+
+void KRFBCanvas::contentsMousePressEvent( QMouseEvent *e )
+{
+ if ( loggedIn_ )
+ connection_->buffer()->mouseEvent( e );
+}
+
+void KRFBCanvas::contentsMouseReleaseEvent( QMouseEvent *e )
+{
+ if ( loggedIn_ )
+ connection_->buffer()->mouseEvent( e );
+}
+
+void KRFBCanvas::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ if ( loggedIn_ )
+ connection_->buffer()->mouseEvent( e );
+}
+
+void KRFBCanvas::keyPressEvent( QKeyEvent *e )
+{
+ if ( loggedIn_ )
+ connection_->buffer()->keyPressEvent( e );
+}
+
+void KRFBCanvas::keyReleaseEvent( QKeyEvent *e )
+{
+ if ( loggedIn_ )
+ connection_->buffer()->keyReleaseEvent( e );
+}
+
+void KRFBCanvas::refresh()
+{
+ if ( loggedIn_ )
+ connection_->refresh();
+}
+
+void KRFBCanvas::clipboardChanged()
+{
+ if ( loggedIn_ ) {
+ connection_->sendCutText( qApp->clipboard()->text() );
+ }
+}
diff --git a/noncore/comm/keypebble/krfbcanvas.h b/noncore/comm/keypebble/krfbcanvas.h
new file mode 100644
index 0000000..7864f1c
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbcanvas.h
@@ -0,0 +1,54 @@
+// -*- c++ -*-
+
+#ifndef KRFBCANVAS_H
+#define KRFBCANVAS_H
+
+#include <qscrollview.h>
+#include <qurl.h>
+
+class KRFBConnection;
+
+/**
+ * Displays data from an KRFBDecoder, and sends events to the
+ * KRFBConnection.
+ */
+class KRFBCanvas : public QScrollView
+{
+ Q_OBJECT
+public:
+ KRFBCanvas( QWidget *parent, const char *name=0 );
+ ~KRFBCanvas();
+
+ void setConnection( KRFBConnection * );
+ KRFBConnection *connection() { return connection_; };
+
+public slots:
+ void openConnection();
+ void openURL( const QUrl & );
+ void closeConnection();
+ void passwordRequired( KRFBConnection * );
+
+ void refresh();
+ void bell();
+
+protected:
+ virtual void keyPressEvent( QKeyEvent * );
+ virtual void keyReleaseEvent( QKeyEvent * );
+ virtual void contentsMousePressEvent( QMouseEvent * );
+ virtual void contentsMouseReleaseEvent( QMouseEvent * );
+ virtual void contentsMouseMoveEvent( QMouseEvent * );
+
+ virtual void viewportPaintEvent( QPaintEvent *e );
+
+protected slots:
+ void loggedIn();
+ void viewportUpdate( int x, int y, int w, int h );
+ void clipboardChanged();
+
+private:
+ KRFBConnection *connection_;
+ QString password;
+ bool loggedIn_;
+};
+
+#endif // KRFBCANVAS_H
diff --git a/noncore/comm/keypebble/krfbconnection.cpp b/noncore/comm/keypebble/krfbconnection.cpp
new file mode 100644
index 0000000..c413186
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbconnection.cpp
@@ -0,0 +1,242 @@
+#include <assert.h>
+#include <qsocket.h>
+#include <qtimer.h>
+#include <string.h>
+
+#include "krfbconnection.h"
+#include "krfblogin.h"
+#include "krfboptions.h"
+#include "krfbdecoder.h"
+#include "krfbbuffer.h"
+
+KRFBConnection::KRFBConnection( QObject *parent )
+ : QObject( parent, "KRFBConnection" )
+{
+ portBase_ = 5900;
+ currentState_ = Disconnected;
+ sock = 0;
+ minData_ = 0;
+ options_ = new KRFBOptions();
+ updater = 0;
+ decoder_ = 0;
+ buffer_ = 0;
+}
+
+KRFBConnection::~KRFBConnection()
+{
+ if ( ( currentState_ != Disconnected ) && ( currentState_ != Disconnecting ) && sock ) {
+ disconnectDone();
+ }
+ delete options_;
+}
+
+void KRFBConnection::connectTo( const QCString &host, int display )
+{
+ if ( currentState_ != Disconnected );
+ disconnect();
+
+ this->host_= host;
+ this->display_ = display;
+
+ sock = new QSocket( this, "rfbSocket" );
+ CHECK_PTR( sock );
+
+ // Connect to something to notice connection or error
+ connect( sock, SIGNAL( error( int ) ), SLOT( gotSocketError( int ) ) );
+ connect( sock, SIGNAL( connected() ), SLOT( gotSocketConnection() ) );
+
+ qWarning( "Connecting..." );
+
+ currentState_ = Connecting;
+ sock->connectToHost( host_, portBase_ + display_ );
+}
+
+void KRFBConnection::disconnect()
+{
+ qWarning( "Disconnecting from server" );
+
+ if ( ( currentState_ != Disconnected )
+ && ( currentState_ != Disconnecting )
+ && sock ) {
+ currentState_ = Disconnecting;
+
+ connect( sock, SIGNAL( delayedCloseFinished() ), SLOT( disconnectDone() ) );
+ sock->close();
+
+ if ( sock->state() != QSocket::Closing )
+ disconnectDone();
+ }
+}
+
+void KRFBConnection::disconnectDone()
+{
+ qWarning( "KRFBConnection disconnected" );
+ currentState_ = Disconnected;
+ delete sock;
+ sock = 0;
+ minData_ = 0;
+ delete updater;
+ delete decoder_;
+ delete buffer_;
+ emit disconnected();
+}
+
+void KRFBConnection::gotSocketConnection()
+{
+ currentState_ = LoggingIn;
+
+ qWarning( "Connected, logging in..." );
+
+ static QString statusMsg = tr( "Connected" );
+ emit statusChanged( statusMsg );
+
+ // Do some login stuff
+ login = new KRFBLogin( this );
+}
+
+void KRFBConnection::gotRFBConnection()
+{
+ qWarning( "Logged into server" );
+
+ currentState_ = Connected;
+ emit connected();
+
+ // Create the decoder and start doing stuff
+ decoder_ = new KRFBDecoder( this );
+ CHECK_PTR( decoder_ );
+
+ buffer_ = new KRFBBuffer( decoder_, this, "RFB Buffer" );
+ CHECK_PTR( buffer_ );
+ decoder_->setBuffer( buffer_ );
+
+ connect( decoder_, SIGNAL( status( const QString & ) ),
+ this, SIGNAL( statusChanged( const QString & ) ) );
+ emit loggedIn();
+
+ decoder_->start();
+
+ updater = new QTimer;
+ connect( updater, SIGNAL( timeout() ), SLOT( updateTimer() ) );
+ updater->start( options_->updateRate );
+}
+
+void KRFBConnection::gotSocketError( int errno )
+{
+ currentState_ = Error;
+
+ // Do some error handling stuff
+ qWarning( "KRFBConnection: Socket error %d", errno );
+
+ static QString refused = tr( "Connection Refused" );
+ static QString host = tr( "Host not found" );
+ static QString read = tr( "Read Error: QSocket reported an error reading\n"
+ "data, the remote host has probably dropped the\n"
+ "connection." );
+ static QString confused = tr( "QSocket reported an invalid error code" );
+
+ QString msg;
+ switch ( errno ) {
+ case QSocket::ErrConnectionRefused:
+ msg = refused;
+ break;
+ case QSocket::ErrHostNotFound:
+ msg = host;
+ break;
+ case QSocket::ErrSocketRead:
+ msg = read;
+ break;
+ default:
+ msg = confused;
+ };
+
+ QObject::disconnect( sock, SIGNAL( readyRead() ), this, SLOT( gotMoreData() ) );
+ delete sock;
+ sock = 0;
+ currentState_ = Disconnected;
+
+ emit error( msg );
+}
+
+void KRFBConnection::gotMoreData()
+{
+ assert( minData_ > 0 );
+
+ if ( sock->size() >= minData_ ) {
+ minData_ = 0;
+ QObject::disconnect( sock, SIGNAL( readyRead() ), this, SLOT( gotMoreData() ) );
+ emit gotEnoughData();
+ }
+}
+
+void KRFBConnection::waitForData( unsigned int sz )
+{
+ assert( minData_ == 0 );
+ assert( sz > 0 );
+ assert( currentState_ != Error );
+
+ if ( sock->size() >= sz ) {
+ // qWarning( "No need to wait for data" );
+ emit gotEnoughData();
+ }
+ else {
+ // qWarning( "Waiting for %u bytes", sz );
+
+ minData_ = sz;
+ connect( sock, SIGNAL( readyRead() ), SLOT( gotMoreData() ) );
+ }
+}
+
+int KRFBConnection::read( void *buf, int sz )
+{
+ return sock->readBlock( (char *) buf, sz );
+}
+
+int KRFBConnection::write( void *buf, int sz )
+{
+ return sock->writeBlock( (const char *) buf, sz );
+}
+
+KRFBConnection::State KRFBConnection::state() const
+{
+ return currentState_;
+}
+
+void KRFBConnection::setPortBase( int base )
+{
+ portBase_ = base;
+}
+
+int KRFBConnection::portBase() const
+{
+ return portBase_;
+}
+
+void KRFBConnection::setPassword( const QCString &pass )
+{
+ this->pass_ = pass;
+}
+
+void KRFBConnection::updateTimer()
+{
+ decoder_->sendUpdateRequest( true );
+}
+
+void KRFBConnection::refresh()
+{
+ decoder_->sendUpdateRequest( false );
+}
+
+void KRFBConnection::sendCutText( const QString &text )
+{
+ decoder_->sendCutEvent( text );
+}
+
+const QUrl &KRFBConnection::url()
+{
+ url_.setProtocol( "vnc" );
+ url_.setPort( display() );
+ url_.setHost( host() );
+ url_.setPath( "/" );
+
+ return url_;
+}
diff --git a/noncore/comm/keypebble/krfbconnection.h b/noncore/comm/keypebble/krfbconnection.h
new file mode 100644
index 0000000..fe477c1
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbconnection.h
@@ -0,0 +1,152 @@
+// -*- c++ -*-
+
+#ifndef KRFBCONNECTION_H
+#define KRFBCONNECTION_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qcstring.h>
+#include <qurl.h>
+
+class KRFBLogin;
+class KRBUpdateHandler;
+class KRFBOptions;
+class QSocket;
+class KRFBDecoder;
+class KRFBBuffer;
+class QTimer;
+
+/**
+ * Encapsulates the RFB socket.
+ *
+ */
+class KRFBConnection : public QObject
+{
+ Q_OBJECT
+
+public:
+ friend class KRFBLogin;
+ friend class KRFBDecoder;
+
+ //* The state of the connection.
+ enum State {
+ Connecting,
+ LoggingIn,
+ Connected,
+ Disconnecting,
+ Disconnected,
+ Error
+ };
+
+ KRFBConnection( QObject *parent = 0 );
+ ~KRFBConnection();
+
+ //* Get the state of a connection.
+ State state() const;
+
+ //* Get the options for this connection
+ KRFBOptions *options() const { return options_; };
+
+ KRFBBuffer *buffer() const { return buffer_; };
+
+ KRFBDecoder *decoder() const { return decoder_; };
+
+ //* Set the base from which the port for a given display will be calculated.
+ void setPortBase( int base );
+
+ //* Get the base from which the port for a given display is calculated.
+ int portBase() const;
+
+ //* Set the password which will be used to login
+ void setPassword( const QCString &pass );
+
+ //* Open a connection
+ void connectTo( const QCString &host, int display );
+
+ //* Close the connection
+ void disconnect();
+
+ //* Get the host
+ const QCString host() const { return host_; };
+
+ //* Get the display
+ int display() const { return display_; };
+
+ //* Get the current host/display as a URL
+ const QUrl &url();
+
+ //* Reload the display
+ void refresh();
+
+ //* Send text to the remote clipboard
+ void sendCutText( const QString & );
+
+protected slots:
+ //* When the shit hits the fan
+ void gotSocketError( int );
+
+ //* When we have an open socket
+ void gotSocketConnection();
+
+ //* When we have logged in
+ void gotRFBConnection();
+
+ //* When some more data arrived
+ void gotMoreData();
+
+ void updateTimer();
+
+ void disconnectDone();
+
+signals:
+ //* Emitted when the status of the connection changes.
+ void statusChanged( const QString & );
+
+ /**
+ * Emitted when we *really* need a password. If the password
+ * was specified before you tried to connect then you won't
+ * see this.
+ */
+ void passwordRequired( KRFBConnection * );
+
+ //* When we have a working RFB connection
+ void connected();
+
+ void loggedIn();
+
+ void disconnected();
+
+ //* What happened?
+ void error( const QString &msg );
+
+ //* Emitted in response to a waitForData() call.
+ void gotEnoughData();
+
+private:
+ //
+ // The following are called by our friends.
+ //
+
+ void waitForData( unsigned int );
+
+ int read( void *buf, int sz );
+ int write( void *buf, int sz );
+
+private:
+ QCString host_;
+ int portBase_;
+ int display_;
+ QCString pass_;
+ QSocket *sock;
+ State currentState_;
+ unsigned int minData_;
+ QTimer *updater;
+ KRFBLogin *login;
+ KRFBDecoder *decoder_;
+ KRFBOptions *options_;
+ KRFBBuffer *buffer_;
+ QUrl url_;
+};
+
+#endif // KRFBCONNECTION_H
+
diff --git a/noncore/comm/keypebble/krfbdecoder.cpp b/noncore/comm/keypebble/krfbdecoder.cpp
new file mode 100644
index 0000000..174dd7b
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbdecoder.cpp
@@ -0,0 +1,839 @@
+#include "krfbconnection.h"
+#include "krfboptions.h"
+#include "krfbserverinfo.h"
+#include "krfbdecoder.h"
+#include "krfbbuffer.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qpixmap.h>
+#include <qsocket.h>
+#include <qevent.h>
+#include <qstring.h>
+#include <qclipboard.h>
+
+#include <assert.h>
+
+//
+// Endian stuff
+//
+#ifndef KDE_USE_FINAL
+const int endianTest = 1;
+#endif
+
+#define Swap16IfLE(s) \
+ (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
+
+#define Swap32IfLE(l) \
+ (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
+ (((l) & 0x00ff0000) >> 8) | \
+ (((l) & 0x0000ff00) << 8) | \
+ (((l) & 0x000000ff) << 24)) : (l))
+
+//
+// The lengths of the messages we need to wait for
+//
+const int ServerInitLength = 24;
+const int UpdateHeaderLength = 4;
+const int RectHeaderLength = 12;
+const int RectChunkSize = 4;
+const int CopyRectPosLength = 4;
+const int ServerCutLenLength = 7;
+
+//
+// Client -> Server Message Identifiers
+//
+static CARD8 SetPixelFormatId = 0;
+//static CARD8 FixColourMapEntriesId = 1; // Not used
+static CARD8 SetEncodingsId = 2;
+static CARD8 UpdateRequestId = 3;
+static CARD8 KeyEventId = 4;
+static CARD8 PointerEventId = 5;
+static CARD8 ClientCutTextId = 6;
+
+//
+// Server -> Client Message Identifiers
+//
+static CARD8 UpdateId = 0;
+static CARD8 BellId = 2;
+static CARD8 ServerCutId = 3;
+
+//
+// Encoding identifiers
+//
+static CARD32 RawEncoding = Swap32IfLE( 0 );
+static CARD32 CopyRectEncoding = Swap32IfLE(1 );
+static CARD32 RreEncoding = Swap32IfLE( 2 );
+static CARD32 CorreEncoding = Swap32IfLE( 4 );
+static CARD32 HexTileEncoding = Swap32IfLE( 5 );
+
+static struct {
+ int keysym;
+ int keycode;
+} keyMap[] = {
+ { 0xff08, Qt::Key_Backspace },
+ { 0xff09, Qt::Key_Tab },
+ { 0xff0d, Qt::Key_Return },
+ { 0xff1b, Qt::Key_Escape },
+ { 0xff63, Qt::Key_Insert },
+ { 0xffff, Qt::Key_Delete },
+ { 0xff50, Qt::Key_Home },
+ { 0xff57, Qt::Key_End },
+ { 0xff55, Qt::Key_Prior },
+ { 0xff56, Qt::Key_Next },
+ { 0xff51, Qt::Key_Left },
+ { 0xff52, Qt::Key_Up },
+ { 0xff53, Qt::Key_Right },
+ { 0xff54, Qt::Key_Down },
+ { 0xffbe, Qt::Key_F1 },
+ { 0xffbf, Qt::Key_F2 },
+ { 0xffc0, Qt::Key_F3 },
+ { 0xffc1, Qt::Key_F4 },
+ { 0xffc2, Qt::Key_F5 },
+ { 0xffc3, Qt::Key_F6 },
+ { 0xffc4, Qt::Key_F7 },
+ { 0xffc5, Qt::Key_F8 },
+ { 0xffc6, Qt::Key_F9 },
+ { 0xffc7, Qt::Key_F10 },
+ { 0xffc8, Qt::Key_F11 },
+ { 0xffc9, Qt::Key_F12 },
+ { 0xffe1, Qt::Key_Shift },
+ { 0xffe2, Qt::Key_Shift },
+ { 0xffe3, Qt::Key_Control },
+ { 0xffe4, Qt::Key_Control },
+ { 0xffe7, Qt::Key_Meta },
+ { 0xffe8, Qt::Key_Meta },
+ { 0xffe9, Qt::Key_Alt },
+ { 0xffea, Qt::Key_Alt },
+ { 0, 0 }
+};
+
+
+KRFBDecoder::KRFBDecoder( KRFBConnection *con )
+ : QObject( con, "RFB Decoder" )
+{
+ assert( con );
+ assert( con->state() == KRFBConnection::Connected );
+
+ this->con = con;
+ this->buf = 0;
+ this->info = 0;
+ this->format = 0;
+ this->buttonMask = 0;
+ currentState = Idle;
+}
+
+KRFBDecoder::~KRFBDecoder()
+{
+ if ( info )
+ delete info;
+ if ( format )
+ delete format;
+}
+
+void KRFBDecoder::start()
+{
+ sendClientInit();
+}
+
+void KRFBDecoder::sendClientInit()
+{
+ con->write( &( con->options()->shared ), 1 );
+
+ // Wait for server init
+ qWarning( "Waiting for server init" );
+
+ static QString statusMsg = tr( "Waiting for server initialisation..." );
+ emit status( statusMsg );
+
+ currentState = AwaitingServerInit;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerInit() ) );
+ con->waitForData( ServerInitLength );
+}
+
+void KRFBDecoder::gotServerInit()
+{
+ qWarning( "Got server init" );
+ disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerInit() ) );
+
+ if ( info )
+ delete info;
+ info = new KRFBServerInfo;
+ CHECK_PTR( info );
+
+ con->read( &(info->width), 2 );
+ info->width = Swap16IfLE( info->width );
+ con->read( &info->height, 2 );
+ info->height = Swap16IfLE( info->height );
+
+ con->read( &(info->bpp), 1 );
+ con->read( &(info->depth), 1 );
+ con->read( &(info->bigEndian), 1 );
+ con->read( &(info->trueColor), 1 );
+
+ con->read( &(info->redMax), 2 );
+ info->redMax = Swap16IfLE( info->redMax );
+ con->read( &(info->greenMax), 2 );
+ info->greenMax = Swap16IfLE( info->greenMax );
+ con->read( &(info->blueMax), 2 );
+ info->blueMax = Swap16IfLE( info->blueMax );
+
+ con->read( &(info->redShift), 1 );
+ con->read( &(info->greenShift), 1 );
+ con->read( &(info->blueShift), 1 );
+
+ con->read( info->padding, 3 );
+
+ con->read( &(info->nameLength), 4 );
+ info->nameLength = Swap32IfLE( info->nameLength );
+
+ qWarning( "Width = %d, Height = %d", info->width, info->height );
+ qWarning( "Bpp = %d, Depth = %d, Big = %d, True = %d",
+ info->bpp, info->depth, info->bigEndian, info->trueColor );
+ qWarning( "RedMax = %d, GreenMax = %d, BlueMax = %d",
+ info->redMax, info->greenMax, info->blueMax );
+ qWarning( "RedShift = %d, GreenShift = %d, BlueShift = %d",
+ info->redShift, info->greenShift,info-> blueShift );
+
+ buf->resize( info->width, info->height );
+
+ // Wait for desktop name
+ qWarning( "Waiting for desktop name" );
+
+ static QString statusMsg = tr( "Waiting for desktop name..." );
+ emit status( statusMsg );
+
+ currentState = AwaitingDesktopName;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotDesktopName() ) );
+ con->waitForData( info->nameLength );
+}
+
+void KRFBDecoder::gotDesktopName()
+{
+ assert( info );
+ assert( currentState == AwaitingDesktopName );
+
+ qWarning( "Got desktop name" );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotDesktopName() ) );
+
+ char *buf = new char[ info->nameLength + 1 ];
+ CHECK_PTR( buf );
+
+ con->read( buf, info->nameLength );
+ buf[ info->nameLength ] = '\0';
+ info->name = buf;
+
+ qWarning( "Desktop: %s", info->name.latin1() );
+
+ delete buf;
+
+ // Get the format we'll really use and tell the server
+ decidePixelFormat();
+ sendPixelFormat();
+ sendAllowedEncodings();
+ currentState = Idle;
+
+ QString msg;
+ msg = tr( "Connected to %1" );
+ msg = msg.arg( info->name );
+ emit status( msg );
+
+ sendUpdateRequest( false );
+}
+
+void KRFBDecoder::decidePixelFormat()
+{
+ assert( info );
+
+ if ( format )
+ delete format;
+ format = new KRFBPixelFormat;
+ CHECK_PTR( format );
+
+ // What depth do we want?
+ //
+ // We'll use the minimum of the remote and local depths, UNLESS an
+ // eight bit session has been specifically requested by the user.
+ int screenDepth = QPixmap::defaultDepth();
+ int bestDepth = ( screenDepth > info->depth ) ? info->depth : screenDepth;
+ int chosenDepth;
+
+ if ( con->options()->colors256 )
+ chosenDepth = 8;
+ else
+ chosenDepth = bestDepth;
+
+ qWarning( "Screen depth=%d, server depth=%d, best depth=%d, " \
+ "eight bit %d, chosenDepth=%d",
+ screenDepth,
+ info->depth,
+ bestDepth,
+ con->options()->colors256, chosenDepth );
+
+ format->depth = chosenDepth;
+
+ // If we're using the servers native depth
+ if ( chosenDepth == info->depth ) {
+ // Use the servers native format
+ format->bpp = info->bpp;
+ // format->bigEndian = info->bigEndian;
+ format->bigEndian = true;
+ format->trueColor = info->trueColor;
+ format->redMax = info->redMax;
+ format->greenMax = info->greenMax;
+ format->blueMax = info->blueMax;
+ format->redShift = info->redShift;
+ format->greenShift = info->greenShift;
+ format->blueShift = info->blueShift;
+ }
+ else {
+ if ( chosenDepth == 8 ) {
+ format->bpp = 8;
+ format->bigEndian = true;
+ format->trueColor = true;
+ format->redMax = 7;
+ format->greenMax = 7;
+ format->blueMax = 3;
+ format->redShift = 0;
+ format->greenShift = 3;
+ format->blueShift = 6;
+ }
+ }
+
+ format->redMax = Swap16IfLE( format->redMax );
+ format->greenMax = Swap16IfLE( format->greenMax );
+ format->blueMax = Swap16IfLE( format->blueMax );
+}
+
+void KRFBDecoder::sendPixelFormat()
+{
+ static char padding[3];
+ con->write( &SetPixelFormatId, 1 );
+ con->write( padding, 3 );
+
+ con->write( &(format->bpp), 1 );
+ con->write( &(format->depth), 1 );
+ con->write( &(format->bigEndian), 1 );
+ con->write( &(format->trueColor), 1 );
+
+ con->write( &(format->redMax), 2 );
+ con->write( &(format->greenMax), 2 );
+ con->write( &(format->blueMax), 2 );
+
+ con->write( &(format->redShift), 1 );
+ con->write( &(format->greenShift), 1 );
+ con->write( &(format->blueShift), 1 );
+ con->write( format->padding, 3 ); // Padding
+}
+
+void KRFBDecoder::sendAllowedEncodings()
+{
+ static CARD8 padding[1];
+ con->write( &SetEncodingsId, 1 );
+ con->write( padding, 1 );
+
+ static CARD16 noEncodings = con->options()->encodings();
+ noEncodings = Swap16IfLE( noEncodings );
+ con->write( &noEncodings, 2 );
+
+ if ( con->options()->corre )
+ con->write( &CorreEncoding, 4 );
+ if ( con->options()->hexTile )
+ con->write( &HexTileEncoding, 4 );
+ if ( con->options()->rre )
+ con->write( &RreEncoding, 4 );
+ if ( con->options()->copyrect )
+ con->write( &CopyRectEncoding, 4 );
+ // We always support this
+ con->write( &RawEncoding, 4 );
+}
+
+void KRFBDecoder::sendUpdateRequest( bool incremental )
+{
+ if ( currentState != Idle )
+ return;
+
+ con->write( &UpdateRequestId, 1 );
+ con->write( &incremental, 1 );
+
+ static CARD16 x = 0, y = 0;
+ static CARD16 w = Swap16IfLE( info->width );
+ static CARD16 h = Swap16IfLE( info->height );
+
+ con->write( &x, 2 );
+ con->write( &y, 2 );
+ con->write( &w, 2 );
+ con->write( &h, 2 );
+
+ // Now wait for the update
+ currentState = AwaitingUpdate;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
+ con->waitForData( UpdateHeaderLength );
+}
+
+void KRFBDecoder::gotUpdateHeader()
+{
+ assert( currentState == AwaitingUpdate );
+
+ // qWarning( "Got update header" );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotUpdateHeader() ) );
+
+ CARD8 msgType;
+ con->read( &msgType, 1 );
+
+ if ( msgType != UpdateId ) {
+ // We might have a bell or server cut
+ if ( msgType == ServerCutId ) {
+ oldState = currentState;
+ gotServerCut();
+ }
+ else if ( msgType == BellId ) {
+ oldState = currentState;
+ gotBell();
+ }
+ else {
+ int msg = msgType;
+ QString protocolError = tr( "Protocol Error: Message Id %1 was "
+ "found when expecting an update "
+ "message." ).arg( msg );
+ currentState = Error;
+ emit error( protocolError );
+ }
+ return;
+ }
+
+ CARD8 padding;
+ con->read( &padding, 1 );
+
+ con->read( &noRects, 2 );
+ noRects = Swap16IfLE( noRects );
+
+ // qWarning( "Expecting %d rects", noRects );
+
+ // Now wait for the data
+ currentState = AwaitingRectHeader;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
+ con->waitForData( RectHeaderLength );
+}
+
+void KRFBDecoder::gotRectHeader()
+{
+ assert( currentState == AwaitingRectHeader );
+
+ // qWarning( "Got rect header" );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotRectHeader() ) );
+
+ con->read( &x, 2 );
+ x = Swap16IfLE( x );
+ con->read( &y, 2 );
+ y = Swap16IfLE( y );
+
+ con->read( &w, 2 );
+ w = Swap16IfLE( w );
+ con->read( &h, 2 );
+ h = Swap16IfLE( h );
+
+ con->read( &encoding, 4 );
+
+ // CARD32 encodingLocal = Swap32IfLE( encoding );
+ // qWarning( "Rect: x=%d, y= %d, w=%d, h=%d, encoding=%ld",
+ // x, y, w, h, encodingLocal );
+
+ //
+ // Each encoding needs to be handled differently. Some require
+ // waiting for more data, but others like a copyrect do not.
+ // Our constants have already been byte swapped, so we use
+ // the remote value as is.
+ //
+ if ( encoding == RawEncoding ) {
+ // qWarning( "Raw encoding" );
+ handleRawRect();
+ }
+ else if ( encoding == CopyRectEncoding ) {
+// qWarning( "CopyRect encoding" );
+ handleCopyRect();
+ }
+ else if ( encoding == RreEncoding ) {
+ qWarning( "RRE encoding" );
+ handleRRERect();
+ }
+ else if ( encoding == CorreEncoding ) {
+ qWarning( "CoRRE encoding" );
+ handleCoRRERect();
+ }
+ else if ( encoding == HexTileEncoding ) {
+ qWarning( "HexTile encoding" );
+ handleHexTileRect();
+ }
+ else {
+ int msg = Swap32IfLE( encoding );
+ QString protocolError = tr( "Protocol Error: An unknown encoding was "
+ "used by the server %1" ).arg( msg );
+ currentState = Error;
+ qWarning( "Unknown encoding, %d", msg );
+ emit error( protocolError );
+ return;
+ }
+}
+
+//
+// Raw Encoding
+//
+
+void KRFBDecoder::handleRawRect()
+{
+ // We need something a bit cleverer here to handle large
+ // rectanges nicely. The chunking should be based on the
+ // overall size (but has to be in complete lines).
+
+ // qWarning( "Handling a raw rect chunk" );
+
+ // CARD32 lineCount = w * format->bpp / 8;
+
+ if ( h > RectChunkSize ) {
+ // if ( con->sock->size() / lineCount ) {
+ // getRawRectChunk( con->sock->size() / lineCount );
+ // }
+ // else {
+ getRawRectChunk( RectChunkSize );
+ // }
+ }
+ else {
+ getRawRectChunk( h );
+ }
+}
+
+void KRFBDecoder::getRawRectChunk( int lines )
+{
+ this->lines = lines;
+ CARD32 count = lines * w * format->bpp / 8;
+
+ // Wait for server init
+ // qWarning( "Waiting for raw rect chunk, %ld", count );
+
+ currentState = AwaitingRawRectChunk;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRawRectChunk() ) );
+ con->waitForData( count );
+}
+
+void KRFBDecoder::gotRawRectChunk()
+{
+ assert( currentState == AwaitingRawRectChunk );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotRawRectChunk() ) );
+
+ // qWarning( "Got raw rect chunk" );
+
+ //
+ // Read the rect data and copy it to the buffer.
+ //
+
+ // TODO: Replace this!
+ int count = lines * w * format->bpp / 8;
+ char *hack = new char[ count ];
+ con->read( hack, count );
+ buf->drawRawRectChunk( hack, x, y, w, lines );
+ delete hack;
+ // /TODO:
+
+ h = h - lines;
+ y = y + lines;
+
+ if ( h > 0 ) {
+ handleRawRect();
+ }
+ else {
+ noRects--;
+
+ // qWarning( "There are %d rects left", noRects );
+
+ if ( noRects ) {
+ currentState = AwaitingRectHeader;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
+ con->waitForData( RectHeaderLength );
+ }
+ else
+ currentState = Idle;
+ }
+}
+
+//
+// Copy Rectangle Encoding
+//
+
+void KRFBDecoder::handleCopyRect()
+{
+ currentState = AwaitingCopyRectPos;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotCopyRectPos() ) );
+ con->waitForData( CopyRectPosLength );
+}
+
+void KRFBDecoder::gotCopyRectPos()
+{
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotCopyRectPos() ) );
+
+ CARD16 srcX;
+ CARD16 srcY;
+
+ con->read( &srcX, 2 );
+ con->read( &srcY, 2 );
+
+ srcX = Swap16IfLE( srcX );
+ srcY = Swap16IfLE( srcY );
+
+ buf->copyRect( srcX, srcY, x, y, w, h );
+
+ noRects--;
+
+ // qWarning( "There are %d rects left", noRects );
+
+ if ( noRects ) {
+ currentState = AwaitingRectHeader;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
+ con->waitForData( RectHeaderLength );
+ }
+ else
+ currentState = Idle;
+}
+
+void KRFBDecoder::handleRRERect()
+{
+ qWarning( "RRE not implemented" );
+}
+
+void KRFBDecoder::handleCoRRERect()
+{
+ qWarning( "CoRRE not implemented" );
+}
+
+void KRFBDecoder::handleHexTileRect()
+{
+ qWarning( "HexTile not implemented" );
+}
+
+void KRFBDecoder::sendMouseEvent( QMouseEvent *e )
+{
+ // Deal with the buttons
+ if ( e->type() != QEvent::MouseMove ) {
+ buttonMask = 0;
+ if ( e->type() == QEvent::MouseButtonPress ) {
+ if ( e->button() & LeftButton )
+ buttonMask |= 0x01;
+ if ( e->button() & MidButton )
+ buttonMask |= 0x04;
+ if ( e->button() & RightButton )
+ buttonMask |= 0x02;
+ }
+ else if ( e->type() == QEvent::MouseButtonRelease ) {
+ if ( e->button() & LeftButton )
+ buttonMask &= 0x06;
+ if ( e->button() & MidButton )
+ buttonMask |= 0x03;
+ if ( e->button() & RightButton )
+ buttonMask |= 0x05;
+ }
+ }
+
+ CARD16 x = Swap16IfLE( e->x() );
+ CARD16 y = Swap16IfLE( e->y() );
+
+ con->write( &PointerEventId, 1 );
+ con->write( &buttonMask, 1 );
+ con->write( &x, 2 );
+ con->write( &y, 2 );
+}
+
+
+void KRFBDecoder::sendCutEvent( const QString &unicode )
+{
+ //
+ // Warning: There is a bug in the RFB protocol because there is no way to find
+ // out the codepage in use on the remote machine. This could be fixed by requiring
+ // the remote server to use utf8 etc. but for now we have to assume they're the
+ // same. I've reported this problem to the ORL guys, but they apparantly have no
+ // immediate plans to fix the issue. :-( (rich)
+ //
+
+ CARD8 padding[3];
+ QCString text = unicode.local8Bit();
+ CARD32 length = text.length();
+ length = Swap32IfLE( length );
+
+ con->write( &ClientCutTextId, 1 );
+ con->write( &padding, 3 );
+ con->write( &length, 4 );
+ con->write( text.data(), length );
+}
+
+void KRFBDecoder::gotServerCut()
+{
+ qWarning( "Got server cut" );
+
+ currentState = AwaitingServerCutLength;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutLength() ) );
+ con->waitForData( ServerCutLenLength );
+}
+
+void KRFBDecoder::gotServerCutLength()
+{
+ assert( currentState = AwaitingServerCutLength );
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotServerCutLength() ) );
+
+ CARD8 padding[3];
+ con->read( padding, 3 );
+
+ con->read( &serverCutTextLen, 4 );
+ serverCutTextLen = Swap32IfLE( serverCutTextLen );
+
+ currentState = AwaitingServerCutText;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutText() ) );
+ con->waitForData( serverCutTextLen );
+}
+
+void KRFBDecoder::gotServerCutText()
+{
+ assert( currentState = AwaitingServerCutText );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotServerCutText() ) );
+
+ //
+ // Warning: There is a bug in the RFB protocol because there is no way to find
+ // out the codepage in use on the remote machine. This could be fixed by requiring
+ // the remote server to use utf8 etc. but for now we have to assume they're the
+ // same. I've reported this problem to the ORL guys, but they apparantly have no
+ // immediate plans to fix the issue. :-( (rich)
+ //
+
+ char *cutbuf = new char[ serverCutTextLen + 1 ];
+ CHECK_PTR( cutbuf );
+
+ con->read( cutbuf, serverCutTextLen );
+ cutbuf[ serverCutTextLen ] = '\0';
+
+ qWarning( "Server cut: %s", cutbuf );
+
+ QString cutText( cutbuf ); // DANGER!!
+ qApp->clipboard()->setText( cutText );
+
+ delete cutbuf;
+
+ // Now wait for the update (again)
+ if ( oldState == AwaitingUpdate ) {
+ currentState = AwaitingUpdate;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
+ con->waitForData( UpdateHeaderLength );
+ }
+ else if ( oldState == Idle ) {
+ currentState = Idle;
+ }
+ else {
+ qWarning( "Async handled in weird state" );
+ currentState = oldState;
+ };
+}
+
+void KRFBDecoder::gotBell()
+{
+ qWarning( "Got server bell" );
+ buf->soundBell();
+
+ // Now wait for the update (again)
+ if ( oldState == AwaitingUpdate ) {
+ currentState = AwaitingUpdate;
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
+ con->waitForData( UpdateHeaderLength );
+ }
+ else if ( oldState == Idle ) {
+ currentState = Idle;
+ }
+ else {
+ qWarning( "Async handled in weird state" );
+ currentState = oldState;
+ };
+}
+
+void KRFBDecoder::sendKeyPressEvent( QKeyEvent *event )
+{
+ int key;
+ key = toKeySym( event );
+ if ( key ) {
+ key = Swap32IfLE( key );
+
+ CARD8 mask = true;
+
+ CARD16 padding = 0;
+ con->write( &KeyEventId, 1 );
+ con->write( &mask, 1 );
+ con->write( &padding, 2 );
+ con->write( &key, 4 );
+ }
+}
+
+void KRFBDecoder::sendKeyReleaseEvent( QKeyEvent *event )
+{
+ int key;
+ key = toKeySym( event );
+ if ( key ) {
+ key = Swap32IfLE( key );
+
+ CARD8 mask = false;
+
+ CARD16 padding = 0;
+ con->write( &KeyEventId, 1 );
+ con->write( &mask, 1 );
+ con->write( &padding, 2 );
+ con->write( &key, 4 );
+ }
+}
+
+int KRFBDecoder::toKeySym( QKeyEvent *k )
+{
+ int ke = 0;
+
+ ke = k->ascii();
+ // Markus: Crappy hack. I dont know why lower case letters are
+ // not defined in qkeydefs.h. The key() for e.g. 'l' == 'L'.
+ // This sucks. :-(
+
+ if ( (ke == 'a') || (ke == 'b') || (ke == 'c') || (ke == 'd')
+ || (ke == 'e') || (ke == 'f') || (ke == 'g') || (ke == 'h')
+ || (ke == 'i') || (ke == 'j') || (ke == 'k') || (ke == 'l')
+ || (ke == 'm') || (ke == 'n') || (ke == 'o') || (ke == 'p')
+ || (ke == 'q') || (ke == 'r') || (ke == 's') || (ke == 't')
+ || (ke == 'u') || (ke == 'v') ||( ke == 'w') || (ke == 'x')
+ || (ke == 'y') || (ke == 'z') ) {
+ ke = k->key();
+ ke = ke + 0x20;
+ return ke;
+ }
+
+ // qkeydefs = xkeydefs! :-)
+ if ( ( k->key() >= 0x0a0 ) && k->key() <= 0x0ff )
+ return k->key();
+
+ if ( ( k->key() >= 0x20 ) && ( k->key() <= 0x7e ) )
+ return k->key();
+
+ // qkeydefs != xkeydefs! :-(
+ // This is gonna suck :-(
+
+ int i = 0;
+ while ( keyMap[i].keycode ) {
+ if ( k->key() == keyMap[i].keycode )
+ return keyMap[i].keysym;
+ i++;
+ }
+
+ return 0;
+}
+
diff --git a/noncore/comm/keypebble/krfbdecoder.h b/noncore/comm/keypebble/krfbdecoder.h
new file mode 100644
index 0000000..4ba0185
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbdecoder.h
@@ -0,0 +1,134 @@
+// -*- c++ -*-
+
+#ifndef KRFBDECODER_H
+#define KRFBDECODER_H
+
+#include <qobject.h>
+
+class KRFBConnection;
+class KRFBServerInfo;
+class KRFBPixelFormat;
+class KRFBBuffer;
+
+
+typedef unsigned char CARD8;
+typedef unsigned short CARD16;
+typedef unsigned long CARD32;
+
+/**
+ * Negotiates the pixel format to be used then decodes the resulting
+ * data stream.
+ *
+ * @author Richard Moore, rich@kde.org
+ */
+class KRFBDecoder : public QObject
+{
+ Q_OBJECT
+
+public:
+ friend class KRFBBuffer;
+
+ enum State {
+ AwaitingServerInit,
+ AwaitingDesktopName,
+ AwaitingUpdate,
+ AwaitingRectHeader,
+ AwaitingRawRectChunk,
+ AwaitingCopyRectPos,
+ AwaitingServerCutLength,
+ AwaitingServerCutText,
+ Idle,
+ Error
+ };
+
+ /**
+ * Create a KRFBDecoder that reads data from a logged in KRFBConnection
+ * and sends its output to a KRFBBuffer.
+ */
+ KRFBDecoder( KRFBConnection *con );
+ ~KRFBDecoder();
+
+ void setBuffer( KRFBBuffer *buf ) { this->buf = buf; };
+ void start();
+
+ int toKeySym( QKeyEvent *k );
+
+ //
+ // Client -> Server messages
+ //
+ void sendUpdateRequest( bool incremental );
+ void sendMouseEvent( QMouseEvent *e );
+ void sendKeyPressEvent( QKeyEvent *e );
+ void sendKeyReleaseEvent( QKeyEvent *e );
+ void sendCutEvent( const QString &text );
+
+protected:
+ //
+ // Initial format negotiation
+ //
+ void decidePixelFormat();
+ void sendPixelFormat();
+ void sendClientInit();
+ void sendAllowedEncodings();
+
+ //
+ // Rectange processing
+ //
+ void handleRawRect();
+ void handleCopyRect();
+ void handleRRERect();
+ void handleCoRRERect();
+ void handleHexTileRect();
+
+ void getRawRectChunk( int lines );
+
+protected slots:
+ void gotServerInit();
+ void gotDesktopName();
+ void gotUpdateHeader();
+ void gotRectHeader();
+ void gotRawRectChunk();
+ void gotCopyRectPos();
+ void gotServerCut();
+ void gotServerCutLength();
+ void gotServerCutText();
+ void gotBell();
+
+signals:
+ void error( const QString & );
+ void status( const QString & );
+
+private:
+ State currentState;
+
+ // Used to store the state we were in before a cut or bell msg
+ State oldState;
+
+ // The number of rects we're expecting
+ CARD16 noRects;
+
+ //
+ // Info about the current rect.
+ //
+ CARD16 x, y, w, h;
+ int lines;
+ CARD32 encoding;
+
+ CARD32 serverCutTextLen;
+
+ /** Where we draw the data (and the source of our events). */
+ KRFBBuffer *buf;
+ /** The connection to the server. */
+ KRFBConnection *con;
+
+ /** Info about the RFB server. */
+ KRFBServerInfo *info;
+ /** The pixel format we want. */
+ KRFBPixelFormat *format;
+
+ CARD8 buttonMask;
+};
+
+#endif // KRFBDECODER_H
+
+
diff --git a/noncore/comm/keypebble/krfblogin.cpp b/noncore/comm/keypebble/krfblogin.cpp
new file mode 100644
index 0000000..073ba0e
--- a/dev/null
+++ b/noncore/comm/keypebble/krfblogin.cpp
@@ -0,0 +1,255 @@
+#include <assert.h>
+
+
+extern "C" {
+#include "vncauth.h"
+}
+
+#include "krfblogin.h"
+#include "krfbconnection.h"
+#include <qtimer.h>
+
+// The length of the various messages (used to decide how many bytes to
+// wait for).
+const int ServerVersionLength = 12;
+const int ClientVersionLength = 12;
+const int AuthSchemeLength = 4;
+const int FailureReasonSizeLength = 4;
+const int ChallengeLength = 16;
+const int AuthResultLength = 4;
+
+// Authentication results
+enum AuthResult {
+ AuthOk,
+ AuthFailed,
+ AuthTooMany
+};
+
+typedef unsigned char CARD8;
+typedef unsigned short CARD16;
+typedef unsigned long CARD32;
+
+const int endianTest = 1;
+
+// Endian stuff
+#define Swap16IfLE(s) \
+ (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
+
+#define Swap32IfLE(l) \
+ (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
+ (((l) & 0x00ff0000) >> 8) | \
+ (((l) & 0x0000ff00) << 8) | \
+ (((l) & 0x000000ff) << 24)) : (l))
+
+KRFBLogin::KRFBLogin( KRFBConnection *con )
+ : QObject( con, "RFB login manager" )
+{
+ assert( con );
+ this->con = con;
+ currentState = AwaitingServerVersion;
+
+ connect( this, SIGNAL( error( const QString & ) ),
+ con, SIGNAL( error( const QString & ) ) );
+
+ connect( this, SIGNAL( passwordRequired( KRFBConnection * ) ),
+ con, SIGNAL( passwordRequired( KRFBConnection * ) ) );
+
+ qWarning( "Waiting for server version..." );
+
+ static QString statusMsg = tr( "Waiting for server version..." );
+ emit status( statusMsg );
+
+ // Kick off the state machine
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerVersion() ) );
+ con->waitForData( ServerVersionLength );
+}
+
+KRFBLogin::~KRFBLogin()
+{
+
+}
+
+KRFBLogin::State KRFBLogin::state() const
+{
+ return currentState;
+}
+
+void KRFBLogin::gotServerVersion()
+{
+ qWarning( "Got server version" );
+
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotServerVersion() ) );
+
+ // Read the server's version message
+ char serverVersion[ ServerVersionLength + 1 ];
+ con->read( serverVersion, ServerVersionLength );
+ serverVersion[ ServerVersionLength ] = '\0';
+
+ QCString rfbString( serverVersion, ServerVersionLength + 1 );
+ versionString = rfbString;
+
+ QRegExp regexp( "RFB [0-9][0-9][0-9]\\.[0-9][0-9][0-9]\n" );
+
+ if ( rfbString.find( regexp ) == -1 ) {
+ static QString msg = tr( "Error: Invalid server version, %1" ).arg( rfbString );
+
+ qWarning( msg );
+ emit error( msg );
+ currentState = Error;
+ return;
+ }
+
+ // Calculate the actual version number
+ serverMajor = (serverVersion[4] - '0') * 100
+ + (serverVersion[5] - '0') * 10
+ + (serverVersion[6] - '0');
+ serverMinor = (serverVersion[8] - '0') * 100
+ + (serverVersion[9] - '0') * 10
+ + (serverVersion[10] - '0');
+
+ qWarning("Server Version: %03d.%03d", serverMajor, serverMinor );
+
+ if ( serverMajor != 3 ) {
+ QString msg = tr( "Error: Unsupported server version, %1" )
+ .arg( rfbString );
+
+ qWarning( msg );
+ emit error( msg );
+ currentState = Error;
+ return;
+ }
+
+ if ( serverMinor != 3 ) {
+ qWarning( "Minor version mismatch: %d", serverMinor );
+ }
+
+ // Setup for the next state
+ sendClientVersion();
+
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthScheme() ) );
+ con->waitForData( AuthSchemeLength );
+}
+
+void KRFBLogin::gotAuthScheme()
+{
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotAuthScheme() ) );
+
+ // Got data
+ CARD32 scheme;
+ con->read( &scheme, AuthSchemeLength );
+ scheme = Swap32IfLE( scheme );
+
+ static QString statusMsgOk = tr( "Logged in" );
+
+ switch ( scheme ) {
+ case 0:
+ qWarning( "Failed" );
+ // Handle failure
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotFailureReasonSize() ) );
+ con->waitForData( FailureReasonSizeLength );
+ break;
+ case 1:
+ // Handle no auth
+ emit status( statusMsgOk );
+ con->gotRFBConnection();
+ break;
+ case 2:
+ // Handle VNC auth
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotChallenge() ) );
+ con->waitForData( ChallengeLength );
+ break;
+ default:
+ qWarning( "Unknown authentication scheme, 0x%08lx", scheme );
+ currentState = Error;
+ break;
+ };
+}
+
+void KRFBLogin::gotChallenge()
+{
+ disconnect( con, SIGNAL( gotEnoughData() ),
+ this, SLOT( gotChallenge() ) );
+
+ QTimer::singleShot( 0, this, SLOT(getPassword()) );
+}
+
+void KRFBLogin::getPassword()
+{
+ // Got data
+ CARD8 challenge[ ChallengeLength ];
+ con->read( challenge, ChallengeLength );
+
+ // Last chance to enter a password
+ if ( con->pass_.isNull() ) {
+ qWarning( "krfblogin needs a password" );
+ emit passwordRequired( con );
+ }
+
+ if ( con->pass_.isNull() ) {
+ QString msg = tr( "Error: This server requires a password, but none "
+ "has been specified.\n" );
+
+ emit error( msg );
+ return;
+ }
+
+ vncEncryptBytes( (unsigned char *) challenge, con->pass_.data() );
+ con->write( challenge, ChallengeLength );
+
+ connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthResult() ) );
+ con->waitForData( AuthResultLength );
+}
+
+void KRFBLogin::gotFailureReasonSize()
+{
+ disconnect( con, SIGNAL( gotEnoughData() ), this,
+ SLOT( gotFailureReasonSize() ) );
+}
+
+void KRFBLogin::gotAuthResult()
+{
+ // Got data
+ disconnect( con, SIGNAL( gotEnoughData() ), this,
+ SLOT( gotAuthResult() ) );
+
+ long result;
+ con->read( &result, AuthResultLength );
+ result = Swap32IfLE( result );
+
+ qWarning( "Authentication Result is 0x%08lx", result );
+
+ static QString failed = tr( "Error: The password you specified was incorrect." );
+ static QString tooMany = tr( "Error: Too many invalid login attempts have been made\n"
+ "to this account, please try later." );
+
+ static QString statusMsgOk = tr( "Logged in" );
+ static QString statusMsgFailed = tr( "Login Failed" );
+ static QString statusMsgTooMany = tr( "Too many failures" );
+
+ switch( result ) {
+ case AuthOk:
+ emit status( statusMsgOk );
+ con->gotRFBConnection();
+ break;
+ case AuthFailed:
+ qWarning( "Dammit" );
+ emit status( statusMsgFailed );
+ emit error( failed );
+ break;
+ case AuthTooMany:
+ emit status( statusMsgTooMany );
+ emit error( tooMany );
+ break;
+ default:
+ qWarning( "Invalid authentication result, %lx", result );
+ break;
+ }
+}
+
+void KRFBLogin::sendClientVersion()
+{
+ qWarning( "Sending client version" );
+ con->write( (void*)"RFB 003.003\n", ClientVersionLength );
+}
diff --git a/noncore/comm/keypebble/krfblogin.h b/noncore/comm/keypebble/krfblogin.h
new file mode 100644
index 0000000..5208210
--- a/dev/null
+++ b/noncore/comm/keypebble/krfblogin.h
@@ -0,0 +1,62 @@
+// -*- c++ -*-
+
+#ifndef KRFBLOGIN_H
+#define KRFBLOGIN_H
+
+#include <qobject.h>
+
+class KRFBConnection;
+
+/**
+ * Handles logging into the RFB server.
+ *
+ * @version $Id$
+ * @author Richard Moore, rich@kde.org
+ */
+class KRFBLogin : QObject
+{
+ Q_OBJECT
+
+public:
+ enum State {
+ AwaitingServerVersion,
+ AwaitingAuthScheme,
+ AwaitingChallenge,
+ WaitingForResponse,
+ Authenticated,
+ Ready,
+ Failed,
+ Error
+ };
+
+ KRFBLogin( KRFBConnection *con );
+ ~KRFBLogin();
+
+ KRFBLogin::State state() const;
+
+protected:
+ void sendClientVersion();
+
+protected slots:
+ void getPassword();
+ void gotServerVersion();
+ void gotAuthScheme();
+ void gotChallenge();
+ void gotAuthResult();
+ void gotFailureReasonSize();
+
+signals:
+ void passwordRequired( KRFBConnection * );
+ void error( const QString & );
+ void status( const QString & );
+
+private:
+ KRFBConnection *con;
+ State currentState;
+ QCString versionString;
+ int serverMajor;
+ int serverMinor;
+};
+
+#endif // KRFBLOGIN_H
+
diff --git a/noncore/comm/keypebble/krfboptions.cpp b/noncore/comm/keypebble/krfboptions.cpp
new file mode 100644
index 0000000..9daf3f0
--- a/dev/null
+++ b/noncore/comm/keypebble/krfboptions.cpp
@@ -0,0 +1,52 @@
+#include <qpe/config.h>
+#include <qpe/qpeapplication.h>
+#include "krfboptions.h"
+
+KRFBOptions::KRFBOptions()
+{
+ Config config( "keypebble" );
+ readSettings( &config );
+}
+
+KRFBOptions::~KRFBOptions()
+{
+ Config config( "keypebble" );
+ writeSettings( &config );
+}
+
+void KRFBOptions::readSettings( Config *config )
+{
+ hexTile = config->readBoolEntry( "HexTile" );
+ corre = config->readBoolEntry( "CORRE" );
+ rre = config->readBoolEntry( "RRE" );
+ copyrect = config->readBoolEntry( "CopyRect", true );
+ colors256 = config->readBoolEntry( "Colors256" );
+ shared = config->readBoolEntry( "Shared" );
+ readOnly = config->readBoolEntry( "ReadOnly" );
+ updateRate = config->readNumEntry( "UpdateRate", 50 );
+}
+
+void KRFBOptions::writeSettings( Config *config )
+{
+ config->writeEntry( "HexTile", hexTile );
+ config->writeEntry( "CORRE", corre );
+ config->writeEntry( "RRE", rre );
+ config->writeEntry( "CopyRect", copyrect );
+ config->writeEntry( "Colors256", colors256 );
+ config->writeEntry( "Shared", shared );
+ config->writeEntry( "ReadOnly", readOnly );
+ config->writeEntry( "UpdateRate", updateRate );
+}
+
+int KRFBOptions::encodings()
+{
+ // Initially one because we always support raw encoding
+ int count = 1;
+
+ count += hexTile ? 1 : 0;
+ count += corre ? 1 : 0;
+ count += rre ? 1 : 0;
+ count += copyrect ? 1 : 0;
+
+ return count;
+}
diff --git a/noncore/comm/keypebble/krfboptions.h b/noncore/comm/keypebble/krfboptions.h
new file mode 100644
index 0000000..41cea35
--- a/dev/null
+++ b/noncore/comm/keypebble/krfboptions.h
@@ -0,0 +1,31 @@
+// -*- c++ -*-
+
+#ifndef KRFBOPTIONS_H
+#define KRFBOPTIONS_H
+
+class Config;
+
+class KRFBOptions
+{
+public:
+ KRFBOptions();
+ ~KRFBOptions();
+
+ int encodings();
+ void readSettings( Config *config );
+ void writeSettings( Config *config );
+
+ bool hexTile;
+ bool corre;
+ bool rre;
+ bool copyrect;
+
+ bool colors256;
+ bool shared;
+ bool readOnly;
+ bool deIconify;
+
+ int updateRate;
+};
+
+#endif // KRFBOPTIONS_H
diff --git a/noncore/comm/keypebble/krfbserverinfo.h b/noncore/comm/keypebble/krfbserverinfo.h
new file mode 100644
index 0000000..7449da9
--- a/dev/null
+++ b/noncore/comm/keypebble/krfbserverinfo.h
@@ -0,0 +1,42 @@
+// -*- c++ -*-
+
+#ifndef KRFBSERVERINFO_H
+#define KRFBSERVERINFO_H
+
+#include <qstring.h>
+
+typedef unsigned char CARD8;
+typedef unsigned short CARD16;
+typedef unsigned long CARD32;
+
+class KRFBPixelFormat
+{
+public:
+ CARD8 bpp;
+ CARD8 depth;
+ CARD8 bigEndian;
+ CARD8 trueColor;
+ CARD16 redMax;
+ CARD16 greenMax;
+ CARD16 blueMax;
+ CARD8 redShift;
+ CARD8 greenShift;
+ CARD8 blueShift;
+ CARD8 padding[3]; // 3 bytes padding
+};
+
+/**
+ * Information sent by the server in its init message.
+ */
+class KRFBServerInfo : public KRFBPixelFormat
+{
+public:
+ CARD16 width;
+ CARD16 height;
+ CARD32 nameLength;
+ QString name;
+};
+
+#endif // KRFBSERVERINFO_H
+
+
diff --git a/noncore/comm/keypebble/kvnc.cpp b/noncore/comm/keypebble/kvnc.cpp
new file mode 100644
index 0000000..bb18999
--- a/dev/null
+++ b/noncore/comm/keypebble/kvnc.cpp
@@ -0,0 +1,191 @@
+#include <qiconset.h>
+#include <qdialog.h>
+#include <qpixmap.h>
+#include <qdom.h>
+#include <qaction.h>
+#include <qpe/qpemenubar.h>
+#include <qstatusbar.h>
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qpe/qpetoolbar.h>
+#include <qtimer.h>
+#include <qmessagebox.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/global.h>
+#include <assert.h>
+
+#include "kvnc.h"
+#include "krfbcanvas.h"
+#include "kvncoptionsdlg.h"
+#include "krfbconnection.h"
+
+
+/* XPM */
+static char * menu_xpm[] = {
+"12 12 5 1",
+" c None",
+". c #000000",
+"+ c #FFFDAD",
+"@ c #FFFF00",
+"# c #E5E100",
+" ",
+" ",
+" ......... ",
+" .+++++++. ",
+" .+@@@@#. ",
+" .+@@@#. ",
+" .+@@#. ",
+" .+@#. ",
+" .+#. ",
+" .+. ",
+" .. ",
+" "};
+
+const int StatusTextId = 0;
+
+KVNC::KVNC( const char *name ) : QMainWindow( 0, name )
+{
+ setCaption( tr("VNC Viewer") );
+ fullscreen = false;
+
+ canvas = new KRFBCanvas( this, "canvas" );
+ setCentralWidget( canvas );
+
+ connect( canvas->connection(), SIGNAL(statusChanged(const QString &)),
+ this, SLOT(statusMessage(const QString &)) );
+ connect( canvas->connection(), SIGNAL(error(const QString &)),
+ this, SLOT(error(const QString &)) );
+ connect( canvas->connection(), SIGNAL(connected()), this, SLOT(connected()) );
+ connect( canvas->connection(), SIGNAL(loggedIn()), this, SLOT(loggedIn()) );
+ connect( canvas->connection(), SIGNAL(disconnected()), this, SLOT(disconnected()) );
+
+ setupActions();
+
+ cornerButton = new QPushButton( this );
+ cornerButton->setPixmap( QPixmap( (const char**)menu_xpm ) );
+ connect( cornerButton, SIGNAL(pressed()), this, SLOT(showMenu()) );
+ canvas->setCornerWidget( cornerButton );
+
+ QTimer::singleShot( 0, canvas, SLOT(openConnection()) );
+}
+
+KVNC::~KVNC()
+{
+
+}
+
+void KVNC::openURL( const QUrl &url )
+{
+ canvas->openURL( url );
+}
+
+void KVNC::setupActions()
+{
+ cornerMenu = new QPopupMenu( this );
+
+ fullScreenAction = new QAction( tr("Full Screen"), QString::null, 0, 0 );
+ connect( fullScreenAction, SIGNAL(activated()),
+ this, SLOT( toggleFullScreen() ) );
+ fullScreenAction->addTo( cornerMenu );
+ fullScreenAction->setEnabled( false );
+
+ optionsAction = new QAction( tr("Settings"), QString::null, 0, 0 );
+ connect( optionsAction, SIGNAL(activated()), this, SLOT( showOptions() ) );
+ optionsAction->addTo( cornerMenu );
+
+ connectAction = new QAction( tr("Connect..."), QString::null, 0, 0 );
+ connect( connectAction, SIGNAL(activated()),
+ canvas, SLOT( openConnection() ) );
+ connectAction->addTo( cornerMenu );
+
+ disconnectAction = new QAction( tr("Disconnect"), QString::null, 0, 0 );
+ connect( disconnectAction, SIGNAL(activated()),
+ this, SLOT( closeConnection() ) );
+ disconnectAction->addTo( cornerMenu );
+ disconnectAction->setEnabled( false );
+}
+
+void KVNC::toggleFullScreen()
+{
+ if ( fullscreen ) {
+ canvas->releaseKeyboard();
+ canvas->reparent( this, 0, QPoint(0,0), false );
+ canvas->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ setCentralWidget( canvas );
+ canvas->show();
+ fullScreenAction->setText( tr("Full Screen") );
+ } else {
+ canvas->setFrameStyle( QFrame::NoFrame );
+ canvas->reparent( 0,WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop,
+ QPoint(0,0),false);
+ canvas->resize(qApp->desktop()->width(), qApp->desktop()->height());
+ canvas->raise();
+ canvas->setFocus();
+ canvas->grabKeyboard();
+ canvas->show();
+
+ fullScreenAction->setText( tr("Stop Full Screen") );
+ }
+
+ fullscreen = !fullscreen;
+}
+
+void KVNC::closeConnection()
+{
+ if ( fullscreen )
+ toggleFullScreen();
+ canvas->closeConnection();
+}
+
+void KVNC::showMenu()
+{
+ QPoint pt = mapToGlobal(cornerButton->pos());
+ QSize s = cornerMenu->sizeHint();
+ pt.ry() -= s.height();
+ pt.rx() -= s.width();
+ cornerMenu->popup( pt );
+}
+
+void KVNC::connected()
+{
+ static QString msg = tr( "Connected to remote host" );
+ statusMessage( msg );
+ connectAction->setEnabled( false );
+ disconnectAction->setEnabled( true );
+ fullScreenAction->setEnabled( true );
+}
+
+void KVNC::loggedIn()
+{
+ static QString msg = tr( "Logged in to remote host" );
+ statusMessage( msg );
+}
+
+void KVNC::disconnected()
+{
+ static QString msg = tr( "Connection closed" );
+ statusMessage( msg );
+ connectAction->setEnabled( true );
+ disconnectAction->setEnabled( false );
+ fullScreenAction->setEnabled( false );
+}
+
+void KVNC::statusMessage( const QString &m )
+{
+ Global::statusMessage( m );
+}
+
+void KVNC::error( const QString &msg )
+{
+ statusMessage( msg );
+ QMessageBox::warning( this, tr("VNC Viewer"), msg );
+}
+
+void KVNC::showOptions()
+{
+ KVNCOptionsDlg *wdg = new KVNCOptionsDlg( canvas->connection()->options(), this );
+ wdg->showMaximized();
+ wdg->exec();
+ delete wdg;
+}
+
diff --git a/noncore/comm/keypebble/kvnc.h b/noncore/comm/keypebble/kvnc.h
new file mode 100644
index 0000000..92666c5
--- a/dev/null
+++ b/noncore/comm/keypebble/kvnc.h
@@ -0,0 +1,56 @@
+// -*- c++ -*-
+
+#ifndef KVNC_H
+#define KVNC_H
+
+#include <qmainwindow.h>
+#include <qurl.h>
+
+class QAction;
+class KRFBCanvas;
+class QPushButton;
+class QToolBar;
+
+/**
+ * Top level window for Keystone.
+ *
+ * @author Richard Moore, rich@kde.org
+ * @version $Id$
+ */
+class KVNC : public QMainWindow
+{
+ Q_OBJECT
+public:
+ KVNC( const char *name = 0 );
+ ~KVNC();
+
+public slots:
+ void toggleFullScreen();
+ void openURL( const QUrl & );
+ void closeConnection();
+ void showOptions();
+
+protected:
+ void setupActions();
+
+protected slots:
+ void showMenu();
+
+ void connected();
+ void loggedIn();
+ void disconnected();
+ void statusMessage( const QString & );
+ void error( const QString & );
+
+private:
+ bool fullscreen;
+ KRFBCanvas *canvas;
+ QPopupMenu *cornerMenu;
+ QPushButton *cornerButton;
+ QAction *fullScreenAction;
+ QAction *optionsAction;
+ QAction *disconnectAction;
+ QAction *connectAction;
+};
+
+#endif // KVNC_H
diff --git a/noncore/comm/keypebble/kvncconnectdlg.cpp b/noncore/comm/keypebble/kvncconnectdlg.cpp
new file mode 100644
index 0000000..467cebf
--- a/dev/null
+++ b/noncore/comm/keypebble/kvncconnectdlg.cpp
@@ -0,0 +1,79 @@
+#include <qstring.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qfont.h>
+
+#include <assert.h>
+
+#include "krfbconnection.h"
+#include "kvncoptionsdlg.h"
+#include "kvncconnectdlg.h"
+
+
+KVNCConnectDlg::KVNCConnectDlg( KRFBConnection *con,
+ QWidget *parent, const char *name )
+ : QDialog( parent, name, true )
+{
+ setCaption( tr("Connect to VNC server") );
+ assert( con );
+ this->con = con;
+
+ QGridLayout *inner = new QGridLayout( this, 3, 2, 6 );
+
+ QLabel *label = new QLabel( tr("Host Name:"),
+ this , "hostLabel");
+ hostNameCombo = new QComboBox( true, this );
+ hostNameCombo->setInsertionPolicy( QComboBox::AtTop );
+ hostNameCombo->setMaxCount( 10 );
+ hostNameCombo->insertItem( "localhost" );
+ hostNameCombo->setFocus();
+
+ inner->addWidget( label, 0, 0 );
+ inner->addWidget( hostNameCombo, 0, 1 );
+
+ label = new QLabel( tr("Display Number:"), this, "displayNumber" );
+ displayNumberEdit = new QSpinBox( this );
+
+ inner->addWidget( label, 1, 0 );
+ inner->addWidget( displayNumberEdit, 1, 1 );
+
+ // if ( viewer->display() != -1 ) {
+ // displayNumberEdit->setValue( viewer->display() );
+ displayNumberEdit->setValue( 1 );
+ // }
+
+ label = new QLabel( tr("Password:"), this );
+ inner->addWidget( label, 2, 0 );
+
+ passwordEdit = new QLineEdit( this );
+ passwordEdit->setEchoMode( QLineEdit::Password );
+ inner->addWidget( passwordEdit, 2, 1 );
+
+ inner->setColStretch( 0, 0 );
+ inner->setColStretch( 1, 15 );
+}
+
+
+void KVNCConnectDlg::accept()
+{
+ int dis;
+ // viewer->setHost(hostNameCombo->currentText());
+ QString temp = displayNumberEdit->text();
+ if(temp.isEmpty())
+ dis = -1;
+ else
+ dis = temp.toUInt();
+ // viewer->setDisplay(dis);
+ QDialog::accept();
+}
+
+void KVNCConnectDlg::options()
+{
+ KVNCOptionsDlg *wdg = new KVNCOptionsDlg( con->options(), this );
+ wdg->exec();
+ delete wdg;
+}
+
diff --git a/noncore/comm/keypebble/kvncconnectdlg.h b/noncore/comm/keypebble/kvncconnectdlg.h
new file mode 100644
index 0000000..cf34aab
--- a/dev/null
+++ b/noncore/comm/keypebble/kvncconnectdlg.h
@@ -0,0 +1,39 @@
+// -*- c++ -*-
+
+#ifndef KVNCCONNECTDLG_H
+#define KVNCCONNECTDLG_H
+
+#include <qdialog.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qurl.h>
+
+class KRFBConnection;
+
+class KVNCConnectDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ KVNCConnectDlg( KRFBConnection *con,
+ QWidget *parent = 0, const char *name = 0 );
+
+ QString hostname() { return hostNameCombo->currentText(); };
+ int display() { return displayNumberEdit->value(); };
+ QString password() const { return passwordEdit->text(); }
+
+protected:
+ void accept();
+
+protected slots:
+ void options();
+
+private:
+ QComboBox *hostNameCombo;
+ QSpinBox *displayNumberEdit;
+ QLineEdit *passwordEdit;
+ KRFBConnection *con;
+};
+
+#endif // KVNCCONNECTDLG_H
diff --git a/noncore/comm/keypebble/kvncoptionsdlg.cpp b/noncore/comm/keypebble/kvncoptionsdlg.cpp
new file mode 100644
index 0000000..b9f57d1
--- a/dev/null
+++ b/noncore/comm/keypebble/kvncoptionsdlg.cpp
@@ -0,0 +1,53 @@
+#include <qframe.h>
+#include <qvbox.h>
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qapplication.h>
+#include "krfboptions.h"
+
+#include "kvncoptionsdlg.h"
+
+KVNCOptionsDlg::KVNCOptionsDlg( KRFBOptions *options,
+ QWidget *parent, char *name, bool modal )
+ : VncOptionsBase( parent, name, modal )
+{
+ this->options = options;
+
+ hex->setChecked( options->hexTile );
+ corre->setChecked( options->corre );
+ rre->setChecked( options->rre );
+ copyRect->setChecked( options->copyrect );
+
+ // TODO
+ hex->setEnabled( false );
+ corre->setEnabled( false );
+ rre->setEnabled( false );
+ // /TODO
+
+ deIconify->setChecked( options->deIconify );
+ bit->setChecked( options->colors256 );
+ shared->setChecked( options->shared );
+ timeBox->setValue( options->updateRate );
+}
+
+KVNCOptionsDlg::~KVNCOptionsDlg()
+{
+}
+
+void KVNCOptionsDlg::accept()
+{
+ options->hexTile = hex->isChecked();
+ options->corre = corre->isChecked();
+ options->rre = rre->isChecked();
+ options->copyrect = copyRect->isChecked();
+ options->deIconify = deIconify->isChecked();
+ options->colors256 = bit->isChecked();
+ options->shared = shared->isChecked();
+ options->updateRate = timeBox->value();
+
+ QDialog::accept();
+}
+
diff --git a/noncore/comm/keypebble/kvncoptionsdlg.h b/noncore/comm/keypebble/kvncoptionsdlg.h
new file mode 100644
index 0000000..a166490
--- a/dev/null
+++ b/noncore/comm/keypebble/kvncoptionsdlg.h
@@ -0,0 +1,30 @@
+// -*- c++ -*-
+
+#ifndef KVNCOPTIONSDIALOG_H
+#define KVNCOPTIONSDIALOG_H
+
+#include "vncoptionsbase.h"
+
+class KRFBOptions;
+
+class KVNCOptionsDlg : public VncOptionsBase
+{
+Q_OBJECT
+
+public:
+ KVNCOptionsDlg( KRFBOptions *options,
+ QWidget *parent = 0, char *name = 0, bool modal = true );
+ ~KVNCOptionsDlg();
+
+protected:
+ void accept();
+
+private:
+ KRFBOptions *options;
+};
+
+#endif // KVNCOPTIONSDIALOG_H
+
+
+
+
diff --git a/noncore/comm/keypebble/main.cpp b/noncore/comm/keypebble/main.cpp
new file mode 100644
index 0000000..a32a368
--- a/dev/null
+++ b/noncore/comm/keypebble/main.cpp
@@ -0,0 +1,18 @@
+
+
+#include <qurl.h>
+#include <qpe/qpeapplication.h>
+#include "kvnc.h"
+
+int main( int argc, char **argv )
+{
+ QPEApplication app( argc, argv );
+ KVNC *view = new KVNC( "Keypebble" );
+ app.showMainWidget( view );
+
+ if ( argc > 1 )
+ view->openURL( QUrl(argv[1]) );
+
+ return app.exec();
+}
+
diff --git a/noncore/comm/keypebble/qpe-keypebble.control b/noncore/comm/keypebble/qpe-keypebble.control
new file mode 100644
index 0000000..75c1b9f
--- a/dev/null
+++ b/noncore/comm/keypebble/qpe-keypebble.control
@@ -0,0 +1,10 @@
+Files: bin/keypebble apps/Applications/keypebble.desktop pics/vnc.png
+Priority: optional
+Section: qpe/applications
+Maintainer: Martin Jones <mjones@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-2
+Depends: qpe-base ($QPE_VERSION)
+Description: VNC Viewer
+ Virtual Network Computing (VNC) viewer
diff --git a/noncore/comm/keypebble/vncauth.c b/noncore/comm/keypebble/vncauth.c
new file mode 100644
index 0000000..dc276bf
--- a/dev/null
+++ b/noncore/comm/keypebble/vncauth.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
+ *
+ * This 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 software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+/*
+ * vncauth.c - Functions for VNC password management and authentication.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include "vncauth.h"
+#include "d3des.h"
+
+
+/*
+ * We use a fixed key to store passwords, since we assume that our local
+ * file system is secure but nonetheless don't want to store passwords
+ * as plaintext.
+ */
+
+unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7};
+
+
+/*
+ * Encrypt a password and store it in a file. Returns 0 if successful,
+ * 1 if the file could not be written.
+ */
+
+int
+vncEncryptAndStorePasswd(char *passwd, char *fname)
+{
+ FILE *fp;
+ int i;
+ unsigned char encryptedPasswd[8];
+
+ if ((fp = fopen(fname,"w")) == NULL) return 1;
+
+ chmod(fname, S_IRUSR|S_IWUSR);
+
+ /* pad password with nulls */
+
+ for (i = 0; i < 8; i++) {
+ if (i < strlen(passwd)) {
+ encryptedPasswd[i] = passwd[i];
+ } else {
+ encryptedPasswd[i] = 0;
+ }
+ }
+
+ /* Do encryption in-place - this way we overwrite our copy of the plaintext
+ password */
+
+ deskey(fixedkey, EN0);
+ des(encryptedPasswd, encryptedPasswd);
+
+ for (i = 0; i < 8; i++) {
+ putc(encryptedPasswd[i], fp);
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+
+/*
+ * Decrypt a password from a file. Returns a pointer to a newly allocated
+ * string containing the password or a null pointer if the password could
+ * not be retrieved for some reason.
+ */
+
+char *
+vncDecryptPasswdFromFile(char *fname)
+{
+ FILE *fp;
+ int i, ch;
+ unsigned char *passwd = (unsigned char *)malloc(9);
+
+ if ((fp = fopen(fname,"r")) == NULL) return NULL;
+
+ for (i = 0; i < 8; i++) {
+ ch = getc(fp);
+ if (ch == EOF) {
+ fclose(fp);
+ return NULL;
+ }
+ passwd[i] = ch;
+ }
+
+ deskey(fixedkey, DE1);
+ des(passwd, passwd);
+
+ passwd[8] = 0;
+
+ return (char *)passwd;
+}
+
+
+/*
+ * Generate CHALLENGESIZE random bytes for use in challenge-response
+ * authentication.
+ */
+
+void
+vncRandomBytes(unsigned char *bytes)
+{
+ int i;
+ unsigned int seed = (unsigned int) time(0);
+
+ srandom(seed);
+ for (i = 0; i < CHALLENGESIZE; i++) {
+ bytes[i] = (unsigned char)(random() & 255);
+ }
+}
+
+
+/*
+ * Encrypt CHALLENGESIZE bytes in memory using a password.
+ */
+
+void
+vncEncryptBytes(unsigned char *bytes, char *passwd)
+{
+ unsigned char key[8];
+ int i;
+
+ /* key is simply password padded with nulls */
+
+ for (i = 0; i < 8; i++) {
+ if (i < strlen(passwd)) {
+ key[i] = passwd[i];
+ } else {
+ key[i] = 0;
+ }
+ }
+
+ deskey(key, EN0);
+
+ for (i = 0; i < CHALLENGESIZE; i += 8) {
+ des(bytes+i, bytes+i);
+ }
+}
diff --git a/noncore/comm/keypebble/vncauth.h b/noncore/comm/keypebble/vncauth.h
new file mode 100644
index 0000000..38b289e
--- a/dev/null
+++ b/noncore/comm/keypebble/vncauth.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
+ *
+ * This 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 software 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 software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+/*
+ * vncauth.h - describes the functions provided by the vncauth library.
+ */
+
+#define MAXPWLEN 8
+#define CHALLENGESIZE 16
+
+extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
+extern char *vncDecryptPasswdFromFile(char *fname);
+extern void vncRandomBytes(unsigned char *bytes);
+extern void vncEncryptBytes(unsigned char *bytes, char *passwd);
diff --git a/noncore/comm/keypebble/vncoptionsbase.ui b/noncore/comm/keypebble/vncoptionsbase.ui
new file mode 100644
index 0000000..d049a79
--- a/dev/null
+++ b/noncore/comm/keypebble/vncoptionsbase.ui
@@ -0,0 +1,270 @@
+<!DOCTYPE UI><UI>
+<class>VncOptionsBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>VncOptionsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>234</width>
+ <height>221</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>VNC Viewer Options</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TabWidget3</cstring>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Data Encoding</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Check for screen updates every:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>timeBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>500</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Milliseconds</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>bit</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Request 8-bit session</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>deIconify</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Raise on bell</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>shared</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Request shared session</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Connection</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>hex</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Hextile encoding</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>corre</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>CoRRE encoding</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>rre</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>RRE encoding</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>copyRect</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Copy rectangle encoding</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer3</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/noncore/games/chess/Makefile.in b/noncore/games/chess/Makefile.in
new file mode 100644
index 0000000..7354d76
--- a/dev/null
+++ b/noncore/games/chess/Makefile.in
@@ -0,0 +1,134 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) -DQCONFIG=\"qpe\"
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) -DQCONFIG=\"qpe\"
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = chess
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = chess.h
+SOURCES = chess.cpp \
+ main.cpp
+OBJECTS = chess.o \
+ main.o \
+ mainwindow.o
+INTERFACES = mainwindow.ui
+UICDECLS = mainwindow.h
+UICIMPLS = mainwindow.cpp
+SRCMOC = moc_chess.cpp \
+ moc_mainwindow.cpp
+OBJMOC = moc_chess.o \
+ moc_mainwindow.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake chess.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+chess.o: chess.cpp \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ chess.h
+
+main.o: main.cpp \
+ mainwindow.h
+
+mainwindow.h: mainwindow.ui
+ $(UIC) mainwindow.ui -o $(INTERFACE_DECL_PATH)/mainwindow.h
+
+mainwindow.cpp: mainwindow.ui
+ $(UIC) mainwindow.ui -i mainwindow.h -o mainwindow.cpp
+
+mainwindow.o: mainwindow.cpp \
+ mainwindow.h \
+ mainwindow.ui
+
+moc_chess.o: moc_chess.cpp \
+ chess.h
+
+moc_mainwindow.o: moc_mainwindow.cpp \
+ mainwindow.h
+
+moc_chess.cpp: chess.h
+ $(MOC) chess.h -o moc_chess.cpp
+
+moc_mainwindow.cpp: mainwindow.h
+ $(MOC) mainwindow.h -o moc_mainwindow.cpp
+
+
diff --git a/noncore/games/chess/boardview.cw b/noncore/games/chess/boardview.cw
new file mode 100644
index 0000000..020af96
--- a/dev/null
+++ b/noncore/games/chess/boardview.cw
@@ -0,0 +1,23 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>BoardView</class>
+ <header location="global">/home/luke/depot/qpe/chess/chess.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="XPM.GZ" length="4605">789c6dd7d96ee33a1206e0fb7e8aa0ebae31a863c9966d613017d9e3ecce9e0ce6a228c94b6c67f192d83998771f9af517e10493b4daf89a25b258a428f75f7fb61e2ecfb6fefcf56b3697f9b0d82a0632ddfa532e2693d5bffff3afbf7ffd4ed3adf027d94a7fffe3d76ff7b9556c9dbfbe5401ef9bf8d8c464136f9b186ee27513cf9bd8dec47c13d30d74bfb52c3d28cdd322a9058fd6aee7f5a29e047f697bbd96b483573fe2173ffc82fbdbb87fb0762389fdcdd6ee859fe0716ccfd7e6def7fed8c5f1d5c5f77c58c2788959ea70230dfd3982dba9de7f6ff9693b757ee4dbb7f9a3fdf5473d7aea464dfb23fa3e3fdafe319f3d75a3a1edbc0fb7913f9991df8b19f7977081f1ae83c5da89cd8dd0bf34601bffceaced14facfd22c53f36db484f95570a9e3398ed6f1c27ec8c4e239877378d79c85bd4f477089f117d1219ee666c4d7d4cd04fddd98d1de5ebb995abc3ca863fb04467eb26746fc398c7ce5c0aced7c1dade3bfc2983f5766acf7be19f59f466b3d4b752bc1fd9a9f58ffd28311cf6d33f2b9323735ff17752bc17855b4f697c119f2cbcd884fe15cd757d6c711b5ea2dd48766708efd959871ffb319f53c86ad1e67d1fafc89ba9d60bcaf68edffca8ce7ab8033c4b7a2b57e3bc1ae95b7eac1db70091fa9db895a6e61ab472b3af4277730e6cb5d33e69bc3781e6865c6f31ce6d3f6f9b75c881738d3f5e2b119ed27708ef655b4aedf0d6cf5fc50e709f27d84510fb930e3f94a615bdf6bb3f627f7b0cd47f3f5f36d877a5103b67af6cddace23759e20fe00b6e77da016acb77370a6e71df5cc18bf1fadfb610c0bcef304ae6aeab619ef83f57b92f286e5c3cfd1a1de3c803378095bbd9bea98cf305af7430b16d47319adf53f34637daee00af9f7d52ed57c692f5acf7fbdbfc8f3bc113c834be43b35a37d185d84feeed482fd47e77086fdbf0b57d81f75b54b311f8ad6f95e9a319f1adc44fed3689ddf132c589f8e59e385a3b5fdcc8cf1bb30d697a2311eea53a07e1cce7b6948a2f52007676ad956bb14e7e53e6cebb382adff67339eb7a5dac6930f33ce87266cf5388dd6f50ccf83f87a8baed77bb4aed78edaa5c877085738ff3fcdd89f13b58d4f68b7f1e5d48cfd589a118ff10bd49b9ea235fe12aef0fc55669c6fe17c718d42701ececcfafea2118cfb3935e3bcf98cd6f18ecc785fbd99f1beabab4bab77c38cef2b613d5c5908ced357b8c2799aa9637c12ade32dcc787fedc04d7c1fb935e33c7b8cd6f509df578aac10acef02aef0bc76ccbade7caeb6fb656ec6fe1c98f1fc5ec2a82f9f9931bf5ab4e67b0263bf70d80f455956e8efc6acf9d185ba4a51bfb119e779789f97be7f9d1fbda9637b19adf73b33e21fe026ea7162c6f31ad6a7acaad4e9fe1fc1d6be1badf53b36a39e4fb0e5771f1dda257c7fa89a668a76657013b6f509eb5bf99f225bbb3b5fff32b1b0e3c25fffefb3d4288de78a7bdce7010ffdf5cca38dabef7fc73ce1177fcf6b8c77fcc6ef3cf56d6f3ce3392ff8833f79c92bfee26ddef1f1bbbcc785c6f3be8f3be0433ef2b11d3ee6133ee5333ee70bbee42e5ff135dff02ddff13d5388179fc5d4f7f4c08ffcc4354e38e53a3738f39f4d6e719b73ce898958d7a7c74312725450491537a9477d1ad0909e69e4e39b34a609bdf01dbdb2d6abf0fd3ff8e8377aa729cd684e8b704de8833e69e97f57f4e5fbdf8efd3fd30eed724a7bb44f733ff6fa3ae0aebf6be5a30f7d2f473ebe8378f1f1c77442a77416fb3ea70bba0c77f47c465dbaa2eb6ffddfd0adefddfabea37b7aa0477aa21a25beff25a5a17fcbff994a4ea88ebe1b9451d3d734a116b529f7d15df1cbefe71bfbe753ba145af72d224e7ca5f84c4aa9bc7b7edca5f4bfe72f03df3ea485f83b652463bf0a19d765e2df012febfcb9f53d7f79f5f16ff22e5399c95c16f2219f7ec512ffe9eb232bf9fa96ff48b67ddb8eecca9eef719fbb72208772b45ee175fda523c7dff2efcb899cfad57a973339478de672219721ba2b573fea3fe61db9f6792eb9292c37722b77d4926558dbaecfa62ff73eff4eec7fc2d7f2208f612dfde5ef3c44e493cfa523354924953af22fa5e1f7f7adaf9dff4f9d5fcb25aeae7468202d1fdd96dcb123ddcfe179d9f3fbef3a5c95131abbf54fc1fe0deb3771e9a32bd7e35e7cbefc4e757d377043f78c6be4af71f87be25edcab7b73ef6eaaf16eb67e92dddc2ddc87fbf4ff6e9f9ffe73e93f57eecb6dfb081ff7fbbffffcf53f54dd2532</data>
+ </pixmap>
+ <slot access="public">newGame()</slot>
+ <slot access="public">swapSides()</slot>
+ <slot access="public">setTheme(QString)</slot>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/noncore/games/chess/chess.cpp b/noncore/games/chess/chess.cpp
new file mode 100644
index 0000000..96a838a
--- a/dev/null
+++ b/noncore/games/chess/chess.cpp
@@ -0,0 +1,358 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+// human is not offered a promotion yet
+
+#include <qcanvas.h>
+#include <qmainwindow.h>
+#include <qlist.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+
+#include <qpe/config.h>
+#include <qpe/resource.h>
+
+#include "chess.h"
+
+#define CHESS_DEBUG
+
+int pieceSize = 40;
+static QVector < QImage > imgList;
+int timeMoves, timeTime;
+
+int BoardView::convertToRank(int r)
+{
+ r = r / pieceSize;
+ if (humanSide == sideWhite)
+ r = 8 - r;
+ else
+ r++;
+ return r;
+}
+
+char BoardView::convertToFile(int f)
+{
+ f = f / pieceSize;
+ if (humanSide == sideWhite)
+ return f + 'a';
+ else
+ return 'h' - f;
+}
+
+int BoardView::convertFromFile(char f)
+{
+ if (humanSide == sideWhite)
+ f = f - 'a';
+ else
+ f = 'h' - f;
+ return f * pieceSize;
+}
+
+int BoardView::convertFromRank(int r)
+{
+ if (humanSide == sideWhite)
+ r = 8 - r;
+ else
+ r--;
+ return r * pieceSize;
+}
+
+// Pieces
+Piece::Piece(QCanvas * canvas, int t):QCanvasRectangle(canvas)
+{
+ type = t;
+ setSize(pieceSize, pieceSize);
+ show();
+}
+
+Piece *BoardView::newPiece(int t, char f, int r)
+{
+ Piece *tmpPiece = new Piece(canvas(), t);
+ tmpPiece->move(convertFromFile(f), convertFromRank(r));
+ list.append(tmpPiece);
+ return tmpPiece;
+}
+
+void BoardView::deletePiece(Piece * p)
+{
+ list.remove(p);
+ canvas()->update();
+}
+
+void Piece::drawShape(QPainter & p)
+{
+ p.drawImage(int (x()), int (y()), *(imgList[type]));
+}
+
+void BoardView::buildImages(QImage theme)
+{
+ imgList.resize(12);
+ int x;
+ int y = 0;
+
+ for (int j = 0; j < 2; j++) {
+ x = 0;
+ for (int i = 0; i < 6; i++) {
+ imgList.insert(i + (j * 6),
+ new QImage(theme.
+ copy(x, y, pieceSize, pieceSize)));
+ x += pieceSize;
+ }
+ y += pieceSize;
+ }
+}
+
+void BoardView::readStdout()
+{
+ QString input( crafty->readStdout() );
+#ifdef CHESS_DEBUG
+ qDebug("received this string from crafty->\n%s\n", input.latin1());
+#endif
+
+ int startPosition = input.find("setboard");
+ if (startPosition != -1)
+ decodePosition(input.remove(0, startPosition + 9));
+
+ if (input.contains("Black mates")) {
+ playingGame = FALSE;
+ emit(showMessage("Black mates"));
+ } else if (input.contains("White mates")) {
+ playingGame = FALSE;
+ emit(showMessage("White mates"));
+ } else if (input.contains(" resigns")) {
+ playingGame = FALSE;
+ emit(showMessage("Computer resigns"));
+ } else if (input.contains("Draw")) {
+ playingGame = FALSE;
+ emit(showMessage("Draw"));
+ }
+}
+
+// this is pretty close to getting done right
+// maybe dont use sprites and just draw a picture
+// there'll be lots of drawing done anyway
+// eg creating pictures for the webpages,
+// and presenting options for promotions
+void BoardView::decodePosition(const QString & t)
+{
+ qDebug("decode copped %s \n", t.latin1());
+
+ int count = 0;
+ int stringPos = 0;
+ for (int file = 0; file < 8; file++) {
+ for (int rank = 0; rank < 8; rank++) {
+ if (count)
+ count--;
+ else {
+ if (t.at(stringPos).isNumber())
+ count = t.at(stringPos).digitValue();
+ else {
+ newPiece(t.at(stringPos).latin1(), 'a' + file,
+ rank + 1);
+ }
+ }
+ }
+ }
+}
+
+void BoardView::undo()
+{
+ crafty->writeToStdin("undo\n");
+ crafty->writeToStdin("savepos\nclock\n");
+}
+
+void BoardView::emitErrorMessage()
+{
+ if (activeSide != humanSide)
+ emit(showMessage("Not your move"));
+ else
+ emit(showMessage("You are not playing a game"));
+}
+
+void BoardView::annotateGame()
+{
+ crafty->
+ writeToStdin
+ ("savegame game.save\nannotateh game.save bw 0 1.0 1\n");
+ emit(showMessage("Annotating game"));
+}
+
+Piece *BoardView::findPiece(char f, int r)
+{
+ QListIterator < Piece > it(list);
+ Piece *tmpPiece;
+ for (; it.current(); ++it) {
+ tmpPiece = it.current();
+ if (convertToRank(tmpPiece->x()) == r
+ && convertToFile(tmpPiece->y()) == f)
+ return tmpPiece;
+ }
+ return 0;
+}
+
+void BoardView::newGame()
+{
+ activeSide = sideWhite;
+ emit(showMessage("New game"));
+ crafty->writeToStdin("new\n");
+ crafty->writeToStdin("savepos\n");
+ crafty->writeToStdin("time " +
+ QString::number(timeMoves) +
+ "/" + QString::number(timeTime) + "\n");
+ activeSide = sideWhite;
+ if (humanSide == sideBlack)
+ crafty->writeToStdin("go\n");
+}
+
+void BoardView::setTheme(QString filename)
+{
+ QImage theme = Resource::loadImage(QString("chess/") + filename);
+ pieceSize = theme.height() / 2;
+ setFrameStyle(QFrame::Plain);
+ setFixedSize(8 * pieceSize, 8 * pieceSize);
+ canvas()->setBackgroundColor(Qt::red);
+ canvas()->resize(8 * pieceSize, 8 * pieceSize);
+ whiteSquare = theme.copy(6 * pieceSize, 0, pieceSize, pieceSize);
+ activeWhiteSquare = theme.copy(7 * pieceSize, 0, pieceSize, pieceSize);
+ blackSquare =
+ theme.copy(6 * pieceSize, pieceSize, pieceSize, pieceSize);
+ activeBlackSquare =
+ theme.copy(7 * pieceSize, pieceSize, pieceSize, pieceSize);
+ buildImages(theme);
+ drawBackgroundImage(QPoint(-1, -1));
+}
+
+
+// sets the bg to the default background image for the current theme
+// also resposible for drawing the "active" marker
+void BoardView::drawBackgroundImage(QPoint activeSquare)
+{
+ bg = QPixmap(8 * pieceSize, 8 * pieceSize);
+ QPainter p(&bg);
+ bool col = FALSE;
+ for (int i = 0; i < 8; i++) {
+ for (int j = 0; j < 8; j++) {
+ QPoint point(i * pieceSize, j * pieceSize);
+ if (col) {
+ if (point.x() == activeSquare.x()
+ && point.y() == activeSquare.y())
+ p.drawImage(point, activeBlackSquare);
+ else
+ p.drawImage(point, blackSquare);
+ col = FALSE;
+ } else {
+ if (point.x() == activeSquare.x()
+ && point.y() == activeSquare.y())
+ p.drawImage(point, activeWhiteSquare);
+ else
+ p.drawImage(point, whiteSquare);
+ col = TRUE;
+ }
+ }
+ col = !col;
+ }
+ canvas()->setBackgroundPixmap(bg);
+ canvas()->update();
+}
+
+
+// Board view widget
+void BoardView::contentsMousePressEvent(QMouseEvent * e)
+{
+ QCanvasItemList cList = canvas()->collisions(e->pos());
+ if (activeSide == humanSide && playingGame) {
+ if (!activePiece) {
+ if (cList.count()) {
+ activePiece = (Piece *) (*(cList.at(0)));
+ drawBackgroundImage(QPoint
+ (activePiece->x(), activePiece->y()));
+ }
+ } else {
+ if (!(activePiece == (Piece *) (*(cList.at(0))))) {
+ char fromFile = convertToFile(activePiece->x());
+ int fromRank = convertToRank(activePiece->y());
+ char toFile = convertToFile(e->pos().x());
+ int toRank = convertToRank(e->pos().y());
+ QString moveS;
+ moveS.append(fromFile);
+ moveS.append(moveS.number(fromRank));
+ moveS.append(toFile);
+ moveS.append(moveS.number(toRank));
+ if ((activePiece->type == wPawn
+ && fromRank == 7 && toRank == 8)
+ || (activePiece->type == bPawn
+ && fromRank == 2 && toRank == 1)) {
+ // offer a promotion
+ emit(showMessage
+ ("you are meant to be offered a promotion here"));
+ char promoteTo = wQueen; // doesnt matter for now
+ moveS.append(promoteTo);
+ moveS.append("\n");
+ crafty->writeToStdin(moveS.latin1());
+ }
+ }
+ activePiece = 0;
+ drawBackgroundImage(QPoint(-1, -1));
+ }
+ }
+
+ else {
+ emitErrorMessage();
+ }
+}
+
+void BoardView::swapSides()
+{
+ if (activeSide == humanSide && playingGame) {
+ humanSide = !humanSide;
+ crafty->writeToStdin("savepos\ngo\n");
+ } else
+ emitErrorMessage();
+}
+
+BoardView::BoardView(QCanvas *c, QWidget *w, const char *name)
+ : QCanvasView(c, w, name) {
+ humanSide = sideWhite;
+ activeSide = sideWhite;
+ playingGame = TRUE;
+ activePiece = 0;
+ list.setAutoDelete(TRUE);
+ setCanvas(new QCanvas());
+ Config c("Chess", Config::User);
+ c.setGroup("Theme");
+ QString theme = c.readEntry("imagefile", "simple-28");
+ setTheme(theme);
+ crafty = new CraftyProcess(this);
+ crafty->addArgument("crafty");
+ if (!crafty->start()) {
+ QMessageBox::critical(0,
+ tr("Could not find crafty chess engine"),
+ tr("Quit"));
+ exit(-1);
+ }
+
+ connect(crafty, SIGNAL(readyReadStdout()), this, SLOT(readStdout()));
+ connect(crafty, SIGNAL(processExited()), this, SLOT(craftyDied()));
+// crafty->writeToStdin("xboard\nics\nkibitz=2\n");
+ newGame();
+}
diff --git a/noncore/games/chess/chess.db b/noncore/games/chess/chess.db
new file mode 100644
index 0000000..b520b30
--- a/dev/null
+++ b/noncore/games/chess/chess.db
@@ -0,0 +1,2 @@
+<!DOCTYPE DB><DB version="1.0">
+</DB>
diff --git a/noncore/games/chess/chess.h b/noncore/games/chess/chess.h
new file mode 100644
index 0000000..067b2f8
--- a/dev/null
+++ b/noncore/games/chess/chess.h
@@ -0,0 +1,128 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/
+#ifndef CHESS_H
+#define CHESS_H
+
+#include <qwidget.h>
+#include <qcanvas.h>
+#include <qmainwindow.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qstack.h>
+#include <qvector.h>
+#include <qpe/process.h>
+
+#define wPawn 'P'
+#define wKnight 'N'
+#define wBishop 'B'
+#define wRook 'R'
+#define wQueen 'Q'
+#define wKing 'K'
+#define bPawn 'p'
+#define bKnight 'n'
+#define bBishop 'b'
+#define bRook 'r'
+#define bQueen 'q'
+#define bKing 'k'
+#define NONE N
+
+#define sideWhite 0
+#define sideBlack 1
+
+
+class Piece:public QCanvasRectangle {
+ public:
+ Piece(QCanvas *, int);
+ ~Piece() {
+ };
+
+ char type;
+
+ protected:
+ void drawShape(QPainter &);
+};
+
+
+class CraftyProcess : public Process {
+ public:
+ CraftyProcess(QObject *parent) : Process( parent ) { qDebug("CraftyProcess functions not implemented"); }
+ ~CraftyProcess() { }
+ bool start() { qDebug("CraftyProcess functions not implemented"); return FALSE; }
+ const char *readStdout() { qDebug("CraftyProcess functions not implemented"); return "Blah"; }
+ void writeToStdin(const char *) { qDebug("CraftyProcess functions not implemented"); }
+};
+
+
+class BoardView:public QCanvasView {
+ Q_OBJECT public:
+ BoardView(QCanvas *, QWidget *, const char *);
+ ~BoardView() {
+ };
+
+ protected:
+ void contentsMousePressEvent(QMouseEvent *);
+
+ signals:
+ void showMessage(const QString &);
+
+ public slots:void readStdout();
+ void craftyDied() {
+ qFatal("Crafty died unexpectedly\n");
+ };
+ void newGame();
+ void setTheme(QString);
+ void swapSides();
+ void undo();
+ void annotateGame();
+
+ private:
+ CraftyProcess * crafty;
+ QList < Piece > list;
+ Piece *activePiece;
+
+ void revertLastMove();
+ void emitErrorMessage();
+ void drawBackgroundImage(QPoint activeSquare);
+
+ void buildImages(QImage);
+
+ char convertToFile(int);
+ int convertToRank(int);
+ int convertFromFile(char);
+ int convertFromRank(int);
+
+ void decodePosition(const QString & t);
+
+ Piece *findPiece(char f, int r);
+ Piece *newPiece(int, char, int);
+ void deletePiece(Piece *);
+
+ int pieceSize;
+ QPixmap bg;
+ QImage whiteSquare, blackSquare, activeWhiteSquare, activeBlackSquare;
+
+ bool humanSide;
+ bool activeSide;
+ bool playingGame;
+};
+
+#endif
diff --git a/noncore/games/chess/chess.pro b/noncore/games/chess/chess.pro
new file mode 100644
index 0000000..f6650a0
--- a/dev/null
+++ b/noncore/games/chess/chess.pro
@@ -0,0 +1,14 @@
+SOURCES += chess.cpp main.cpp
+HEADERS += chess.h
+DESTDIR = ../bin
+TARGET = chess
+DEPENDPATH += $(QPEDIR)/include
+INTERFACES = mainwindow.ui
+IMAGES = images/new.png images/repeat.png images/txt.png images/back.png
+TEMPLATE =app
+CONFIG += qt warn_on release
+INCLUDEPATH += $(QPEDIR)/include
+LIBS += -lqpe
+DBFILE = chess.db
+LANGUAGE = C++
+CPP_ALWAYS_CREATE_SOURCE = TRUE
diff --git a/noncore/games/chess/main.cpp b/noncore/games/chess/main.cpp
new file mode 100644
index 0000000..a56913f
--- a/dev/null
+++ b/noncore/games/chess/main.cpp
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#include <qpe/qpetoolbar.h>
+#include <qmainwindow.h>
+#include <qcanvas.h>
+#include "chess.h"
+
+
+class CanvasMainWindow : public QMainWindow {
+public:
+ CanvasMainWindow(QWidget* parent=0, const char* name=0, WFlags f=0)
+ : QMainWindow(parent,name,f), canvas(232, 258) {
+ view = new BoardView(&canvas, this, 0);
+ setToolBarsMovable( FALSE );
+ QPEToolBar* toolbar = new QPEToolBar(this);
+ toolbar->setHorizontalStretchable( TRUE );
+ }
+
+private:
+ QCanvas canvas;
+ BoardView *view;
+};
+
+
+int main( int argc, char **argv ) {
+ QPEApplication a(argc,argv);
+ CanvasMainWindow *mw = new CanvasMainWindow();
+ a.showMainWidget( mw );
+ return a.exec();
+}
+
diff --git a/noncore/games/chess/mainwindow.ui b/noncore/games/chess/mainwindow.ui
new file mode 100644
index 0000000..dc3ae0f
--- a/dev/null
+++ b/noncore/games/chess/mainwindow.ui
@@ -0,0 +1,220 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>MainWindow</class>
+<widget class="QMainWindow">
+ <property name="name">
+ <cstring>MainWindow</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>256</width>
+ <height>338</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Chess</string>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>236</y>
+ <width>221</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>TextLabel1</string>
+ </property>
+ </widget>
+ <widget class="BoardView">
+ <property name="name">
+ <cstring>ChessBoard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>224</width>
+ <height>224</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>224</width>
+ <height>224</height>
+ </size>
+ </property>
+ </widget>
+</widget>
+<menubar>
+ <property name="name">
+ <cstring>menubar</cstring>
+ </property>
+ <item text="Game" name="PopupMenu_2">
+ <action name="newGame"/>
+ <action name="annotateGame"/>
+ </item>
+ <item text="Position" name="PopupMenu_3">
+ <action name="swapSides"/>
+ <action name="undo"/>
+ </item>
+</menubar>
+<toolbars>
+</toolbars>
+<customwidgets>
+ <customwidget>
+ <class>BoardView</class>
+ <header location="global">/home/luke/depot/qpe/chess/chess.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ <signal>showMessage(const QString&amp;)</signal>
+ <slot access="public" specifier="">newGame()</slot>
+ <slot access="public" specifier="">swapSides()</slot>
+ <slot access="public" specifier="">setTheme(QString)</slot>
+ <slot access="public" specifier="">undo()</slot>
+ <slot access="public" specifier="">annotateGame()</slot>
+ </customwidget>
+</customwidgets>
+<actions>
+ <actiongroup>
+ <property name="name">
+ <cstring>gameActions</cstring>
+ </property>
+ <property name="text">
+ <string>ActionGroup</string>
+ </property>
+ <property name="usesDropDown">
+ <bool>false</bool>
+ </property>
+ <action>
+ <property name="name">
+ <cstring>newGame</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>new.png</iconset>
+ </property>
+ <property name="text">
+ <string>New Game</string>
+ </property>
+ <property name="menuText">
+ <string>New Game</string>
+ </property>
+ <property name="toolTip">
+ <string>New Game</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>swapSides</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>repeat.png</iconset>
+ </property>
+ <property name="text">
+ <string>Swap sides</string>
+ </property>
+ <property name="toolTip">
+ <string>Swap sides</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>annotateGame</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>txt.png</iconset>
+ </property>
+ <property name="text">
+ <string>Annotate game</string>
+ </property>
+ <property name="toolTip">
+ <string>Annotate game</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>undo</cstring>
+ </property>
+ <property name="iconSet">
+ <iconset>back.png</iconset>
+ </property>
+ <property name="text">
+ <string>Undo move</string>
+ </property>
+ <property name="toolTip">
+ <string>Undo move</string>
+ </property>
+ </action>
+ <action>
+ <property name="name">
+ <cstring>saveGame</cstring>
+ </property>
+ <property name="text">
+ <string>Action</string>
+ </property>
+ </action>
+ </actiongroup>
+</actions>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="3456">789ce5d35d5313491406e07b7e458abea3b68e99cfccd4d65ee0079ac8a720a2d65ef474cf2424229004152dffbba7cf795941182a59bcd8aa6548524fbafb9d9ed3278fd63a47bb5b9db5472bb3b99d1fbb8e1bd96967cd5f9c9c5cbefffbaf6f2bab49dce1ff5eaf13affeb1b24aa6e33aa62b7f620fa7b01517ec423c850bb571b0c3f8bbe0a8db7591ae1fa9c3257e0aa7b0ac8f0ab6aeefc305bc073b783d38ee462ed6f5953a5ce20d38859f894b7629de820bb519c20ee3af829328764924be50275d7806a76a732c2ed9ba7e08176a33811d2cf548a3c4a59a97a9d3aedad4708af153b1655bf14bb880bfc00e3e0fcee2ac9be9f926629b65998eefc21e3e0acee3cce73affb33acfe037ff58e737629b97f026ece128b897e4be9788bfaa7b119cc319fc445cb12bf1215caa8d813d2cfd59243d5fe8faaeb82ab242d7d770097f803d2ce751a66554a6e28f70a636d24fa5633b191fc325fc1cf6f049b04d6d6435ef139cc16fc5ce5aabf3b7e11ade09ae525b573a7f5f5dc5f00bb1aff2ca8b07b0559b315c63fc20d86555ed32f15ced62f812ce61e95fe7d99a67610b3770ada65eb0e776f1bafe4c5cb36bf16bd8c245709dd7719d8b5371cddfc8b821d8aa290e6e78b4d1f9a5ba89e1c7e2a6b14d13bc37879b2bdf7f91b9fffadf65d8df90519123ffc08c9a1a1ad2a86d3ff767d0318d69421fe8843ed229a72c9d4167742ef79ed28ce69c7471f713b567d027beef675ea733bfd0257da5f5bb52da32e8313de18ca7f48c67add30657f539bde07df597c818d04bdae41a84593557654a5bb44d3bb44b7bbfeea53563c2ab467c1a61569f77123e5fd13e1d704a7533a535e3351dd21b3afa65dfeb9cf09677f86ec19a7679e64cea71f3daa788ebb45846cccf93dcaae1942bbb793be38e339ff2b34f28e5f7ab6f4e29e33a8c68f3f6dd5a320cdf29a7deb58c824aeeb31d434b64f48de1351b5736b6fd17d192e1a9321577d5cfe73e5c32c31ac79db16dfccf3e30f55219533e8b53634c73bd3bcc90e285332cf7f21177f51977d9f046775d2e9e6146fc8bbdabcab816c89872270f1e98e1f909c6b4c5cf7f71f5e2f7637e9fe9e742f5e8d3399feb3e0dcc9877744083f613693d174b23befbcc4ccc84b2f0fa1719d7d37c783d28a3b58affd18cef7faefc007d894af5</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>newGame</sender>
+ <signal>activated()</signal>
+ <receiver>ChessBoard</receiver>
+ <slot>newGame()</slot>
+ </connection>
+ <connection>
+ <sender>swapSides</sender>
+ <signal>activated()</signal>
+ <receiver>ChessBoard</receiver>
+ <slot>swapSides()</slot>
+ </connection>
+ <connection>
+ <sender>annotateGame</sender>
+ <signal>activated()</signal>
+ <receiver>ChessBoard</receiver>
+ <slot>annotateGame()</slot>
+ </connection>
+ <connection>
+ <sender>undo</sender>
+ <signal>activated()</signal>
+ <receiver>ChessBoard</receiver>
+ <slot>undo()</slot>
+ </connection>
+ <connection>
+ <sender>ChessBoard</sender>
+ <signal>showMessage(const QString&amp;)</signal>
+ <receiver>TextLabel1</receiver>
+ <slot>setText(const QString&amp;)</slot>
+ </connection>
+</connections>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/noncore/games/chess/pieces.png b/noncore/games/chess/pieces.png
new file mode 100644
index 0000000..4baeb4a
--- a/dev/null
+++ b/noncore/games/chess/pieces.png
Binary files differ
diff --git a/noncore/games/chess/qpe-chess.control b/noncore/games/chess/qpe-chess.control
new file mode 100644
index 0000000..2a7d2d2
--- a/dev/null
+++ b/noncore/games/chess/qpe-chess.control
@@ -0,0 +1,9 @@
+Files: bin/chess apps/Games/chess.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Luke Graham <luke@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Crafty GUI
+ A GUI for the crafty chess engine
diff --git a/noncore/games/chess/simple-l.png b/noncore/games/chess/simple-l.png
new file mode 100644
index 0000000..908e2e1
--- a/dev/null
+++ b/noncore/games/chess/simple-l.png
Binary files differ
diff --git a/noncore/games/fifteen/.cvsignore b/noncore/games/fifteen/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/noncore/games/fifteen/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/noncore/games/fifteen/Makefile.in b/noncore/games/fifteen/Makefile.in
new file mode 100644
index 0000000..23c7334
--- a/dev/null
+++ b/noncore/games/fifteen/Makefile.in
@@ -0,0 +1,118 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = fifteen
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = fifteen.h
+SOURCES = fifteen.cpp \
+ main.cpp
+OBJECTS = fifteen.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_fifteen.cpp
+OBJMOC = moc_fifteen.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake fifteen.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+fifteen.o: fifteen.cpp \
+ fifteen.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+main.o: main.cpp \
+ fifteen.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_fifteen.o: moc_fifteen.cpp \
+ fifteen.h
+
+moc_fifteen.cpp: fifteen.h
+ $(MOC) fifteen.h -o moc_fifteen.cpp
+
+
diff --git a/noncore/games/fifteen/fifteen.cpp b/noncore/games/fifteen/fifteen.cpp
new file mode 100644
index 0000000..293cd65
--- a/dev/null
+++ b/noncore/games/fifteen/fifteen.cpp
@@ -0,0 +1,364 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "fifteen.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qvbox.h>
+#include <qaction.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qmessagebox.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/qpemenubar.h>
+#include <qstringlist.h>
+#include <qapplication.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+FifteenMainWindow::FifteenMainWindow(QWidget *parent, const char* name)
+ : QMainWindow( parent, name )
+{
+ // random seed
+ srand(time(0));
+
+ setToolBarsMovable( FALSE );
+ QVBox *vbox = new QVBox( this );
+ PiecesTable *table = new PiecesTable( vbox );
+ setCentralWidget(vbox);
+
+ QPEToolBar *toolbar = new QPEToolBar(this);
+ toolbar->setHorizontalStretchable( TRUE );
+ addToolBar(toolbar);
+
+ QPEMenuBar *menubar = new QPEMenuBar( toolbar );
+ menubar->setMargin(0);
+
+ QPopupMenu *game = new QPopupMenu( this );
+
+ QWidget *spacer = new QWidget( toolbar );
+ spacer->setBackgroundMode( PaletteButton );
+ toolbar->setStretchableWidget( spacer );
+
+ QAction *a = new QAction( tr( "Randomize" ), Resource::loadPixmap( "new" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), table, SLOT( slotRandomize() ) );
+ a->addTo( game );
+ a->addTo( toolbar );
+
+ a = new QAction( tr( "Solve" ), Resource::loadPixmap( "repeat" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), table, SLOT( slotReset() ) );
+ a->addTo( game );
+ a->addTo( toolbar );
+
+ menubar->insertItem( tr( "Game" ), game );
+}
+
+PiecesTable::PiecesTable(QWidget* parent, const char* name )
+ : QTableView(parent, name), _menu(0), _randomized(false)
+{
+ // setup table view
+ setFrameStyle(StyledPanel | Sunken);
+ setBackgroundMode(NoBackground);
+ setMouseTracking(true);
+
+ setNumRows(4);
+ setNumCols(4);
+
+ // init arrays
+ initMap();
+ readConfig();
+ initColors();
+
+ // set font
+ QFont f = font();
+ f.setPixelSize(18);
+ f.setBold( TRUE );
+ setFont(f);
+}
+
+PiecesTable::~PiecesTable()
+{
+ writeConfig();
+}
+
+void PiecesTable::writeConfig()
+{
+ Config cfg("Fifteen");
+ cfg.setGroup("Game");
+ QStringList map;
+ for (unsigned int i = 0; i < 16; i++)
+ map.append( QString::number( _map[i] ) );
+ cfg.writeEntry("Map", map, '-');
+ cfg.writeEntry("Randomized", _randomized );
+}
+
+void PiecesTable::readConfig()
+{
+ Config cfg("Fifteen");
+ cfg.setGroup("Game");
+ QStringList map = cfg.readListEntry("Map", '-');
+ _randomized = cfg.readBoolEntry( "Randomized", FALSE );
+ unsigned int i = 0;
+ for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) {
+ _map[i] = (*it).toInt();
+ i++;
+ if ( i > 15 ) break;
+ }
+}
+
+void PiecesTable::paintCell(QPainter *p, int row, int col)
+{
+ int w = cellWidth();
+ int h = cellHeight();
+ int x2 = w - 1;
+ int y2 = h - 1;
+
+ int number = _map[col + row * numCols()] + 1;
+
+ // draw cell background
+ if(number == 16)
+ p->setBrush(colorGroup().background());
+ else
+ p->setBrush(_colors[number-1]);
+ p->setPen(NoPen);
+ p->drawRect(0, 0, w, h);
+
+ // draw borders
+ if (height() > 40) {
+ p->setPen(colorGroup().text());
+ if(col < numCols()-1)
+ p->drawLine(x2, 0, x2, y2); // right border line
+
+ if(row < numRows()-1)
+ p->drawLine(0, y2, x2, y2); // bottom boder line
+ }
+
+ // draw number
+ if (number == 16) return;
+ p->setPen(black);
+ p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(number));
+}
+
+void PiecesTable::resizeEvent(QResizeEvent *e)
+{
+ QTableView::resizeEvent(e);
+
+ setCellWidth(contentsRect().width()/ numRows());
+ setCellHeight(contentsRect().height() / numCols());
+}
+
+void PiecesTable::initColors()
+{
+ _colors.resize(numRows() * numCols());
+ for (int r = 0; r < numRows(); r++)
+ for (int c = 0; c < numCols(); c++)
+ _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150);
+}
+
+void PiecesTable::initMap()
+{
+ _map.resize(16);
+ for (unsigned int i = 0; i < 16; i++)
+ _map[i] = i;
+
+ _randomized = false;
+}
+
+void PiecesTable::randomizeMap()
+{
+ initMap();
+ _randomized = true;
+ // find the free position
+ int pos = _map.find(15);
+
+ int move = 0;
+ while ( move < 333 ) {
+
+ int frow = pos / numCols();
+ int fcol = pos - frow * numCols();
+
+ // find click position
+ int row = rand()%4;
+ int col = rand()%4;
+
+ // sanity check
+ if ( row < 0 || row >= numRows() ) continue;
+ if ( col < 0 || col >= numCols() ) continue;
+ if ( row != frow && col != fcol ) continue;
+
+ move++;
+
+ // rows match -> shift pieces
+ if(row == frow) {
+
+ if (col < fcol) {
+ for(int c = fcol; c > col; c--) {
+ _map[c + row * numCols()] = _map[ c-1 + row *numCols()];
+ }
+ }
+ else if (col > fcol) {
+ for(int c = fcol; c < col; c++) {
+ _map[c + row * numCols()] = _map[ c+1 + row *numCols()];
+ }
+ }
+ }
+ // cols match -> shift pieces
+ else if (col == fcol) {
+
+ if (row < frow) {
+ for(int r = frow; r > row; r--) {
+ _map[col + r * numCols()] = _map[ col + (r-1) *numCols()];
+ }
+ }
+ else if (row > frow) {
+ for(int r = frow; r < row; r++) {
+ _map[col + r * numCols()] = _map[ col + (r+1) *numCols()];
+ }
+ }
+ }
+ // move free cell to click position
+ _map[pos=(col + row * numCols())] = 15;
+ repaint();
+ }
+}
+
+void PiecesTable::checkwin()
+{
+ if(!_randomized) return;
+
+ int i;
+ for (i = 0; i < 16; i++)
+ if(i != _map[i])
+ break;
+
+ if (i == 16) {
+ QMessageBox::information(this, tr("Fifteen Pieces"),
+ tr("Congratulations!\nYou win the game!"));
+ _randomized = FALSE;
+ }
+
+}
+
+void PiecesTable::slotRandomize()
+{
+ randomizeMap();
+}
+
+void PiecesTable::slotReset()
+{
+ initMap();
+ repaint();
+}
+
+void PiecesTable::mousePressEvent(QMouseEvent* e)
+{
+ QTableView::mousePressEvent(e);
+
+ if (e->button() == RightButton) {
+
+ // setup RMB pupup menu
+ if(!_menu) {
+ _menu = new QPopupMenu(this);
+ _menu->insertItem(tr("R&andomize Pieces"), mRandomize);
+ _menu->insertItem(tr("&Reset Pieces"), mReset);
+ _menu->adjustSize();
+ }
+
+ // execute RMB popup and check result
+ switch(_menu->exec(mapToGlobal(e->pos()))) {
+ case mRandomize:
+ randomizeMap();
+ break;
+ case mReset:
+ initMap();
+ repaint();
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ // GAME LOGIC
+
+ // find the free position
+ int pos = _map.find(15);
+ if(pos < 0) return;
+
+ int frow = pos / numCols();
+ int fcol = pos - frow * numCols();
+
+ // find click position
+ int row = findRow(e->y());
+ int col = findCol(e->x());
+
+ // sanity check
+ if (row < 0 || row >= numRows()) return;
+ if (col < 0 || col >= numCols()) return;
+ if ( row != frow && col != fcol ) return;
+
+ // valid move?
+ if(row != frow && col != fcol) return;
+
+ // rows match -> shift pieces
+ if(row == frow) {
+
+ if (col < fcol) {
+ for(int c = fcol; c > col; c--) {
+ _map[c + row * numCols()] = _map[ c-1 + row *numCols()];
+ updateCell(row, c, false);
+ }
+ }
+ else if (col > fcol) {
+ for(int c = fcol; c < col; c++) {
+ _map[c + row * numCols()] = _map[ c+1 + row *numCols()];
+ updateCell(row, c, false);
+ }
+ }
+ }
+ // cols match -> shift pieces
+ else if (col == fcol) {
+
+ if (row < frow) {
+ for(int r = frow; r > row; r--) {
+ _map[col + r * numCols()] = _map[ col + (r-1) *numCols()];
+ updateCell(r, col, false);
+ }
+ }
+ else if (row > frow) {
+ for(int r = frow; r < row; r++) {
+ _map[col + r * numCols()] = _map[ col + (r+1) *numCols()];
+ updateCell(r, col, false);
+ }
+ }
+ }
+ // move free cell to click position
+ _map[col + row * numCols()] = 15;
+ updateCell(row, col, false);
+
+ // check if the player wins with this move
+ checkwin();
+ }
+}
diff --git a/noncore/games/fifteen/fifteen.h b/noncore/games/fifteen/fifteen.h
new file mode 100644
index 0000000..703a8a7
--- a/dev/null
+++ b/noncore/games/fifteen/fifteen.h
@@ -0,0 +1,83 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __fifteenapplet_h__
+#define __fifteenapplet_h__
+
+#include <qmainwindow.h>
+#include <qtableview.h>
+#include <qarray.h>
+
+class QPopupMenu;
+
+class PiecesTable : public QTableView
+{
+ Q_OBJECT
+
+ public:
+ PiecesTable(QWidget* parent = 0, const char* name = 0);
+ ~PiecesTable();
+
+ protected slots:
+ void slotRandomize();
+ void slotReset();
+
+ protected:
+ void resizeEvent(QResizeEvent*);
+ void mousePressEvent(QMouseEvent*);
+
+ void paintCell(QPainter *, int row, int col);
+
+ void initMap();
+ void initColors();
+ void randomizeMap();
+ void checkwin();
+ void readConfig();
+ void writeConfig();
+
+ private:
+ QArray<int> _map;
+ QArray<QColor> _colors;
+ QPopupMenu *_menu;
+ bool _randomized;
+
+ enum MenuOp { mRandomize = 1, mReset = 2 };
+};
+
+class FifteenWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ FifteenWidget(QWidget *parent = 0, const char *name = 0);
+
+private:
+ PiecesTable *_table;
+};
+
+class FifteenMainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ FifteenMainWindow(QWidget *parent=0, const char* name=0);
+};
+
+#endif
diff --git a/noncore/games/fifteen/fifteen.pro b/noncore/games/fifteen/fifteen.pro
new file mode 100644
index 0000000..167f4f8
--- a/dev/null
+++ b/noncore/games/fifteen/fifteen.pro
@@ -0,0 +1,10 @@
+DESTDIR = ../bin
+TEMPLATE = app
+CONFIG = qt warn_on release
+HEADERS = fifteen.h
+SOURCES = fifteen.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+TARGET = fifteen
diff --git a/noncore/games/fifteen/main.cpp b/noncore/games/fifteen/main.cpp
new file mode 100644
index 0000000..4838a36
--- a/dev/null
+++ b/noncore/games/fifteen/main.cpp
@@ -0,0 +1,33 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "fifteen.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv)
+{
+ QPEApplication app( argc, argv );
+
+ FifteenMainWindow mw;
+ mw.setCaption( FifteenMainWindow::tr("Fifteen Pieces") );
+ app.showMainWidget( &mw );
+ return app.exec();
+}
diff --git a/noncore/games/fifteen/qpe-fifteen.control b/noncore/games/fifteen/qpe-fifteen.control
new file mode 100644
index 0000000..d77eb32
--- a/dev/null
+++ b/noncore/games/fifteen/qpe-fifteen.control
@@ -0,0 +1,11 @@
+Files: bin/fifteen apps/Games/fifteen.desktop pics/Fifteen.png
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-4
+Depends: qpe-base ($QPE_VERSION)
+Description: Fifteen pieces game
+ A game for the Qtopia environment
+.
diff --git a/noncore/games/go/.cvsignore b/noncore/games/go/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/noncore/games/go/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/noncore/games/go/Makefile.in b/noncore/games/go/Makefile.in
new file mode 100644
index 0000000..27304f1
--- a/dev/null
+++ b/noncore/games/go/Makefile.in
@@ -0,0 +1,158 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = go
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = amigo.h \
+ go.h \
+ goplayutils.h \
+ gowidget.h
+SOURCES = amigo.c \
+ goplayer.c \
+ goplayutils.c \
+ killable.c \
+ gowidget.cpp \
+ main.cpp
+OBJECTS = amigo.o \
+ goplayer.o \
+ goplayutils.o \
+ killable.o \
+ gowidget.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_gowidget.cpp
+OBJMOC = moc_gowidget.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake go.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+amigo.o: amigo.c \
+ go.h \
+ goplayutils.h \
+ amigo.h
+
+goplayer.o: goplayer.c \
+ go.h \
+ goplayutils.h \
+ amigo.h
+
+goplayutils.o: goplayutils.c \
+ goplayutils.h \
+ amigo.h \
+ go.h
+
+killable.o: killable.c \
+ go.h \
+ goplayutils.h \
+ amigo.h
+
+gowidget.o: gowidget.cpp \
+ gowidget.h \
+ amigo.h \
+ go.h \
+ goplayutils.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+main.o: main.cpp \
+ gowidget.h \
+ amigo.h \
+ go.h \
+ goplayutils.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_gowidget.o: moc_gowidget.cpp \
+ gowidget.h \
+ amigo.h \
+ go.h \
+ goplayutils.h
+
+moc_gowidget.cpp: gowidget.h
+ $(MOC) gowidget.h -o moc_gowidget.cpp
+
+
diff --git a/noncore/games/go/README b/noncore/games/go/README
new file mode 100644
index 0000000..c6fa1f5
--- a/dev/null
+++ b/noncore/games/go/README
@@ -0,0 +1,3 @@
+This Go player For Qtopia is based on Xamigo, which in turn was
+based on Amigo. The original README files are included as README.XAMIGO
+and README.AMIGO.
diff --git a/noncore/games/go/README.AMIGO b/noncore/games/go/README.AMIGO
new file mode 100644
index 0000000..03978e7
--- a/dev/null
+++ b/noncore/games/go/README.AMIGO
@@ -0,0 +1,42 @@
+ This is version 1.0 of AmiGo --- a Go board and player for the Amiga.
+The Amiga interface and board manager were written by Todd R. Johnson.
+The player is a C port of a Pascal player written by Stoney Ballard.
+The interface allows you to play human vs. human, human vs. Amiga, or
+Amiga vs. Amiga.
+
+ The board manager and player could both use some work. Currently,
+you cannot save/load games, take back a move, or automatically score a
+game. It is also limited to a 19 by 19 board. I'm releasing AmiGo
+now because 1) I'm in the final phases of my dissertation and probably
+won't have much time to do any further work on AmiGo, and 2) a lot of
+people have been asking for an Amiga Go player. I am also releasing
+all of the source code so that others can add to and modify AmiGo.
+Note that all of my code in this release is public domain, while the
+ported go player retains the original copyright.
+
+ If you distribute AmiGo, I urge you to include the source
+code. If anyone makes changes, I would appreciate a copy. In fact, I
+am willing to act as a clearinghouse for AmiGo changes.
+
+Todd R. Johnson
+tj@cis.ohio-state.edu
+8/8/89
+
+Here is the message attached to the original USENET posting of Stoney
+Ballard's Pascal code. Note that the board manager mentioned here is
+not included in this distribution.
+
+This go board manager and rudimentary go player was written by
+Stoney Ballard at Perq Systems in 1983-1984. It is written in
+Perq Pascal and utilizes some Perq libraries for I/O. The code
+is offered here if someone is interested to convert it to Unix.
+
+The wonderful part about it is that a game is recorded as a tree
+and can be played forward or backward, branching at any point
+where there were alternate moves.
+
+For some time, this program was also used to generate the go
+boards displayed in the American Go Journal. For this it used
+some large font digits which are now lost.
+
+Fred Hansen
diff --git a/noncore/games/go/README.XAMIGO b/noncore/games/go/README.XAMIGO
new file mode 100644
index 0000000..219b25f
--- a/dev/null
+++ b/noncore/games/go/README.XAMIGO
@@ -0,0 +1,26 @@
+
+ Xamigo 1.1
+
+This is an alpha release of xamigo --- a port (read: quick hack) of the
+Amiga Go program AmiGo. I don't have time to get it real nice now,
+but will spend some more time on it when my thesis is out of the way.
+Sadly this is the second time I've said that :-)
+
+The `readme' from the original distribution is included as README.AMIGO
+
+An Imakefile is included, so you should be able to type
+ xmkmf
+ make
+to build xamigo. Let me know if you have problems with the Imakefile,
+preferably with fixes :-)
+
+You *have* to install the app-defaults file (Xamigo.ad) before you use
+xamigo. This should either go in /usr/lib/X11/app-defaults,
+or in your own app-defaults directory, as file Xamigo (ie lose the '.ad')
+If you do the latter, you have to:
+ setenv XAPPLRESDIR <full path of your app-defaults directory>
+
+Feel free to mail me any comments and suggestions for improvements.
+
+Neil
+neilb@scs.leeds.ac.uk
diff --git a/noncore/games/go/amigo.c b/noncore/games/go/amigo.c
new file mode 100644
index 0000000..cd61013
--- a/dev/null
+++ b/noncore/games/go/amigo.c
@@ -0,0 +1,656 @@
+/* Go started 4/17/88 by Todd R. Johnson */
+/* 8/8/89 cleaned up for first release */
+/* Public Domain */
+
+#include "go.h"
+#include "goplayutils.h"
+#include "amigo.h"
+
+
+extern char *playReason;
+extern short playLevel, showTrees;
+
+struct bRec goboard[19][19]; /*-- The main go board --*/
+
+struct Group GroupList[MAXGROUPS]; /*-- The list of Groups --*/
+short DeletedGroups[4]; /*-- Codes of deleted groups --*/
+
+short GroupCount = 0; /*-- The total number of groups --*/
+short DeletedGroupCount; /*-- The total number of groups --*/
+ /*-- deleted on a move --*/
+short ko, koX, koY;
+short blackTerritory,whiteTerritory;
+short blackPrisoners, whitePrisoners;
+short showMoveReason = FALSE,
+ groupInfo = FALSE,
+ whitePassed = FALSE,
+ blackPassed = FALSE;
+
+
+/* Arrays for use when checking around a point */
+short xVec[4] = {0, 1, 0, -1};
+short yVec[4] = {-1, 0, 1, 0};
+
+short
+member(group, grouplist, cnt)
+ short group;
+ short grouplist[4];
+ short cnt;
+{
+ unsigned short i;
+
+
+ for (i = 0; i < cnt; i++)
+ if (grouplist[i] == group)
+ return TRUE;
+ return FALSE;
+}
+
+/* Does a stone at x, y connect to any groups of color? */
+short
+Connect( color, x, y, fGroups, fCnt, eGroups, eCnt)
+ enum bVal color;
+ short x, y;
+ short fGroups[4], eGroups[4];
+ short *fCnt, *eCnt;
+{
+ unsigned short point = 0;
+ short tx, ty, total = 0;
+ enum bVal opcolor = WHITE;
+
+
+ *fCnt = 0;
+ *eCnt = 0;
+ if (color == WHITE)
+ opcolor = BLACK;
+ for (point = 0; point <= 3; point++ )
+ {
+ tx = x + xVec[point];
+ ty = y + yVec[point];
+ if (!LegalPoint(tx,ty))
+ continue;
+ if (goboard[tx][ty].Val == color)
+ {
+ total++;
+ if (!member(goboard[tx][ty].GroupNum, fGroups, *fCnt))
+ fGroups[(*fCnt)++] = goboard[tx][ty].GroupNum;
+ }
+ else if (goboard[tx][ty].Val == opcolor)
+ {
+ total++;
+ if (!member(goboard[tx][ty].GroupNum, eGroups, *eCnt))
+ eGroups[(*eCnt)++] = goboard[tx][ty].GroupNum;
+ }
+ }
+ return total;
+}
+
+/* Returns the maximum number of liberties for a given intersection */
+short
+Maxlibs(x, y)
+ short x, y;
+{
+ short cnt = 4;
+
+
+ if (x == 0 || x == 18)
+ cnt--;
+ if (y == 0 || y == 18)
+ cnt--;
+ return cnt;
+}
+
+DeleteGroupFromStone(x,y)
+ short x,y;
+{
+ if (goboard[x][y].Val != EMPTY)
+ GroupCapture(goboard[x][y].GroupNum);
+}
+
+/* Determine whether x, y is suicide for color */
+short
+Suicide(color, x, y)
+ enum bVal color;
+ short x, y;
+{
+ enum bVal opcolor = BLACK;
+ short friendlycnt, friendlygroups[4],
+ enemycnt, enemygroups[4],
+ total;
+ short maxlibs, i, libcnt = 0;
+
+
+ if (color == BLACK)
+ opcolor = WHITE;
+ maxlibs = Maxlibs( x, y);
+ total = Connect(color, x, y, friendlygroups, &friendlycnt,
+ enemygroups, &enemycnt);
+
+ if (total < maxlibs)
+ return FALSE;
+
+ /* Check for a capture */
+ for (i = 0; i < enemycnt; i++)
+ if (GroupList[enemygroups[i]].liberties == 1)
+ return FALSE;
+ for (i = 0; i < friendlycnt; i++)
+ libcnt += (GroupList[friendlygroups[i]].liberties - 1);
+ if (libcnt != 0)
+ return FALSE;
+ return TRUE;
+}
+
+/* Returns the number of liberties for x, y */
+short
+StoneLibs(x, y)
+ short x, y;
+{
+ short cnt = 0, tx, ty;
+ unsigned short point;
+
+
+ for (point = 0; point <= 3; point++)
+ {
+ tx = x + xVec[point];
+ ty = y + yVec[point];
+ if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY)
+ cnt++;
+ }
+ return cnt;
+}
+
+void
+EraseMarks()
+{
+ register short i;
+ register struct bRec *gpt = &goboard[0][0];
+
+
+ for (i=0; i<361; gpt++,i++)
+ gpt->marked = FALSE;
+}
+
+/* Place a stone of color at x, y */
+short
+GoPlaceStone(color, x, y)
+ enum bVal color;
+ short x, y;
+{
+ short fgroups[4], egroups[4]; /* group codes surrounding stone */
+ short fcnt, ecnt, i;
+ short lowest = GroupCount + 1;
+
+
+ DeletedGroupCount = 0;
+ if (goboard[x][y].Val != EMPTY || Suicide(color,x,y))
+ return FALSE;
+
+ if (ko && koX == x && koY == y)
+ return FALSE;
+
+ ko = FALSE;
+ placestone(color, x, y);
+ goboard[x][y].Val = color;
+ /* Does the new stone connect to any friendly stone(s)? */
+ Connect(color, x, y, fgroups, &fcnt, egroups, &ecnt);
+ if (fcnt)
+ {
+ /* Find the connecting friendly group with the lowest code */
+ for (i = 0; i < fcnt; i++)
+ if (fgroups[i] <= lowest)
+ lowest = fgroups[i];
+ /*-- Renumber resulting group --*/
+ /*-- Raise the stone count of the lowest by one to account --*/
+ /*-- for new stone --*/
+ goboard[x][y].GroupNum = lowest;
+ GroupList[lowest].count++;
+ for (i = 0; i < fcnt; i++)
+ if (fgroups[i] != lowest)
+ MergeGroups(lowest, fgroups[i]);
+ /* Fix the liberties of the resulting group */
+ CountLiberties(lowest);
+ }
+ else
+ {
+ /* Isolated stone. Create new group. */
+ GroupCount++;
+ lowest = GroupCount;
+ GroupList[lowest].color = color;
+ GroupList[lowest].count = 1;
+ GroupList[lowest].internal = 0;
+ GroupList[lowest].external = StoneLibs( x, y);
+ GroupList[lowest].liberties = GroupList[lowest].external;
+ GroupList[lowest].eyes = 0;
+ GroupList[lowest].alive = 0;
+ GroupList[lowest].territory = 0;
+ goboard[x][y].GroupNum = lowest;
+ }
+ /* Now fix the liberties of enemy groups adjacent to played stone */
+ FixLibs(color, x, y, PLACED); /* Fix the liberties of opcolor */
+ ReEvalGroups(color, x, y, lowest);
+ RelabelGroups();
+ return TRUE;
+}
+
+/* Remove a stone from the board */
+void
+GoRemoveStone(x, y)
+ short x, y;
+{
+ goboard[x][y].Val = EMPTY;
+ goboard[x][y].GroupNum = 0;
+ removestone( x, y);
+}
+
+/* Merges two groups -- Renumbers stones and deletes second group from
+list. Fixes stone count of groups. This does not fix anything else.
+FixLibs must be called to fix liberties, etc. */
+void
+MergeGroups(g1, g2)
+ short g1, g2;
+{
+ short x, y;
+
+
+ ForeachPoint(y,x)
+ if (goboard[x][y].GroupNum == g2)
+ goboard[x][y].GroupNum = g1;
+ GroupList[g1].count += GroupList[g2].count;
+ DeleteGroup( g2 ); /* Removes group from GroupList */
+}
+
+/* Stores a group code to be deleted */
+void
+DeleteGroup(code)
+ short code;
+{
+ DeletedGroups[DeletedGroupCount++] = code;
+}
+
+/* Re-evaluate the groups given the last move. This assumes that the
+last move has been merged into adjoining groups and all liberty counts
+are correct. Handles capture. Checks for Ko. Keeps track of captured
+stones. code is the group number of the stone just played. */
+void
+ReEvalGroups(color, x, y, code)
+ enum bVal color;
+ short x, y, code;
+{
+ short fgroups[4], egroups[4],
+ fcnt, ecnt, i, killcnt = 0, count = 0;
+ enum bVal opcolor = BLACK;
+
+ if (color == BLACK)
+ opcolor = WHITE;
+ /* Check for capture */
+ Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt);
+ if (ecnt)
+ {
+ /* See if any of the groups have no liberties */
+ for (i = 0; i < ecnt; i++)
+ if (GroupList[egroups[i]].liberties == 0)
+ {
+ killcnt++;
+ count = GroupList[egroups[i]].count;
+ GroupCapture( egroups[i]);
+ }
+ }
+ /* Check for ko. koX and koY are set in GroupCapture above. */
+ if (killcnt == 1 && count == 1 && GroupList[ code ].count == 1
+ && GroupList[ code ].liberties == 1)
+ {
+ ko = TRUE;
+ }
+ if (killcnt)
+ intrPrisonerReport( blackPrisoners, whitePrisoners);
+ /* Set eye count for groups */
+ CountEyes();
+}
+
+/* Remove a captured group from the board and fix the liberties of any
+ adjacent groups. Fixes prisoner count. Sets KoX and KoY */
+/*-- update display of captured stones -neilb --*/
+void
+GroupCapture(code)
+ short code;
+{
+ short x, y;
+
+ if (GroupList[code].color == BLACK)
+ blackPrisoners += GroupList[code].count;
+ else
+ whitePrisoners += GroupList[code].count;
+ intrPrisonerReport(blackPrisoners, whitePrisoners);
+ ForeachPoint(y,x)
+ if (goboard[x][y].GroupNum == code)
+ {
+ FixLibs(GroupList[code].color,x,y,REMOVED);
+ GoRemoveStone(x, y);
+ koX = x;
+ koY = y;
+ }
+ DeleteGroup( code);
+}
+
+/* Fix the liberties of groups adjacent to x, y. move indicates
+ whether a stone of color was placed or removed at x, y
+ This does not change liberty counts of friendly groups when a stone
+ is placed. Does not do captures. */
+void
+FixLibs( color, x, y, move)
+ enum bVal color;
+ short x, y, move;
+{
+ short fgroups[4], fcnt, egroups[4], ecnt, i;
+ enum bVal opcolor = BLACK;
+
+ if (color == BLACK)
+ opcolor = WHITE;
+ Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt);
+ if (move == PLACED)
+ for (i = 0; i < ecnt; i++)
+ GroupList[egroups[i]].liberties--;
+ else /* Stone removed so increment opcolor */
+ for (i = 0; i < ecnt; i++)
+ GroupList[egroups[i]].liberties++;
+}
+
+void
+goSetHandicap(handicap)
+ int handicap;
+{
+ if (handicap < 2)
+ return;
+
+ GoPlaceStone(BLACK,3,3);
+ GoPlaceStone(BLACK,15,15);
+
+ if (handicap >= 3)
+ GoPlaceStone(BLACK,15,3);
+ if (handicap >= 4)
+ GoPlaceStone(BLACK,3,15);
+ if (handicap == 5 || handicap == 7 || handicap == 9)
+ GoPlaceStone(BLACK,9,9);
+ if (handicap >= 6)
+ {
+ GoPlaceStone(BLACK,15,9);
+ GoPlaceStone(BLACK,3,9);
+ }
+ if (handicap >= 8)
+ {
+ GoPlaceStone(BLACK,9,15);
+ GoPlaceStone(BLACK,9,3);
+ }
+}
+
+void
+goRestart(handicap)
+ int handicap;
+{
+ register short i;
+ register struct bRec *gpt = &goboard[0][0];
+
+
+ GroupCount = 0;
+ ko = FALSE;
+ blackPrisoners = whitePrisoners = 0;
+ intrPrisonerReport(0, 0);
+ for (i=0; i<361; gpt++,i++)
+ {
+ gpt->Val = EMPTY;
+ gpt->GroupNum = 0;
+ }
+ goSetHandicap(handicap);
+}
+
+
+/* if any groups have been deleted as a result of the last move, this
+ routine will delete the old group numbers from GroupList and
+ reassign group numbers. */
+void
+RelabelGroups()
+{
+ unsigned short i, j, x, y;
+
+ for (i = 0; i < DeletedGroupCount; i++)
+ {
+ /* Relabel all higher groups */
+ ForeachPoint(y,x)
+ if (goboard[x][y].GroupNum > DeletedGroups[i])
+ goboard[x][y].GroupNum--;
+ /* Move the groups down */
+ for (y = DeletedGroups[i]; y < GroupCount; y++)
+ GroupList[y] = GroupList[y+1];
+ /* fix the group numbers stored in the deleted list */
+ for (j = i+1; j < DeletedGroupCount; j++)
+ if (DeletedGroups[j] > DeletedGroups[i])
+ DeletedGroups[j]--;
+ GroupCount--;
+ }
+}
+
+/* Returns liberty count for x, y intersection. Sets marked to true
+ for each liberty */
+short
+CountAndMarkLibs( x, y)
+ short x, y;
+{
+ short tx,ty,i;
+ short cnt = 0;
+
+
+ for (i=0;i<4;i++)
+ {
+ tx = x + xVec[i];
+ ty = y + yVec[i];
+ if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY
+ && goboard[tx][ty].marked == FALSE)
+ {
+ cnt++;
+ goboard[tx][ty].marked = TRUE;
+ }
+ }
+ return cnt;
+}
+
+/* Determine the number of liberties for a group given the group code
+ num */
+void
+CountLiberties( code)
+ short code;
+{
+ short x, y, libcnt = 0;
+
+ ForeachPoint(y,x)
+ if (goboard[x][y].GroupNum == code)
+ libcnt += CountAndMarkLibs( x, y);
+ EraseMarks();
+ GroupList[code].liberties = libcnt;
+}
+
+void
+CheckForEye( x, y, groups, cnt, recheck)
+ short x, y, groups[4], cnt, *recheck;
+{
+ short i;
+
+ for (i = 0; i < (cnt-1); i++)
+ if (groups[i] != groups[i+1])
+ {
+ /* Mark liberty for false eye check */
+ goboard[x][y].marked = TRUE;
+ (*recheck)++;
+ return;
+ }
+ /* It is an eye */
+ GroupList[groups[i]].eyes += 1;
+}
+
+/* Set the eye count for the groups */
+void CountEyes()
+{
+ short i, x, y,
+ wgroups[4], bgroups[4], wcnt, bcnt, max, cnt, recheck = 0, eye;
+
+ for (i = 1; i <= GroupCount; i++)
+ GroupList[i].eyes = 0;
+
+ ForeachPoint(y,x)
+ {
+ if (goboard[x][y].Val != EMPTY)
+ continue;
+ cnt = Connect(WHITE,x,y,wgroups,&wcnt,bgroups,&bcnt);
+ max = Maxlibs( x, y);
+ if (cnt == max && wcnt == 1 && bcnt == 0)
+ GroupList[wgroups[0]].eyes++;
+ else if (cnt == max && bcnt == 1 && wcnt == 0)
+ GroupList[bgroups[0]].eyes++;
+ else if (cnt == max && ( bcnt == 0 || wcnt == 0 ))
+ {
+ goboard[x][y].marked = TRUE;
+ recheck++;
+ }
+ }
+
+ /*-- Now recheck marked liberties to see if two or more one eye --*/
+ /*-- groups contribute to a false eye */
+ if (recheck == 0)
+ return;
+
+ ForeachPoint(y,x)
+ if (goboard[x][y].marked)
+ {
+ recheck--;
+ goboard[x][y].marked = FALSE;
+ Connect( WHITE, x, y, wgroups, &wcnt, bgroups, &bcnt);
+ /* If all the groups have at least one eye then all the
+ groups are safe from capture because of the common
+ liberty at x, y */
+ eye = TRUE;
+ for (i = 0; i < wcnt; i++)
+ if (GroupList[wgroups[i]].eyes == 0)
+ eye = FALSE;
+ if (eye)
+ for (i = 0; i < wcnt; i++)
+ GroupList[wgroups[i]].eyes++;
+ for (i = 0; i < bcnt; i++)
+ if (GroupList[bgroups[i]].eyes == 0)
+ eye = FALSE;
+ if (eye)
+ for (i = 0; i < bcnt; i++)
+ GroupList[bgroups[i]].eyes++;
+ if (recheck == 0)
+ return;
+ }
+}
+
+
+short foo[19][19];
+
+/*----------------------------------------------------------------
+-- CountUp() --
+-- Count up final scores at the end of the game. --
+----------------------------------------------------------------*/
+CountUp( wtotal, btotal )
+ int *wtotal, *btotal;
+{
+ short x,y;
+ short CountFromPoint();
+ short vv;
+ char buff[512];
+
+
+ blackTerritory = whiteTerritory = 0;
+ ForeachPoint(y,x)
+ {
+ goboard[x][y].marked = FALSE;
+ foo[x][y] = CNT_UNDECIDED;
+ }
+ ForeachPoint(y,x)
+ if (goboard[x][y].Val==EMPTY && foo[x][y]==CNT_UNDECIDED)
+ {
+ FillPoints(x,y,CountFromPoint(x,y));
+ }
+
+ *wtotal = whiteTerritory + blackPrisoners;
+ *btotal = blackTerritory + whitePrisoners;
+ /*
+ sprintf(buff,"White : %3d territory + %3d prisoners = %d\n\
+Black : %3d territory + %3d prisoners = %d\n\n%s.\n",
+ whiteTerritory,blackPrisoners,*wtotal,
+ blackTerritory,whitePrisoners,*btotal,
+ (*btotal>*wtotal?"Black wins":(*wtotal>*btotal?"White wins":
+ "A draw")));
+
+
+
+ XtVaSetValues(message,XtNstring,buff,0);
+ printf( "CountUp() %s", buff );
+ */
+}
+
+FillPoints(x,y,val)
+ short x,y,val;
+{
+ int i;
+ short tx,ty;
+
+
+ if ((foo[x][y] = val) == CNT_BLACK_TERR)
+ blackTerritory++;
+ else if (val == CNT_WHITE_TERR)
+ whiteTerritory++;
+ for (i=0;i<4;i++)
+ {
+ tx = x + xVec[i];
+ ty = y + yVec[i];
+ if (!LegalPoint(tx,ty))
+ continue;
+ if (goboard[tx][ty].Val==EMPTY && foo[tx][ty]==CNT_UNDECIDED)
+ FillPoints(tx,ty,val);
+ }
+}
+
+short
+CountFromPoint(x,y)
+ short x,y;
+{
+ int i;
+ short tx,ty;
+ short blkcnt=0,whtcnt=0;
+ short baz;
+
+
+ goboard[x][y].marked = TRUE;
+ for (i=0;i<4;i++)
+ {
+ tx = x + xVec[i];
+ ty = y + yVec[i];
+ if (!LegalPoint(tx,ty))
+ continue;
+ if (goboard[tx][ty].Val == BLACK)
+ blkcnt++;
+ else if (goboard[tx][ty].Val == WHITE)
+ whtcnt++;
+ else
+ {
+ if (goboard[tx][ty].marked)
+ continue;
+ baz = CountFromPoint(tx,ty);
+ if (baz == CNT_NOONE)
+ return CNT_NOONE;
+ else if (baz == CNT_BLACK_TERR)
+ blkcnt++;
+ else if (baz == CNT_WHITE_TERR)
+ whtcnt++;
+ }
+ if (blkcnt && whtcnt)
+ return CNT_NOONE;
+ }
+ if (blkcnt && !whtcnt)
+ return CNT_BLACK_TERR;
+ else if (whtcnt && !blkcnt)
+ return CNT_WHITE_TERR;
+ else
+ return CNT_UNDECIDED;
+}
diff --git a/noncore/games/go/amigo.h b/noncore/games/go/amigo.h
new file mode 100644
index 0000000..5150ac0
--- a/dev/null
+++ b/noncore/games/go/amigo.h
@@ -0,0 +1,146 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+/*=========================================================================
+=== ===
+=== FILE amigo.h ===
+=== ===
+=== CONTENTS prototypes for the various AmiGo routines. ===
+=== added by neilb ===
+=== ===
+=========================================================================*/
+
+#ifndef __amigo_h
+#define __amigo_h
+
+#include "go.h"
+#include "goplayutils.h"
+
+#ifdef __STDC__
+#define PROTO(fp) fp
+#else
+#define PROTO(fp) ()
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* From goplayer.c */
+
+
+
+/* Procedures from amigo.c */
+
+short Connect PROTO((enum bVal, short, short, short[4], short[4], short *, short * ));
+short Maxlibs PROTO((short, short));
+short Suicide PROTO((enum bVal, short, short));
+short StoneLibs PROTO((short, short));
+void EraseMarks PROTO(());
+short GoPlaceStone PROTO((enum bVal, short, short));
+void GoRemoveStone PROTO((short, short));
+void MergeGroups PROTO((short, short));
+void DeleteGroup PROTO((short));
+void ReEvalGroups PROTO((enum bVal, short, short, short));
+void GroupCapture PROTO((short));
+void FixLibs PROTO((enum bVal, short, short, short));
+int CountUp PROTO((int*, int*));
+/*void main PROTO(());*/
+void goRestart PROTO((int));
+void RelabelGroups PROTO(());
+short CountAndMarkLibs PROTO((short, short));
+void CountLiberties PROTO((short));
+void CheckForEye PROTO((short, short, short[4], short, short *));
+void CountEyes PROTO(());
+void printGroupReport PROTO((short, short));
+
+
+/* killable.c */
+
+int tryPlay PROTO(( short, short, short ));
+int sSpanGroup PROTO(( short, short, sPointList * ));
+int spanGroup PROTO(( short, short, pointList *));
+int pause PROTO(());
+
+int genState PROTO(());
+int initGPUtils PROTO(());
+int genBord PROTO((enum bVal));
+
+short genMove PROTO(( enum bVal, short *, short * ));
+short checkPos PROTO(( short, short, short ));
+short takeCorner PROTO(( short *, short * ));
+short extend PROTO(( short *, short * ));
+short noNbrs PROTO(( short, short ));
+short extend2 PROTO(( short *, short * ));
+short lookForSave PROTO(( short *, short * ));
+short lookForSaveN PROTO(( short *, short * ));
+short lookForKill PROTO(( short *, short * ));
+short doubleAtari PROTO(( short *, short * ));
+short lookForAttack PROTO(( short *, short * ));
+short threaten PROTO(( short *, short * ));
+short connectCut PROTO(( short *, short * ));
+short heCanCut PROTO(( short, short ));
+short safeMove PROTO(( short, short ));
+short extendWall PROTO(( short *, short * ));
+short findAttack2 PROTO(( short *, short * ));
+short blockCut PROTO(( short *, short * ));
+short cutHim PROTO(( short *, short * ));
+short atariAnyway PROTO(( short *, short * ));
+short underCut PROTO(( short *, short * ));
+short dropToEdge PROTO(( short *, short * ));
+short pushWall PROTO(( short *, short * ));
+short reduceHisLiberties PROTO(( short *, short * ));
+short dropToEdge2 PROTO(( short *, short * ));
+
+
+/* goplayutils.c */
+
+short saveable PROTO((short, short, short *, short *));
+short killable PROTO((short, short, short *, short *));
+int initBoolBoard PROTO((boolBoard));
+int intersectPlist PROTO((pointList *, pointList *, pointList *));
+int initArray PROTO((intBoard));
+int initState PROTO(());
+int copyArray PROTO((intBoard, intBoard));
+int stake PROTO(());
+int spread PROTO(());
+int respreicen PROTO(());
+int tryPlay PROTO((short, short, short));
+int saveState PROTO(());
+int restoreState PROTO(());
+short tencen PROTO((short, short));
+int genConnects PROTO(());
+int sortLibs PROTO(());
+
+
+/*-- from xinterface.c --*/
+void removestone PROTO((short, short));
+void placestone PROTO((enum bVal, short, short));
+
+void intrMoveReport PROTO((enum bVal,char *,char *));
+void intrPrisonerReport PROTO(( short, short ));
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/noncore/games/go/go.h b/noncore/games/go/go.h
new file mode 100644
index 0000000..9aa644b
--- a/dev/null
+++ b/noncore/games/go/go.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+/* AmiGo Include */
+/* MSG types for getinput() */
+
+#ifndef __go_h
+#define __go_h
+
+
+#define INTERSECTIONMSG 1 /* User buttoned an intersection */
+#define QUITMSG 2 /* User buttoned QUIT icon */
+#define PLAYMSG 3
+#define RESTARTMSG 4
+#define PASSMSG 5
+
+#define TRUE 1
+#define FALSE 0
+
+#define MAXGROUPS 100
+
+#define PLACED 0
+#define REMOVED 1
+
+#define numPoints 19
+#define maxPoint numPoints - 1
+
+/*-- definitions used when counting up --*/
+
+#define CNT_UNDECIDED 0
+#define CNT_BLACK_TERR 1
+#define CNT_WHITE_TERR 2
+#define CNT_NOONE 3
+
+/*-- macro functions --*/
+
+#define LegalPoint(x,y) (x>=0 && x<=18 && y>=0 && y<=18)
+#define ForeachPoint(a,b) for(a=0;a<19;a++) for (b=0;b<19;b++)
+
+enum bVal {BLACK, WHITE, EMPTY};
+typedef enum bVal sType;
+struct Group
+{
+ enum bVal color; /* The color of the group */
+ short code, /* The code used to mark stones in the group */
+ count, /* The number of stones in the group */
+ internal, /* The number of internal liberties */
+ external, /* The number of external liberties */
+ liberties, /* The total number of liberties */
+ eyes, /* The number of eyes */
+ alive, /* A judgement of how alive this group is */
+ territory; /* The territory this group controls */
+};
+
+struct bRec
+{
+ enum bVal Val; /* What is at this intersection */
+ short xOfs,
+ yOfs;
+ short mNum;
+ short GroupNum; /* What group the stone belongs to */
+ short marked; /* TRUE or FALSE */
+};
+
+#endif
diff --git a/noncore/games/go/go.pro b/noncore/games/go/go.pro
new file mode 100644
index 0000000..deb90c5
--- a/dev/null
+++ b/noncore/games/go/go.pro
@@ -0,0 +1,19 @@
+DESTDIR = ../bin
+TEMPLATE = app
+CONFIG = qt warn_on release
+HEADERS = amigo.h \
+ go.h \
+ goplayutils.h \
+ gowidget.h
+SOURCES = amigo.c \
+ goplayer.c \
+ goplayutils.c \
+ killable.c \
+ gowidget.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+TARGET = go
+
+TRANSLATIONS = ../i18n/de/go.ts \ No newline at end of file
diff --git a/noncore/games/go/goplayer.c b/noncore/games/go/goplayer.c
new file mode 100644
index 0000000..88c0f61
--- a/dev/null
+++ b/noncore/games/go/goplayer.c
@@ -0,0 +1,1499 @@
+/* The go player */
+/* Ported from Pascal to C by Todd R. Johnson 4/17/88 */
+/* From the original pascal file:
+Go Move Generator
+Copyright (c) 1983 by Three Rivers Computer Corp.
+
+Written: January 17, 1983 by Stoney Ballard
+Edit History:
+*/
+
+#include "go.h"
+#include "goplayutils.h"
+#include "amigo.h"
+
+#define BIGGEST 32767 /* maximum value for short */
+
+/* From go.c */
+extern struct bRec goboard[19][19];
+extern short ko, koX, koY;
+
+/* From goplayutils.c */
+extern intBoard bord;
+extern intBoard ndbord;
+extern intBoard claim;
+extern intBoard legal;
+extern intBoard connectMap;
+extern intBoard threatBord;
+extern short maxGroupID;
+extern short treeLibLim;
+extern short killFlag;
+extern short depthLimit;
+extern short showTrees;
+extern short utilPlayLevel;
+extern groupRec gList[maxGroup];
+extern short sGlist[maxGroup + 1];
+extern pointList pList;
+extern pointList pList1;
+extern pointList plist2;
+extern pointList plist3;
+extern intBoard groupIDs;
+extern intBoard protPoints;
+extern sType mySType;
+
+
+short saveNLibs;
+pointList dapList1, dapList2, dapList3;
+char *playReason;
+short maxPlayLevel = 7;
+short playLevel = 7;
+
+genBord(color)
+ enum bVal color;
+{
+ short x, y, nomoves = TRUE;
+ char mv[8];
+
+ maxPlayLevel = 7;
+ utilPlayLevel = playLevel;
+ mySType = color;
+ if (playLevel < 2)
+ treeLibLim = 2;
+ else
+ treeLibLim = 3;
+ depthLimit = 100;
+ for (y = 0; y <= 18; y++)
+ for (x = 0; x <= 18; x++)
+ if (goboard[x][y].Val == color)
+ {
+ bord[x][y] = 1;
+ legal[x][y] = FALSE;
+ nomoves = FALSE;
+ }
+ else if (goboard[x][y].Val == EMPTY)
+ {
+ bord[x][y] = 0;
+ legal[x][y] = TRUE;
+ }
+ else
+ {
+ bord[x][y] = -1;
+ legal[x][y] = FALSE;
+ nomoves = FALSE;
+ }
+ if (ko)
+ {
+ legal[koX][koY] = FALSE;
+ }
+
+ if (! nomoves)
+ genState();
+ else
+ initGPUtils();
+}
+
+
+short getMove( x, y )
+short *x, *y;
+{
+ if (takeCorner(x, y)) return TRUE;
+ if (lookForSave(x, y)) return TRUE;
+ if (lookForSaveN(x, y)) return TRUE;
+ if (extend(x, y)) return TRUE;
+ if (lookForKill(x, y)) return TRUE;
+ if (doubleAtari(x, y)) return TRUE;
+ if (lookForAttack(x, y)) return TRUE;
+ if (threaten(x, y)) return TRUE;
+ if (extend2(x, y)) return TRUE;
+ if (connectCut(x, y)) return TRUE;
+ if (blockCut(x, y)) return TRUE;
+ if (cutHim(x, y)) return TRUE;
+ if (extendWall(x, y)) return TRUE;
+ if (findAttack2(x, y)) return TRUE;
+ if (atariAnyway(x, y)) return TRUE;
+ if (underCut(x, y)) return TRUE;
+ if (dropToEdge(x, y)) return TRUE;
+ if (pushWall(x, y)) return TRUE;
+ if (reduceHisLiberties(x, y)) return TRUE;
+ if (dropToEdge2(x, y)) return TRUE;
+ return FALSE;
+}
+
+short genMove( color, x, y )
+enum bVal color;
+short *x, *y;
+{
+ if (playLevel > 2)
+ saveNLibs = TRUE;
+ else
+ saveNLibs = FALSE;
+ genBord(color);
+ if (getMove(x, y))
+ return TRUE;
+ return FALSE;
+}
+
+short checkPos(x, y, field)
+short x, y, field;
+{
+ short ok;
+ ok = (((field == 0) && (claim[x][y] == 0)) ||
+ ((field > 0) &&
+ (claim[x][y] >= 0) && (claim[x][y] <= field)) ||
+ ((field < 0) &&
+ (claim[x][y] <= 0) && (claim[x][y] >= field))) &&
+ (bord[x-1][y] == 0) &&
+ (bord[x+1][y] == 0) &&
+ (bord[x][y-1] == 0) &&
+ (bord[x][y+1] == 0);
+ if (ok) return TRUE; else return FALSE;
+}
+
+short takeCorner( x, y )
+short *x, *y;
+{
+ short field = -1, i;
+ i = 18 - 3;
+ playReason = "takeCorner";
+ while (field != -4)
+ {
+ if (field == -1) field = 0;
+ else if (field == 0) field = 4;
+ else field = -4;
+ if (checkPos(2, 3, field)) { *x = 2; *y = 3; return TRUE; }
+ if (checkPos(3, 2, field)) { *x = 3; *y = 2; return TRUE; }
+ if (checkPos(2, i, field)) { *x = 2; *y = i; return TRUE; }
+ if (checkPos(3, i + 1, field)) { *x = 3; *y = i+1; return TRUE; }
+ if (checkPos(i, i + 1, field)) { *x = i; *y = i+1; return TRUE; }
+ if (checkPos(i + 1, i, field)) { *x = i+1; *y = i; return TRUE; }
+ if (checkPos(i, 2, field)) { *x = i; *y = 2; return TRUE; }
+ if (checkPos(i + 1, 3, field)) { *x = i+1; *y = 3; return TRUE; }
+ if (checkPos(2, 4, field)) { *x = 2; *y = 4; return TRUE; }
+ if (checkPos(4, 2, field)) { *x = 4; *y = 2; return TRUE; }
+ if (checkPos(2, i - 1, field)) { *x = 2; *y = i-1; return TRUE; }
+ if (checkPos(4, i + 1, field)) { *x = 4; *y = i+1; return TRUE; }
+ if (checkPos(i - 1, i + 1, field)) { *x = i-1; *y = i+1; return TRUE; }
+ if (checkPos(i + 1, i - 1, field)) { *x = i+1; *y = i-1; return TRUE; }
+ if (checkPos(i + 1, 4, field)) { *x = i+1; *y = 4; return TRUE; }
+ if (checkPos(i - 1, 2, field)) { *x = i-1; *y = 2; return TRUE; }
+ }
+ return FALSE;
+}
+
+printBoard(brd, name)
+intBoard brd;
+char *name;
+{
+ short x, y;
+ printf( "%s\n", name );
+ for (y = 0; y <= 18; y++)
+ {
+ for (x = 0; x <= 18; x++)
+ printf("%d ", brd[x][y]);
+ printf("\n");
+ }
+}
+
+short noNbrs( x, y )
+short x, y;
+{
+ if (x > 0 && bord[x-1][y] != 0) return FALSE;
+ if (x < 18 && bord[x+1][y] != 0) return FALSE;
+ if (y > 0 && bord[x][y-1] != 0) return FALSE;
+ if (y < 18 && bord[x][y+1] != 0) return FALSE;
+ return TRUE;
+}
+
+short extend(x, y)
+short *x, *y;
+{
+ short i;
+ playReason = "extend";
+ for (i = 2; i <= 18-2; i++)
+ if (claim[2][i] == 0 && noNbrs( 2, i ))
+ {
+ *x = 2;
+ *y = i;
+ return TRUE;
+ }
+ for (i = 2; i <= 18-2; i++)
+ if (claim[i][18-2] == 0 && noNbrs( 2, i ))
+ {
+ *x = i;
+ *y = 18-2;
+ return TRUE;
+ }
+ for (i = 18-2; i >= 2; i--)
+ if (claim[18-2][i] == 0 && noNbrs( 18-2, i ))
+ {
+ *x = 18-2;
+ *y = i;
+ return TRUE;
+ }
+ for (i = 18-2; i >= 2; i--)
+ if (claim[i][2] == 0 && noNbrs( i, 2 ))
+ {
+ *x = i;
+ *y = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+short extend2( x, y )
+short *x, *y;
+{
+ short i, lowest = BIGGEST, value;
+ playReason = "extend2";
+ for (i = 3; i <= 18-3; i++)
+ if (legal[2][i]) /* if there is nobody there */
+ {
+ value = claim[2][i]; /* get influence */
+ if ((value < 7) && /* a reasonable hole in my wall */
+ (value > -5) && /* or a reasonable gap in his */
+ (bord[2][i + 1] == 0) && /* not in contact with any stones */
+ (bord[2][i - 1] == 0))
+ if (value < lowest)
+ {
+ lowest = value; /* lowest gets the smallest value */
+ *x = 2; /* that was seen along all the 3-lines */
+ *y = i; /* x and y save that location */
+ }
+ }
+ for (i = 3; i <= 18-3; i++)
+ if (legal[i][2])
+ {
+ value = claim[i][2];
+ if ((value < 7) &&
+ (value > -5) &&
+ (bord[i + 1][2] == 0) &&
+ (bord[i - 1][2] == 0))
+ if (value < lowest)
+ {
+ lowest = value;
+ *x = i;
+ *y = 2;
+ }
+ }
+ for (i = 18-3; i >= 3; i--)
+ if (legal[18 - 2][i])
+ {
+ value = claim[18 - 2][i];
+ if ((value < 7) &&
+ (value > -5) &&
+ (bord[18 - 2][i + 1] == 0) &&
+ (bord[18 - 2][i - 1] == 0))
+ if (value < lowest)
+ {
+ lowest = value;
+ *x = 18 - 2;
+ *y = i;
+ }
+ }
+ for (i = 3; i <= 18-3; i++)
+ if (legal[i][18 - 2])
+ {
+ value = claim[i][18 - 2];
+ if ((value < 7) &&
+ (value > -5) &&
+ (bord[i + 1][18 - 2] == 0) &&
+ (bord[i - 1][18 - 2] == 0))
+ if (value < lowest)
+ {
+ lowest = value;
+ *x = i;
+ *y = 18 - 2;
+ }
+ }
+ if (lowest == BIGGEST) return FALSE;
+ return TRUE;
+}
+
+ /*
+ check to see if I can save anything in atari
+ */
+short lookForSave(x, y)
+short *x, *y;
+ { /* lookForSave */
+ short i;
+ playReason = "lookForSave";
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((gList[i].libC == 1) &&
+ (ndbord[gList[i].lx][gList[i].ly] == 1))
+ if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */
+ return TRUE;
+ return FALSE;
+ } /* lookForSave */
+
+ /*
+ check to see if I can save anything with n libs
+ */
+short lookForSaveN(x, y)
+short *x, *y;
+ { /* lookForSaveN */
+ short i;
+ if (saveNLibs)
+ {
+ playReason = "lookForSaveN";
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((gList[i].libC > 1) &&
+ (gList[i].libC <= treeLibLim) &&
+ (ndbord[gList[i].lx][gList[i].ly] == 1))
+ {
+ if (killable(gList[i].lx, gList[i].ly, x, y))
+ if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } /* lookForSaveN */
+
+
+/*----------------------------------------------------------------
+-- lookForKill() --
+-- check to see if I can kill anything. --
+----------------------------------------------------------------*/
+short
+lookForKill(x, y)
+ short *x, *y;
+{
+ short i;
+ char mv[8];
+
+ playReason = "lookForKill";
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((gList[i].libC == 1) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1))
+ { /* we found a live enemy group with one liberty */
+ /* find the liberty */
+ spanGroup(gList[i].lx, gList[i].ly, &pList);
+ *x = pList.p[1].px;
+ *y = pList.p[1].py;
+ if (legal[*x][*y])
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+short doubleAtari(x, y)
+short *x, *y;
+ { /* doubleAtari */
+ short i, j;
+ playReason = "doubleAtari";
+ for (i = 1; i <= maxGroupID - 1; i++)
+ if ((gList[i].libC == 2) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1)) /* found an atariable group of his */
+ {
+ spanGroup(gList[i].lx, gList[i].ly, &dapList1);
+ for (j = i + 1; j <= maxGroupID; j++)
+ if ((gList[j].libC == 2) &&
+ (ndbord[gList[j].lx][gList[j].ly] == -1))
+ {
+ spanGroup(gList[j].lx, gList[j].ly, &dapList2);
+ intersectPlist(&dapList1, &dapList2, &dapList3);
+ if (dapList3.indx > 0)
+ if (legal[dapList3.p[1].px][dapList3.p[1].py])
+ {
+ tryPlay(dapList3.p[1].px, dapList3.p[1].py, 1);
+ if (gList[groupIDs[dapList3.p[1].px][
+ dapList3.p[1].py]].libC > 1)
+ {
+ *x = dapList3.p[1].px;
+ *y = dapList3.p[1].py;
+ restoreState();
+ return TRUE;
+ }
+ restoreState();
+ }
+ }
+ }
+ return FALSE;
+ } /* doubleAtari */
+
+short lookForAttack(x, y)
+short *x, *y;
+ { /* lookForAttack */
+ short tx, ty, i;
+ playReason = "lookForAttack";
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((! gList[i].isLive) &&
+ (gList[i].libC > 1) &&
+ (gList[i].libC <= (treeLibLim + 1)) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1))
+ {
+ if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */
+ {
+ *x = tx; /* yep - do so */
+ *y = ty;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } /* lookForAttack */
+
+ /*
+ Plays a move that requires a response on the opponent's part
+ */
+short threaten(x, y)
+short *x, *y;
+ { /* threaten */
+ short i, j, gx, gy, tNum;
+ playReason = "threaten";
+ initArray(threatBord);
+ for (i = 1; i <= maxGroupID; i++)
+ if ((! gList[i].isLive) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1))
+ {
+ spanGroup(gList[i].lx, gList[i].ly, &pList);
+ for (j = 1; j <= pList.indx; j++)
+ if (legal[pList.p[j].px][pList.p[j].py])
+ {
+ tryPlay(pList.p[j].px, pList.p[j].py, 1);
+ if (gList[groupIDs[pList.p[j].px][pList.p[j].py]].libC > 1)
+ if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
+ threatBord[pList.p[j].px][pList.p[j].py] += 1;
+ restoreState();
+ }
+ }
+ tNum = 0;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if ((threatBord[i][j] > tNum) &&
+ ((threatBord[i][j] > 1) ||
+ (connectMap[i][j] > 0)))
+ {
+ tNum = threatBord[i][j];
+ *x = i;
+ *y = j;
+ }
+ if (tNum > 0) return TRUE;
+ else return FALSE;
+ } /* threaten */
+
+ /*
+ connects against enemy cuts
+ */
+short connectCut(x, y)
+short *x, *y;
+ { /* connectCut */
+ short i, j, nap, gid, infl;
+ playReason = "connectCut";
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if (legal[i][j] &&
+ (protPoints[i][j] == 0)) /* not a protected point */
+ {
+ nap = 0; /* how many of my stones am I adjacent to? */
+ if ((i > 0) && (bord[i - 1][j] == 1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i - 1;
+ pList.p[nap].py = j;
+ }
+ if ((j > 0) && (bord[i][j - 1] == 1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i;
+ pList.p[nap].py = j - 1;
+ }
+ if ((i < maxPoint) && (bord[i + 1][j] == 1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i + 1;
+ pList.p[nap].py = j;
+ }
+ if ((j < maxPoint) && (bord[i][j + 1] == 1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i;
+ pList.p[nap].py = j + 1;
+ }
+ if (nap == 1) /* possible knight's || 2-point extention */
+ {
+ gid = groupIDs[pList.p[1].px][pList.p[1].py];
+ if ((i > 0) && (i < maxPoint) &&
+ (ndbord[i - 1][j] == 1) &&
+ (ndbord[i + 1][j] == 0)) /* contact on left */
+ {
+ if (((j > 0) && (ndbord[i][j - 1] == -1) &&
+ (ndbord[i + 1][j - 1] == 1) &&
+ (gid != groupIDs[i + 1][j - 1])) ||
+ ((j < maxPoint) && (ndbord[i][j + 1] == -1) &&
+ (ndbord[i + 1][j + 1] == 1) &&
+ (gid != groupIDs[i + 1][j + 1])) ||
+ ((((j > 0) && (ndbord[i][j - 1] == -1)) ||
+ ((j < maxPoint) && (ndbord[i][j + 1] == -1))) &&
+ (i < (maxPoint - 1)) &&
+ (ndbord[i + 2][j] == 1) &&
+ (gid != groupIDs[i + 2][j])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((i < maxPoint) && (i > 0) &&
+ (ndbord[i + 1][j] == 1) &&
+ (ndbord[i - 1][j] == 0)) /* r */
+ {
+ if (((j > 0) && (ndbord[i][j - 1] == -1) &&
+ (ndbord[i - 1][j - 1] == 1) &&
+ (gid != groupIDs[i - 1][j - 1])) ||
+ ((j < maxPoint) && (ndbord[i][j + 1] == -1) &&
+ (ndbord[i - 1][j + 1] == 1) &&
+ (gid != groupIDs[i - 1][j + 1])) ||
+ ((((j > 0) && (ndbord[i][j - 1] == -1)) ||
+ ((j < maxPoint) && (ndbord[i][j + 1] == -1))) &&
+ (i > 1) &&
+ (ndbord[i - 2][j] == 1) &&
+ (gid != groupIDs[i - 2][j])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((j > 0) && (j < maxPoint) &&
+ (ndbord[i][j - 1] == 1) &&
+ (ndbord[i][j + 1] == 0)) /* top */
+ {
+ if (((i > 0) && (ndbord[i - 1][j] == -1) &&
+ (ndbord[i - 1][j + 1] == 1) &&
+ (gid != groupIDs[i - 1][j + 1])) ||
+ ((i < maxPoint) && (ndbord[i + 1][j] == -1) &&
+ (ndbord[i + 1][j + 1] == 1) &&
+ (gid != groupIDs[i + 1][j + 1])) ||
+ ((((i > 0) && (ndbord[i - 1][j] == -1)) ||
+ ((i < maxPoint) && (ndbord[i + 1][j] == -1))) &&
+ (j < (maxPoint - 1)) &&
+ (ndbord[i][j + 2] == 1) &&
+ (gid != groupIDs[i][j + 2])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((j > 0) && (j < maxPoint) &&
+ (ndbord[i][j + 1] == 1) &&
+ (ndbord[i][j - 1] == 0)) /* bottom */
+ {
+ if (((i > 0) && (ndbord[i - 1][j] == -1) &&
+ (ndbord[i - 1][j - 1] == 1) &&
+ (gid != groupIDs[i - 1][j - 1])) ||
+ ((i < maxPoint) && (ndbord[i + 1][j] == -1) &&
+ (ndbord[i + 1][j - 1] == 1) &&
+ (gid != groupIDs[i + 1][j - 1])) ||
+ ((((i > 0) && (ndbord[i - 1][j] == -1)) ||
+ ((i < maxPoint) && (ndbord[i + 1][j] == -1))) &&
+ (j > 1) &&
+ (ndbord[i][j - 2] == 1) &&
+ (gid != groupIDs[i][j - 2])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ else if (nap == 2) /* diagonal or 1-point extention */
+ {
+ if (groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py])
+ {
+ if ((pList.p[1].px != pList.p[2].px) &&
+ (pList.p[1].py != pList.p[2].py)) /* diag */
+ {
+ spanGroup(pList.p[1].px,
+ pList.p[1].py, &pList1);
+ spanGroup(pList.p[2].px,
+ pList.p[2].py, &plist2);
+ intersectPlist(&pList1, &plist2, &plist3);
+ if (plist3.indx == 1)
+ if ((i > 0) && (ndbord[i - 1][j] == -1) ||
+ (i < maxPoint) && (ndbord[i + 1][j] == -1) ||
+ (j > 0) && (ndbord[i][j - 1] == -1) ||
+ (j < maxPoint) && (ndbord[i][j + 1] == -1))
+ { /* must make direct connection */
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ else if (heCanCut(i, j))
+ { /* protect point if possible */
+ infl = 1000;
+ if ((i > 0) && legal[i - 1][j] &&
+ ((i == 1) || (ndbord[i - 2][j] == 0)) &&
+ ((j == 0) || (ndbord[i - 1][j - 1] == 0)) &&
+ ((j == maxPoint) ||
+ (ndbord[i - 1][j + 1] == 0)))
+ if (safeMove(i - 1, j))
+ if (claim[i - 1][j] < infl)
+ {
+ *x = i - 1;
+ *y = j;
+ infl = claim[i - 1][j];
+ }
+ if ((j > 0) && legal[i][j - 1] &&
+ ((j == 1) || (ndbord[i][j - 2] == 0)) &&
+ ((i == 0) || (ndbord[i - 1][j - 1] == 0)) &&
+ ((i == maxPoint) ||
+ (ndbord[i + 1][j - 1] == 0)))
+ if (safeMove(i, j - 1))
+ if (claim[i][j - 1] < infl)
+ {
+ *x = i;
+ *y = j - 1;
+ infl = claim[i][j - 1];
+ }
+ if ((i < maxPoint) && legal[i + 1][j] &&
+ ((i == (maxPoint - 1)) ||
+ (ndbord[i + 2][j] == 0)) &&
+ ((j == 0) || (ndbord[i + 1][j - 1] == 0)) &&
+ ((j == maxPoint) ||
+ (ndbord[i + 1][j + 1] == 0)))
+ if (safeMove(i + 1, j))
+ if (claim[i + 1][j] < infl)
+ {
+ *x = i + 1;
+ *y = j;
+ infl = claim[i + 1][j];
+ }
+ if ((j < maxPoint) && legal[i][j + 1] &&
+ ((j == (maxPoint - 1)) ||
+ (ndbord[i][j + 2] == 0)) &&
+ ((i == 0) || (ndbord[i - 1][j + 1] == 0)) &&
+ ((i == maxPoint) ||
+ (ndbord[i + 1][j + 1] == 0)))
+ if (safeMove(i, j + 1))
+ if (claim[i][j + 1] < infl)
+ {
+ *x = i;
+ *y = j + 1;
+ infl = claim[i][j + 1];
+ }
+ if (infl < 1000)
+ return TRUE;
+ *x = i; /* direct connection */
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else /* 1-point extension, only protect if threatened */
+ {
+ if ((i > 0) && (ndbord[i - 1][j] == -1) ||
+ (j > 0) && (ndbord[i][j - 1] == -1) ||
+ (i < maxPoint) && (ndbord[i + 1][j] == -1) ||
+ (j < maxPoint) && (ndbord[i][j + 1] == -1))
+ {
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ }
+ else if (nap == 3) /* unprotected, but me on 3 sides */
+ {
+ if ((groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py]) ||
+ (groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[3].px][pList.p[3].py]) ||
+ (groupIDs[pList.p[3].px][pList.p[3].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py]))
+ {
+ spanGroup(pList.p[1].px, pList.p[1].py, &pList1);
+ spanGroup(pList.p[2].px, pList.p[2].py, &plist2);
+ intersectPlist(&pList1, &plist2, &plist3);
+ spanGroup(pList.p[3].px, pList.p[3].py, &plist2);
+ intersectPlist(&plist2, &plist3, &pList1);
+ if (pList1.indx == 1) /* a common connect point */
+ if (heCanCut(i, j))
+ if (safeMove(i, j))
+ {
+ *x = i;
+ *y = j;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+ } /* connectCut */
+
+short heCanCut(x, y)
+short x, y;
+ { /* heCanCut */
+ short gx, gy, result;
+ if (playLevel > 3)
+ {
+ tryPlay(x, y, -1); /* try his cut */
+ result = ! killable(x, y, &gx, &gy);
+ restoreState();
+ return result;
+ }
+ else
+ return FALSE;
+ } /* heCanCut */
+
+ /*
+ Checks out a move.
+ If my stone is not killable then true.
+ */
+short safeMove(x, y)
+short x, y;
+ { /* safeMove */
+ short gbx, gby, result;
+ tryPlay(x, y, 1); /* try playing at point */
+ if (killFlag) /* I shouldn't kill if lookForKill didn't */
+ result = FALSE;
+ else if (gList[groupIDs[x][y]].libC < 2)
+ { /* if it is in atari or dead */
+ result = FALSE; /* reject it */
+ }
+ else if (gList[groupIDs[x][y]].libC <= treeLibLim) /* see if killable */
+ if (playLevel > 0)
+ result = ! killable(x, y, &gbx, &gby);
+ else
+ result = TRUE;
+ else
+ result = TRUE;
+ restoreState();
+ return result;
+ } /* safeMove */
+
+ /*
+ Extends walls in a connected fashion.
+ Finds the lowest influence (mine) point that is connected to one
+ of my groups.
+ Only looks in the center of the board.
+ */
+short extendWall(x, y)
+short *x, *y;
+ { /* extendWall */
+ short infl, i, j;
+ playReason = "extendWall";
+ *x = iNil;
+ *y = iNil;
+ infl = 11;
+ for (i = 2; i <= maxPoint - 2; i++)
+ for (j = 2; j <= maxPoint - 2; j++)
+ if (legal[i][j])
+ if (connectMap[i][j] > 0)
+ if ((claim[i][j] < infl) &&
+ (ndbord[i - 1][j] < 1) &&
+ (ndbord[i + 1][j] < 1) &&
+ (ndbord[i][j - 1] < 1) &&
+ (ndbord[i][j + 1] < 1) &&
+ ((claim[i - 1][j] < 0) ||
+ (claim[i + 1][j] < 0) ||
+ (claim[i][j - 1] < 0) ||
+ (claim[i][j + 1] < 0)))
+ if (safeMove(i, j))
+ {
+ infl = claim[i][j];
+ *x = i;
+ *y = j;
+ }
+ if (*x != iNil) return TRUE;
+ return FALSE;
+ } /* extendWall */
+
+
+ /*
+ check to see if I can attack one of his groups
+ uses limited depth search so that it can work on larger lib counts
+ */
+short findAttack2(x, y)
+short *x, *y;
+ { /* findAttack2 */
+ short tx, ty, i, otll;
+ if (playLevel < 7)
+ return FALSE;
+ playReason = "findAttack2";
+ depthLimit = 8;
+ otll = treeLibLim;
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((! gList[i].isLive) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1) &&
+ (gList[i].libC > 1))
+ {
+ treeLibLim = 6;
+ if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */
+ {
+ *x = tx; /* yep - do so */
+ *y = ty;
+ return TRUE;
+ }
+ treeLibLim = otll;
+ }
+ depthLimit = 100;
+ return FALSE;
+ } /* findAttack2 */
+
+
+ /*
+ blocks enemy cuts thru 1-point extensions
+ */
+short blockCut(x, y)
+short *x, *y;
+ { /* blockCut */
+ short i, j;
+ playReason = "blockCut";
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if (legal[i][j])
+ {
+ if ((i > 0) && (j > 0) && (j < maxPoint))
+ {
+ if ((ndbord[i - 1][j] == -1) &&
+ (ndbord[i - 1][j - 1] == 1) &&
+ (ndbord[i - 1][j + 1] == 1) &&
+ (groupIDs[i - 1][j - 1] != groupIDs[i - 1][j + 1]))
+ {
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if ((i < maxPoint) && (j > 0) && (j < maxPoint))
+ {
+ if ((ndbord[i + 1][j] == -1) &&
+ (ndbord[i + 1][j - 1] == 1) &&
+ (ndbord[i + 1][j + 1] == 1) &&
+ (groupIDs[i + 1][j - 1] != groupIDs[i + 1][j + 1]))
+ {
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if ((j > 0) && (i > 0) && (i < maxPoint))
+ {
+ if ((ndbord[i][j - 1] == -1) &&
+ (ndbord[i - 1][j - 1] == 1) &&
+ (ndbord[i + 1][j - 1] == 1) &&
+ (groupIDs[i - 1][j - 1] != groupIDs[i + 1][j - 1]))
+ {
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if ((j < maxPoint) && (i > 0) && (i < maxPoint))
+ {
+ if ((ndbord[i][j + 1] == -1) &&
+ (ndbord[i - 1][j + 1] == 1) &&
+ (ndbord[i + 1][j + 1] == 1) &&
+ (groupIDs[i - 1][j + 1] != groupIDs[i + 1][j + 1]))
+ {
+ *x = i;
+ *y = j;
+ if (heCanCut(*x, *y))
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ } /* blockCut */
+
+
+ /*
+ cuts the enemy
+ */
+short cutHim(x, y)
+short *x, *y;
+ { /* cutHim */
+ short i, j, nap, gid;
+ playReason = "cutHim";
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if (legal[i][j])
+ {
+ nap = 0; /* how many of his stones am I adjacent to? */
+ if ((i > 0) && (ndbord[i - 1][j] == -1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i - 1;
+ pList.p[nap].py = j;
+ }
+ if ((j > 0) && (ndbord[i][j - 1] == -1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i;
+ pList.p[nap].py = j - 1;
+ }
+ if ((i < maxPoint) && (ndbord[i + 1][j] == -1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i + 1;
+ pList.p[nap].py = j;
+ }
+ if ((j < maxPoint) && (ndbord[i][j + 1] == -1))
+ {
+ nap = nap + 1;
+ pList.p[nap].px = i;
+ pList.p[nap].py = j + 1;
+ }
+ if (nap == 1) /* possible knight's or 2-point extention */
+ {
+ gid = groupIDs[pList.p[1].px][pList.p[1].py];
+ if ((i > 0) && (i < maxPoint) &&
+ (ndbord[i - 1][j] == -1) &&
+ (connectMap[i][j] > 0)) /* contact on left */
+ {
+ if (((j > 0) &&
+ (ndbord[i + 1][j - 1] == -1) &&
+ (gid != groupIDs[i + 1][j - 1])) ||
+ ((j < maxPoint) &&
+ (ndbord[i + 1][j + 1] == -1) &&
+ (gid != groupIDs[i + 1][j + 1])) ||
+ ((i < (maxPoint - 1)) &&
+ (ndbord[i + 1][j] == 0) &&
+ (ndbord[i + 2][j] == -1) &&
+ (gid != groupIDs[i + 2][j])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((i < maxPoint) && (i > 0) &&
+ (ndbord[i + 1][j] == -1) &&
+ (connectMap[i][j] > 0)) /* r */
+ {
+ if (((j > 0) &&
+ (ndbord[i - 1][j - 1] == -1) &&
+ (gid != groupIDs[i - 1][j - 1])) ||
+ ((j < maxPoint) &&
+ (ndbord[i - 1][j + 1] == -1) &&
+ (gid != groupIDs[i - 1][j + 1])) ||
+ ((i > 1) &&
+ (ndbord[i - 1][j] == 0) &&
+ (ndbord[i - 2][j] == -1) &&
+ (gid != groupIDs[i - 2][j])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((j > 0) && (j < maxPoint) &&
+ (ndbord[i][j - 1] == -1) &&
+ (connectMap[i][j] > 0)) /* top */
+ {
+ if (((i > 0) &&
+ (ndbord[i - 1][j + 1] == -1) &&
+ (gid != groupIDs[i - 1][j + 1])) ||
+ ((i < maxPoint) &&
+ (ndbord[i + 1][j + 1] == -1) &&
+ (gid != groupIDs[i + 1][j + 1])) ||
+ ((j < (maxPoint - 1)) &&
+ (ndbord[i][j + 1] == 0) &&
+ (ndbord[i][j + 2] == -1) &&
+ (gid != groupIDs[i][j + 2])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else if ((j > 0) && (j < maxPoint) &&
+ (ndbord[i][j + 1] == -1) &&
+ (connectMap[i][j] > 0)) /* bottom */
+ {
+ if (((i > 0) &&
+ (ndbord[i - 1][j - 1] == -1) &&
+ (gid != groupIDs[i - 1][j - 1])) ||
+ ((i < maxPoint) &&
+ (ndbord[i + 1][j - 1] == -1) &&
+ (gid != groupIDs[i + 1][j - 1])) ||
+ ((j > 1) &&
+ (ndbord[i][j - 1] == 0) &&
+ (ndbord[i][j - 2] == -1) &&
+ (gid != groupIDs[i][j - 2])))
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ else if (nap == 2) /* diagonal or 1-point extention */
+ {
+ if (groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py])
+ {
+ if ((pList.p[1].px != pList.p[2].px) &&
+ (pList.p[1].py != pList.p[2].py)) /* diag */
+ {
+ spanGroup(pList.p[1].px,
+ pList.p[1].py, &pList1);
+ spanGroup(pList.p[2].px,
+ pList.p[2].py, &plist2);
+ intersectPlist(&pList1, &plist2, &plist3);
+ if (plist3.indx == 1)
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ else /* 1-point extension, only cut if connected */
+ {
+ if (connectMap[i][j] > 0)
+ {
+ *x = i;
+ *y = j;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ }
+ else if (nap == 3) /* unprotected, but him on 3 sides */
+ {
+ if ((groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py]) ||
+ (groupIDs[pList.p[1].px][pList.p[1].py] !=
+ groupIDs[pList.p[3].px][pList.p[3].py]) ||
+ (groupIDs[pList.p[3].px][pList.p[3].py] !=
+ groupIDs[pList.p[2].px][pList.p[2].py]))
+ {
+ spanGroup(pList.p[1].px, pList.p[1].py, &pList1);
+ spanGroup(pList.p[2].px, pList.p[2].py, &plist2);
+ intersectPlist(&pList1, &plist2, &plist3);
+ spanGroup(pList.p[3].px, pList.p[3].py, &plist2);
+ intersectPlist(&plist2, &plist3, &pList1);
+ if (pList1.indx == 1) /* a common connect point */
+ if (safeMove(i, j))
+ {
+ *x = i;
+ *y = j;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+ } /* cutHim */
+
+
+ /*
+ ataris a group just for the hell of it
+ */
+short atariAnyway(x, y)
+short *x, *y;
+ { /* atariAnyway */
+ short i;
+ playReason = "atariAnyway";
+ for (i = 1; i <= maxGroupID; i++) /* scan the group list */
+ if ((gList[i].libC == 2) &&
+ (ndbord[gList[i].lx][gList[i].ly] == -1))
+ {
+ spanGroup(gList[i].lx, gList[i].ly, &pList);
+ if (legal[pList.p[1].px][pList.p[1].py] &&
+ ((connectMap[pList.p[1].px][pList.p[1].py] > 0) ||
+ ((pList.p[1].px > 0) &&
+ (connectMap[pList.p[1].px - 1][pList.p[1].py] > 0)) ||
+ ((pList.p[1].px < maxPoint) &&
+ (connectMap[pList.p[1].px + 1][pList.p[1].py] > 0)) ||
+ ((pList.p[1].py > 0) &&
+ (connectMap[pList.p[1].px][pList.p[1].py - 1] > 0)) ||
+ ((pList.p[1].py < maxPoint) &&
+ (connectMap[pList.p[1].px][pList.p[1].py + 1] > 0))))
+ if (safeMove(pList.p[1].px, pList.p[1].py))
+ {
+ *x = pList.p[1].px;
+ *y = pList.p[1].py;
+ return TRUE;
+ }
+ if (legal[pList.p[2].px][pList.p[2].py] &&
+ ((connectMap[pList.p[2].px][pList.p[2].py] > 0) ||
+ ((pList.p[2].px > 0) &&
+ (connectMap[pList.p[2].px - 1][pList.p[2].py] > 0)) ||
+ ((pList.p[2].px < maxPoint) &&
+ (connectMap[pList.p[2].px + 1][pList.p[2].py] > 0)) ||
+ ((pList.p[2].py > 0) &&
+ (connectMap[pList.p[2].px][pList.p[2].py - 1] > 0)) ||
+ ((pList.p[2].py < maxPoint) &&
+ (connectMap[pList.p[2].px][pList.p[2].py + 1] > 0))))
+ if (safeMove(pList.p[2].px, pList.p[2].py))
+ {
+ *x = pList.p[2].px;
+ *y = pList.p[2].py;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } /* atariAnyway */
+
+
+ /*
+ undercuts his groups
+ */
+short underCut(x, y)
+short *x, *y;
+ { /* underCut */
+ short i, j;
+ playReason = "underCut";
+ for (i = 1; i <= maxPoint - 1; i++)
+ {
+ if (legal[0][i])
+ {
+ if (ndbord[1][i] == -1)
+ if (safeMove(0, i))
+ {
+ *x = 0;
+ *y = i;
+ return TRUE;
+ }
+ }
+ if (legal[maxPoint][i])
+ {
+ if (ndbord[maxPoint - 1][i] == -1)
+ if (safeMove(maxPoint, i))
+ {
+ *x = maxPoint;
+ *y = i;
+ return TRUE;
+ }
+ }
+ if (legal[i][0])
+ {
+ if (ndbord[i][1] == -1)
+ if (safeMove(i, 0))
+ {
+ *x = i;
+ *y = 0;
+ return TRUE;
+ }
+ }
+ if (legal[i][maxPoint])
+ {
+ if (ndbord[i][maxPoint - 1] == -1)
+ if (safeMove(i, maxPoint))
+ {
+ *x = i;
+ *y = maxPoint;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ } /* underCut */
+
+ /*
+ drops to the edge of the board if threatened
+ */
+short dropToEdge(x, y)
+short *x, *y;
+ { /* dropToEdge */
+ short i;
+ playReason = "dropToEdge";
+ for (i = 1; i <= maxPoint - 1; i++)
+ {
+ if (legal[1][i])
+ if ((ndbord[2][i] == 1) &&
+ (ndbord[0][i] == 0) &&
+ (ndbord[1][i - 1] < 1) &&
+ (ndbord[1][i + 1] < 1) &&
+ ((ndbord[2][i - 1] == -1) ||
+ (ndbord[2][i + 1] == -1) ||
+ (ndbord[1][i - 1] == -1) ||
+ (ndbord[1][i + 1] == -1)))
+ {
+ *x = 1;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[maxPoint - 1][i])
+ if ((ndbord[maxPoint - 2][i] == 1) &&
+ (ndbord[maxPoint][i] == 0) &&
+ (ndbord[maxPoint - 1][i - 1] < 1) &&
+ (ndbord[maxPoint - 1][i + 1] < 1) &&
+ ((ndbord[maxPoint - 2][i - 1] == -1) ||
+ (ndbord[maxPoint - 2][i + 1] == -1) ||
+ (ndbord[maxPoint - 1][i - 1] == -1) ||
+ (ndbord[maxPoint - 1][i + 1] == -1)))
+ {
+ *x = maxPoint - 1;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[i][1])
+ if ((ndbord[i][2] == 1) &&
+ (ndbord[i][0] == 0) &&
+ (ndbord[i - 1][1] < 1) &&
+ (ndbord[i + 1][1] < 1) &&
+ ((ndbord[i - 1][2] == -1) ||
+ (ndbord[i + 1][2] == -1) ||
+ (ndbord[i - 1][1] == -1) ||
+ (ndbord[i + 1][1] == -1)))
+ {
+ *x = i;
+ *y = 1;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[i][maxPoint - 1])
+ if ((ndbord[i][maxPoint - 2] == 1) &&
+ (ndbord[i][maxPoint] == 0) &&
+ (ndbord[i - 1][maxPoint - 1] < 1) &&
+ (ndbord[i + 1][maxPoint - 1] < 1) &&
+ ((ndbord[i - 1][maxPoint - 2] == -1) ||
+ (ndbord[i + 1][maxPoint - 2] == -1) ||
+ (ndbord[i - 1][maxPoint - 1] == -1) ||
+ (ndbord[i + 1][maxPoint - 1] == -1)))
+ {
+ *x = i;
+ *y = maxPoint - 1;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[0][i])
+ if ((ndbord[1][i] == 1) &&
+ (ndbord[0][i - 1] < 1) &&
+ (ndbord[0][i + 1] < 1) &&
+ (((ndbord[1][i - 1] == -1) &&
+ (ndbord[1][i + 1] == -1)) ||
+ (ndbord[0][i - 1] == -1) ||
+ (ndbord[0][i + 1] == -1)))
+ {
+ *x = 0;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[maxPoint][i])
+ if ((ndbord[maxPoint - 1][i] == 1) &&
+ (ndbord[maxPoint][i - 1] < 1) &&
+ (ndbord[maxPoint][i + 1] < 1) &&
+ (((ndbord[maxPoint - 1][i - 1] == -1) &&
+ (ndbord[maxPoint - 1][i + 1] == -1)) ||
+ (ndbord[maxPoint][i - 1] == -1) ||
+ (ndbord[maxPoint][i + 1] == -1)))
+ {
+ *x = maxPoint;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[i][0])
+ if ((ndbord[i][1] == 1) &&
+ (ndbord[i - 1][0] < 1) &&
+ (ndbord[i + 1][0] < 1) &&
+ (((ndbord[i - 1][1] == -1) &&
+ (ndbord[i + 1][1] == -1)) ||
+ (ndbord[i - 1][0] == -1) ||
+ (ndbord[i + 1][0] == -1)))
+ {
+ *x = i;
+ *y = 0;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ if (legal[i][maxPoint])
+ if ((ndbord[i][maxPoint - 1] == 1) &&
+ (ndbord[i - 1][maxPoint] < 1) &&
+ (ndbord[i + 1][maxPoint] < 1) &&
+ (((ndbord[i - 1][maxPoint - 1] == -1) &&
+ (ndbord[i + 1][maxPoint - 1] == -1)) ||
+ (ndbord[i - 1][maxPoint] == -1) ||
+ (ndbord[i + 1][maxPoint] == -1)))
+ {
+ *x = i;
+ *y = maxPoint;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } /* dropToEdge */
+
+ /*
+ Pushes walls in a tightly connected fashion.
+ Finds the lowest influence (mine) point that is connected to one
+ of my groups.
+ */
+short pushWall(x, y)
+short *x, *y;
+ { /* pushWall */
+ short infl, i, j, na;
+ playReason = "pushWall";
+ *x = iNil;
+ *y = iNil;
+ infl = 11;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if (legal[i][j])
+ if (connectMap[i][j] > 0)
+ if ((claim[i][j] < infl) &&
+ (((i > 0) && (ndbord[i - 1][j] == 1)) ||
+ ((i < maxPoint) && (ndbord[i + 1][j] == 1)) ||
+ ((j > 0) && (ndbord[i][j - 1] == 1)) ||
+ ((j < maxPoint) && (ndbord[i][j + 1] == 1)) ||
+ ((i > 0) && (j > 0) && (ndbord[i - 1][j - 1] == 1)) ||
+ ((i < maxPoint) && (j > 0) && (ndbord[i + 1][j - 1] == 1)) ||
+ ((i > 0) && (j < maxPoint) && (ndbord[i - 1][j + 1] == 1)) ||
+ ((i < maxPoint) && (j < maxPoint) &&
+ (ndbord[i + 1][j + 1] == 1))) &&
+ (((i > 0) && (claim[i - 1][j] < 0)) ||
+ ((i < maxPoint) && (claim[i + 1][j] < 0)) ||
+ ((j > 0) && (claim[i][j - 1] < 0)) ||
+ ((j < maxPoint) && (claim[i][j + 1] < 0))))
+ {
+ na = 0;
+ if ((i > 0) && (ndbord[i - 1][j] != 0))
+ na = na + 1;
+ if ((i < maxPoint) && (ndbord[i + 1][j] != 0))
+ na = na + 1;
+ if ((j > 0) && (ndbord[i][j - 1] != 0))
+ na = na + 1;
+ if ((j < maxPoint) && (ndbord[i][j + 1] != 0))
+ na = na + 1;
+ if (na < 3)
+ if (safeMove(i, j))
+ {
+ infl = claim[i][j];
+ *x = i;
+ *y = j;
+ }
+ }
+ if (*x != iNil) return TRUE;
+ return FALSE;
+ } /* pushWall */
+
+
+ /*
+ reduces the liberty count of one of his groups
+ */
+short reduceHisLiberties(x, y)
+short *x, *y;
+ { /* reduceHisLiberties */
+ short i, j;
+ playReason = "reduceHisLiberties";
+ sortLibs();
+ for (i = 1; i <= maxGroupID; i++)
+ if ((! gList[sGlist[i]].isLive) &&
+ (gList[sGlist[i]].libC > 2) &&
+ (ndbord[gList[sGlist[i]].lx][gList[sGlist[i]].ly] == -1))
+ {
+ spanGroup(gList[sGlist[i]].lx, gList[sGlist[i]].ly, &pList);
+ for (j = 1; j <= pList.indx; j++)
+ if (legal[pList.p[j].px][pList.p[j].py] &&
+ (connectMap[pList.p[j].px][pList.p[j].py] > 0))
+ if (safeMove(pList.p[j].px, pList.p[j].py))
+ {
+ *x = pList.p[j].px;
+ *y = pList.p[j].py;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } /* reduceHisLiberties */
+
+
+ /*
+ connects a group to the edge
+ */
+short dropToEdge2(x, y)
+short *x, *y;
+ { /* dropToEdge2 */
+ short i;
+ playReason = "dropToEdge2";
+ for (i = 1; i <= maxPoint - 1; i++)
+ {
+ if (legal[i][0])
+ {
+ if ((ndbord[i][1] == 1) &&
+ ((ndbord[i - 1][0] < 1) ||
+ (groupIDs[i - 1][0] != groupIDs[i][1])) &&
+ ((ndbord[i + 1][0] < 1) ||
+ (groupIDs[i + 1][0] != groupIDs[i][1])) &&
+ ((ndbord[i - 1][1] == -1) ||
+ (ndbord[i + 1][1] == -1)))
+ {
+ *x = i;
+ *y = 0;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if (legal[0][i])
+ {
+ if ((ndbord[1][i] == 1) &&
+ ((ndbord[0][i - 1] < 1) ||
+ (groupIDs[0][i - 1] != groupIDs[1][i])) &&
+ ((ndbord[0][i + 1] < 1) ||
+ (groupIDs[0][i + 1] != groupIDs[1][i])) &&
+ ((ndbord[1][i - 1] == -1) ||
+ (ndbord[1][i + 1] == -1)))
+ {
+ *x = 0;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if (legal[i][maxPoint])
+ {
+ if ((ndbord[i][maxPoint - 1] == 1) &&
+ ((ndbord[i - 1][maxPoint] < 1) ||
+ (groupIDs[i - 1][maxPoint] != groupIDs[i][maxPoint - 1])) &&
+ ((ndbord[i + 1][maxPoint] < 1) ||
+ (groupIDs[i + 1][maxPoint] != groupIDs[i][maxPoint - 1])) &&
+ ((ndbord[i - 1][maxPoint - 1] == -1) ||
+ (ndbord[i + 1][maxPoint - 1] == -1)))
+ {
+ *x = i;
+ *y = maxPoint;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ if (legal[maxPoint][i])
+ {
+ if ((ndbord[maxPoint - 1][i] == 1) &&
+ ((ndbord[maxPoint][i - 1] < 1) ||
+ (groupIDs[maxPoint][i - 1] != groupIDs[maxPoint - 1][i])) &&
+ ((ndbord[maxPoint][i + 1] < 1) ||
+ (groupIDs[maxPoint][i + 1] != groupIDs[maxPoint - 1][i])) &&
+ ((ndbord[maxPoint - 1][i - 1] == -1) ||
+ (ndbord[maxPoint - 1][i + 1] == -1)))
+ {
+ *x = maxPoint;
+ *y = i;
+ if (safeMove(*x, *y))
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ } /* dropToEdge2 */
+
diff --git a/noncore/games/go/goplayutils.c b/noncore/games/go/goplayutils.c
new file mode 100644
index 0000000..9e2ce4c
--- a/dev/null
+++ b/noncore/games/go/goplayutils.c
@@ -0,0 +1,1317 @@
+/* The go player utilities */
+/* Ported from Pascal to C by Todd R. Johnson */
+/* From the original Pascal file:
+Copyright (c) 1983 by Three Rivers Computer Corp.
+
+Written: January 17, 1983 by Stoney Ballard
+*/
+
+#include "goplayutils.h"
+#include "amigo.h"
+#include "go.h"
+
+extern struct bRec goboard[19][19];
+
+intBoard claim, extra, bord, ndbord, sGroups, threatBord,
+ groupIDs, connectMap, protPoints;
+boolBoard groupSeen, legal;
+short maxGroupID;
+pointList pList, pList1, plist2, plist3, pPlist;
+intList nlcGroup, aList;
+sgRec sList[401];
+groupRec gList[maxGroup];
+short killFlag,
+ numCapt,
+ utilPlayLevel,
+ treeLibLim;
+sType mySType;
+short showTrees;
+short sGlist[maxGroup+1];
+short depthLimit;
+intBoard markBoard;
+short marker;
+
+short adjInAtari, adj2Libs,
+ intersectNum, spanNum, libMark;
+playRec playStack[1025];
+short playMark,
+ newGID,
+ tryLevel,
+ grpMark,
+ gMap[maxGroup];
+short dbStop, inGenState;
+
+ pause()
+{ /* pause */
+/* if (dbStop and ! inGenState)
+ {
+ while ! tabswitch do;
+ repeat
+ if (tabYellow)
+ dbStop = false;
+ until ! tabswitch;
+ } */
+} /* pause */
+
+sstone(w, x, y, numb)
+short w, x, y, numb;
+{ /* sstone */
+ if (w == 1)
+ placestone(mySType, x, y);
+ else if (mySType == WHITE)
+ placestone(BLACK, x, y);
+ else
+ placestone(WHITE, x, y);
+} /* sstone */
+
+rstone(x, y)
+short x, y;
+{ /* rstone */
+ removestone(x, y);
+} /* rstone */
+
+initBoolBoard(bb)
+boolBoard bb;
+{ /* initBoolBoard */
+ short i, j;
+#ifdef DEBUG
+ printf( "initBoolBoard\n" );
+#endif
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ bb[i][j] = FALSE;
+} /* initBoolBoard */
+
+sortLibs()
+{ /* sortLibs */
+ short i, j, t;
+#ifdef DEBUG
+ printf( "sortLibs\n" );
+#endif
+ for (i = 1; i <= maxGroupID; i++)
+ sGlist[i] = i;
+ for (i = 1; i < maxGroupID; i++)
+ for (j = i + 1; j <= maxGroupID; j++)
+ if (gList[sGlist[i]].libC > gList[sGlist[j]].libC)
+ {
+ t = sGlist[i];
+ sGlist[i] = sGlist[j];
+ sGlist[j] = t;
+ }
+} /* sortLibs */
+
+spanGroupspan(x, y, libs, lookFor)
+short x, y, lookFor;
+pointList *libs;
+ { /* span */
+ markBoard[x][y] = marker;
+ if (bord[x][y] == 0)
+ {
+ libs->indx = libs->indx + 1;
+ libs->p[libs->indx].px = x;
+ libs->p[libs->indx].py = y;
+ }
+ else if (bord[x][y] == lookFor)
+ {
+ groupSeen[x][y] = TRUE;
+ if ((x > 0) && (markBoard[x - 1][y] != marker))
+ spanGroupspan(x - 1, y, libs, lookFor);
+ if ((y > 0) && (markBoard[x][y - 1] != marker))
+ spanGroupspan(x, y - 1, libs, lookFor);
+ if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
+ spanGroupspan(x + 1, y, libs, lookFor);
+ if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
+ spanGroupspan(x, y + 1, libs, lookFor);
+ }
+ else if (gList[gMap[groupIDs[x][y]]].libC == 1)
+ adjInAtari = TRUE;
+ else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
+ (! gList[gMap[groupIDs[x][y]]].isLive))
+ adj2Libs = TRUE;
+ } /* span */
+
+spanGroup(x, y, libs)
+short x, y;
+pointList *libs;
+{ /* spanGroup */
+ short lookFor;
+#ifdef DEBUG
+ printf( "spanGroup\n" );
+#endif
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ adjInAtari = FALSE;
+ adj2Libs = FALSE;
+ lookFor = bord[x][y];
+ libs->indx = 0;
+ spanGroupspan(x, y, libs, lookFor);
+} /* spanGroup */
+
+sSpanGroupspan(x, y, libs, lookFor)
+short x, y, lookFor;
+sPointList *libs;
+ { /* span */
+ markBoard[x][y] = marker;
+ if (bord[x][y] == 0)
+ {
+ libs->indx += 1;
+ if (libs->indx <= maxSPoint)
+ {
+ libs->p[libs->indx].px = x;
+ libs->p[libs->indx].py = y;
+ }
+ }
+ else if (bord[x][y] == lookFor)
+ {
+ groupSeen[x][y] = TRUE;
+ if ((x > 0) && (markBoard[x - 1][y] != marker))
+ sSpanGroupspan(x - 1, y, libs, lookFor);
+ if ((y > 0) && (markBoard[x][y - 1] != marker))
+ sSpanGroupspan(x, y - 1, libs, lookFor);
+ if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
+ sSpanGroupspan(x + 1, y, libs, lookFor);
+ if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
+ sSpanGroupspan(x, y + 1, libs, lookFor);
+ }
+ else if (gList[gMap[groupIDs[x][y]]].libC == 1)
+ adjInAtari = TRUE;
+ else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
+ (! gList[gMap[groupIDs[x][y]]].isLive))
+ adj2Libs = TRUE;
+ } /* span */
+
+sSpanGroup(x, y, libs)
+short x, y;
+sPointList *libs;
+{ /* sSpanGroup */
+ short lookFor;
+#ifdef DEBUG
+ printf( "sSpanGroup\n" );
+#endif
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ adjInAtari = FALSE;
+ adj2Libs = FALSE;
+ lookFor = bord[x][y];
+ libs->indx = 0;
+ sSpanGroupspan(x, y, libs, lookFor);
+} /* sSpanGroup */
+
+LAspan(x, y, me, him, iL)
+short x, y, me, him;
+intList *iL;
+ { /* span */
+#ifdef DEBUG
+ printf( "LAspan\n" );
+#endif
+ markBoard[x][y] = marker;
+ if (bord[x][y] == me)
+ {
+ if ((x > 0) && (markBoard[x - 1][y] != marker))
+ LAspan(x - 1, y, me, him, iL);
+ if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
+ LAspan(x + 1, y, me, him, iL);
+ if ((y > 0) && (markBoard[x][y - 1] != marker))
+ LAspan(x, y - 1, me, him, iL);
+ if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
+ LAspan(x, y + 1, me, him, iL);
+ }
+ else if (bord[x][y] == him)
+ if (gList[gMap[groupIDs[x][y]]].groupMark != grpMark)
+ {
+ gList[gMap[groupIDs[x][y]]].groupMark = grpMark;
+ iL->indx = iL->indx + 1;
+ iL->v[iL->indx] = gMap[groupIDs[x][y]];
+ }
+ } /* span */
+
+listAdjacents(x, y, iL)
+short x, y;
+intList *iL;
+{ /* listAdjacents */
+ short me, him;
+#ifdef DEBUG
+ printf( "listAdjacents\n" );
+#endif
+ grpMark = grpMark + 1;
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ iL->indx = 0;
+ me = bord[x][y];
+ him = -me;
+ LAspan(x, y, me , him, iL);
+} /* listAdjacents */
+
+LDspan(x, y, me, diags)
+short x, y, me;
+sPointList *diags;
+ { /* span */
+#ifdef DEBUG
+ printf( "LDspan\n" );
+#endif
+ markBoard[x][y] = marker;
+ if ((x > 0) && (y > 0) &&
+ (bord[x - 1][y - 1] == 0) &&
+ (bord[x][y - 1] != me) &&
+ (bord[x - 1][y] != me) &&
+ (markBoard[x - 1][y - 1] != marker))
+ {
+ markBoard[x - 1][y - 1] = marker;
+ diags->indx = diags->indx + 1;
+ if (diags->indx <= maxSPoint)
+ {
+ diags->p[diags->indx].px = x - 1;
+ diags->p[diags->indx].py = y - 1;
+ }
+ }
+ if ((x < maxPoint) && (y > 0) &&
+ (bord[x + 1][y - 1] == 0) &&
+ (bord[x][y - 1] != me) &&
+ (bord[x + 1][y] != me) &&
+ (markBoard[x + 1][y - 1] != marker))
+ {
+ markBoard[x + 1][y - 1] = marker;
+ diags->indx = diags->indx + 1;
+ if (diags->indx <= maxSPoint)
+ {
+ diags->p[diags->indx].px = x + 1;
+ diags->p[diags->indx].py = y - 1;
+ }
+ }
+ if ((x > 0) && (y < maxPoint) &&
+ (bord[x - 1][y + 1] == 0) &&
+ (bord[x][y + 1] != me) &&
+ (bord[x - 1][y] != me) &&
+ (markBoard[x - 1][y + 1] != marker))
+ {
+ markBoard[x - 1][y + 1] = marker;
+ diags->indx = diags->indx + 1;
+ if (diags->indx <= maxSPoint)
+ {
+ diags->p[diags->indx].px = x - 1;
+ diags->p[diags->indx].py = y + 1;
+ }
+ }
+ if ((x < maxPoint) && (y < maxPoint) &&
+ (bord[x + 1][y + 1] == 0) &&
+ (bord[x][y + 1] != me) &&
+ (bord[x + 1][y] != me) &&
+ (markBoard[x + 1][y + 1] != marker))
+ {
+ markBoard[x + 1][y + 1] = marker;
+ diags->indx = diags->indx + 1;
+ if (diags->indx <= maxSPoint)
+ {
+ diags->p[diags->indx].px = x + 1;
+ diags->p[diags->indx].py = y + 1;
+ }
+ }
+ if ((x > 0) && (bord[x - 1][y] == me) &&
+ (markBoard[x - 1][y] != marker))
+ LDspan(x - 1, y, me, diags);
+ if ((x < maxPoint) && (bord[x + 1][y] == me) &&
+ (markBoard[x + 1][y] != marker))
+ LDspan(x + 1, y, me, diags);
+ if ((y > 0) && (bord[x][y - 1] == me) &&
+ (markBoard[x][y - 1] != marker))
+ LDspan(x, y - 1, me, diags);
+ if ((y < maxPoint) && (bord[x][y + 1] == me) &&
+ (markBoard[x][y + 1] != marker))
+ LDspan(x, y + 1, me , diags);
+} /* span */
+
+listDiags(x, y, diags)
+short x, y;
+sPointList *diags;
+{ /* listDiags */
+ short me;
+#ifdef DEBUG
+ printf( "listDiags\n" );
+#endif
+ me = bord[x][y];
+ diags->indx = 0;
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ LDspan(x, y, me, diags);
+} /* listDiags */
+
+intersectPlist(p1, p2, pr)
+pointList *p1, *p2, *pr;
+{ /* intersectPlist */
+ short i, j, k;
+#ifdef DEBUG
+ printf( "intersectPlist\n" );
+#endif
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ pr->indx = 0;
+ for (i = 1; i <= p1->indx; i++)
+ markBoard[p1->p[i].px][p1->p[i].py] = marker;
+ j = 0;
+ for (i = 1; i <= p2->indx; i++)
+ if (markBoard[p2->p[i].px][p2->p[i].py] == marker)
+ {
+ j = j + 1;
+ pr->p[j] = p2->p[i];
+ }
+ pr->indx = j;
+} /* intersectPlist */
+
+initArray(ary)
+intBoard ary;
+{ /* initArray */
+ short i, j;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ ary[i][j] = 0;
+} /* initArray */
+
+initState()
+{ /* initState */
+ short i, j;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ {
+ extra[i][j] = 0;
+ claim[i][j] = 0;
+ groupIDs[i][j] = 0;
+ connectMap[i][j] = 0;
+ protPoints[i][j] = 0;
+ }
+} /* initState */
+
+copyArray( dest, src )
+intBoard dest, src;
+{
+ short x, y;
+ for (y = 0; y <= maxPoint; y++)
+ for (x = 0; x <= maxPoint; x++)
+ dest[x][y] = src[x][y];
+}
+
+/*
+ generates a one-point spread in the force field array (claim)
+
+ the spread from a single point after four calls is:
+
+ 1
+ 2 2 2
+ 2 4 6 4 2
+ 2 4 8 10 8 4 2
+ 1 2 6 10 62 10 6 2 1
+ 2 4 8 10 8 4 2
+ 2 4 6 4 2
+ 2 2 2
+ 1
+
+*/
+stake()
+{
+ short x, y;
+ initArray( extra );
+ for (y = 0; y <= maxPoint; y++)
+ for (x = 0; x <= maxPoint; x++)
+ {
+ extra[x][y] = extra[x][y] + claim[x][y];
+ if (claim[x][y] > 0)
+ {
+ if (x > 0) extra[x-1][y] += 1;
+ if (y > 0) extra[x][y-1] += 1;
+ if (x < maxPoint) extra[x+1][y] += 1;
+ if (y < maxPoint) extra[x][y+1] += 1;
+ }
+ else if (claim[x][y] < 0)
+ {
+ if (x > 0) extra[x-1][y] -= 1;
+ if (y > 0) extra[x][y-1] -= 1;
+ if (x < maxPoint) extra[x+1][y] -= 1;
+ if (y < maxPoint) extra[x][y+1] -= 1;
+ }
+ }
+ copyArray( claim, extra );
+} /* stake */
+
+/*
+ sets up claim from the current board position
+*/
+spread()
+{
+ short x, y;
+ for (y = 0; y <= maxPoint; y++)
+ for (x = 0; x <= maxPoint; x++)
+ claim[x][y] = ndbord[x][y] * 50;
+ stake();
+ stake();
+ stake();
+ stake();
+} /* spread */
+
+/*
+ gList is initialized with the size, loc, and libCount of each group
+ groupIDs contains the serial numbers of the groups.
+*/
+Resspan(x, y, gID, gSize, libCount, who)
+short x, y, gID, *gSize, *libCount, who;
+ { /* span */
+ if ((bord[x][y] == 0) &&
+ (markBoard[x][y] != marker)) /* a liberty */
+ {
+ markBoard[x][y] = marker;
+ *libCount = *libCount + 1;
+ }
+ else if ((bord[x][y] == who) &&
+ (groupIDs[x][y] == 0))
+ {
+ groupIDs[x][y] = gID;
+ *gSize = *gSize + 1;
+ if (x > 0)
+ Resspan(x - 1, y, gID, gSize, libCount, who);
+ if (x < maxPoint)
+ Resspan(x + 1, y, gID, gSize, libCount, who);
+ if (y > 0)
+ Resspan(x, y - 1, gID, gSize, libCount, who);
+ if (y < maxPoint)
+ Resspan(x, y + 1, gID, gSize, libCount, who);
+ }
+ } /* span */
+
+respreicen()
+{ /* respreicen */
+ short i, j, gID, libCount, gSize, who;
+ gID = 0;
+#ifdef DEBUG
+ printf( "respreicen\n" );
+#endif
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ groupIDs[i][j] = 0;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if ((bord[i][j] != 0) && /* a stone there */
+ (groupIDs[i][j] == 0)) /* not seen yet */
+ {
+ marker = marker + 1;
+ if (marker == 0)
+ {
+ initArray(markBoard);
+ marker = 1;
+ }
+ gID = gID + 1;
+ libCount = 0;
+ gSize = 0;
+ who = bord[i][j];
+ Resspan(i, j, gID, &gSize, &libCount, who); /* span the group, collecting info */
+ gList[gID].groupMark = 0;
+ gList[gID].atLevel = 0;
+ gList[gID].isLive = FALSE; /* we don't know yet */
+ gList[gID].isDead = FALSE;
+ gList[gID].numEyes = -1;
+ gList[gID].size = gSize;
+ gList[gID].libC = libCount;
+ gList[gID].lx = i;
+ gList[gID].ly = j;
+ gMap[gID] = gID; /* set up identity map */
+ }
+ maxGroupID = gID;
+ newGID = gID;
+ grpMark = 0;
+} /* respreicen */
+
+/*
+ play z at [x, y].
+ killFlag is set true if anything is killed.
+*/
+killGroup(x, y, me, him)
+short x, y, me, him;
+ { /* killGroup */
+#ifdef DEBUG
+ printf( "killGroup\n" );
+#endif
+ playMark = playMark + 1;
+ /* record this kill */
+ playStack[playMark].kind = rem;
+ playStack[playMark].uval.rem.who = him;
+ playStack[playMark].uval.rem.xl = x;
+ playStack[playMark].uval.rem.yl = y;
+ playStack[playMark].gID = groupIDs[x][y];
+ playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum;
+ if (showTrees)
+ rstone(x, y);
+ numCapt = numCapt + 1;
+ bord[x][y] = 0;
+ groupIDs[x][y] = 0;
+ if (x > 0)
+ {
+ if (bord[x - 1][y] == me)
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
+ }
+ else if (bord[x - 1][y] == him)
+ killGroup(x - 1, y, me , him);
+ }
+ if (x < maxPoint)
+ {
+ if (bord[x + 1][y] == me)
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
+ }
+ else if (bord[x + 1][y] == him)
+ killGroup(x + 1, y, me, him);
+ }
+ if (y > 0)
+ {
+ if (bord[x][y - 1] == me)
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
+ }
+ else if (bord[x][y - 1] == him)
+ killGroup(x, y - 1, me, him);
+ }
+ if (y < maxPoint)
+ {
+ if (bord[x][y + 1] == me)
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
+ }
+ else if (bord[x][y + 1] == him)
+ killGroup(x, y + 1, me, him);
+ }
+ } /* killGroup */
+
+mergeGroup(sGID, myGID)
+short sGID, myGID;
+ { /* mergeGroup */
+ short i;
+#ifdef DEBUG
+ printf( "mergeGroup\n" );
+#endif
+ for (i = 1; i <= newGID; i++)
+ if (gMap[i] == sGID)
+ {
+ playMark = playMark + 1;
+ playStack[playMark].kind = reMap;
+ playStack[playMark].gID = i;
+ playStack[playMark].uval.reMap.oldGID = sGID;
+ gMap[i] = myGID;
+ }
+ } /* mergeGroup */
+
+tryPlay(x, y, z)
+short x, y, z;
+{ /* plei */
+ short i, me, him, myGID;
+ short isNew;
+#ifdef DEBUG
+ printf( "tryPlay\n" );
+#endif
+ me = z;
+ him = -me;
+ killFlag = FALSE; /* set true if something is killed */
+ numCapt = 0;
+ tryLevel = tryLevel + 1;
+ isNew = FALSE;
+ bord[x][y] = z; /* play the stone */
+ if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */
+ myGID = gMap[groupIDs[x - 1][y]];
+ else if ((x < maxPoint) && (bord[x + 1][y] == me))
+ myGID = gMap[groupIDs[x + 1][y]];
+ else if ((y > 0) && (bord[x][y - 1] == me))
+ myGID = gMap[groupIDs[x][y - 1]];
+ else if ((y < maxPoint) && (bord[x][y + 1] == me))
+ myGID = gMap[groupIDs[x][y + 1]];
+ else /* nobody to connect to */
+ {
+ newGID = newGID + 1;
+ isNew = TRUE;
+ myGID = newGID;
+ gList[myGID].groupMark = 0;
+ gList[myGID].atLevel = tryLevel;
+ gList[myGID].isLive = FALSE;
+ gList[myGID].numEyes = -1;
+ gList[myGID].size = -1;
+ gList[myGID].lx = x;
+ gList[myGID].ly = y;
+ gMap[myGID] = myGID;
+ }
+ groupIDs[x][y] = myGID;
+ playMark = playMark + 1;
+ /* record this move */
+ playStack[playMark].kind = add;
+ playStack[playMark].uval.add.who = me;
+ playStack[playMark].uval.add.xl = x;
+ playStack[playMark].uval.add.yl = y;
+ playStack[playMark].gID = myGID;
+ playStack[playMark].uval.add.sNumber = 0;
+ if (isNew)
+ playStack[playMark].uval.add.nextGID = newGID - 1;
+ else
+ playStack[playMark].uval.add.nextGID = newGID;
+ if (showTrees)
+ sstone(me, x, y, 0);
+ /* merge adjacent groups */
+ if ((x > 0) && (bord[x - 1][y] == me) &&
+ (gMap[groupIDs[x - 1][y]] != myGID))
+ mergeGroup(gMap[groupIDs[x - 1][y]], myGID);
+ if ((x < maxPoint) && (bord[x + 1][y] == me) &&
+ (gMap[groupIDs[x + 1][y]] != myGID))
+ mergeGroup(gMap[groupIDs[x + 1][y]], myGID);
+ if ((y > 0) && (bord[x][y - 1] == me) &&
+ (gMap[groupIDs[x][y - 1]] != myGID))
+ mergeGroup(gMap[groupIDs[x][y - 1]], myGID);
+ if ((y < maxPoint) && (bord[x][y + 1] == me) &&
+ (gMap[groupIDs[x][y + 1]] != myGID))
+ mergeGroup(gMap[groupIDs[x][y + 1]], myGID);
+ /* kill opposing groups, listing affected groups */
+ nlcGroup.indx = 1;
+ nlcGroup.v[1] = myGID; /* init list to include me */
+ if ((x > 0) && (bord[x - 1][y] == him) &&
+ (gList[gMap[groupIDs[x - 1][y]]].libC == 1))
+ {
+ killFlag = TRUE;
+ killGroup(x - 1, y, me, him);
+ }
+ if ((x < maxPoint) && (bord[x + 1][y] == him) &&
+ (gList[gMap[groupIDs[x + 1][y]]].libC == 1))
+ {
+ killFlag = TRUE;
+ killGroup(x + 1, y, me, him);
+ }
+ if ((y > 0) && (bord[x][y - 1] == him) &&
+ (gList[gMap[groupIDs[x][y - 1]]].libC == 1))
+ {
+ killFlag = TRUE;
+ killGroup(x, y - 1, me, him);
+ }
+ if ((y < maxPoint) && (bord[x][y + 1] == him) &&
+ (gList[gMap[groupIDs[x][y + 1]]].libC == 1))
+ {
+ killFlag = TRUE;
+ killGroup(x, y + 1, me, him);
+ }
+ /* list groups adjacent to me */
+ if ((x > 0) && (bord[x - 1][y] == him))
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
+ }
+ if ((x < maxPoint) && (bord[x + 1][y] == him))
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
+ }
+ if ((y > 0) && (bord[x][y - 1] == him))
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
+ }
+ if ((y < maxPoint) && (bord[x][y + 1] == him))
+ {
+ nlcGroup.indx = nlcGroup.indx + 1;
+ nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
+ }
+ /* fix liberty count for affected groups */
+ grpMark = grpMark + 1;
+ for (i = 1; i <= nlcGroup.indx; i++)
+ if (gList[nlcGroup.v[i]].groupMark != grpMark)
+ {
+ if (gList[nlcGroup.v[i]].atLevel != tryLevel)
+ {
+ playMark = playMark + 1;
+ playStack[playMark].kind = chLib;
+ playStack[playMark].gID = nlcGroup.v[i];
+ playStack[playMark].uval.chLib.oldLevel =
+ gList[nlcGroup.v[i]].atLevel;
+ playStack[playMark].uval.chLib.oldLC =
+ gList[nlcGroup.v[i]].libC;
+ }
+ gList[nlcGroup.v[i]].groupMark = grpMark;
+ gList[nlcGroup.v[i]].atLevel = tryLevel;
+ spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist);
+ gList[nlcGroup.v[i]].libC = pPlist.indx;
+ }
+} /* plei */
+
+saveState()
+{ /* saveState */
+ playMark = 0;
+ tryLevel = 0;
+ newGID = maxGroupID;
+} /* saveState */
+
+/*
+ undoes a move sequence back to uMark
+*/
+undoTo(uMark)
+short uMark;
+{ /* undoTo */
+ short i, xl, yl;
+#ifdef DEBUG
+ printf( "undoTo\n" );
+#endif
+ for (i = playMark; i >= uMark + 1; i--)
+ if (playStack[i].kind == rem)
+ {
+ xl = playStack[i].uval.rem.xl;
+ yl = playStack[i].uval.rem.yl;
+ bord[xl][yl] = playStack[i].uval.rem.who;
+ groupIDs[xl][yl] = playStack[i].gID;
+ if (showTrees)
+ sstone(playStack[i].uval.rem.who, xl, yl,
+ playStack[i].uval.rem.sNumber);
+ }
+ else if (playStack[i].kind == add)
+ {
+ xl = playStack[i].uval.add.xl;
+ yl = playStack[i].uval.add.yl;
+ bord[xl][yl] = 0;
+ groupIDs[xl][yl] = 0;
+ tryLevel = tryLevel - 1;
+ newGID = playStack[i].uval.add.nextGID;
+ if (showTrees)
+ rstone(xl, yl);
+ }
+ else if (playStack[i].kind == reMap)
+ gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID;
+ else /* change libs of group - gID is pre-mapped */
+ {
+ gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC;
+ gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel;
+ }
+ playMark = uMark;
+} /* undoTo */
+
+/*
+ restores the state of the world after trying a move sequence
+*/
+restoreState()
+{ /* restoreState */
+#ifdef DEBUG
+ printf( "restoreState\n" );
+#endif
+ if (playMark > 0)
+ {
+ undoTo(0);
+ playMark = 0;
+ tryLevel = 0;
+ }
+} /* restoreState */
+
+/* exception bpt; */
+
+
+/*
+ returns true if (the group (at gx, gy) is saveable.
+ if so, returns the point to play at in savex, savey
+*/
+short saveable(gx, gy, savex, savey)
+short gx, gy, *savex, *savey;
+{ /* saveable */
+ short me, him, gx1, gx2, i, j, smark, mark2, tl, result;
+ char sChar;
+ sPointList dList;
+ point tp;
+ short libList[maxSPoint+1];
+#ifdef DEBUG
+ printf( "saveable\n" );
+#endif
+ dbStop = TRUE;
+ me = bord[gx][gy];
+ him = -me;
+ if (me == 1)
+ sChar = '|';
+ else
+ sChar = '>';
+/* write(sChar); */
+ spanGroup(gx, gy, &plist3); /* find my liberties */
+ if (adjInAtari) /* one of my options is to kill */
+ {
+ listAdjacents(gx, gy, &aList);
+ for (i = 1; i <= aList.indx; i++)
+ if (gList[aList.v[i]].libC == 1)
+ {
+ spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly,
+ &pList1); /* find it's liberty */
+ plist3.indx = plist3.indx + 1;
+ plist3.p[plist3.indx].px = pList1.p[1].px;
+ plist3.p[plist3.indx].py = pList1.p[1].py;
+ }
+ }
+ for (i = 1; i <= maxSPoint; i++)
+ libList[i] = -1;
+ if ((utilPlayLevel > 4) &&
+ (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */
+ {
+ listDiags(gx, gy, &dList);
+ j = 0;
+ i = plist3.indx;
+ while ((j < dList.indx) &&
+ (i < maxSPoint))
+ {
+ j = j + 1;
+ i = i + 1;
+ libList[i] = 100;
+ plist3.p[i].px = dList.p[j].px;
+ plist3.p[i].py = dList.p[j].py;
+ }
+ plist3.indx = i;
+ }
+ if (plist3.indx > 1) /* sort by decreasing lib count */
+ {
+ for (i = 1; i <= plist3.indx; i++)
+ if (libList[i] != 100)
+ {
+ mark2 = playMark;
+ tryPlay(plist3.p[i].px, plist3.p[i].py, me);
+ libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
+ if (libList[i] > treeLibLim) /* i'm safe */
+ {
+ *savex = plist3.p[i].px;
+ *savey = plist3.p[i].py;
+ result = TRUE;
+ goto one;
+ }
+ undoTo(mark2);
+ }
+ for (i = 1; i <= plist3.indx - 1; i++)
+ for (j = i + 1; j <= plist3.indx; j++)
+ if (libList[i] < libList[j])
+ {
+ tl = libList[i];
+ libList[i] = libList[j];
+ libList[j] = tl;
+ tp = plist3.p[i];
+ plist3.p[i] = plist3.p[j];
+ plist3.p[j] = tp;
+ }
+ }
+ for (i = 1; i <= plist3.indx; i++)
+ {
+ *savex = plist3.p[i].px;
+ *savey = plist3.p[i].py;
+ if (legal[*savex][*savey])
+ {
+ smark = playMark;
+ tryPlay(*savex, *savey, me);
+ pause();
+ if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1)
+ if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
+ {
+ restoreState();
+/* sClearChar(sChar, rXor); */
+ return TRUE;
+ }
+ else if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
+ if (! killable(gx, gy, &gx1, &gx2))
+ {
+ restoreState();
+/* sClearChar(sChar, rXor); */
+ return TRUE;
+ }
+ undoTo(smark);
+ }
+ }
+ result = FALSE;
+one:
+ restoreState();
+/* sClearChar(sChar, rXor); */
+ return result;
+} /* saveable */
+
+/*
+ marks unsavable groups as dead
+*/
+markDead()
+{ /* markDead */
+ short i, j, gx, gy, result;
+#ifdef DEBUG
+ printf( "markDead\n" );
+#endif
+ for (i = 1; i <= maxGroupID; i++)
+ if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
+ result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy);
+ else
+ result = FALSE;
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if (bord[i][j] == 0)
+ ndbord[i][j] = 0;
+ else if (gList[groupIDs[i][j]].isDead)
+ ndbord[i][j] = 0;
+ else
+ ndbord[i][j] = bord[i][j];
+} /* markDead */
+
+/*
+ marks groups with two eyes as live
+*/
+MLspan(x, y, saw1, sawm1, size, sMark)
+short x, y, *saw1, *sawm1, *size, sMark;
+ { /* span */
+ if (ndbord[x][y] == 1)
+ *saw1 = TRUE;
+ else if (ndbord[x][y] == -1)
+ *sawm1 = TRUE;
+ else if (sGroups[x][y] == 0)
+ {
+ sGroups[x][y] = sMark;
+ *size = *size + 1;
+ if (x > 0)
+ MLspan(x - 1, y, saw1, sawm1, size, sMark);
+ if (x < maxPoint)
+ MLspan(x + 1, y, saw1, sawm1, size, sMark);
+ if (y > 0)
+ MLspan(x, y - 1, saw1, sawm1, size, sMark);
+ if (y < maxPoint)
+ MLspan(x, y + 1, saw1, sawm1, size, sMark);
+ }
+ } /* span */
+
+short CLspan(x, y, numEyes, who)
+short x, y, *numEyes, who;
+ { /* span */
+ markBoard[x][y] = marker;
+ if (ndbord[x][y] == 0)
+ {
+ if ((sList[sGroups[x][y]].sm != marker) &&
+ (sList[sGroups[x][y]].w == who))
+ {
+ sList[sGroups[x][y]].sm = marker;
+ if (sList[sGroups[x][y]].s > 6)
+ return TRUE;
+ *numEyes = *numEyes + 1;
+ if (*numEyes > 1)
+ return TRUE;
+ }
+ }
+ else if (bord[x][y] == who)
+ {
+ if ((x > 0) &&
+ (markBoard[x - 1][y] != marker))
+ if (CLspan(x - 1, y, numEyes, who)) return TRUE;
+ if ((x < maxPoint) &&
+ (markBoard[x + 1][y] != marker))
+ if (CLspan(x + 1, y, numEyes, who)) return TRUE;
+ if ((y > 0) &&
+ (markBoard[x][y - 1] != marker))
+ if (CLspan(x, y - 1, numEyes, who)) return TRUE;
+ if ((y < maxPoint) &&
+ (markBoard[x][y + 1] != marker))
+ if (CLspan(x, y + 1, numEyes, who)) return TRUE;
+ }
+ return FALSE;
+ } /* span */
+
+short checkLive(x, y)
+short x, y;
+ { /* checkLive */
+ short numEyes, who;
+#ifdef DEBUG
+ printf( "checkLive\n" );
+#endif
+ numEyes = 0;
+ who = bord[x][y];
+ marker = marker + 1;
+ return CLspan(x, y, &numEyes, who);
+ } /* checkLive */
+
+markLive()
+{ /* markLive */
+ short i, j, size, sMark = 0;
+ short saw1, sawm1;
+#ifdef DEBUG
+ printf( "markLive\n" );
+#endif
+ initArray(sGroups);
+ for (i = 0; i <= maxPoint; i++)
+ for (j = 0; j <= maxPoint; j++)
+ if ((sGroups[i][j] == 0) &&
+ (ndbord[i][j] == 0))
+ {
+ size = 0;
+ sMark = sMark + 1;
+ sawm1 = FALSE;
+ saw1 = FALSE;
+ MLspan(i, j, &saw1, &sawm1, &size, sMark);
+ sList[sMark].s = size;
+ sList[sMark].sm = 0;
+ if (sawm1)
+ if (saw1)
+ sList[sMark].w = 0;
+ else
+ sList[sMark].w = -1;
+ else if (saw1)
+ sList[sMark].w = 1;
+ else
+ sList[sMark].w = 0;
+ }
+ for (i = 1; i <= maxGroupID; i++)
+ if (! gList[i].isDead)
+ gList[i].isLive = checkLive(gList[i].lx, gList[i].ly);
+} /* markLive */
+
+/*
+ generates the connection map and the protected point map.
+*/
+genConnects()
+{ /* genConnects */
+ short x, y, numStones;
+#ifdef DEBUG
+ printf( "genConnects\n" );
+#endif
+ for (x = 0; x <= maxPoint; x++)
+ for (y = 0; y <= maxPoint; y++)
+ {
+ connectMap[x][y] = 0;
+ protPoints[x][y] = 0;
+ }
+ for (x = 0; x <= maxPoint; x++)
+ for (y = 0; y <= maxPoint; y++)
+ if (bord[x][y] == 1) /* map connections to this stone */
+ {
+ if (x > 0) /* direct connection */
+ connectMap[x - 1][y] += 1;
+ if (x < maxPoint)
+ connectMap[x + 1][y] += 1;
+ if (y > 0)
+ connectMap[x][y - 1] += 1;
+ if (y < maxPoint)
+ connectMap[x][y + 1] += 1;
+ if ((x > 0) && (y > 0) && /* diagonal connection */
+ (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0))
+ connectMap[x - 1][y - 1] += 1;
+ if ((x < maxPoint) && (y > 0) &&
+ (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0))
+ connectMap[x + 1][y - 1] += 1;
+ if ((x < maxPoint) && (y < maxPoint) &&
+ (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0))
+ connectMap[x + 1][y + 1] += 1;
+ if ((x > 0) && (y < maxPoint) &&
+ (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0))
+ connectMap[x - 1][y + 1] += 1;
+ if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */
+ connectMap[x - 2][y] += 1;
+ if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3))
+ connectMap[x + 2][y] += 1;
+ if ((y > 1) && (claim[x][y - 1] > 3))
+ connectMap[x][y - 2] += 1;
+ if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3))
+ connectMap[x][y + 2] += 1;
+ if ((x > 1) && (y > 0) && /* knight's move */
+ (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3))
+ connectMap[x - 2][y - 1] += 1;
+ if ((x > 0) && (y > 1) &&
+ (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3))
+ connectMap[x - 1][y - 2] += 1;
+ if ((x < (maxPoint - 1)) && (y > 0) &&
+ (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3))
+ connectMap[x + 2][y - 1] += 1;
+ if ((x < maxPoint) && (y > 1) &&
+ (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3))
+ connectMap[x + 1][y - 2] += 1;
+ if ((x > 1) && (y < maxPoint) &&
+ (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3))
+ connectMap[x - 2][y + 1] += 1;
+ if ((x > 0) && (y < (maxPoint - 1)) &&
+ (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3))
+ connectMap[x - 1][y + 2] += 1;
+ if ((x < (maxPoint - 1)) && (y < maxPoint) &&
+ (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3))
+ connectMap[x + 2][y + 1] += 1;
+ if ((x < maxPoint) && (y < (maxPoint - 1)) &&
+ (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3))
+ connectMap[x + 1][y + 2] += 1;
+ }
+ else if (bord[x][y] == 0) /* see if protected point */
+ {
+ numStones = 0;
+ if (x == 0)
+ numStones = numStones + 1;
+ if (y == 0)
+ numStones = numStones + 1;
+ if (x == maxPoint)
+ numStones = numStones + 1;
+ if (y == maxPoint)
+ numStones = numStones + 1;
+ if ((x > 0) && (bord[x - 1][y] == 1))
+ numStones = numStones + 1;
+ if ((y > 0) && (bord[x][y - 1] == 1))
+ numStones = numStones + 1;
+ if ((x < maxPoint) && (bord[x + 1][y] == 1))
+ numStones = numStones + 1;
+ if ((y < maxPoint) && (bord[x][y + 1] == 1))
+ numStones = numStones + 1;
+ if (numStones == 4)
+ protPoints[x][y] = 1;
+ else if (numStones == 3)
+ {
+ if ((x > 0) &&
+ ((bord[x - 1][y] == 0) ||
+ ((bord[x - 1][y] == -1) &&
+ (gList[groupIDs[x - 1][y]].libC == 1))))
+ protPoints[x][y] = 1;
+ else if ((x < maxPoint) &&
+ ((bord[x + 1][y] == 0) ||
+ ((bord[x + 1][y] == -1) &&
+ (gList[groupIDs[x + 1][y]].libC == 1))))
+ protPoints[x][y] = 1;
+ else if ((y > 0) &&
+ ((bord[x][y - 1] == 0) ||
+ ((bord[x][y - 1] == -1) &&
+ (gList[groupIDs[x][y - 1]].libC == 1))))
+ protPoints[x][y] = 1;
+ else if ((y < maxPoint) &&
+ ((bord[x][y + 1] == 0) ||
+ ((bord[x][y + 1] == -1) &&
+ (gList[groupIDs[x][y + 1]].libC == 1))))
+ protPoints[x][y] = 1;
+ }
+ }
+ for (x = 0; x <= maxPoint; x++)
+ for (y = 0; y <= maxPoint; y++)
+ if (bord[x][y] != 0)
+ {
+ connectMap[x][y] = 0;
+ protPoints[x][y] = 0;
+ }
+} /* genConnects */
+
+/*
+ generates the whole state of the game.
+*/
+genState()
+{ /* genState */
+#ifdef DEBUG
+ printf( "genState\n" );
+#endif
+ inGenState = TRUE;
+ respreicen();
+ markDead();
+ markLive();
+ spread();
+ genConnects();
+#ifdef DEBUG
+/* printBoard( claim, "claim" ); */
+/* printBoard( bord, "bord" ); */
+/* printBoard( ndbord, "ndbord" );
+ printBoard( sGroups, "sGroups" );
+ printBoard( groupIDs, "groupIDs" );
+ printBoard( connectMap, "connectMap" );
+ printBoard( protPoints, "protPoints" ); */
+#endif
+ inGenState = FALSE;
+} /* genState */
+
+/*
+ generates a value for the [x, y] location that appears to get larger
+ for points that are saddle points in the influence graph (klein)
+*/
+short tencen(x, y)
+short x, y;
+{ /* tencen */
+ short a, b, c, d, w, z;
+#ifdef DEBUG
+ printf( "tencen\n" );
+#endif
+ if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */
+ {
+ return 50;
+ }
+ w = claim[x][y]; /* w <= -1 */
+ a = iNil;
+ if (x > 0)
+ if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */
+ a = claim[x - 1][y] - w; /* score is sum of his influence on central */
+ b = iNil; /* point and my influence on this neighbor */
+ if (y > 0)
+ if (claim[x][y - 1] > -1)
+ b = claim[x][y - 1] - w;
+ c = iNil;
+ if (x < maxPoint)
+ if (claim[x + 1][y] > -1)
+ c = claim[x + 1][y] - w;
+ d = iNil;
+ if (y < maxPoint)
+ if (claim[x][y + 1] > -1)
+ d = claim[x][y + 1] - w;
+ z = a; /* z = max(a, b, c, d) */
+ if (z != iNil)
+ {
+ if ((b != iNil) &&
+ (b > z))
+ z = b;
+ }
+ else
+ z = b;
+ if (z != iNil)
+ {
+ if ((c != iNil) &&
+ (c > z))
+ z = c;
+ }
+ else
+ z = c;
+ if (z != iNil)
+ {
+ if ((d != iNil) &&
+ (d > z))
+ z = d;
+ }
+ else
+ z = d;
+ if ((z != iNil) &&
+ ((x == 0) ||
+ (y == 0) ||
+ (x == maxPoint) ||
+ (y == maxPoint)))
+ z = z * 2; /* double z if (on the edge of the board ?? */
+ if (z != iNil)
+ return z;
+ else
+ return 50;
+} /* tencen */
+
+initGPUtils()
+{ /* initGPUtils */
+#ifdef DEBUG
+ printf( "initGPUtils\n" );
+#endif
+ initArray(markBoard);
+ initState();
+ marker = 0;
+ playMark = 0;
+ gList[0].isLive = FALSE;
+ gList[0].isDead = FALSE;
+ gList[0].libC = 0;
+ gList[0].size = 0;
+ gList[0].numEyes = 0;
+ gList[0].lx = -1;
+ gList[0].ly = -1;
+ gMap[0] = 0;
+ dbStop = FALSE;
+ inGenState = FALSE;
+} /* initGPUtils */
+
diff --git a/noncore/games/go/goplayutils.h b/noncore/games/go/goplayutils.h
new file mode 100644
index 0000000..11ab658
--- a/dev/null
+++ b/noncore/games/go/goplayutils.h
@@ -0,0 +1,85 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __goplayutils_h
+#define __goplayutils_h
+
+#define iNil 32767 /* a distinguished value like nil */
+#define maxGroup 512
+#define maxSPoint 16
+#define tryLimit 300
+
+typedef short intBoard[19][19]; /* these were -2 to maxPoint + 2 */
+
+typedef short boolBoard[19][19];
+
+typedef struct
+{
+ short px, py;
+} point;
+
+typedef struct
+{
+ point p[401];
+ short indx;
+} pointList;
+
+typedef struct
+{
+ point p[maxSPoint+1];
+ short indx;
+} sPointList;
+
+typedef struct
+{
+ short indx,
+ v[401];
+} intList;
+
+typedef struct { short w, s, sm; } sgRec;
+
+typedef struct
+{
+ short groupMark,
+ atLevel,
+ isLive,
+ isDead,
+ libC,
+ numEyes,
+ size,
+ lx, ly;
+} groupRec;
+
+typedef enum {rem, add, chLib, reMap} playType;
+
+typedef struct { short who, xl, yl, nextGID, sNumber; } remAddRec;
+typedef struct { short oldLC, oldLevel; } chLibRec;
+typedef struct { short oldGID; } reMapRec;
+typedef struct
+{
+ short gID;
+ playType kind;
+ union {
+ remAddRec rem, add;
+ chLibRec chLib;
+ reMapRec reMap;
+ } uval;
+} playRec;
+
+#endif
diff --git a/noncore/games/go/gowidget.cpp b/noncore/games/go/gowidget.cpp
new file mode 100644
index 0000000..fca9797
--- a/dev/null
+++ b/noncore/games/go/gowidget.cpp
@@ -0,0 +1,449 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "gowidget.h"
+
+#include <qpe/config.h>
+#include <qpe/resource.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/qpemenubar.h>
+#include <qpopupmenu.h>
+#include <qaction.h>
+#include <qapplication.h> //processEvents()
+#include <qlabel.h>
+
+//#include <stdio.h>
+
+#include "amigo.h"
+#include "goplayutils.h"
+
+static const enum bVal computer_color = BLACK;
+
+static int current_handicap = 1;
+
+static QBrush *goBrush;
+//static QImage *newBlackStone;
+//static QImage *blackStone;
+//static QImage *whiteStone;
+static QPixmap *newBlackStone;
+static QPixmap *blackStone;
+static QPixmap *whiteStone;
+
+GoMainWidget::GoMainWidget( QWidget *parent, const char* name) :
+ QMainWindow( parent, name )
+{
+ setToolBarsMovable( FALSE );
+ GoWidget *go = new GoWidget(this);
+
+ setCentralWidget(go);
+ toolbar = new QPEToolBar(this);
+ toolbar->setHorizontalStretchable( TRUE );
+ addToolBar(toolbar);
+
+ QPEMenuBar *mb = new QPEMenuBar( toolbar );
+ mb->setMargin(0);
+ QPopupMenu *file = new QPopupMenu( this );
+
+ QAction *a = new QAction( tr( "New Game" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), go, SLOT( newGame() ) );
+ a->addTo( file );
+
+ a = new QAction( tr( "Pass" ), Resource::loadPixmap( "pass" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), go, SLOT( pass() ) );
+ a->addTo( file );
+ a->addTo( toolbar );
+
+
+ a = new QAction( tr( "Resign" ), Resource::loadPixmap( "reset" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), go, SLOT( resign() ) );
+ a->addTo( file );
+
+ a = new QAction( tr( "Two player option" ), QString::null, 0, this, 0 );
+ a->setToggleAction( TRUE );
+ connect( a, SIGNAL( toggled(bool) ), go, SLOT( setTwoplayer(bool) ) );
+ a->addTo( file );
+
+ mb->insertItem( tr( "Game" ), file );
+
+ QLabel *turnLabel = new QLabel( toolbar );
+ turnLabel->setBackgroundMode( PaletteButton );
+ connect( go, SIGNAL(showTurn(const QPixmap&)),
+ turnLabel, SLOT(setPixmap(const QPixmap&)) );
+
+
+ QLabel * scoreLabel = new QLabel( toolbar );
+ scoreLabel->setBackgroundMode( PaletteButton );
+ connect( go, SIGNAL(showScore(const QString&)),
+ scoreLabel, SLOT(setText(const QString&)) );
+
+ toolbar->setStretchableWidget( scoreLabel );
+
+ go->readConfig();
+}
+
+void GoMainWidget::resizeEvent( QResizeEvent * )
+{
+ //### this won't work because of the text label...
+ /*
+ if ( width() > height() )
+ moveToolBar( toolbar, Left );
+ else
+ moveToolBar( toolbar, Top );
+ */
+}
+
+GoWidget *GoWidget::self = 0;
+
+GoWidget::GoWidget( QWidget *parent, const char* name) :
+ QWidget( parent, name )
+{
+ if ( self )
+ fatal( "Only one Go widget allowed" );
+ self = this;
+ twoplayer = FALSE;
+
+
+ d = bx = by = 1;
+
+ QPixmap pix = Resource::loadPixmap( "pine" );
+ goBrush = new QBrush( black, pix );
+ /*
+ QString fn = Resource::findPixmap("Go-black");
+ blackStone = new QImage( fn );
+ fn = Resource::findPixmap("Go-black-highlight");
+ newBlackStone = new QImage( fn );
+ fn = Resource::findPixmap("Go-white");
+ whiteStone = new QImage( fn );
+ */
+ blackStone = new QPixmap(Resource::loadPixmap( "Go-black" ));
+ whiteStone = new QPixmap(Resource::loadPixmap( "Go-white" ));
+ newBlackStone = new QPixmap(Resource::loadPixmap( "Go-black-highlight" ));
+
+ init();
+}
+
+GoWidget::~GoWidget()
+{
+ writeConfig();
+}
+
+void GoWidget::writeConfig()
+{
+ Config cfg("Go");
+ cfg.setGroup("Game");
+ cfg.writeEntry("TwoPlayer", twoplayer);
+ cfg.writeEntry("CurrentPlayer", currentPlayer);
+ cfg.writeEntry("NPassed", nPassed);
+ QString b;
+ for (int i=0; i<19; i++)
+ for (int j=0; j<19; j++)
+ b += board[i][j] == BLACK ? 'B' : board[i][j] == WHITE ? 'W' : '.';
+ cfg.writeEntry("Board", b);
+ cfg.writeEntry("LastX", lastX);
+ cfg.writeEntry("LastY", lastY);
+ extern int blackPrisoners, whitePrisoners;
+ cfg.writeEntry("BlackPrisoners", blackPrisoners);
+ cfg.writeEntry("WhitePrisoners", whitePrisoners);
+}
+
+void GoWidget::readConfig()
+{
+ init();
+ Config cfg("Go");
+ cfg.setGroup("Game");
+ twoplayer = cfg.readBoolEntry("TwoPlayer");
+ currentPlayer = (bVal)cfg.readNumEntry("CurrentPlayer",1);
+ nPassed = cfg.readNumEntry("NPassed",0);
+ QString b = cfg.readEntry("Board");
+ if ( b.length() == 19*19 )
+ for (int i=0; i<19; i++)
+ for (int j=0; j<19; j++) {
+ QChar ch = b[j+19*i];
+ if ( ch != '.' )
+ GoPlaceStone( ch == 'B' ? BLACK : WHITE, i, j );
+ }
+ lastX = cfg.readNumEntry("LastX");
+ lastY = cfg.readNumEntry("LastY");
+ extern int blackPrisoners, whitePrisoners;
+ blackPrisoners = cfg.readNumEntry("BlackPrisoners",0);
+ whitePrisoners = cfg.readNumEntry("WhitePrisoners",0);
+ reportPrisoners(blackPrisoners,whitePrisoners);
+ emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone );
+}
+
+void GoWidget::resizeEvent( QResizeEvent * )
+{
+ d = QMIN(width(),height())/19;
+ // int r = (d/2-1);
+ bx = (width() - 18*d)/2 ;
+ by = (height() - 18*d)/2 ;
+}
+
+void GoWidget::init()
+{
+ lastX = lastY = newX = newY = -1;
+ nPassed = 0;
+ for ( int i = 0; i < 19; i++ )
+ for ( int j = 0; j < 19; j++ )
+ board[i][j]=-1;
+ gameActive = TRUE;
+ goRestart(current_handicap);
+
+ if ( twoplayer ) {
+ currentPlayer = BLACK;
+ } else {
+ doComputerMove();
+ currentPlayer = WHITE;
+ }
+ emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone );
+}
+
+void GoWidget::paintEvent( QPaintEvent *e )
+{
+ int i,j;
+
+ int r = whiteStone->width()/2;
+
+ QPainter p(this);
+ p.fillRect( bx - d/2, by - d/2, 19*d, 19*d, *goBrush );
+
+ int xMin = QMAX( x2board(e->rect().left()), 0 );
+ int xMax = QMIN( x2board(e->rect().right()), 18 );
+ int yMin = QMAX( y2board(e->rect().top()), 0 );
+ int yMax = QMIN( y2board(e->rect().bottom()), 18 );
+
+ QColor pine( 255, 186, 89 );
+ p.setPen( pine.dark() );
+
+ for ( i = xMin; i < xMax+1 ; i ++ ) {
+ p.drawLine( bx+i*d, by, bx+i*d, by+18*d );
+ }
+ for ( j = yMin; j < yMax+1 ; j ++ ) {
+ p.drawLine( bx, by+j*d, bx+18*d, by+j*d);
+ }
+
+ // dots are at (3,3), (3,9), (3,15) and so on
+ p.setBrush( black );
+ for ( i = 3; i < xMax+1; i+=6 )
+ for ( j = 3; j < yMax+1; j+=6 )
+ p.drawEllipse( bx+i*d-2, by+j*d-2, 5, 5 );
+
+
+ for ( i = xMin; i < xMax+1; i++ )
+ for ( j = yMin; j < yMax+1; j++ ) {
+ if ( board[i][j] == WHITE ||
+ currentPlayer==WHITE && newX == i && newY == j )
+ p.drawPixmap( bx+i*d - r, by+j*d - r, *whiteStone );
+ else if ( i == lastX && j == lastY )
+ p.drawPixmap( bx+i*d - r, by+j*d - r, *newBlackStone );
+ else if ( board[i][j] == BLACK ||
+ currentPlayer==BLACK && newX == i && newY == j)
+ p.drawPixmap( bx+i*d - r, by+j*d - r, *blackStone );
+ }
+}
+
+void GoWidget::doMove( int x, int y )
+{
+
+ if ( !GoPlaceStone( currentPlayer, x, y ) ) {
+ //printf( "Illegal move (%d,%d)\n", x, y );
+ return;
+ }
+ //printf( "you do (%d,%d)\n", x, y );
+ nPassed = 0;
+ if ( twoplayer )
+ currentPlayer = (currentPlayer==WHITE) ? BLACK : WHITE;
+ else
+ doComputerMove();
+
+ emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone );
+
+}
+
+void GoWidget::pass()
+{
+ if ( !gameActive )
+ return;
+ nPassed++;
+ if ( nPassed >= 2 )
+ endGame();
+ else if ( !twoplayer )
+ doComputerMove();
+}
+
+void GoWidget::resign()
+{
+ if ( gameActive )
+ endGame();
+}
+
+
+void GoWidget::newGame()
+{
+ init();
+ update();
+}
+
+
+void GoWidget::endGame()
+{
+ gameActive = FALSE;
+
+ int w,b;
+ CountUp( &w, &b);
+ QString s = tr("White %1, Black %2. ").arg(w).arg(b);
+ if ( w > b )
+ s += tr("White wins.");
+ else if ( w < b )
+ s += tr("Black wins.");
+ else
+ s += tr("A draw.");
+ emit showScore( s );
+}
+
+void GoWidget::doComputerMove()
+{
+ int ox = lastX;
+ int oy = lastY;
+ lastX = lastY = -1;
+ emit showTurn( *blackStone );
+ refresh( ox, oy);
+ qApp->processEvents();
+ short int x,y;
+ if ( genMove( computer_color, &x, &y ) ) {
+ lastX = x;
+ lastY = y;
+ //printf( "I do (%d,%d)\n", x, y );
+ GoPlaceStone(computer_color,x,y);
+ nPassed = 0;
+ } else {
+ emit showScore( tr("I pass") );
+ nPassed++;
+ if ( nPassed >= 2 )
+ endGame();
+ }
+}
+
+void GoWidget::mousePressEvent( QMouseEvent *me )
+{
+ if ( !gameActive )
+ return;
+ int x = x2board(me->x());
+ int y = y2board(me->y());
+ showStone(x,y,currentPlayer);
+}
+
+void GoWidget::mouseMoveEvent( QMouseEvent *me )
+{
+ if ( !gameActive )
+ return;
+ int x = x2board(me->x());
+ int y = y2board(me->y());
+ if ( x != newX || y != newY )
+ showStone(x,y,currentPlayer);
+}
+
+void GoWidget::showStone( int x, int y, enum bVal c )
+{
+
+ if ( newX > -1 ) {
+ refresh( newX, newY );
+ newY = newX = -1;
+ }
+ if ( x < 0 || x > 18 || y < 0 || y > 18 ) {
+ newX = newY = -1;
+ return;
+ }
+ if ( board[x][y] == -1 && !Suicide( c, x, y ) ) {
+ newX = x;
+ newY = y;
+ refresh(x,y);
+ }
+
+}
+
+void GoWidget::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( gameActive && newX > -1 )
+ doMove( newX, newY );
+ newX = newY = -1;
+}
+
+void GoWidget::refresh( int x, int y )
+{
+ update( bx+d*x-d/2-1, by+d*y-d/2-1, d+2, d+2 );
+}
+
+void GoWidget::removeStone(short x, short y)
+{
+ board[x][y]=-1;
+ refresh( x, y );
+}
+
+void GoWidget::placeStone (enum bVal c, short x, short y )
+{
+ board[x][y]=c;
+ refresh( x, y );
+}
+
+void GoWidget::reportPrisoners( int blackcnt, int whitecnt )
+{
+ QString s = tr( "Prisoners: black %1, white %2" ).arg(blackcnt).arg(whitecnt);
+ emit showScore( s );
+}
+
+void GoWidget::setTwoplayer( bool b )
+{
+ twoplayer = b;
+}
+
+void GoWidget::setHandicap( int h )
+{
+ current_handicap = h;
+}
+
+
+extern "C" {
+
+void removestone(short x, short y)
+{
+ GoWidget::self->removeStone(x,y);
+}
+
+void placestone (enum bVal c, short x, short y )
+{
+ GoWidget::self->placeStone(c,x,y);
+}
+
+void intrMoveReport(enum bVal c ,char *coord ,char *reason )
+{
+ qDebug( "intrMoveReport colour %d, %s %s", c, coord, reason );
+}
+
+void intrPrisonerReport( short blackcnt, short whitecnt )
+{
+ GoWidget::self->reportPrisoners(blackcnt,whitecnt);
+}
+
+}
+
diff --git a/noncore/games/go/gowidget.h b/noncore/games/go/gowidget.h
new file mode 100644
index 0000000..94de2cc
--- a/dev/null
+++ b/noncore/games/go/gowidget.h
@@ -0,0 +1,111 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef GOWIDGET_H
+#define GOWIDGET_H
+
+#include <qmainwindow.h>
+#include "amigo.h"
+
+
+class QToolBar;
+
+class GoMainWidget : public QMainWindow
+{
+ Q_OBJECT
+public:
+ GoMainWidget( QWidget *parent=0, const char* name=0);
+protected:
+ void resizeEvent( QResizeEvent * );
+private:
+ QToolBar *toolbar;
+
+};
+
+
+class QLabel;
+class GoWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ GoWidget( QWidget *parent=0, const char* name=0);
+ ~GoWidget();
+
+ void doMove( int x, int y );
+ void doComputerMove();
+
+ void readConfig();
+ void writeConfig();
+
+public slots:
+ void pass();
+ void resign();
+ void newGame();
+ void setTwoplayer( bool );
+ void setHandicap( int );
+signals:
+ void showScore( const QString& );
+ void showTurn( const QPixmap& );
+
+protected:
+ void paintEvent( QPaintEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ void resizeEvent( QResizeEvent * );
+private:
+ void init();
+ void removeStone(short x, short y);
+ void placeStone (enum bVal c, short x, short y );
+
+ void refresh( int x, int y );
+ void showStone( int x, int y, enum bVal );
+ void reportPrisoners(int,int);
+
+ inline int x2board( int x ) { return (x-bx+d/2)/d; }
+ inline int y2board( int y ) { return (y-by+d/2)/d; }
+
+ void endGame();
+
+ bool twoplayer;
+ enum bVal currentPlayer;
+ bool gameActive;
+ int nPassed;
+ signed char board[19][19];
+
+ int d; //distance between lines
+ int bx; //vertical baseline
+ int by; //horizontal baseline
+
+ int lastX,lastY;
+ int newX,newY;
+
+ static GoWidget *self;
+
+ friend void removestone(short x, short y);
+ friend void intrPrisonerReport( short, short );
+ friend void placestone(enum bVal c, short x, short y );
+};
+
+
+
+
+
+#endif
diff --git a/noncore/games/go/killable.c b/noncore/games/go/killable.c
new file mode 100644
index 0000000..3ed2d2e
--- a/dev/null
+++ b/noncore/games/go/killable.c
@@ -0,0 +1,373 @@
+/* By Stoney Ballard */
+/* Ported from Pascal to C by Todd R. Johnson */
+
+#include "go.h"
+#include "goplayutils.h"
+#include "amigo.h"
+
+extern intBoard bord, groupIDs;
+extern boolBoard legal;
+extern groupRec gList[maxGroup];
+extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim,
+ utilPlayLevel, killFlag, depthLimit, dbStop, showTrees;
+extern pointList plist2;
+
+/*
+ returns true if the group (at x, y) is killable.
+ if so, returns the point to play at in killx, killy.
+*/
+
+ short me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2;
+ char sChar;
+ sPointList lList, dList;
+ point tp;
+ short libList[maxSPoint+1];
+ short esc;
+
+short mtNbrs(x, y)
+short x, y;
+ { /* mtNbrs */
+ short n = 0;
+ if ((x > 0) && (bord[x - 1][y] == 0))
+ n = n + 1;
+ if ((x < maxPoint) && (bord[x + 1][y] == 0))
+ n = n + 1;
+ if ((y > 0) && (bord[x][y - 1] == 0))
+ n = n + 1;
+ if ((y < maxPoint) && (bord[x][y + 1] == 0))
+ n = n + 1;
+ return n;
+ } /* mtNbrs */
+
+short killTree(tx, ty, gx, gy, escape, tkMark)
+short tx, ty, gx, gy, *escape, tkMark;
+ { /* killTree */
+ short curMark, mark2, mark3, i, j, k, tl, dStart, result;
+ sPointList lList1, lList2;
+ short libList[maxSPoint+1];
+ point tp;
+ short esc = FALSE;
+ tryCount = tryCount + 1;
+ if (tryCount > tryLimit)
+ {
+ undoTo(tkMark);
+/* for (i = 1; i <= depth - 1; i++)
+ {
+ sClearChar(sChar, rXor);
+ } */
+ depth = 1;
+ return FALSE;
+ }
+/* write(sChar); */
+ depth = depth + 1;
+ curMark = playMark;
+ tryPlay(tx, ty, me); /* try my move */
+ pause();
+ if (gList[gMap[groupIDs[tx][ty]]].libC == 0) /* I'm dead */
+ {
+ result = FALSE;
+ goto one;
+ }
+ else if (killFlag) /* I killed something of his */
+ {
+ result = TRUE;
+ goto one;
+ }
+ else if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) /* safe */
+ {
+ result = FALSE;
+ goto one;
+ }
+ else
+ {
+ sSpanGroup(gx, gy, &lList1); /* find his liberties */
+ if (gList[gMap[groupIDs[tx][ty]]].libC == 1) /* he can kill me */
+ {
+ if (lList1.indx < maxSPoint) /* add that option to his list */
+ {
+ lList1.indx = lList1.indx + 1;
+ spanGroup(tx, ty, &plist2); /* find my liberty */
+ lList1.p[lList1.indx].px = plist2.p[1].px;
+ lList1.p[lList1.indx].py = plist2.p[1].py;
+ }
+ else
+ {
+ result = FALSE;
+ goto one;
+ }
+ }
+ for (i = 1; i <= maxSPoint; i++) /* init liblist so diags can be marked */
+ libList[i] = -1;
+ if ((utilPlayLevel > 4) &&
+ (lList1.indx > 1) &&
+ (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* try diags */
+ {
+ listDiags(gx, gy, &dList);
+ j = 0;
+ i = lList1.indx;
+ while ((j < dList.indx) &&
+ (i < maxSPoint))
+ {
+ j = j + 1;
+ i = i + 1;
+ libList[i] = 0; /* mark this as a diag */
+ lList1.p[i].px = dList.p[j].px;
+ lList1.p[i].py = dList.p[j].py;
+ }
+ lList1.indx = i;
+ }
+ if (lList1.indx > 1) /* sort by decreasing lib count */
+ {
+ for (i = 1; i <= lList1.indx; i++)
+ if (libList[i] != 0) /* diags are tried last */
+ {
+ mark2 = playMark;
+ tryPlay(lList1.p[i].px, lList1.p[i].py, him);
+ libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
+ if ((libList[i] > treeLibLim) ||
+ ((libList[i] > (depthLimit - depth)) &&
+ (libList[i] > 2)))
+ {
+ *escape = TRUE;
+ result = FALSE;
+ goto one;
+ }
+ undoTo(mark2);
+ }
+ for (i = 1; i <= lList1.indx - 1; i++)
+ for (j = i + 1; j <= lList1.indx; j++)
+ if (libList[i] < libList[j])
+ {
+ tl = libList[i];
+ libList[i] = libList[j];
+ libList[j] = tl;
+ tp = lList1.p[i];
+ lList1.p[i] = lList1.p[j];
+ lList1.p[j] = tp;
+ }
+ }
+ for (i = 1; i <= lList1.indx + 1; i++) /* try his responses */
+ {
+ mark2 = playMark;
+ if (i <= lList1.indx) /* try his move */
+ {
+ tryPlay(lList1.p[i].px, lList1.p[i].py, him); /* play his response */
+ pause();
+ if (gList[gMap[groupIDs[lList1.p[i].px]
+ [lList1.p[i].py]]].libC < 2)
+ goto two; /* a bogus move */
+ }
+ else if (gList[gMap[groupIDs[gx][gy]]].libC <= 1)
+ {
+ result = TRUE;
+ goto one;
+ }
+ if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
+ {
+ *escape = TRUE;
+ result = FALSE;
+ goto one;
+ }
+ if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
+ { /* look at my responses */
+ sSpanGroup(gx, gy, &lList2); /* list his liberties */
+ dStart = lList2.indx + 1;
+ if (adjInAtari) /* he wins */
+ {
+ result = FALSE;
+ goto one;
+ }
+ if ((lList2.indx > 2) && adj2Libs) /* he wins */
+ {
+ result = FALSE;
+ goto one;
+ }
+ for (k = 1; k <= maxSPoint; k++)
+ libList[k] = -1;
+ if (utilPlayLevel > 4) /* account for diagonal moves */
+ {
+ listDiags(gx, gy, &dList);
+ j = 0;
+ k = lList2.indx;
+ while ((j < dList.indx) &&
+ (k < maxSPoint))
+ {
+ j = j + 1;
+ k = k + 1;
+ libList[k] = 100;
+ lList2.p[k].px = dList.p[j].px;
+ lList2.p[k].py = dList.p[j].py;
+ }
+ lList2.indx = k;
+ }
+ if (lList2.indx > 1) /* sort by increasing lib count */
+ {
+ for (k = 1; k <= lList2.indx; k++)
+ if (libList[k] != 100) /* diags go last */
+ {
+ mark3 = playMark;
+ tryPlay(lList2.p[k].px, lList2.p[k].py, me);
+ libList[k] = gList[gMap[groupIDs[gx][gy]]].libC;
+ undoTo(mark3);
+ }
+ for (k = 1; k <= lList2.indx - 1; k++)
+ for (j = k + 1; j <= lList2.indx; j++)
+ if (libList[k] > libList[j])
+ {
+ tl = libList[k];
+ libList[k] = libList[j];
+ libList[j] = tl;
+ tp = lList2.p[k];
+ lList2.p[k] = lList2.p[j];
+ lList2.p[j] = tp;
+ }
+ else if ((libList[k] == libList[j]) &&
+ (libList[k] == 1))
+ if (mtNbrs(lList2.p[k].px, lList2.p[k].py) <
+ mtNbrs(lList2.p[j].px, lList2.p[j].py))
+ {
+ tl = libList[k];
+ libList[k] = libList[j];
+ libList[j] = tl;
+ tp = lList2.p[k];
+ lList2.p[k] = lList2.p[j];
+ lList2.p[j] = tp;
+ }
+ }
+ for (j = 1; j <= lList2.indx; j++)
+ {
+ if (killTree(lList2.p[j].px, lList2.p[j].py, gx,
+ gy, &esc, tkMark))
+ goto two; /* this kills him */
+ if (esc && (j >= dStart))
+ {
+ result = FALSE;
+ goto one; /* don't bother with more diags if escapes */
+ }
+ }
+ result = FALSE; /* none of my responses kills him */
+ goto one;
+ }
+ two:
+ undoTo(mark2);
+ }
+ result = TRUE; /* none of his responses saves him */
+ }
+ one:
+ undoTo(curMark);
+/* sClearChar(sChar, rXor); */
+ depth = depth - 1;
+ return result;
+ } /* killTree */
+
+short tKillTree(tx, ty, gx, gy)
+short tx, ty, gx, gy;
+ { /* tKillTree */
+ short tkMark, escape;
+ tryCount = 0;
+ tkMark = playMark;
+ return killTree(tx, ty, gx, gy, &escape, tkMark);
+ } /* tKillTree */
+
+short killable(gx, gy, killx, killy)
+short gx, gy, *killx, *killy;
+{ /* killable */
+#ifdef DEBUG
+ printf( "killable\n" );
+ showTrees = TRUE;
+#endif
+ dbStop = TRUE;
+ him = bord[gx][gy]; /* find out who I am */
+ me = -him;
+/* if (me == 1)
+ sChar = '>';
+ else
+ sChar = '|'; */
+/* write(sChar); */
+ depth = 1;
+ topMark = playMark;
+ sSpanGroup(gx, gy, &lList); /* find his liberties */
+ if (lList.indx == 1)
+ {
+ *killx = lList.p[1].px;
+ *killy = lList.p[1].py;
+ return TRUE;
+ }
+ else if (lList.indx > treeLibLim)
+ return FALSE;
+ else if (adjInAtari)
+ return FALSE;
+ else if ((lList.indx > 2) && adj2Libs)
+ return FALSE;
+ else
+ {
+ for (i = 1; i <= maxSPoint; i++)
+ libList[i] = -1;
+ if (utilPlayLevel > 4) /* account for diagonal moves */
+ {
+ listDiags(gx, gy, &dList);
+ j = 0;
+ i = lList.indx;
+ while ((j < dList.indx) &&
+ (i < maxSPoint))
+ {
+ j = j + 1;
+ i = i + 1;
+ libList[i] = 100;
+ lList.p[i].px = dList.p[j].px;
+ lList.p[i].py = dList.p[j].py;
+ }
+ lList.indx = i;
+ }
+ if (lList.indx > 1) /* sort by increasing lib count */
+ {
+ for (i = 1; i <= lList.indx; i++)
+ if (libList[i] != 100) /* diags go last */
+ {
+ mark2 = playMark;
+ tryPlay(lList.p[i].px, lList.p[i].py, me);
+ libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
+ undoTo(mark2);
+ }
+ for (i = 1; i <= lList.indx - 1; i++)
+ for (j = i + 1; j <= lList.indx; j++)
+ if (libList[i] > libList[j])
+ {
+ tl = libList[i];
+ libList[i] = libList[j];
+ libList[j] = tl;
+ tp = lList.p[i];
+ lList.p[i] = lList.p[j];
+ lList.p[j] = tp;
+ }
+ else if ((libList[i] == libList[j]) &&
+ (libList[i] == 1))
+ if (mtNbrs(lList.p[i].px, lList.p[i].py) <
+ mtNbrs(lList.p[j].px, lList.p[j].py))
+ {
+ tl = libList[i];
+ libList[i] = libList[j];
+ libList[j] = tl;
+ tp = lList.p[i];
+ lList.p[i] = lList.p[j];
+ lList.p[j] = tp;
+ }
+ }
+ for (i = 1; i <= lList.indx; i++)
+ {
+ if (legal[lList.p[i].px][lList.p[i].py])
+ {
+ *killx = lList.p[i].px;
+ *killy = lList.p[i].py;
+ if (tKillTree(*killx, *killy, gx, gy))
+ {
+/* sClearChar(sChar, rXor); */
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ }
+/* sClearChar(sChar, rXor); */
+} /* killable */
+
diff --git a/noncore/games/go/main.cpp b/noncore/games/go/main.cpp
new file mode 100644
index 0000000..c7e2669
--- a/dev/null
+++ b/noncore/games/go/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "gowidget.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <stdio.h>
+
+int main( int argc, char ** argv)
+{
+ QPEApplication app( argc, argv );
+
+ GoMainWidget m;
+ m.setCaption( GoWidget::tr("Go") );
+ app.showMainWidget( &m );
+ return app.exec();
+}
diff --git a/noncore/games/go/qpe-go.control b/noncore/games/go/qpe-go.control
new file mode 100644
index 0000000..edc106b
--- a/dev/null
+++ b/noncore/games/go/qpe-go.control
@@ -0,0 +1,9 @@
+Files: bin/go apps/Games/go.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: The game of Go
+ A game for the Qtopia environment.
diff --git a/noncore/games/mindbreaker/.cvsignore b/noncore/games/mindbreaker/.cvsignore
new file mode 100644
index 0000000..415ec09
--- a/dev/null
+++ b/noncore/games/mindbreaker/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+moc_*
+helpdialog.cpp
+helpdialog.h
diff --git a/noncore/games/mindbreaker/Makefile.in b/noncore/games/mindbreaker/Makefile.in
new file mode 100644
index 0000000..88f6fb1
--- a/dev/null
+++ b/noncore/games/mindbreaker/Makefile.in
@@ -0,0 +1,117 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = mindbreaker
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = mindbreaker.h
+SOURCES = main.cpp \
+ mindbreaker.cpp
+OBJECTS = main.o \
+ mindbreaker.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_mindbreaker.cpp
+OBJMOC = moc_mindbreaker.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake mindbreaker.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ mindbreaker.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+mindbreaker.o: mindbreaker.cpp \
+ mindbreaker.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+moc_mindbreaker.o: moc_mindbreaker.cpp \
+ mindbreaker.h
+
+moc_mindbreaker.cpp: mindbreaker.h
+ $(MOC) mindbreaker.h -o moc_mindbreaker.cpp
+
+
diff --git a/noncore/games/mindbreaker/main.cpp b/noncore/games/mindbreaker/main.cpp
new file mode 100644
index 0000000..8ba0fde
--- a/dev/null
+++ b/noncore/games/mindbreaker/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mindbreaker.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ MindBreaker w(0, "new window");
+ w.setCaption("Mind Breaker");
+ QPEApplication::setInputMethodHint( &w, QPEApplication::AlwaysOff );
+ a.showMainWidget(&w);
+
+ return a.exec();
+}
diff --git a/noncore/games/mindbreaker/mindbreaker.cpp b/noncore/games/mindbreaker/mindbreaker.cpp
new file mode 100644
index 0000000..b0e4d88
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.cpp
@@ -0,0 +1,818 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mindbreaker.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include <qlabel.h>
+#include <qstyle.h>
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+static int pegRTTI = 3393393;
+
+/* helper class, */
+class Peg : public QCanvasRectangle
+{
+public:
+ Peg(QCanvas *canvas, int type, int go = -1, int pos = -1);
+ int rtti() const {return pegRTTI; }
+ void advance(int phase);
+
+ bool hit( const QPoint &) const;
+
+/* a placed peg is one that has been set down on the board correctly and
+ should not be moved, only copied */
+ bool placed() const;
+ void setPlaced(bool);
+
+ int pegGo() const;
+ int pegPos() const;
+ void setPegPos(int);
+
+ int type() const;
+
+ static void buildImages();
+ static QImage imageForType(int t);
+
+ static int eggLevel;
+
+protected:
+ void drawShape(QPainter &);
+private:
+ static QVector<QImage> normalPegs;
+ static QVector<QImage> specialPegs;
+
+ bool isplaced;
+ int pegtype;
+ int peg_go;
+ int peg_pos;
+
+ int aniStep;
+};
+
+int Peg::eggLevel = 0;
+QVector<QImage> Peg::normalPegs;
+QVector<QImage> Peg::specialPegs;
+
+void Peg::buildImages()
+{
+
+ QImage pegs = Resource::loadImage("mindbreaker/pegs");
+ int x = 0;
+ int y = 0;
+ int i;
+ eggLevel = 0;
+ normalPegs.resize(10);
+ for (i = 0; i < 6; i++) {
+ normalPegs.insert(i, new QImage(pegs.copy(x, y, peg_size, peg_size)));
+ x += peg_size;
+ }
+ specialPegs.resize(5);
+ for (i = 0; i < 5; i++) {
+ specialPegs.insert(i, new QImage(pegs.copy(x,y,peg_size, peg_size)));
+ x += peg_size;
+ }
+
+ QImage image = Resource::loadImage("mindbreaker/mindbreaker");
+ /* copy from master image to functional images */
+ x = 0;
+ y = panel_height;
+ normalPegs.insert(8,
+ new QImage(image.copy(x, y, panel_width, panel_height)));
+ y += panel_height;
+ y += title_height;
+ normalPegs.insert(9,
+ new QImage(image.copy(x, y, title_width, title_height)));
+ y += title_height;
+
+ x = 6 * peg_size;
+ normalPegs.insert(6,
+ new QImage(image.copy(x, y, answerpeg_size, answerpeg_size)));
+ x += answerpeg_size;
+ normalPegs.insert(7,
+ new QImage(image.copy(x, y, answerpeg_size, answerpeg_size)));
+}
+
+QImage Peg::imageForType(int t)
+{
+ if (eggLevel > t ) {
+ if( t < 5) {
+ return *specialPegs[t];
+ } else {
+ return *normalPegs[rand() % 6];
+ }
+ }
+ return *normalPegs[t];
+}
+
+Peg::Peg(QCanvas *canvas , int t, int g = -1, int p = -1)
+ : QCanvasRectangle(canvas)
+{
+ setSize(normalPegs[t]->width(), normalPegs[t]->height() );
+ pegtype = t;
+ isplaced = FALSE;
+ peg_pos = p;
+ peg_go = g;
+ aniStep = rand() % 6;
+ setAnimated(TRUE);
+}
+
+void Peg::advance(int phase) {
+ if (phase == 0)
+ aniStep = (++aniStep) % 6;
+ else {
+ hide();
+ show();
+ }
+}
+
+void Peg::drawShape(QPainter &p )
+{
+ if ((pegtype == 5) && eggLevel > 5) {
+ p.drawImage(x(), y(), *normalPegs[aniStep]);
+ } else
+ p.drawImage(x(), y(), imageForType(pegtype));
+}
+
+bool Peg::hit( const QPoint &p ) const
+{
+ int ix = p.x() - int(x());
+ int iy = p.y() - int(y());
+ if (!normalPegs[pegtype]->valid(ix, iy))
+ return FALSE;
+ QRgb pixel = normalPegs[pegtype]->pixel(ix, iy);
+ return (qAlpha(pixel ) != 0);
+}
+
+inline bool Peg::placed() const
+{
+ return isplaced;
+}
+
+inline int Peg::pegGo() const
+{
+ return peg_go;
+}
+
+inline int Peg::pegPos() const
+{
+ return peg_pos;
+}
+
+inline void Peg::setPegPos(int p)
+{
+ peg_pos = p;
+}
+
+inline void Peg::setPlaced(bool p)
+{
+ isplaced = p;
+}
+
+inline int Peg::type() const
+{
+ return pegtype;
+}
+
+/* Load the main image, copy from it the pegs, the board, and the answer image
+ * and use these to create the tray, answer and board
+ */
+MindBreaker::MindBreaker( QWidget *parent=0, const char *name=0, int wFlags=0 )
+: QMainWindow(parent, name, wFlags),
+ canvas(board_height, board_width)
+{
+ MindBreakerBoard *m = new MindBreakerBoard(canvas, this);
+ setCentralWidget(m);
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar *tb = new QPEToolBar(this);
+ tb->setHorizontalStretchable( TRUE );
+
+ QPixmap newicon = Resource::loadPixmap("new");
+ new QToolButton(newicon, tr("New Game"), 0,
+ m, SLOT(clear()), tb, "NewGame");
+
+ score = new QToolButton(tb);
+ score->setText("");
+ score->setMaximumHeight(20);
+ score->setUsesTextLabel(TRUE);
+ tb->setStretchableWidget(score);
+
+ connect(m, SIGNAL(scoreChanged(int, int)), this, SLOT(setScore(int, int)));
+ connect(score, SIGNAL(clicked()), m, SLOT(resetScore()));
+
+ int a, b;
+ m->getScore(&a, &b);
+ setScore(a,b);
+}
+
+void MindBreaker::setScore(int turns, int games)
+{
+ double average;
+ double total_turns = turns;
+ double total_games = games;
+
+ if(total_games > 0)
+ average = total_turns / total_games;
+ else
+ average = 0.0;
+
+ score->setText(tr("win avg: %1 turns (%2 games)").arg(average).arg(games));
+}
+
+
+MindBreakerBoard::MindBreakerBoard( QCanvas &c, QWidget *parent=0,
+ const char *name=0, int wFlags=0 )
+ : QCanvasView(&c, parent, name, wFlags)
+{
+ int i, x, y;
+ struct timeval tv;
+
+ current_go = 0;
+ gettimeofday(&tv, 0);
+
+ srand(tv.tv_usec);
+
+ canvas()->setAdvancePeriod(500);
+
+ QImage image = Resource::loadImage("mindbreaker/mindbreaker");
+
+ /* copy from master image to functional images */
+ x = 0;
+ y = 0;
+ panelImage = image.copy(x,y, panel_width, panel_height);
+ y += panel_height;
+ y += panel_height;
+
+ titleImage = image.copy(x, y, title_width, title_height);
+
+ Peg::buildImages(); // must be done BEFORE any pegs are made
+
+ current_highlight = new Peg(canvas(), 8);
+ current_highlight->setPlaced(TRUE);
+ current_highlight->setX(0);
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ current_highlight->setZ(0);
+ current_highlight->show();
+
+
+ /* set up the game */
+ Config c("MindBreaker", Config::User);
+ c.setGroup("Board");
+ game_over = FALSE;
+ if (c.readNumEntry("Answer0") < 0) {
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ total_turns = 0;
+ total_games = 0;
+ } else {
+ int j;
+ c.setGroup("Score");
+ total_turns = c.readNumEntry("Turns");
+ total_games = c.readNumEntry("Games");
+ if(total_turns < 0)
+ total_turns = 0;
+ if(total_games < 0)
+ total_games = 0;
+
+
+ checkScores();
+ c.setGroup("Board");
+ for(i = 0; i < 4; i++)
+ answer[i] = c.readNumEntry(QString("Answer%1").arg(i));
+ /* read, and parse past guesses */
+ current_go = 0;
+ for(j=0; j < 9; j++) {
+ current_guess[0] = c.readNumEntry(QString("Go%1p0").arg(j));
+ if (current_guess[0] < 0)
+ break;
+ placeGuessPeg(0, current_guess[0]);
+ current_guess[1] = c.readNumEntry(QString("Go%1p1").arg(j));
+ placeGuessPeg(1, current_guess[1]);
+ current_guess[2] = c.readNumEntry(QString("Go%1p2").arg(j));
+ placeGuessPeg(2, current_guess[2]);
+ current_guess[3] = c.readNumEntry(QString("Go%1p3").arg(j));
+ placeGuessPeg(3, current_guess[3]);
+ checkGuess();
+ }
+ for(i = 0; i < 4; i++) {
+ current_guess[i] = c.readNumEntry(QString("CurrentGo%1").arg(i));
+ if (current_guess[i] != 6)
+ placeGuessPeg(i, current_guess[i]);
+ }
+ }
+
+ /* draw initial screen */
+ drawBackground();
+ canvas()->update();
+}
+
+MindBreakerBoard::~MindBreakerBoard()
+{
+ int i, j;
+ if (game_over) {
+ current_go = 0;
+ /* clear the answer, clear the guess */
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ }
+
+ Config c("MindBreaker", Config::User);
+ c.setGroup("Board");
+ c.clearGroup();
+ /* write the board */
+ for (i = 0; i < current_go; i++) {
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("Go%1p%2").arg(i).arg(j), past_guesses[4*i+j]);
+ }
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("CurrentGo%1").arg(j), current_guess[j]);
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("Answer%1").arg(j), answer[j]);
+
+ c.setGroup("Score");
+ /* write the score */
+
+ c.writeEntry("Turns", total_turns);
+ c.writeEntry("Games", total_games);
+}
+
+void MindBreakerBoard::getScore(int *a, int *b)
+{
+ *a = total_turns;
+ *b = total_games;
+ return;
+}
+
+void MindBreakerBoard::placeGuessPeg(int pos, int pegId)
+{
+ int x = first_peg_x_diff + (pos * peg_spacing);
+ int y = board_height - ((current_go + 1) * panel_height)
+ + first_peg_y_diff;
+
+ Peg *peg = new Peg(canvas(), pegId, current_go, pos);
+ peg->setPegPos(pos);
+ peg->setPlaced(TRUE);
+ peg->setX(x);
+ peg->setY(y);
+ peg->setZ(2);
+ peg->show();
+}
+
+void MindBreakerBoard::drawBackground()
+{
+ int i, j, x, y, x_gap, y_gap;
+ QPixmap background = QPixmap(canvas()->width(), canvas()->height());
+
+ QPainter painter(&background);
+
+ painter.fillRect(0, 0, canvas()->width(), canvas()->height(), QColor(0,0,0));
+ /* very first thing is to draw the bins, as everything else needs
+ * to be drawn over them */
+
+ QPen pen(QColor(85, 45, 27), 4);
+ painter.setPen(pen);
+ x_gap = canvas()->width() - (panel_width + (2 * bin_margin));
+ //x_gap += peg_size >> 1;
+ if (x_gap < 1)
+ x_gap = 1;
+
+ y_gap = board_height / 6;
+ y_gap -= (2 * bin_margin);
+ //y_gap += peg_size >> 1;
+ if (y_gap < 1)
+ y_gap = 1;
+ x = panel_width + bin_margin - (peg_size >> 1);
+ y = bin_margin - (peg_size >> 1) + 2;
+
+ for (i = 0; i < 6; i++) {
+ for (j = 0; j < 10; j++) {
+ int rx = x + (rand() % x_gap);
+ int ry = y + (rand() % y_gap);
+ painter.drawImage(rx,ry, Peg::imageForType(i));
+ }
+ y += board_height / 6;
+ }
+ /* now draw the surrounding boxes */
+ x_gap = canvas()->width() - panel_width;
+ if (x_gap < 1) x_gap = 1;
+ y_gap = board_height / 6;
+ x = panel_width;
+ y = 1;
+
+ for (i = 0; i < 6; i++) {
+ painter.drawRect(x, y, x_gap, y_gap);
+ y += y_gap;
+ }
+
+ x = 0;
+ y = 0;
+
+ painter.drawImage(x,y, titleImage);
+ y = title_height;
+ /* now nine gues panels */
+ for (i = 0; i < 9; i ++) {
+ painter.drawImage(x, y, panelImage);
+ y += panel_height;
+ }
+
+ painter.flush();
+ canvas()->setBackgroundPixmap(background);
+}
+
+void MindBreakerBoard::checkGuess()
+{
+ int i,j;
+ int num_white = 0;
+ int num_black = 0;
+ int copy_answer[4];
+ int copy_guess[4];
+
+ for(i = 0; i < 4; i++) {
+ copy_answer[i] = answer[i];
+ copy_guess[i] = current_guess[i];
+ if (current_guess[i] == 6)
+ return;
+ if (answer[i] == current_guess[i]) {
+ num_black++;
+ copy_answer[i] = 6;
+ copy_guess[i] = 7;
+ }
+ }
+
+ /* now sure that user has completed a 'guess' */
+ for (i = 0; i < 4; i++) {
+ if (copy_guess[i] == 7)
+ continue; // already marked for a black
+ for (j = 0; j < 4; j++) {
+ if(copy_guess[i] == copy_answer[j]) {
+ copy_answer[j] = 6;
+ num_white++;
+ break;
+ }
+ }
+ }
+
+ int x = answerpegx;
+ int y = (board_height - ((current_go + 1) * panel_height)) + answerpegy;
+
+ if (num_black == 4)
+ game_over = TRUE;
+
+ while(num_black > 0) {
+ Peg *p = new Peg(canvas(), 7);
+ p->setPlaced(TRUE);
+ p->setX(x);
+ p->setY(y);
+ p->setZ(1);
+ p->show();
+ num_black--;
+
+ if (x == answerpegx)
+ x = answerpegx + answerpeg_diff;
+ else {
+ x = answerpegx;
+ y += answerpeg_diff;
+ }
+ }
+ while(num_white > 0){
+ Peg *p = new Peg(canvas(), 6);
+ p->setPlaced(TRUE);
+ p->setX(x);
+ p->setY(y);
+ p->setZ(1);
+ p->show();
+ num_white--;
+
+ if (x == answerpegx)
+ x = answerpegx + answerpeg_diff;
+ else {
+ x = answerpegx;
+ y += answerpeg_diff;
+ }
+ }
+ /* move to next go */
+ for(i = 0; i < 4; i++) {
+ past_guesses[4*current_go+i] = current_guess[i];
+ current_guess[i] = 6;
+ }
+
+ current_go++;
+ if((current_go > 8) || game_over) {
+ total_games++;
+ if(!game_over)
+ total_turns += 10;
+ else
+ total_turns += current_go;
+
+ emit scoreChanged(total_turns, total_games);
+ Peg *p = new Peg(canvas(), 9);
+ game_over = TRUE;
+ p->setPlaced(TRUE);
+ p->setX(0);
+ p->setY(0);
+ p->setZ(0);
+ p->show();
+
+ for (i = 0; i < 4; i++) {
+ p = new Peg(canvas(), answer[i], -1);
+ p->setX(first_peg_x_diff + (i * peg_spacing));
+ p->setY(5);
+ p->setZ(3);
+ p->show();
+ }
+ } else {
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ }
+ canvas()->update();
+}
+
+void MindBreakerBoard::clear()
+{
+ if(!game_over) {
+ total_games++;
+ total_turns += 10;
+ emit scoreChanged(total_turns, total_games);
+ }
+ int i;
+ /* reset the game board */
+ game_over = FALSE;
+ /* clear the answer, clear the guess */
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ current_go = 0;
+
+ QCanvasItemList list = canvas()->allItems();
+ QCanvasItemList::Iterator it = list.begin();
+ for (; it != list.end(); ++it) {
+ if (*it == current_highlight)
+ continue;
+ if (*it)
+ delete *it;
+ }
+
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ checkScores();
+ drawBackground();
+ canvas()->update();
+}
+
+void MindBreakerBoard::resetScore()
+{
+ /* are u sure */
+
+ if (QMessageBox::information(this, tr( "Reset Statistics" ),
+ tr( "Reset the win ratio?" ),
+ tr( "OK" ), tr( "Cancel" ) ) == 0) {
+ total_turns = 0;
+ total_games = 0;
+ Peg::eggLevel = 0;
+ drawBackground();
+ canvas()->update();
+ emit scoreChanged(total_turns, total_games);
+ }
+}
+
+/* EVENTS */
+
+void MindBreakerBoard::contentsMousePressEvent(QMouseEvent *e)
+{
+ copy_press = FALSE;
+ null_press = FALSE;
+ /* ok, first work out if it is one of the bins that
+ got clicked */
+ if (e->x() > panel_width) {
+ /* its a bin, but which bin */
+ if(e->y() > board_height)
+ return; // missed everything
+ int bin = (e->y() + 2) / (board_height / 6);
+
+ /* make new peg... set it moving */
+ moving_pos = e->pos();
+ moving = new Peg(canvas(), bin, current_go);
+ moving->setX(e->x() - (peg_size >> 1));
+ moving->setY(e->y() - (peg_size >> 1));
+ moving->setZ(5);
+ moving->show();
+ canvas()->update();
+ return;
+ }
+
+ QCanvasItemList l = canvas()->collisions(e->pos());
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if ( (*it)->rtti() == pegRTTI ) {
+ Peg *item = (Peg *)(*it);
+ if (!item->hit(e->pos()))
+ continue;
+ if (item->type() > 5) {
+ null_press = TRUE;
+ null_point = e->pos();
+ continue; /* not a color peg */
+ }
+ if (item->placed()) {
+ /* copy */
+ if(item->pegGo() == -1)
+ return;
+ if(item->pegGo() == current_go) {
+ copy_press = TRUE;
+ copy_peg = item;
+ }
+ moving = new Peg(canvas(),
+ item->type(), current_go);
+ moving->setX(e->x() - (peg_size >> 1));
+ moving->setY(e->y() - (peg_size >> 1));
+ moving->setZ(5);
+ moving->show();
+ moving_pos = QPoint(e->x(), e->y());
+ canvas()->update();
+ return;
+ }
+ moving = (Peg *)*it;
+ moving_pos = e->pos();
+ canvas()->update();
+ return;
+ }
+ }
+ null_press = TRUE;
+ null_point = e->pos();
+ moving = 0;
+}
+
+void MindBreakerBoard::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if (moving ) {
+ moving->moveBy(e->pos().x() - moving_pos.x(),
+ e->pos().y() - moving_pos.y());
+ moving_pos = e->pos();
+ canvas()->update();
+ return;
+ }
+}
+
+void MindBreakerBoard::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ /* time to put down the peg */
+ if(moving) {
+ if(copy_press) {
+ /* check if collided with original. if so, delete both */
+ copy_press = FALSE;
+ QCanvasItemList l = canvas()->collisions(e->pos());
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if (*it == copy_peg)
+ copy_press = TRUE;
+ }
+ if (copy_press) {
+ current_guess[copy_peg->pegPos()] = 6;
+ delete copy_peg;
+ delete moving;
+ copy_press = FALSE;
+ moving = 0;
+ copy_peg = 0;
+ canvas()->update();
+ return;
+ }
+ }
+
+ /* first work out if in y */
+ if (e->y() > (board_height - (current_go * panel_height))) {
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+ if (e->y() < (board_height - ((current_go + 1) * panel_height))) {
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+ /* ok, a valid go, but which peg */
+ int x_bar = first_peg_x_diff - (peg_size >> 1);
+ x_bar += peg_spacing;
+ int pos = 0;
+ if (e->x() > x_bar)
+ pos = 1;
+ x_bar += peg_spacing;
+ if (e->x() > x_bar)
+ pos = 2;
+ x_bar += peg_spacing;
+ if (e->x() > x_bar)
+ pos = 3;
+ x_bar += peg_spacing;
+
+ if (e->x() > x_bar) {
+ /* invalid x */
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+
+ int x = first_peg_x_diff + (pos * peg_spacing);
+ int y = board_height - ((current_go + 1) * panel_height)
+ + first_peg_y_diff;
+ moving->setPegPos(pos);
+ moving->setX(x);
+ moving->setY(y);
+ moving->setZ(2);
+
+ /* remove all other pegs from this position */
+ QCanvasItemList l = canvas()->collisions(QPoint(x,y));
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if ( (*it)->rtti() == pegRTTI ) {
+ Peg *item = (Peg *)(*it);
+ if ((item != moving) && (item != current_highlight))
+ delete item;
+ }
+ }
+ current_guess[pos] = ((Peg *)moving)->type();
+
+ ((Peg *)moving)->setPlaced(true);
+ canvas()->update();
+ return;
+ }
+ moving = 0;
+ null_point -= e->pos();
+ if(null_point.manhattanLength() < 6) {
+ if (game_over)
+ clear();
+ else
+ checkGuess();
+ }
+}
+
+void MindBreakerBoard::resizeEvent(QResizeEvent *e)
+{
+ QSize s = e->size();
+ int fw = style().defaultFrameWidth();
+ s.setWidth(s.width() - fw);
+ s.setHeight(s.height() - fw);
+
+ /* min size is 200 x 260 */
+ if (s.width() < board_width)
+ s.setWidth(board_width);
+
+ if (s.height() < board_height)
+ s.setHeight(board_height);
+
+ canvas()->resize(s.width() - fw, s.height() - fw);
+ drawBackground();
+}
+
+
+/* Easter egg function... beat the clock */
+void MindBreakerBoard::checkScores()
+{
+ double games = total_games;
+ double turns = total_turns;
+ double g = games / 10.0;
+ Peg::eggLevel = 0;
+
+ double break_even = 5.0;
+ if (g < 1.0)
+ return;
+ double avg = turns / games;
+ g--;
+ while (break_even >= 0.0) {
+ if (avg >= (break_even + g))
+ return;
+ // score a peg.
+ break_even -= 1.0;
+ Peg::eggLevel = int(5.0 - break_even);
+ }
+}
diff --git a/noncore/games/mindbreaker/mindbreaker.h b/noncore/games/mindbreaker/mindbreaker.h
new file mode 100644
index 0000000..fca649a
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef MINDBREAKER_H
+#define MINDBREAKER_H
+
+#include <qwidget.h>
+#include <qmainwindow.h>
+#include <qimage.h>
+#include <qvector.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+
+static const int panel_height = 26;
+static const int panel_width = 180;
+
+static const int title_height = 25;
+static const int title_width = 180;
+
+static const int bin_margin = 10;
+static const int peg_size = 20;
+static const int answerpeg_size = 13;
+
+static const int first_peg_x_diff = 21;
+static const int first_peg_y_diff = ((panel_height - peg_size) >> 1);
+static const int peg_spacing = 30;
+
+static const int answerpegx = 152;
+static const int answerpegy = 2;
+static const int answerpeg_diff = 9;
+
+static const int board_height = (title_height + (panel_height * 9));
+static const int board_width = (panel_width + (bin_margin * 2) + peg_size);
+
+class Peg;
+class QToolButton;
+
+class MindBreakerBoard : public QCanvasView // QWidget
+{
+ Q_OBJECT
+public:
+ MindBreakerBoard(QCanvas &c, QWidget *parent=0, const char *name=0, int wFlags=0 );
+ ~MindBreakerBoard();
+
+ void getScore(int *, int *);
+signals:
+ void scoreChanged(int, int);
+
+public slots:
+ void clear();
+ void resetScore();
+
+protected:
+ void contentsMousePressEvent(QMouseEvent *);
+ void contentsMouseMoveEvent(QMouseEvent *);
+ void contentsMouseReleaseEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ void drawBackground();
+ void checkGuess();
+ void checkScores();
+ void placeGuessPeg(int pos, int pegId);
+
+ QImage panelImage;
+ QImage titleImage;
+
+ Peg *moving;
+ Peg *current_highlight;
+ QPoint moving_pos;
+
+ // the game stuff
+ int answer[4];
+ int current_guess[4];
+ int past_guesses[4*9];
+ int current_go;
+
+ int null_press;
+ QPoint null_point;
+ bool copy_press;
+ Peg *copy_peg;
+ bool game_over;
+
+ int total_turns;
+ int total_games;
+};
+
+class MindBreaker : public QMainWindow // QWidget
+{
+ Q_OBJECT
+public:
+ MindBreaker(QWidget *parent=0, const char *name=0, int wFlags=0 );
+
+public slots:
+ void setScore(int, int);
+
+private:
+ QCanvas canvas;
+ MindBreakerBoard *board;
+ QToolButton *score;
+
+};
+
+
+#endif
diff --git a/noncore/games/mindbreaker/mindbreaker.pro b/noncore/games/mindbreaker/mindbreaker.pro
new file mode 100644
index 0000000..12944d1
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = mindbreaker.h
+SOURCES = main.cpp \
+ mindbreaker.cpp
+TARGET = mindbreaker
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/mindbreaker.ts
diff --git a/noncore/games/mindbreaker/qpe-mindbreaker.control b/noncore/games/mindbreaker/qpe-mindbreaker.control
new file mode 100644
index 0000000..3bad93d
--- a/dev/null
+++ b/noncore/games/mindbreaker/qpe-mindbreaker.control
@@ -0,0 +1,9 @@
+Files: bin/mindbreaker apps/Games/mindbreaker.desktop pics/mindbreaker
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: crack the coloured code
+ A game for the Qtopia environment.
diff --git a/noncore/games/minesweep/.cvsignore b/noncore/games/minesweep/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/noncore/games/minesweep/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/noncore/games/minesweep/Makefile.in b/noncore/games/minesweep/Makefile.in
new file mode 100644
index 0000000..9ed6234
--- a/dev/null
+++ b/noncore/games/minesweep/Makefile.in
@@ -0,0 +1,134 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = minesweep
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = minefield.h \
+ minesweep.h
+SOURCES = main.cpp \
+ minefield.cpp \
+ minesweep.cpp
+OBJECTS = main.o \
+ minefield.o \
+ minesweep.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_minefield.cpp \
+ moc_minesweep.cpp
+OBJMOC = moc_minefield.o \
+ moc_minesweep.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake minesweep.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ minesweep.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+minefield.o: minefield.cpp \
+ minefield.h \
+ $(QPEDIR)/include/qpe/config.h
+
+minesweep.o: minesweep.cpp \
+ minesweep.h \
+ minefield.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+moc_minefield.o: moc_minefield.cpp \
+ minefield.h
+
+moc_minesweep.o: moc_minesweep.cpp \
+ minesweep.h
+
+moc_minefield.cpp: minefield.h
+ $(MOC) minefield.h -o moc_minefield.cpp
+
+moc_minesweep.cpp: minesweep.h
+ $(MOC) minesweep.h -o moc_minesweep.cpp
+
+
diff --git a/noncore/games/minesweep/main.cpp b/noncore/games/minesweep/main.cpp
new file mode 100644
index 0000000..83de9a3
--- a/dev/null
+++ b/noncore/games/minesweep/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "minesweep.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char** argv )
+{
+ QPEApplication a( argc, argv );
+
+ MineSweep ms;
+ QPEApplication::setInputMethodHint( &ms, QPEApplication::AlwaysOff );
+ a.showMainWidget( &ms );
+
+ return a.exec();
+}
diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp
new file mode 100644
index 0000000..be2f9a3
--- a/dev/null
+++ b/noncore/games/minesweep/minefield.cpp
@@ -0,0 +1,623 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "minefield.h"
+
+#include <qpe/config.h>
+
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qtimer.h>
+
+#include <stdlib.h>
+
+static const char *pix_flag[]={
+"13 13 3 1",
+"# c #000000",
+"x c #ff0000",
+". c None",
+".............",
+".............",
+".....#xxxxxx.",
+".....#xxxxxx.",
+".....#xxxxxx.",
+".....#xxxxxx.",
+".....#.......",
+".....#.......",
+".....#.......",
+".....#.......",
+"...#####.....",
+"..#######....",
+"............."};
+
+static const char *pix_mine[]={
+"13 13 3 1",
+"# c #000000",
+". c None",
+"a c #ffffff",
+"......#......",
+"......#......",
+"..#.#####.#..",
+"...#######...",
+"..##aa#####..",
+"..##aa#####..",
+"#############",
+"..#########..",
+"..#########..",
+"...#######...",
+"..#.#####.#..",
+"......#......",
+"......#......"};
+
+class Mine : public QTableItem
+{
+public:
+ enum MineState {
+ Hidden = 0,
+ Empty,
+ Mined,
+ Flagged,
+#ifdef MARK_UNSURE
+ Unsure,
+#endif
+ Exploded,
+ Wrong
+ };
+
+ Mine( QTable* );
+ void paint( QPainter * p, const QColorGroup & cg, const QRect & cr, bool selected );
+ EditType editType() const { return Never; }
+ QSize sizeHint() const { return QSize( 12, 12 ); }
+
+ void activate( bool sure = TRUE );
+ void setHint( int );
+
+ void setState( MineState );
+ MineState state() const { return st; }
+
+ bool isMined() const { return mined; }
+ void setMined( bool m ) { mined = m; }
+
+ static void paletteChange();
+
+private:
+ bool mined;
+ int hint;
+
+ MineState st;
+
+ static QPixmap* knownField;
+ static QPixmap* unknownField;
+ static QPixmap* flag_pix;
+ static QPixmap* mine_pix;
+};
+
+QPixmap* Mine::knownField = 0;
+QPixmap* Mine::unknownField = 0;
+QPixmap* Mine::flag_pix = 0;
+QPixmap* Mine::mine_pix = 0;
+
+Mine::Mine( QTable *t )
+: QTableItem( t, Never, QString::null )
+{
+ mined = FALSE;
+ st = Hidden;
+ hint = 0;
+}
+
+void Mine::activate( bool sure )
+{
+ if ( !sure ) {
+ switch ( st ) {
+ case Hidden:
+ setState( Flagged );
+ break;
+ case Flagged:
+#ifdef MARK_UNSURE
+ setState( Unsure );
+ break;
+ case Unsure:
+#endif
+ setState( Hidden );
+ default:
+ break;
+ }
+ } else if ( st == Flagged ) {
+ return;
+ } else {
+ if ( mined ) {
+ setState( Exploded );
+ } else {
+ setState( Empty );
+ }
+ }
+}
+
+void Mine::setState( MineState s )
+{
+ st = s;
+}
+
+void Mine::setHint( int h )
+{
+ hint = h;
+}
+
+void Mine::paletteChange()
+{
+ delete knownField;
+ knownField = 0;
+ delete unknownField;
+ unknownField = 0;
+ delete mine_pix;
+ mine_pix = 0;
+ delete flag_pix;
+ flag_pix = 0;
+}
+
+void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr, bool )
+{
+ if ( !knownField ) {
+ knownField = new QPixmap( cr.width(), cr.height() );
+ QPainter pp( knownField );
+ QBrush br( cg.button().dark(115) );
+ qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, TRUE, &br );
+ }
+
+ const int pmmarg=cr.width()/5;
+
+ if ( !unknownField ) {
+ unknownField = new QPixmap( cr.width(), cr.height() );
+ QPainter pp( unknownField );
+ QBrush br( cg.button() );
+ qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, FALSE, &br );
+ }
+
+ if ( !flag_pix ) {
+ flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
+ flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
+ }
+
+ if ( !mine_pix ) {
+ mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
+ mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
+ }
+
+ p->save();
+
+ switch(st) {
+ case Hidden:
+ p->drawPixmap( 0, 0, *unknownField );
+ break;
+ case Empty:
+ p->drawPixmap( 0, 0, *knownField );
+ if ( hint > 0 ) {
+ switch( hint ) {
+ case 1:
+ p->setPen( blue );
+ break;
+ case 2:
+ p->setPen( green );
+ case 3:
+ p->setPen( red );
+ break;
+ default:
+ p->setPen( darkMagenta );
+ break;
+ }
+ p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, QString().setNum( hint ) );
+ }
+ break;
+ case Mined:
+ p->drawPixmap( 0, 0, *knownField );
+ p->drawPixmap( pmmarg, pmmarg, *mine_pix );
+ break;
+ case Exploded:
+ p->drawPixmap( 0, 0, *knownField );
+ p->drawPixmap( pmmarg, pmmarg, *mine_pix );
+ p->setPen( red );
+ p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" );
+ break;
+ case Flagged:
+ p->drawPixmap( 0, 0, *unknownField );
+ p->drawPixmap( pmmarg, pmmarg, *flag_pix );
+ break;
+#ifdef MARK_UNSURE
+ case Unsure:
+ p->drawPixmap( 0, 0, *unknownField );
+ p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "?" );
+ break;
+#endif
+ case Wrong:
+ p->drawPixmap( 0, 0, *unknownField );
+ p->drawPixmap( pmmarg, pmmarg, *flag_pix );
+ p->setPen( red );
+ p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" );
+ break;
+ }
+
+ p->restore();
+}
+
+/*
+ MineField implementation
+*/
+
+MineField::MineField( QWidget* parent, const char* name )
+: QTable( parent, name )
+{
+ setState( GameOver );
+ setShowGrid( FALSE );
+ horizontalHeader()->hide();
+ verticalHeader()->hide();
+ setTopMargin( 0 );
+ setLeftMargin( 0 );
+
+ setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) );
+
+ setSelectionMode( QTable::NoSelection );
+ setFocusPolicy( QWidget::NoFocus );
+
+ setCurrentCell( -1, -1 );
+
+ connect( this, SIGNAL( pressed( int, int, int, const QPoint& ) ), this, SLOT( cellPressed( int, int ) ) );
+ connect( this, SIGNAL( clicked( int, int, int, const QPoint& ) ), this, SLOT( cellClicked( int, int ) ) );
+
+ holdTimer = new QTimer( this );
+ connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) );
+
+ flagAction = NoAction;
+ ignoreClick = FALSE;
+ currRow = currCol = 0;
+ minecount=0;
+ mineguess=0;
+ nonminecount=0;
+}
+
+MineField::~MineField()
+{
+}
+
+void MineField::setState( State st )
+{
+ stat = st;
+}
+
+
+void MineField::setup( int level )
+{
+ lev = level;
+ setState( Waiting );
+ viewport()->setUpdatesEnabled( FALSE );
+
+ int cellsize;
+
+ int x;
+ int y;
+ for ( x = 0; x < numCols(); x++ )
+ for ( y = 0; y < numRows(); y++ )
+ clearCell( y, x );
+
+ switch( lev ) {
+ case 1:
+ setNumRows( 9 );
+ setNumCols( 9 );
+ minecount = 12;
+ cellsize = 21;
+ break;
+ case 2:
+ setNumRows( 16 );
+ setNumCols( 16 );
+ minecount = 45;
+ cellsize = 14;
+ break;
+ case 3:
+ setNumRows( 18 );
+ setNumCols( 18 );
+ minecount = 66 ;
+ cellsize = 12;
+ break;
+ }
+ nonminecount = numRows()*numCols() - minecount;
+ mineguess = minecount;
+ emit mineCount( mineguess );
+ Mine::paletteChange();
+
+ for ( y = 0; y < numRows(); y++ )
+ setRowHeight( y, cellsize );
+ for ( x = 0; x < numCols(); x++ )
+ setColumnWidth( x, cellsize );
+ for ( x = 0; x < numCols(); x++ )
+ for ( y = 0; y < numRows(); y++ )
+ setItem( y, x, new Mine( this ) );
+
+ updateGeometry();
+ viewport()->setUpdatesEnabled( TRUE );
+ viewport()->repaint( TRUE );
+}
+
+
+void MineField::placeMines()
+{
+ int mines = minecount;
+ while ( mines ) {
+ int col = int((double(rand()) / double(RAND_MAX)) * numCols());
+ int row = int((double(rand()) / double(RAND_MAX)) * numRows());
+
+ Mine* mine = (Mine*)item( row, col );
+
+ if ( mine && !mine->isMined() && mine->state() == Mine::Hidden ) {
+ mine->setMined( TRUE );
+ mines--;
+ }
+ }
+}
+
+void MineField::paintFocus( QPainter*, const QRect& )
+{
+}
+
+void MineField::viewportMousePressEvent( QMouseEvent* e )
+{
+ QTable::viewportMousePressEvent( e );
+}
+
+void MineField::viewportMouseReleaseEvent( QMouseEvent* e )
+{
+ QTable::viewportMouseReleaseEvent( e );
+ if ( flagAction == FlagNext ) {
+ flagAction = NoAction;
+ }
+}
+
+void MineField::keyPressEvent( QKeyEvent* e )
+{
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction;
+#else
+ flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction;
+#endif
+}
+
+void MineField::keyReleaseEvent( QKeyEvent* )
+{
+ flagAction = NoAction;
+}
+
+int MineField::getHint( int row, int col )
+{
+ int hint = 0;
+ for ( int c = col-1; c <= col+1; c++ )
+ for ( int r = row-1; r <= row+1; r++ ) {
+ Mine* mine = (Mine*)item( r, c );
+ if ( mine && mine->isMined() )
+ hint++;
+ }
+
+ return hint;
+}
+
+void MineField::setHint( Mine* mine )
+{
+ if ( !mine )
+ return;
+
+ int row = mine->row();
+ int col = mine->col();
+ int hint = getHint( row, col );
+
+ if ( !hint ) {
+ for ( int c = col-1; c <= col+1; c++ )
+ for ( int r = row-1; r <= row+1; r++ ) {
+ Mine* mine = (Mine*)item( r, c );
+ if ( mine && mine->state() == Mine::Hidden ) {
+ mine->activate( TRUE );
+ nonminecount--;
+ setHint( mine );
+ updateCell( r, c );
+ }
+ }
+ }
+
+ mine->setHint( hint );
+ updateCell( row, col );
+}
+
+/*
+ state == Waiting means no "hold"
+
+
+*/
+void MineField::cellPressed( int row, int col )
+{
+ if ( state() == GameOver )
+ return;
+ currRow = row;
+ currCol = col;
+ if ( state() == Playing )
+ holdTimer->start( 150, TRUE );
+}
+
+void MineField::held()
+{
+ flagAction = FlagNext;
+ updateMine( currRow, currCol );
+ ignoreClick = TRUE;
+}
+
+/*
+ Only place mines after first click, since it is pointless to
+ kill the player before the game has started.
+*/
+
+void MineField::cellClicked( int row, int col )
+{
+ if ( state() == GameOver )
+ return;
+ if ( state() == Waiting ) {
+ Mine* mine = (Mine*)item( row, col );
+ if ( !mine )
+ return;
+ mine->setState( Mine::Empty );
+ nonminecount--;
+ placeMines();
+ setState( Playing );
+ emit gameStarted();
+ updateMine( row, col );
+ } else { // state() == Playing
+ holdTimer->stop();
+ if ( ignoreClick )
+ ignoreClick = FALSE;
+ else
+ updateMine( row, col );
+ }
+}
+
+void MineField::updateMine( int row, int col )
+{
+ Mine* mine = (Mine*)item( row, col );
+ if ( !mine )
+ return;
+
+ bool wasFlagged = mine->state() == Mine::Flagged;
+ bool wasEmpty = mine->state() == Mine::Empty;
+
+ mine->activate( flagAction == NoAction );
+
+ if ( mine->state() == Mine::Exploded ) {
+ emit gameOver( FALSE );
+ setState( GameOver );
+ return;
+ } else if ( mine->state() == Mine::Empty ) {
+ setHint( mine );
+ if ( !wasEmpty )
+ nonminecount--;
+ }
+
+ if ( flagAction != NoAction ) {
+ if ( mine->state() == Mine::Flagged ) {
+ --mineguess;
+ emit mineCount( mineguess );
+ if ( mine->isMined() )
+ --minecount;
+ } else if ( wasFlagged ) {
+ ++mineguess;
+ emit mineCount( mineguess );
+ if ( mine->isMined() )
+ ++minecount;
+ }
+ }
+
+ updateCell( row, col );
+
+ if ( !minecount && !mineguess || !nonminecount ) {
+ emit gameOver( TRUE );
+ setState( GameOver );
+ }
+}
+
+void MineField::showMines()
+{
+ for ( int c = 0; c < numCols(); c++ )
+ for ( int r = 0; r < numRows(); r++ ) {
+ Mine* mine = (Mine*)item( r, c );
+ if ( !mine )
+ continue;
+ if ( mine->isMined() && mine->state() == Mine::Hidden )
+ mine->setState( Mine::Mined );
+ if ( !mine->isMined() && mine->state() == Mine::Flagged )
+ mine->setState( Mine::Wrong );
+
+ updateCell( r, c );
+ }
+}
+
+void MineField::paletteChange( const QPalette &o )
+{
+ Mine::paletteChange();
+ QTable::paletteChange( o );
+}
+
+void MineField::writeConfig(Config& cfg) const
+{
+ cfg.setGroup("Field");
+ cfg.writeEntry("Level",lev);
+ QString grid="";
+ if ( stat == Playing ) {
+ for ( int x = 0; x < numCols(); x++ )
+ for ( int y = 0; y < numRows(); y++ ) {
+ char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
+ Mine* mine = (Mine*)item( y, x );
+ int st = (int)mine->state(); if ( mine->isMined() ) st+=5;
+ grid += code + st;
+ }
+ }
+ cfg.writeEntry("Grid",grid);
+}
+
+void MineField::readConfig(Config& cfg)
+{
+ cfg.setGroup("Field");
+ lev = cfg.readNumEntry("Level",1);
+ setup(lev);
+ flagAction = NoAction;
+ ignoreClick = FALSE;
+ currRow = currCol = 0;
+ QString grid = cfg.readEntry("Grid");
+ if ( !grid.isEmpty() ) {
+ int i=0;
+ minecount=0;
+ mineguess=0;
+ for ( int x = 0; x < numCols(); x++ ) {
+ for ( int y = 0; y < numRows(); y++ ) {
+ char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
+ int st = (char)(QChar)grid[i++]-code;
+ Mine* mine = (Mine*)item( y, x );
+ if ( st >= 5 ) {
+ st-=5;
+ mine->setMined(TRUE);
+ minecount++;
+ mineguess++;
+ }
+ mine->setState((Mine::MineState)st);
+ switch ( mine->state() ) {
+ case Mine::Flagged:
+ if (mine->isMined())
+ minecount--;
+ mineguess--;
+ break;
+ case Mine::Empty:
+ --nonminecount;
+ }
+ }
+ }
+ for ( int x = 0; x < numCols(); x++ ) {
+ for ( int y = 0; y < numRows(); y++ ) {
+ Mine* mine = (Mine*)item( y, x );
+ if ( mine->state() == Mine::Empty )
+ mine->setHint(getHint(y,x));
+ }
+ }
+ }
+ setState( Playing );
+ emit mineCount( mineguess );
+}
+
diff --git a/noncore/games/minesweep/minefield.h b/noncore/games/minesweep/minefield.h
new file mode 100644
index 0000000..4ede435
--- a/dev/null
+++ b/noncore/games/minesweep/minefield.h
@@ -0,0 +1,87 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MINEFIELD_H
+#define MINEFIELD_H
+
+#include <qtable.h>
+
+class Mine;
+class Config;
+
+class MineField : public QTable
+{
+ Q_OBJECT
+public:
+ MineField( QWidget* parent = 0, const char* name = 0 );
+ ~MineField();
+
+ enum State { Waiting, Playing, GameOver };
+
+ State state() const { return stat; }
+
+ void readConfig(Config&);
+ void writeConfig(Config&) const;
+
+ int level() const { return lev; }
+
+public slots:
+ void setup( int level );
+
+ void showMines();
+
+signals:
+ void gameOver( bool won );
+ void gameStarted();
+ void mineCount( int );
+
+protected:
+ void paintFocus( QPainter*, const QRect& );
+ void viewportMousePressEvent( QMouseEvent* );
+ void viewportMouseReleaseEvent( QMouseEvent* );
+ void keyPressEvent( QKeyEvent* );
+ void keyReleaseEvent( QKeyEvent* );
+
+ int getHint( int row, int col );
+ void setHint( Mine* );
+ void updateMine( int row, int col );
+ void paletteChange( const QPalette & );
+
+protected slots:
+ void cellPressed( int row, int col );
+ void cellClicked( int row, int col );
+ void held();
+
+private:
+ State stat;
+ void MineField::setState( State st );
+ void MineField::placeMines();
+ enum FlagAction { NoAction, FlagOn, FlagNext };
+ FlagAction flagAction;
+ bool ignoreClick;
+ int currRow;
+ int currCol;
+ int minecount;
+ int mineguess;
+ int nonminecount;
+ int lev;
+ QTimer *holdTimer;
+};
+
+#endif // MINEFIELD_H
diff --git a/noncore/games/minesweep/minesweep.cpp b/noncore/games/minesweep/minesweep.cpp
new file mode 100644
index 0000000..6492462
--- a/dev/null
+++ b/noncore/games/minesweep/minesweep.cpp
@@ -0,0 +1,390 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "minesweep.h"
+#include "minefield.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qpe/qpetoolbar.h>
+#include <qpe/qpemenubar.h>
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qlcdnumber.h>
+#include <qmessagebox.h>
+#include <qtimer.h>
+#include <qpalette.h>
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+
+
+
+static const char *pix_new[]={
+"20 20 3 1",
+" c None",
+"# c #00FF00",
+". c #000000",
+" ",
+" ...... ",
+" ..######.. ",
+" .##########. ",
+" .############. ",
+" .##############. ",
+" .##############. ",
+" .################. ",
+" .################. ",
+" .################. ",
+" .################. ",
+" .################. ",
+" .################. ",
+" .##############. ",
+" .##############. ",
+" .############. ",
+" .##########. ",
+" ..######.. ",
+" ...... ",
+" "};
+
+
+/* XPM */
+static const char * happy_xpm[] = {
+"20 20 3 1",
+" c None",
+". c #ffff3f ",
+"# c #000000",
+" ",
+" ###### ",
+" ##......## ",
+" #..........# ",
+" #............# ",
+" #..............# ",
+" #..............# ",
+" #....##....##....# ",
+" #....##....##....# ",
+" #................# ",
+" #................# ",
+" #................# ",
+" #...#........#...# ",
+" #.##........##.# ",
+" #...########...# ",
+" #...######...# ",
+" #..........# ",
+" ##......## ",
+" ###### ",
+" "};
+
+
+/* XPM */
+static const char * worried_xpm[] = {
+"20 20 3 1",
+" c None",
+". c #ffff3f",
+"# c #000000",
+" ",
+" ###### ",
+" ##......## ",
+" #..........# ",
+" #............# ",
+" #..............# ",
+" #..............# ",
+" #....##....##....# ",
+" #....##....##....# ",
+" #................# ",
+" #................# ",
+" #................# ",
+" #................# ",
+" #....######....# ",
+" #..............# ",
+" #............# ",
+" #..........# ",
+" ##......## ",
+" ###### ",
+" "};
+
+
+/* XPM */
+static const char * dead_xpm[] = {
+"20 20 3 1",
+" c None",
+". c #ffff3f",
+"# c #000000",
+" ",
+" ###### ",
+" ##......## ",
+" #..........# ",
+" #............# ",
+" #..............# ",
+" #..#.#...#.#...# ",
+" #....#.....#.....# ",
+" #...#.#...#.#....# ",
+" #................# ",
+" #................# ",
+" #................# ",
+" #......####......# ",
+" #....# #....# ",
+" #...#......#...# ",
+" #............# ",
+" #..........# ",
+" ##......## ",
+" ###### ",
+" "};
+
+
+class ResultIndicator : private QLabel
+{
+public:
+ static void showResult( QWidget *ref, bool won );
+private:
+ ResultIndicator( QWidget *parent, const char *name, WFlags f)
+ :QLabel( parent, name, f ) {}
+
+ void timerEvent( QTimerEvent *);
+ void center();
+ bool twoStage;
+ int timerId;
+};
+
+void ResultIndicator::showResult( QWidget *ref, bool won )
+{
+ ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel );
+
+ r->setAlignment( AlignCenter );
+ r->setFrameStyle( Sunken|StyledPanel );
+ if ( won ) {
+ r->setText( MineSweep::tr("You won!") );
+ r->center();
+ r->show();
+ r->twoStage = FALSE;
+ r->timerId = r->startTimer(1500);
+ } else {
+ QPalette p( red );
+ r->setPalette( p );
+ r->setText( MineSweep::tr("You exploded!") );
+ r->resize( ref->size() );
+ r->move( ref->mapToGlobal(QPoint(0,0)) );
+ r->show();
+ r->twoStage = TRUE;
+ r->timerId =r->startTimer(200);
+ }
+}
+
+void ResultIndicator::center()
+{
+ QWidget *w = parentWidget();
+
+ QPoint pp = w->mapToGlobal( QPoint(0,0) );
+ QSize s = sizeHint()*3;
+ pp = QPoint( pp.x() + w->width()/2 - s.width()/2,
+ pp.y() + w->height()/ 2 - s.height()/2 );
+
+ setGeometry( QRect(pp, s) );
+
+}
+
+void ResultIndicator::timerEvent( QTimerEvent *te )
+{
+ if ( te->timerId() != timerId )
+ return;
+ killTimer( timerId );
+ if ( twoStage ) {
+ center();
+ twoStage = FALSE;
+ timerId = startTimer( 1000 );
+ } else {
+ delete this;
+ }
+}
+
+
+MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f )
+: QMainWindow( parent, name, f )
+{
+ srand(::time(0));
+ setCaption( tr("Mine Hunt") );
+ setIcon( Resource::loadPixmap( "minesweep_icon" ) );
+
+ QPEToolBar *menuToolBar = new QPEToolBar( this );
+ QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar );
+
+ QPopupMenu *gameMenu = new QPopupMenu( this );
+ gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) );
+ gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) );
+ gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) );
+
+ menuBar->insertItem( tr("Game"), gameMenu );
+
+ QPEToolBar *toolBar = new QPEToolBar( this );
+ toolBar->setHorizontalStretchable( TRUE );
+
+ guessLCD = new QLCDNumber( toolBar );
+ toolBar->setStretchableWidget( guessLCD );
+
+ QPalette lcdPal( red );
+ lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() );
+ lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() );
+
+// guessLCD->setPalette( lcdPal );
+ guessLCD->setSegmentStyle( QLCDNumber::Flat );
+ guessLCD->setFrameStyle( QFrame::NoFrame );
+ guessLCD->setNumDigits( 2 );
+ guessLCD->setBackgroundMode( PaletteButton );
+ newGameButton = new QPushButton( toolBar );
+ newGameButton->setPixmap( QPixmap( pix_new ) );
+ newGameButton->setFocusPolicy(QWidget::NoFocus);
+ connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) );
+
+ timeLCD = new QLCDNumber( toolBar );
+// timeLCD->setPalette( lcdPal );
+ timeLCD->setSegmentStyle( QLCDNumber::Flat );
+ timeLCD->setFrameStyle( QFrame::NoFrame );
+ timeLCD->setNumDigits( 5 ); // "mm:ss"
+ timeLCD->setBackgroundMode( PaletteButton );
+
+ setToolBarsMovable ( FALSE );
+
+ addToolBar( menuToolBar );
+ addToolBar( toolBar );
+
+ QFrame *mainframe = new QFrame( this );
+ mainframe->setFrameShape( QFrame::Box );
+ mainframe->setFrameShadow( QFrame::Raised );
+ mainframe->setMargin(5);
+ mainframe->setLineWidth(2);
+ QBoxLayout *box = new QVBoxLayout( mainframe );
+ field = new MineField( mainframe );
+ box->addWidget( field, 0, AlignCenter );
+ QFont fnt = field->font();
+ fnt.setBold( TRUE );
+ field->setFont( QFont( fnt ) );
+ field->setFocus();
+ setCentralWidget( mainframe );
+
+ connect( field, SIGNAL( gameOver( bool ) ), this, SLOT( gameOver( bool ) ) );
+ connect( field, SIGNAL( mineCount( int ) ), this, SLOT( setCounter( int ) ) );
+ connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) );
+
+ timer = new QTimer( this );
+
+ connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) );
+
+ readConfig();
+}
+
+MineSweep::~MineSweep()
+{
+ writeConfig();
+}
+
+void MineSweep::gameOver( bool won )
+{
+ field->showMines();
+ if ( won ) {
+ newGameButton->setPixmap( QPixmap( happy_xpm ) );
+ } else {
+ newGameButton->setPixmap( QPixmap( dead_xpm ) );
+ }
+ ResultIndicator::showResult( this, won );
+ timer->stop();
+}
+
+void MineSweep::newGame()
+{
+ newGame(field->level());
+}
+
+void MineSweep::newGame(int level)
+{
+ timeLCD->display( "0:00" );
+ field->setup( level );
+ newGameButton->setPixmap( QPixmap( pix_new ) );
+ timer->stop();
+}
+
+void MineSweep::startPlaying()
+{
+ newGameButton->setPixmap( QPixmap( worried_xpm ) );
+ starttime = QDateTime::currentDateTime();
+ timer->start( 1000 );
+}
+
+void MineSweep::beginner()
+{
+ newGame(1);
+}
+
+void MineSweep::advanced()
+{
+ newGame(2);
+}
+
+void MineSweep::expert()
+{
+ newGame(3);
+}
+
+void MineSweep::setCounter( int c )
+{
+ if ( !guessLCD )
+ return;
+
+ guessLCD->display( c );
+}
+
+void MineSweep::updateTime()
+{
+ if ( !timeLCD )
+ return;
+
+ int s = starttime.secsTo(QDateTime::currentDateTime());
+ if ( s/60 > 99 )
+ timeLCD->display( "-----" );
+ else
+ timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) );
+}
+
+void MineSweep::writeConfig() const
+{
+ Config cfg("MineSweep");
+ cfg.setGroup("Panel");
+ cfg.writeEntry("Time",
+ timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1);
+ field->writeConfig(cfg);
+}
+
+void MineSweep::readConfig()
+{
+ Config cfg("MineSweep");
+ field->readConfig(cfg);
+ cfg.setGroup("Panel");
+ int s = cfg.readNumEntry("Time",-1);
+ if ( s<0 ) {
+ newGame();
+ } else {
+ startPlaying();
+ starttime = QDateTime::currentDateTime().addSecs(-s);
+ updateTime();
+ }
+}
diff --git a/noncore/games/minesweep/minesweep.h b/noncore/games/minesweep/minesweep.h
new file mode 100644
index 0000000..e860573
--- a/dev/null
+++ b/noncore/games/minesweep/minesweep.h
@@ -0,0 +1,67 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MINESWEEP_H
+#define MINESWEEP_H
+
+#include <qmainwindow.h>
+#include <qdatetime.h>
+
+class MineField;
+class QLCDNumber;
+class QPushButton;
+
+class MineSweep : public QMainWindow
+{
+ Q_OBJECT
+public:
+ MineSweep( QWidget* parent = 0, const char* name = 0, WFlags f = 0 );
+ ~MineSweep();
+
+public slots:
+ void gameOver( bool won );
+ void newGame();
+
+protected slots:
+ void setCounter( int );
+ void updateTime();
+
+ void beginner();
+ void advanced();
+ void expert();
+
+private slots:
+ void startPlaying();
+
+private:
+ void readConfig();
+ void writeConfig() const;
+
+ void newGame(int);
+ MineField* field;
+ QLCDNumber* guessLCD;
+ QLCDNumber* timeLCD;
+ QPushButton* newGameButton;
+
+ QDateTime starttime;
+ QTimer* timer;
+};
+
+#endif // MINESWEEP_H
+
diff --git a/noncore/games/minesweep/minesweep.pro b/noncore/games/minesweep/minesweep.pro
new file mode 100644
index 0000000..87484bc
--- a/dev/null
+++ b/noncore/games/minesweep/minesweep.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = minefield.h \
+ minesweep.h
+SOURCES = main.cpp \
+ minefield.cpp \
+ minesweep.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
+
+TRANSLATIONS = ../i18n/de/minesweep.ts
diff --git a/noncore/games/minesweep/qpe-minesweep.control b/noncore/games/minesweep/qpe-minesweep.control
new file mode 100644
index 0000000..36bc221
--- a/dev/null
+++ b/noncore/games/minesweep/qpe-minesweep.control
@@ -0,0 +1,9 @@
+Files: bin/minesweep apps/Games/minesweep.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: find the mines
+ A game for the Qtopia environment.
diff --git a/noncore/games/parashoot/.cvsignore b/noncore/games/parashoot/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/games/parashoot/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/games/parashoot/Makefile.in b/noncore/games/parashoot/Makefile.in
new file mode 100644
index 0000000..ff7397e
--- a/dev/null
+++ b/noncore/games/parashoot/Makefile.in
@@ -0,0 +1,203 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = parashoot
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = interface.h \
+ man.h \
+ cannon.h \
+ base.h \
+ bullet.h \
+ helicopter.h
+SOURCES = main.cpp \
+ interface.cpp \
+ man.cpp \
+ cannon.cpp \
+ base.cpp \
+ bullet.cpp \
+ helicopter.cpp
+OBJECTS = main.o \
+ interface.o \
+ man.o \
+ cannon.o \
+ base.o \
+ bullet.o \
+ helicopter.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_interface.cpp \
+ moc_cannon.cpp \
+ moc_bullet.cpp
+OBJMOC = moc_interface.o \
+ moc_cannon.o \
+ moc_bullet.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake parashoot.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ interface.h \
+ cannon.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ base.h \
+ helicopter.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+interface.o: interface.cpp \
+ interface.h \
+ cannon.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ base.h \
+ helicopter.h \
+ man.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+man.o: man.cpp \
+ codes.h \
+ man.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ base.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+cannon.o: cannon.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ codes.h \
+ cannon.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h
+
+base.o: base.cpp \
+ codes.h \
+ base.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ man.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+bullet.o: bullet.cpp \
+ codes.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ man.h \
+ helicopter.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qmath.h
+
+helicopter.o: helicopter.cpp \
+ helicopter.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ man.h \
+ codes.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+moc_interface.o: moc_interface.cpp \
+ interface.h \
+ cannon.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ base.h \
+ helicopter.h
+
+moc_cannon.o: moc_cannon.cpp \
+ cannon.h \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h
+
+moc_bullet.o: moc_bullet.cpp \
+ bullet.h \
+ $(QPEDIR)/include/qpe/sound.h
+
+moc_interface.cpp: interface.h
+ $(MOC) interface.h -o moc_interface.cpp
+
+moc_cannon.cpp: cannon.h
+ $(MOC) cannon.h -o moc_cannon.cpp
+
+moc_bullet.cpp: bullet.h
+ $(MOC) bullet.h -o moc_bullet.cpp
+
+
diff --git a/noncore/games/parashoot/base.cpp b/noncore/games/parashoot/base.cpp
new file mode 100644
index 0000000..c03802f
--- a/dev/null
+++ b/noncore/games/parashoot/base.cpp
@@ -0,0 +1,71 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "codes.h"
+#include "base.h"
+#include "man.h"
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+int damage;
+
+Base::Base(QCanvas* canvas) :
+ QCanvasSprite(0, canvas),
+ kaboom("landmine"),
+ ohdear("crmble01")
+{
+ basearray = new QCanvasPixmapArray();
+ QString b0 = Resource::findPixmap("parashoot/b0001");
+ b0.replace(QRegExp("0001"),"%1");
+ basearray->readPixmaps(b0, 4);
+ setSequence(basearray);
+ setFrame(0);
+ move(2, canvas->height()-50);
+ setZ(10);
+ show();
+ damage = 0;
+}
+
+void Base::damageBase()
+{
+ damage++;
+
+ switch(damage) {
+ case 1: setFrame(1); ohdear.play(); break;
+ case 2: setFrame(2); ohdear.play(); break;
+ case 3: setFrame(3); kaboom.play(); break;
+ }
+ show();
+}
+
+bool Base::baseDestroyed()
+{
+ return (damage >= 3);
+}
+
+Base::~Base()
+{
+}
+
+int Base::rtti() const
+{
+ return base_rtti;
+}
diff --git a/noncore/games/parashoot/base.h b/noncore/games/parashoot/base.h
new file mode 100644
index 0000000..ee7f166
--- a/dev/null
+++ b/noncore/games/parashoot/base.h
@@ -0,0 +1,38 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/sound.h>
+
+#include <qcanvas.h>
+
+class Base : public QCanvasSprite
+{
+
+public:
+ Base(QCanvas*);
+ ~Base();
+ void damageBase();
+ int rtti() const;
+ static bool baseDestroyed();
+
+private:
+ QCanvasPixmapArray* basearray;
+ Sound kaboom, ohdear;
+};
diff --git a/noncore/games/parashoot/bullet.cpp b/noncore/games/parashoot/bullet.cpp
new file mode 100644
index 0000000..584f564
--- a/dev/null
+++ b/noncore/games/parashoot/bullet.cpp
@@ -0,0 +1,142 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "codes.h"
+#include "bullet.h"
+#include "man.h"
+#include "helicopter.h"
+
+#include <qpe/resource.h>
+#include <qpe/qmath.h>
+
+
+int limit;
+int shotcount;
+int nobullets;
+
+Bullet::Bullet(QCanvas* canvas, double angle, int cannonx, int cannony) :
+ QCanvasSprite(0, canvas),
+ bang("collide01")
+{
+ QCanvasPixmapArray* bulletarray = new QCanvasPixmapArray(Resource::findPixmap("parashoot/bullet"));
+ setSequence(bulletarray);
+ if (nobullets < limit) {
+ nobullets++;
+ move(cannonx, cannony);
+ dy = 0;
+ dx = 0;
+ show();
+ setXY(angle);
+ setVelocity(-dx, -dy);
+ bang.play();
+ } else
+ return;
+}
+
+void Bullet::setXY(double angle)
+{
+ double ang = angle;
+ if ( (y() < 0) || (x() < 0) || (y() > canvas()->height()) ||
+ (x() > canvas()->width()) )
+ delete this;
+ else {
+ double radians = 0;
+ radians = ang * 3.14159265/180;
+ dx = (qCos(radians)) *7;
+ dy = (qSin(radians)) *7;
+ }
+}
+
+void Bullet::setLimit(int amount)
+{
+ limit = amount;
+}
+
+void Bullet::setNobullets(int amount)
+{
+ nobullets = amount;
+}
+
+void Bullet::checkCollision()
+{
+ QCanvasItem* item;
+ QCanvasItemList l=collisions(FALSE);
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ if ( (item->rtti()== 1500) && (item->collidesWith(this)) ) {
+ Man* deadman = (Man*)item;
+ if (deadman->frame() != 5) return;
+ deadman->done();
+ emit score(10);
+ setShotCount(shotcount+1);
+ setAnimated(false);
+ nobullets--;
+ delete this;
+ return;
+ }
+ else if ( (item->rtti()==1900) && (item->collidesWith(this)) ) {
+ Helicopter* deadchopper = (Helicopter*) item;
+ deadchopper->done();
+ emit score(50);
+ setAnimated(false);
+ nobullets--;
+ delete this;
+ return;
+ }
+ }
+ //check shot is not out of bounds
+ if ( (y() < 0) || (x() < 0) ||
+ (y() > canvas()->height()) ||
+ ( x() > canvas()->width())) {
+ setAnimated(false);
+ nobullets--;
+ delete this;
+ return;
+ }
+}
+
+void Bullet::advance(int phase)
+{
+ QCanvasSprite::advance(phase);
+
+ if (phase == 0)
+ checkCollision();
+
+}
+
+int Bullet::getShotCount()
+{
+ return shotcount;
+}
+
+void Bullet::setShotCount(int amount)
+{
+ shotcount = amount;
+}
+
+Bullet::~Bullet()
+{
+
+}
+
+int Bullet::rtti() const
+{
+ return bullet_rtti;
+}
diff --git a/noncore/games/parashoot/bullet.h b/noncore/games/parashoot/bullet.h
new file mode 100644
index 0000000..7d15899
--- a/dev/null
+++ b/noncore/games/parashoot/bullet.h
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/sound.h>
+
+#include <qtimer.h>
+#include <qcanvas.h>
+
+#include <math.h>
+
+class Bullet : public QObject, public QCanvasSprite
+{
+ Q_OBJECT
+public:
+ Bullet(QCanvas*, double angle, int cannonx, int cannony);
+ ~Bullet();
+ void setXY(double angle);
+ void checkCollision();
+ void advance(int phase);
+ int rtti() const;
+ static int getShotCount();
+ static void setShotCount(int amount);
+ static void setLimit(int amount);
+ static void setNobullets(int amount);
+
+signals:
+ void score(int);
+
+private:
+ double dx;
+ double dy;
+ int damage;
+ Sound bang;
+};
diff --git a/noncore/games/parashoot/cannon.cpp b/noncore/games/parashoot/cannon.cpp
new file mode 100644
index 0000000..3c0a5fe
--- a/dev/null
+++ b/noncore/games/parashoot/cannon.cpp
@@ -0,0 +1,140 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+#include "codes.h"
+#include "cannon.h"
+
+Cannon::Cannon(QCanvas* canvas) :
+ QCanvasSprite(0, canvas)
+{
+shotsfired=0;
+ index = 8;
+ cannonx = 0;
+ cannony = 0;
+ cannonarray = new QCanvasPixmapArray();
+ QString c0 = Resource::findPixmap("parashoot/can0001");
+ c0.replace(QRegExp("0001"),"%1");
+ cannonarray->readPixmaps(c0,17);
+ setSequence(cannonarray);
+ setFrame(index);
+ move(canvas->width()/2-20, canvas->height()-32);
+ // co ords for barrel of cannon when upright
+ barrelypos = canvas->height()-32;
+ barrelxpos = canvas->width()/2;
+ movedir = NoDir;
+ moveDelay = 0;
+ setAnimated(TRUE);
+ show();
+}
+
+void Cannon::advance(int stage)
+{
+ if ( stage == 1 && moveDelay-- == 0 ) {
+ if (movedir == Left) {
+ if (index > 0) {
+ setFrame(index-1);
+ index--;
+ }
+ }
+ if (movedir == Right) {
+ if (index < 16) {
+ setFrame(index+1);
+ index++;
+ }
+ }
+ moveDelay = 0;
+ }
+}
+
+void Cannon::pointCannon(Direction dir)
+{
+ movedir = dir;
+ moveDelay = 0;
+ advance(1);
+ moveDelay = 1;
+}
+
+void Cannon::setCoords()
+{
+ switch(index) {
+ case 0: cannonx = barrelxpos-29; cannony = barrelypos-8; break;
+ case 1: cannonx = barrelxpos-27; cannony = barrelypos-8; break;
+ case 2: cannonx = barrelxpos-25; cannony = barrelypos-6; break;
+ case 3: cannonx = barrelxpos-23; cannony = barrelypos-4; break;
+ case 4: cannonx = barrelxpos-21; cannony = barrelypos-2; break;
+ case 5: cannonx = barrelxpos-19; cannony = barrelypos; break;
+ case 6: cannonx = barrelxpos-15; cannony = barrelypos; break;
+ case 7: cannonx = barrelxpos-10; cannony = barrelypos; break;
+ case 8: cannonx = barrelxpos; cannony = barrelypos; break;
+ case 9: cannonx = barrelxpos+2; cannony = barrelypos; break;
+ case 10: cannonx = barrelxpos+6; cannony = barrelypos; break;
+ case 11: cannonx = barrelxpos+8; cannony = barrelypos; break;
+ case 12: cannonx = barrelxpos+12; cannony = barrelypos-2; break;
+ case 13: cannonx = barrelxpos+18; cannony = barrelypos-4; break;
+ case 14: cannonx = barrelxpos+22; cannony = barrelypos-6; break;
+ case 15: cannonx = barrelxpos+26; cannony = barrelypos-8; break;
+ case 16: cannonx = barrelxpos+28; cannony = barrelypos-8; break;
+ }
+}
+
+double Cannon::shootAngle()
+{
+ switch(index) {
+ case 0: return 30.0;
+ case 1: return 37.5;
+ case 2: return 45.0;
+ case 3: return 52.5;
+ case 4: return 60.0;
+ case 5: return 67.5;
+ case 6: return 75.0;
+ case 7: return 82.5;
+ case 8: return 90.0;
+ case 9: return 97.5;
+ case 10: return 105.0;
+ case 11: return 112.5;
+ case 12: return 120.0;
+ case 13: return 127.5;
+ case 14: return 135.0;
+ case 15: return 142.5;
+ case 16: return 150.0;
+ }
+ return 0;
+}
+
+void Cannon::shoot()
+{
+ setCoords();
+ Bullet* bullet = new Bullet(canvas(), shootAngle(), cannonx, cannony);
+ connect(bullet, SIGNAL(score(int)), this, SIGNAL(score(int)));
+ shotsfired++;
+}
+
+Cannon::~Cannon()
+{
+}
+
+int Cannon::rtti() const
+{
+ return cannon_rtti;
+}
diff --git a/noncore/games/parashoot/cannon.h b/noncore/games/parashoot/cannon.h
new file mode 100644
index 0000000..44d0c65
--- a/dev/null
+++ b/noncore/games/parashoot/cannon.h
@@ -0,0 +1,58 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qcanvas.h>
+
+#include "bullet.h"
+
+class Cannon : public QObject, public QCanvasSprite
+{
+ Q_OBJECT
+
+public:
+ Cannon(QCanvas*); //create cannon
+ ~Cannon(); //destroy cannon
+
+ enum Direction{ Left, Right, NoDir };
+
+ void pointCannon(Direction dir);
+ void setCoords();
+ double shootAngle();
+ void shoot();
+ int rtti() const;
+
+int shotsFired() { return shotsfired; };
+
+protected:
+ void advance(int stage);
+
+signals:
+ void score(int);
+
+private:
+ QCanvasPixmapArray* cannonarray;
+ int index;
+ int cannonx;
+ int cannony;
+ int barrelxpos;
+ int barrelypos;
+ int moveDelay;
+ Direction movedir;
+ int shotsfired;
+};
diff --git a/noncore/games/parashoot/codes.h b/noncore/games/parashoot/codes.h
new file mode 100644
index 0000000..68acb3f
--- a/dev/null
+++ b/noncore/games/parashoot/codes.h
@@ -0,0 +1,25 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+const int man_rtti = 1500;
+const int bullet_rtti = 1600;
+const int cannon_rtti = 1700;
+const int base_rtti = 1800;
+const int helicopter_rtti = 1900;
diff --git a/noncore/games/parashoot/helicopter.cpp b/noncore/games/parashoot/helicopter.cpp
new file mode 100644
index 0000000..0923124
--- a/dev/null
+++ b/noncore/games/parashoot/helicopter.cpp
@@ -0,0 +1,114 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "helicopter.h"
+#include "man.h"
+#include "codes.h"
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+static QList<Helicopter> all;
+
+Helicopter::Helicopter(QCanvas* canvas) :
+ QCanvasSprite(0, canvas),
+ chikachika("aland01")
+{
+ all.append(this);
+ hits = 0;
+ QCanvasPixmapArray* helicopterarray = new QCanvasPixmapArray();
+ QString h0 = Resource::findPixmap("parashoot/helicopter0001");
+ h0.replace(QRegExp("0001"),"%1");
+ helicopterarray->readPixmaps(h0,3 );
+ setSequence(helicopterarray);
+ setAnimated(true);
+ move(canvas->width(), 5);
+ setVelocity(-2, 0);
+ chikachika.playLoop();
+ show();
+}
+
+Helicopter::~Helicopter()
+{
+ all.remove(this);
+}
+
+int fr = 0;
+
+void Helicopter::advance(int phase)
+{
+ QCanvasSprite::advance(phase);
+ if (phase == 0) {
+ setFrame(fr%3);
+ fr++;
+ checkCollision();
+ }
+}
+
+void Helicopter::checkCollision()
+{
+ if (x() == 6) {
+ setAnimated(false); //setVelocity(0, 0);
+ dropman();
+ }
+ if (x() < 0)
+ done();
+}
+
+void Helicopter::dropman()
+{
+ (void)new Man(canvas(), 15, 25);
+ (void)new Man(canvas(), 35, 25);
+ takeOff();
+}
+
+void Helicopter::done()
+{
+ hits++;
+ if (hits >= 2) {
+ setAnimated(false);
+ delete this;
+ }
+}
+
+void Helicopter::takeOff()
+{
+ setVelocity(-1, 0);
+}
+
+int Helicopter::rtti() const
+{
+ return helicopter_rtti;
+}
+
+void Helicopter::silenceAll()
+{
+ for (Helicopter* h = all.first(); h; h = all.next())
+ h->chikachika.stop();
+}
+
+void Helicopter::deleteAll()
+{
+ Helicopter* h;
+ while ((h = all.first()))
+ delete h;
+}
+
diff --git a/noncore/games/parashoot/helicopter.h b/noncore/games/parashoot/helicopter.h
new file mode 100644
index 0000000..5cb92de
--- a/dev/null
+++ b/noncore/games/parashoot/helicopter.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/sound.h>
+
+#include <qcanvas.h>
+
+class Helicopter : public QCanvasSprite
+{
+
+public:
+ Helicopter(QCanvas*);
+ ~Helicopter();
+ void advance(int phase);
+ void checkCollision();
+ void dropman();
+ void takeOff();
+ void done();
+
+ static void silenceAll();
+ static void deleteAll();
+
+ int rtti() const;
+
+private:
+ int hits;
+ Sound chikachika;
+};
diff --git a/noncore/games/parashoot/interface.cpp b/noncore/games/parashoot/interface.cpp
new file mode 100644
index 0000000..84e5e60
--- a/dev/null
+++ b/noncore/games/parashoot/interface.cpp
@@ -0,0 +1,247 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "interface.h"
+#include "man.h"
+
+#include <qpe/resource.h>
+
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qapplication.h>
+#include <qstyle.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+
+ParaShoot::ParaShoot(QWidget* parent, const char* name, WFlags f) :
+ QMainWindow(parent,name,f),
+ canvas(232, 258),
+ fanfare("level_up"),
+ score(0)
+{
+ canvas.setAdvancePeriod(80);
+ QPixmap bg = Resource::loadPixmap("parashoot/sky");
+ canvas.setBackgroundPixmap(bg);
+
+ pb = new QCanvasView(&canvas, this);
+ pb->setFocus();
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar* toolbar = new QPEToolBar(this);
+ toolbar->setHorizontalStretchable( TRUE );
+
+ setCaption( tr("ParaShoot") );
+ QPixmap newicon = Resource::loadPixmap("parashoot/manicon");
+ setIcon(newicon);
+ new QToolButton(newicon, tr("New Game"), 0,
+ this, SLOT(newGame()), toolbar, "New Game");
+
+ levelscore = new QLabel(toolbar);
+ levelscore->setBackgroundMode( PaletteButton );
+ levelscore->setAlignment( AlignRight | AlignVCenter | ExpandTabs );
+ toolbar->setStretchableWidget( levelscore );
+ showScore(0,0);
+
+ setCentralWidget(pb);
+
+ autoDropTimer = new QTimer(this);
+ connect (autoDropTimer, SIGNAL(timeout()), this, SLOT(play()) );
+
+ pauseTimer = new QTimer(this);
+ connect(pauseTimer, SIGNAL(timeout()), this, SLOT(wait()) );
+
+ setFocusPolicy(StrongFocus);
+
+ newGame();
+}
+
+
+void ParaShoot::resizeEvent(QResizeEvent *)
+{
+ QSize s = centralWidget()->size();
+ int fw = style().defaultFrameWidth();
+ canvas.resize( s.width() - fw - 2, s.height() - fw - 2);
+}
+
+
+void ParaShoot::showScore( int score, int level )
+{
+ levelscore->setText(tr(" Level: %1 Score: %2 ").arg(score).arg(level) );
+}
+
+
+void ParaShoot::newGame()
+{
+ clear();
+ if (pauseTimer->isActive())
+ pauseTimer->stop();
+ clear();
+ Man::setManCount(0);
+ score = 0;
+ Bullet::setShotCount(0);
+ Bullet::setNobullets(0);
+ nomen = 2;
+ Bullet::setLimit(nomen);
+ level = 0;
+ updatespeed = 80;
+ showScore(0,0);
+ gamestopped = false;
+ Helicopter::deleteAll();
+ waitover = true;
+ base = new Base(&canvas);
+ cannon = new Cannon(&canvas);
+ connect( cannon, SIGNAL(score(int)), this, SLOT(increaseScore(int)));
+ autoDropTimer->start(100);
+}
+
+
+void ParaShoot::clear()
+{
+ autoDropTimer->stop();
+// QCanvasItem* item;
+ QCanvasItemList l = canvas.allItems();
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ delete *it;
+ }
+}
+
+void ParaShoot::gameOver()
+{
+ QCanvasItem* item;
+ QCanvasItemList l = canvas.allItems();
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ if ((item->rtti()==1500) || (item->rtti()==1600) || item->rtti()==1900)
+ item->setAnimated(false);
+ }
+ autoDropTimer->stop();
+ Helicopter::silenceAll();
+
+ int shots = Bullet::getShotCount();
+
+ int shotsFired = cannon->shotsFired();
+ if ( shotsFired == 0 )
+ shotsFired = 1;
+ QCanvasText* gameover = new QCanvasText(
+ tr( " GAME OVER!\n"
+ " Your Score: %1\n"
+ " Parachuters Killed: %2\n"
+ " Accuracy: %3% " ).arg(score).arg(shots).arg(shots * 100 / shotsFired ),
+ &canvas);
+ gameover->setColor(red);
+ gameover->setFont( QFont("times", 18, QFont::Bold) );
+ gameover->move(canvas.width()/2 -110, canvas.height()/2 -50);
+ gameover->setZ(500);
+ gameover->show();
+ gamestopped = true;
+ waitover = false;
+ pauseTimer->start(3000);
+}
+
+void ParaShoot::wait()
+{
+ waitover = true;
+ pauseTimer->stop();
+}
+
+void ParaShoot::play()
+{
+ if (Man::getManCount() < nomen ) {
+ new Man(&canvas);
+ }
+ if (Base::baseDestroyed()) {
+ gameOver();
+ return;
+ }
+}
+
+void ParaShoot::increaseScore(int x)
+{
+ score += x;
+ if ( score / 150 != (score-x) / 150 )
+ levelUp();
+ showScore(level,score);
+}
+
+void ParaShoot::levelUp()
+{
+ level++;
+ int stage = level % 3;
+ switch(stage) {
+ case 0:
+ nomen++;
+ Bullet::setLimit(nomen);
+ fanfare.play();
+ break;
+ case 1:
+ new Helicopter(&canvas);
+ break;
+ case 2:
+ moveFaster();
+ fanfare.play();
+ break;
+ default: return;
+ }
+}
+
+void ParaShoot::moveFaster()
+{
+ if (updatespeed > 50)
+ updatespeed = updatespeed-5;
+ else
+ updatespeed = updatespeed-3;
+ canvas.setAdvancePeriod(updatespeed);
+}
+
+void ParaShoot::keyPressEvent(QKeyEvent* event)
+{
+ if (gamestopped) {
+ if (waitover)
+ newGame();
+ else
+ return;
+ } else {
+ switch(event->key()) {
+ case Key_Up:
+ case Key_F1:
+ case Key_F9:
+ case Key_Space:
+ cannon->shoot();
+ break;
+ case Key_Left:
+ cannon->pointCannon(Cannon::Left);
+ lastcannonkey=Key_Left;
+ break;
+ case Key_Right:
+ cannon->pointCannon(Cannon::Right);
+ lastcannonkey=Key_Right;
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+void ParaShoot::keyReleaseEvent(QKeyEvent* event)
+{
+ if ( lastcannonkey == event->key() )
+ cannon->pointCannon(Cannon::NoDir);
+}
diff --git a/noncore/games/parashoot/interface.h b/noncore/games/parashoot/interface.h
new file mode 100644
index 0000000..3f36d0b
--- a/dev/null
+++ b/noncore/games/parashoot/interface.h
@@ -0,0 +1,79 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cannon.h"
+#include "base.h"
+#include "helicopter.h"
+
+#include <qpe/sound.h>
+
+#include <qmainwindow.h>
+#include <qtimer.h>
+#include <qlabel.h>
+
+class QCanvas;
+class Helicopter;
+
+//enum Direction{
+// left, right, up, down };
+
+class ParaShoot : public QMainWindow {
+ Q_OBJECT
+
+public:
+ ParaShoot(QWidget* parent=0, const char* name=0, WFlags f=0);
+
+ void clear();
+ void gameOver();
+ int mancount;
+ void levelUp();
+ void moveFaster();
+
+protected:
+ virtual void keyPressEvent(QKeyEvent*);
+ virtual void keyReleaseEvent(QKeyEvent*);
+ virtual void resizeEvent(QResizeEvent *e);
+
+private slots:
+ void increaseScore(int);
+ void newGame();
+ void play();
+ void wait();
+
+private:
+ void showScore( int score, int level );
+ QCanvasView* pb;
+ QCanvas canvas;
+ Cannon* cannon;
+ Base* base;
+ QCanvasText* gameover;
+ QLabel* levelscore;
+ int nomen;
+ int level;
+ int oldscore;
+ int updatespeed;
+ QTimer* autoDropTimer;
+ QTimer* pauseTimer;
+ bool gamestopped;
+ bool waitover;
+ Sound fanfare;
+ int score;
+ int lastcannonkey;
+};
diff --git a/noncore/games/parashoot/main.cpp b/noncore/games/parashoot/main.cpp
new file mode 100644
index 0000000..60eea18
--- a/dev/null
+++ b/noncore/games/parashoot/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "interface.h"
+
+#include <qpe/qpeapplication.h>
+
+int main(int argc, char **argv)
+{
+ QPEApplication app(argc,argv);
+
+ QPEApplication::grabKeyboard();
+
+ ParaShoot m;
+ QPEApplication::setInputMethodHint( &m, QPEApplication::AlwaysOff );
+ app.showMainWidget(&m);
+
+ return app.exec();
+}
diff --git a/noncore/games/parashoot/man.cpp b/noncore/games/parashoot/man.cpp
new file mode 100644
index 0000000..8435572
--- a/dev/null
+++ b/noncore/games/parashoot/man.cpp
@@ -0,0 +1,174 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "codes.h"
+#include "man.h"
+#include "base.h"
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+int mancount;
+
+Man::Man(QCanvas* canvas) :
+ QCanvasSprite(0, canvas),
+ splat("lose")
+{
+ manarray = new QCanvasPixmapArray();
+ QString m0 = Resource::findPixmap("parashoot/man0001");
+ m0.replace(QRegExp("0001"),"%1");
+ manarray->readPixmaps(m0, 7);
+ setSequence(manarray);
+ setAnimated(true);
+ mancount++;
+ dead = false;
+ start();
+}
+
+Man::Man(QCanvas* canvas, int x, int y) :
+ QCanvasSprite(0, canvas),
+ splat("bang")
+{
+ manarray = new QCanvasPixmapArray();
+ QString m0 = Resource::findPixmap("parashoot/man0001");
+ m0.replace(QString("0001"),"%1");
+ manarray->readPixmaps(m0, 7);
+ setSequence(manarray);
+ move(x, y);
+ setFrame(5);
+ setZ(300);
+ show();
+
+ static bool first_time = TRUE;
+ if (first_time) {
+ first_time = FALSE;
+ QTime midnight(0, 0, 0);
+ srand(midnight.secsTo(QTime::currentTime()) );
+ }
+ int yfallspeed = 0;
+ yfallspeed = (rand() % 3) + 1;
+ setVelocity(0, yfallspeed);
+
+ mancount++;
+ dead = false;
+}
+int f = 0;
+
+void Man::advance(int phase)
+{
+ QCanvasSprite::advance(phase);
+ if (phase == 0) {
+ checkCollision();
+ if (dead) {
+ if (count < 10) {
+ setFrame(6);
+ setVelocity(0,0);
+ count++;
+ } else {
+ delete this;
+ return;
+ }
+ }
+ if (y() > canvas()->height()-43) {
+ setFrame(f%5);
+ f++;
+ move(x(), canvas()->height()-26);
+ setVelocity(-2, 0);
+ }
+ }
+}
+
+void Man::setInitialCoords()
+{
+ static bool first_time = TRUE;
+ if (first_time) {
+ first_time = FALSE;
+ QTime midnight(0, 0, 0);
+ srand(midnight.secsTo(QTime::currentTime()) );
+ }
+ dx = rand() % (canvas()->width()-16);
+ dy = -43; //height of a man off the screen
+}
+
+//check if man has reached the base
+void Man::checkCollision()
+{
+ if ( (x() < 23) && (y() == canvas()->height()-26)) {
+ QCanvasItem* item;
+ QCanvasItemList l=collisions(FALSE);
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ if ( (item->rtti()== 1800) && (item->collidesWith(this)) ) {
+ Base* base = (Base*) item;
+ base->damageBase();
+ start();
+ }
+ }
+ }
+}
+
+void Man::start()
+{
+ setInitialCoords();
+ move(dx, dy);
+ setFrame(5);
+ setZ(300);
+ show();
+
+ static bool first_time = TRUE;
+ if (first_time) {
+ first_time = FALSE;
+ QTime midnight(0, 0, 0);
+ srand(midnight.secsTo(QTime::currentTime()) );
+ }
+ int yfallspeed = 0;
+ yfallspeed = (rand() % 3) + 1;
+ setVelocity(0, yfallspeed);
+}
+
+void Man::done()
+{
+ splat.play();
+ count = 0;
+ dead = true;
+ setFrame(6);
+}
+
+int Man::getManCount()
+{
+ return mancount;
+}
+
+void Man::setManCount(int count)
+{
+ mancount = count;
+}
+
+
+int Man::rtti() const
+{
+ return man_rtti;
+}
+
+Man::~Man()
+{
+ mancount--;
+}
diff --git a/noncore/games/parashoot/man.h b/noncore/games/parashoot/man.h
new file mode 100644
index 0000000..e48fc20
--- a/dev/null
+++ b/noncore/games/parashoot/man.h
@@ -0,0 +1,52 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/sound.h>
+
+#include <qcanvas.h>
+#include <qdatetime.h>
+
+#include <stdlib.h>
+
+class Man : public QCanvasSprite
+{
+
+public:
+ Man (QCanvas*);
+ Man (QCanvas*, int x, int y);
+ ~Man();
+ void advance(int phase);
+ void setInitialCoords();
+ void checkCollision();
+ void start();
+ void done();
+ static int getManCount();
+ static void setManCount(int count);
+ int rtti() const;
+// int mancount;
+
+private:
+ QCanvasPixmapArray* manarray;
+ int dx;
+ int dy;
+ bool dead;
+ int count;
+ Sound splat;
+};
diff --git a/noncore/games/parashoot/parashoot.pro b/noncore/games/parashoot/parashoot.pro
new file mode 100644
index 0000000..631560b
--- a/dev/null
+++ b/noncore/games/parashoot/parashoot.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = interface.h man.h cannon.h base.h bullet.h helicopter.h
+SOURCES = main.cpp interface.cpp man.cpp cannon.cpp base.cpp bullet.cpp helicopter.cpp
+TARGET = parashoot
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/parashoot.ts
diff --git a/noncore/games/parashoot/qpe-parashoot.control b/noncore/games/parashoot/qpe-parashoot.control
new file mode 100644
index 0000000..82e9421
--- a/dev/null
+++ b/noncore/games/parashoot/qpe-parashoot.control
@@ -0,0 +1,9 @@
+Files: bin/parashoot apps/Games/parashoot.desktop pics/parashoot
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: shoot the parachutists
+ A game for the Qtopia environment.
diff --git a/noncore/games/qasteroids/.cvsignore b/noncore/games/qasteroids/.cvsignore
new file mode 100644
index 0000000..c152c55
--- a/dev/null
+++ b/noncore/games/qasteroids/.cvsignore
@@ -0,0 +1,2 @@
+moc_*.cpp
+Makefile
diff --git a/noncore/games/qasteroids/Makefile.in b/noncore/games/qasteroids/Makefile.in
new file mode 100644
index 0000000..7312743
--- a/dev/null
+++ b/noncore/games/qasteroids/Makefile.in
@@ -0,0 +1,155 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = qasteroids
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = ledmeter.h \
+ sprites.h \
+ toplevel.h \
+ view.h
+SOURCES = ledmeter.cpp \
+ toplevel.cpp \
+ view.cpp \
+ main.cpp
+OBJECTS = ledmeter.o \
+ toplevel.o \
+ view.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_ledmeter.cpp \
+ moc_toplevel.cpp \
+ moc_view.cpp
+OBJMOC = moc_ledmeter.o \
+ moc_toplevel.o \
+ moc_view.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake qasteroids.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+ledmeter.o: ledmeter.cpp \
+ ledmeter.h
+
+toplevel.o: toplevel.cpp \
+ toplevel.h \
+ view.h \
+ sprites.h \
+ ledmeter.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+view.o: view.cpp \
+ view.h \
+ sprites.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+main.o: main.cpp \
+ toplevel.h \
+ view.h \
+ sprites.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_ledmeter.o: moc_ledmeter.cpp \
+ ledmeter.h
+
+moc_toplevel.o: moc_toplevel.cpp \
+ toplevel.h \
+ view.h \
+ sprites.h
+
+moc_view.o: moc_view.cpp \
+ view.h \
+ sprites.h
+
+moc_ledmeter.cpp: ledmeter.h
+ $(MOC) ledmeter.h -o moc_ledmeter.cpp
+
+moc_toplevel.cpp: toplevel.h
+ $(MOC) toplevel.h -o moc_toplevel.cpp
+
+moc_view.cpp: view.h
+ $(MOC) view.h -o moc_view.cpp
+
+
diff --git a/noncore/games/qasteroids/ledmeter.cpp b/noncore/games/qasteroids/ledmeter.cpp
new file mode 100644
index 0000000..f4d4d1a
--- a/dev/null
+++ b/noncore/games/qasteroids/ledmeter.cpp
@@ -0,0 +1,135 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#include <qpainter.h>
+#include "ledmeter.h"
+
+KALedMeter::KALedMeter( QWidget *parent ) : QFrame( parent )
+{
+ mCRanges.setAutoDelete( TRUE );
+ mRange = 100;
+ mCount = 20;
+ mCurrentCount = 0;
+ mValue = 0;
+ setMinimumWidth( mCount * 2 + frameWidth() );
+}
+
+void KALedMeter::setRange( int r )
+{
+ mRange = r;
+ if ( mRange < 1 )
+ mRange = 1;
+ setValue( mValue );
+ update();
+}
+
+void KALedMeter::setCount( int c )
+{
+ mCount = c;
+ if ( mCount < 1 )
+ mCount = 1;
+ setMinimumWidth( mCount * 2 + frameWidth() );
+ calcColorRanges();
+ setValue( mValue );
+ update();
+}
+
+void KALedMeter::setValue( int v )
+{
+ mValue = v;
+ if ( mValue > mRange )
+ mValue = mRange;
+ else if ( mValue < 0 )
+ mValue = 0;
+ int c = ( mValue + mRange / mCount - 1 ) * mCount / mRange;
+ if ( c != mCurrentCount )
+ {
+ mCurrentCount = c;
+ update();
+ }
+}
+
+void KALedMeter::addColorRange( int pc, const QColor &c )
+{
+ ColorRange *cr = new ColorRange;
+ cr->mPc = pc;
+ cr->mColor = c;
+ mCRanges.append( cr );
+ calcColorRanges();
+}
+
+void KALedMeter::resizeEvent( QResizeEvent *e )
+{
+ QFrame::resizeEvent( e );
+ int w = ( width() - frameWidth() - 2 ) / mCount * mCount;
+ w += frameWidth() + 2;
+ setFrameRect( QRect( 0, 0, w, height() ) );
+}
+
+void KALedMeter::drawContents( QPainter *p )
+{
+ QRect b = contentsRect();
+
+ unsigned cidx = 0;
+ int ncol = mCount;
+ QColor col = colorGroup().foreground();
+
+ if ( !mCRanges.isEmpty() )
+ {
+ col = mCRanges.at( cidx )->mColor;
+ ncol = mCRanges.at( cidx )->mValue;
+ }
+ p->setBrush( col );
+ p->setPen( col );
+
+ int lw = b.width() / mCount;
+ int lx = b.left() + 1;
+ for ( int i = 0; i < mCurrentCount; i++, lx += lw )
+ {
+ if ( i > ncol )
+ {
+ if ( ++cidx < mCRanges.count() )
+ {
+ col = mCRanges.at( cidx )->mColor;
+ ncol = mCRanges.at( cidx )->mValue;
+ p->setBrush( col );
+ p->setPen( col );
+ }
+ }
+
+ p->drawRect( lx, b.top() + 1, lw - 1, b.height() - 2 );
+ }
+}
+
+void KALedMeter::calcColorRanges()
+{
+ int prev = 0;
+ ColorRange *cr;
+ for ( cr = mCRanges.first(); cr; cr = mCRanges.next() )
+ {
+ cr->mValue = prev + cr->mPc * mCount / 100;
+ prev = cr->mValue;
+ }
+}
+
diff --git a/noncore/games/qasteroids/ledmeter.h b/noncore/games/qasteroids/ledmeter.h
new file mode 100644
index 0000000..b2f06c1
--- a/dev/null
+++ b/noncore/games/qasteroids/ledmeter.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#ifndef __LEDMETER_H__
+#define __LEDMETER_H__
+
+#include <qframe.h>
+#include <qlist.h>
+
+#define QPtrList QList
+
+class KALedMeter : public QFrame
+{
+ Q_OBJECT
+public:
+ KALedMeter( QWidget *parent );
+
+ int range() const { return mRange; }
+ void setRange( int r );
+
+ int count() const { return mCount; }
+ void setCount( int c );
+
+ int value () const { return mValue; }
+
+ void addColorRange( int pc, const QColor &c );
+
+public slots:
+ void setValue( int v );
+
+protected:
+ virtual void resizeEvent( QResizeEvent * );
+ virtual void drawContents( QPainter * );
+ void calcColorRanges();
+
+protected:
+ struct ColorRange
+ {
+ int mPc;
+ int mValue;
+ QColor mColor;
+ };
+
+ int mRange;
+ int mCount;
+ int mCurrentCount;
+ int mValue;
+ QPtrList<ColorRange> mCRanges;
+};
+
+#endif
diff --git a/noncore/games/qasteroids/main.cpp b/noncore/games/qasteroids/main.cpp
new file mode 100644
index 0000000..7d1682c
--- a/dev/null
+++ b/noncore/games/qasteroids/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "toplevel.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char *argv[] )
+{
+ QPEApplication app( argc, argv );
+
+ QPEApplication::grabKeyboard();
+
+ KAstTopLevel *mainWidget = new KAstTopLevel();
+ app.showMainWidget( mainWidget );
+
+ app.exec();
+}
+
diff --git a/noncore/games/qasteroids/qasteroids.pro b/noncore/games/qasteroids/qasteroids.pro
new file mode 100644
index 0000000..14a0901
--- a/dev/null
+++ b/noncore/games/qasteroids/qasteroids.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = ledmeter.h sprites.h toplevel.h view.h
+SOURCES = ledmeter.cpp toplevel.cpp view.cpp main.cpp
+TARGET = qasteroids
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/qasteroids.ts
diff --git a/noncore/games/qasteroids/qpe-qasteroids.control b/noncore/games/qasteroids/qpe-qasteroids.control
new file mode 100644
index 0000000..c1b328e
--- a/dev/null
+++ b/noncore/games/qasteroids/qpe-qasteroids.control
@@ -0,0 +1,9 @@
+Files: bin/qasteroids apps/Games/qasteroids.desktop pics/qasteroids pics/Asteroids.png
+Priority: optional
+Section: qpe/games
+Maintainer: Martin Jones <mjones@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: shoot the asteroids
+ A game for the Qtopia environment.
diff --git a/noncore/games/qasteroids/sprites.h b/noncore/games/qasteroids/sprites.h
new file mode 100644
index 0000000..0827821
--- a/dev/null
+++ b/noncore/games/qasteroids/sprites.h
@@ -0,0 +1,147 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#ifndef __SPRITES_H__
+#define __SPRITES_H__
+
+#include <qcanvas.h>
+
+#define ID_ROCK_LARGE 1024
+#define ID_ROCK_MEDIUM 1025
+#define ID_ROCK_SMALL 1026
+
+#define ID_MISSILE 1030
+
+#define ID_BIT 1040
+#define ID_EXHAUST 1041
+
+#define ID_ENERGY_POWERUP 1310
+#define ID_TELEPORT_POWERUP 1311
+#define ID_BRAKE_POWERUP 1312
+#define ID_SHIELD_POWERUP 1313
+#define ID_SHOOT_POWERUP 1314
+
+#define ID_SHIP 1350
+#define ID_SHIELD 1351
+
+#define MAX_SHIELD_AGE 350
+#define MAX_POWERUP_AGE 500
+#define MAX_MISSILE_AGE 20
+
+class KMissile : public QCanvasSprite
+{
+public:
+ KMissile( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c )
+ { myAge = 0; }
+
+ virtual int rtti() const { return ID_MISSILE; }
+
+ void growOlder() { myAge++; }
+ bool expired() { return myAge > MAX_MISSILE_AGE; }
+
+private:
+ int myAge;
+};
+
+class KBit : public QCanvasSprite
+{
+public:
+ KBit( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c )
+ { death = 7; }
+
+ virtual int rtti() const { return ID_BIT; }
+
+ void setDeath( int d ) { death = d; }
+ void growOlder() { death--; }
+ bool expired() { return death <= 0; }
+
+private:
+ int death;
+};
+
+class KExhaust : public QCanvasSprite
+{
+public:
+ KExhaust( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c )
+ { death = 1; }
+
+ virtual int rtti() const { return ID_EXHAUST; }
+
+ void setDeath( int d ) { death = d; }
+ void growOlder() { death--; }
+ bool expired() { return death <= 0; }
+
+private:
+ int death;
+};
+
+class KPowerup : public QCanvasSprite
+{
+public:
+ KPowerup( QCanvasPixmapArray *s, QCanvas *c, int t ) : QCanvasSprite( s, c ),
+ myAge( 0 ), type(t) { }
+
+ virtual int rtti() const { return type; }
+
+ void growOlder() { myAge++; }
+ bool expired() const { return myAge > MAX_POWERUP_AGE; }
+
+protected:
+ int myAge;
+ int type;
+};
+
+class KRock : public QCanvasSprite
+{
+public:
+ KRock (QCanvasPixmapArray *s, QCanvas *c, int t, int sk, int st) : QCanvasSprite( s, c )
+ { type = t; skip = cskip = sk; step = st; }
+
+ void nextFrame()
+ {
+ if (cskip-- <= 0) {
+ setFrame( (frame()+step+frameCount())%frameCount() );
+ cskip = QABS(skip);
+ }
+ }
+
+ virtual int rtti() const { return type; }
+
+private:
+ int type;
+ int skip;
+ int cskip;
+ int step;
+};
+
+class KShield : public QCanvasSprite
+{
+public:
+ KShield( QCanvasPixmapArray *s, QCanvas *c )
+ : QCanvasSprite( s, c ) {}
+
+ virtual int rtti() const { return ID_SHIELD; }
+};
+
+#endif
diff --git a/noncore/games/qasteroids/toplevel.cpp b/noncore/games/qasteroids/toplevel.cpp
new file mode 100644
index 0000000..57242a0
--- a/dev/null
+++ b/noncore/games/qasteroids/toplevel.cpp
@@ -0,0 +1,514 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+// --- toplevel.cpp ---
+
+#include "toplevel.h"
+#include "ledmeter.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/resource.h>
+
+#include <qaccel.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlcdnumber.h>
+#include <qpushbutton.h>
+
+
+#define SB_SCORE 1
+#define SB_LEVEL 2
+#define SB_SHIPS 3
+
+struct SLevel
+{
+ int nrocks;
+ double rockSpeed;
+};
+
+#define MAX_LEVELS 16
+
+SLevel levels[MAX_LEVELS] =
+{
+ { 1, 0.4 },
+ { 1, 0.6 },
+ { 2, 0.5 },
+ { 2, 0.7 },
+ { 2, 0.8 },
+ { 3, 0.6 },
+ { 3, 0.7 },
+ { 3, 0.8 },
+ { 4, 0.6 },
+ { 4, 0.7 },
+ { 4, 0.8 },
+ { 5, 0.7 },
+ { 5, 0.8 },
+ { 5, 0.9 },
+ { 5, 1.0 }
+};
+
+const char *soundEvents[] =
+{
+ "ShipDestroyed",
+ "RockDestroyed",
+ 0
+};
+
+const char *soundDefaults[] =
+{
+ "Explosion.wav",
+ "ploop.wav",
+ 0
+};
+
+
+KAstTopLevel::KAstTopLevel( QWidget *parent, const char *name )
+ : QMainWindow( parent, name )
+{
+ setCaption( tr("Asteroids") );
+ QWidget *border = new QWidget( this );
+ border->setBackgroundColor( black );
+ setCentralWidget( border );
+
+ QVBoxLayout *borderLayout = new QVBoxLayout( border );
+
+ QWidget *mainWin = new QWidget( border );
+ borderLayout->addWidget( mainWin, 2, AlignHCenter );
+
+ view = new KAsteroidsView( mainWin );
+ connect( view, SIGNAL( shipKilled() ), SLOT( slotShipKilled() ) );
+ connect( view, SIGNAL( rockHit(int) ), SLOT( slotRockHit(int) ) );
+ connect( view, SIGNAL( rocksRemoved() ), SLOT( slotRocksRemoved() ) );
+ connect( view, SIGNAL( updateVitals() ), SLOT( slotUpdateVitals() ) );
+
+ QVBoxLayout *vb = new QVBoxLayout( mainWin );
+ QHBoxLayout *hb = new QHBoxLayout;
+ QHBoxLayout *hbd = new QHBoxLayout;
+ vb->addLayout( hb );
+
+ QFont labelFont( "helvetica", 12 );
+ QColorGroup grp( darkGreen, black, QColor( 128, 128, 128 ),
+ QColor( 64, 64, 64 ), black, darkGreen, black );
+ QPalette pal( grp, grp, grp );
+
+ mainWin->setPalette( pal );
+
+ QLabel *label;
+ label = new QLabel( tr("Score"), mainWin );
+ label->setFont( labelFont );
+ label->setPalette( pal );
+// label->setFixedWidth( label->sizeHint().width() );
+ hb->addWidget( label );
+
+ scoreLCD = new QLCDNumber( 5, mainWin );
+ scoreLCD->setFrameStyle( QFrame::NoFrame );
+ scoreLCD->setSegmentStyle( QLCDNumber::Flat );
+ scoreLCD->setFixedHeight( 16 );
+ scoreLCD->setPalette( pal );
+ hb->addWidget( scoreLCD );
+ hb->addStretch( 1 );
+
+ label = new QLabel( tr("Level"), mainWin );
+ label->setFont( labelFont );
+ label->setPalette( pal );
+// label->setFixedWidth( label->sizeHint().width() );
+ hb->addWidget( label );
+
+ levelLCD = new QLCDNumber( 2, mainWin );
+ levelLCD->setFrameStyle( QFrame::NoFrame );
+ levelLCD->setSegmentStyle( QLCDNumber::Flat );
+ levelLCD->setFixedHeight( 16 );
+ levelLCD->setPalette( pal );
+ hb->addWidget( levelLCD );
+ hb->addStretch( 1 );
+
+ label = new QLabel( tr("Ships"), mainWin );
+ label->setFont( labelFont );
+// label->setFixedWidth( label->sizeHint().width() );
+ label->setPalette( pal );
+ hb->addWidget( label );
+
+ shipsLCD = new QLCDNumber( 1, mainWin );
+ shipsLCD->setFrameStyle( QFrame::NoFrame );
+ shipsLCD->setSegmentStyle( QLCDNumber::Flat );
+ shipsLCD->setFixedHeight( 16 );
+ shipsLCD->setPalette( pal );
+ hb->addWidget( shipsLCD );
+
+// hb->addStrut( 14 );
+
+ vb->addWidget( view, 10 );
+
+// -- bottom layout:
+ vb->addLayout( hbd );
+
+ QFont smallFont( "helvetica", 12 );
+ hbd->addSpacing( 5 );
+
+/*
+ label = new QLabel( tr( "T" ), mainWin );
+ label->setFont( smallFont );
+ label->setFixedWidth( label->sizeHint().width() );
+ label->setPalette( pal );
+ hbd->addWidget( label );
+
+ teleportsLCD = new QLCDNumber( 1, mainWin );
+ teleportsLCD->setFrameStyle( QFrame::NoFrame );
+ teleportsLCD->setSegmentStyle( QLCDNumber::Flat );
+ teleportsLCD->setPalette( pal );
+ teleportsLCD->setFixedHeight( 18 );
+ hbd->addWidget( teleportsLCD );
+
+ hbd->addSpacing( 10 );
+*/
+ label = new QLabel( mainWin );
+ label->setPixmap( Resource::loadPixmap("qasteroids/powerups/brake.png") );
+ label->setFixedWidth( 16 );
+ label->setPalette( pal );
+ hbd->addWidget( label );
+
+ brakesLCD = new QLCDNumber( 1, mainWin );
+ brakesLCD->setFrameStyle( QFrame::NoFrame );
+ brakesLCD->setSegmentStyle( QLCDNumber::Flat );
+ brakesLCD->setPalette( pal );
+ brakesLCD->setFixedHeight( 16 );
+ hbd->addWidget( brakesLCD );
+
+ hbd->addSpacing( 5 );
+
+ label = new QLabel( mainWin );
+ label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shield.png") );
+ label->setFixedWidth( 16 );
+ label->setPalette( pal );
+ hbd->addWidget( label );
+
+ shieldLCD = new QLCDNumber( 1, mainWin );
+ shieldLCD->setFrameStyle( QFrame::NoFrame );
+ shieldLCD->setSegmentStyle( QLCDNumber::Flat );
+ shieldLCD->setPalette( pal );
+ shieldLCD->setFixedHeight( 16 );
+ hbd->addWidget( shieldLCD );
+
+ hbd->addSpacing( 5 );
+
+ label = new QLabel( mainWin );
+ label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shoot.png") );
+ label->setFixedWidth( 16 );
+ label->setPalette( pal );
+ hbd->addWidget( label );
+
+ shootLCD = new QLCDNumber( 1, mainWin );
+ shootLCD->setFrameStyle( QFrame::NoFrame );
+ shootLCD->setSegmentStyle( QLCDNumber::Flat );
+ shootLCD->setPalette( pal );
+ shootLCD->setFixedHeight( 16 );
+ hbd->addWidget( shootLCD );
+
+ hbd->addStretch( 1 );
+
+ label = new QLabel( tr( "Fuel" ), mainWin );
+ label->setFont( smallFont );
+ label->setFixedWidth( label->sizeHint().width() + 5 );
+ label->setPalette( pal );
+ hbd->addWidget( label );
+
+ powerMeter = new KALedMeter( mainWin );
+ powerMeter->setFrameStyle( QFrame::Box | QFrame::Plain );
+ powerMeter->setRange( MAX_POWER_LEVEL );
+ powerMeter->addColorRange( 10, darkRed );
+ powerMeter->addColorRange( 20, QColor(160, 96, 0) );
+ powerMeter->addColorRange( 70, darkGreen );
+ powerMeter->setCount( 15 );
+ powerMeter->setPalette( pal );
+ powerMeter->setFixedSize( 60, 12 );
+ hbd->addWidget( powerMeter );
+
+ shipsRemain = 3;
+ showHiscores = FALSE;
+
+ actions.insert( Qt::Key_Up, Thrust );
+ actions.insert( Qt::Key_Left, RotateLeft );
+ actions.insert( Qt::Key_Right, RotateRight );
+ actions.insert( Qt::Key_Enter, Shoot );
+ actions.insert( Qt::Key_Z, Teleport );
+ actions.insert( Qt::Key_Down, Brake );
+ actions.insert( Qt::Key_P, Pause );
+ actions.insert( Key_F12, Launch );
+ actions.insert( Key_F11, Shield );
+ actions.insert( Key_F9, NewGame );
+
+// actions.insert( Qt::Key_S, Shield );
+// actions.insert( Qt::Key_X, Brake );
+// actions.insert( Qt::Key_L, Launch );
+ actions.insert( Qt::Key_Space, Shoot );
+
+ view->showText( tr( "Press Calendar to start playing" ), yellow );
+
+ setFocusPolicy( StrongFocus );
+
+ slotNewGame();
+}
+
+KAstTopLevel::~KAstTopLevel()
+{
+}
+
+void KAstTopLevel::playSound( const char * )
+{
+}
+
+void KAstTopLevel::keyPressEvent( QKeyEvent *event )
+{
+ if ( event->isAutoRepeat() || !actions.contains( event->key() ) )
+ {
+ event->ignore();
+ return;
+ }
+
+ Action a = actions[ event->key() ];
+
+ switch ( a )
+ {
+ case RotateLeft:
+ view->rotateLeft( TRUE );
+ break;
+
+ case RotateRight:
+ view->rotateRight( TRUE );
+ break;
+
+ case Thrust:
+ view->thrust( TRUE );
+ break;
+
+ case Shoot:
+ view->shoot( TRUE );
+ break;
+
+ case Shield:
+ view->setShield( TRUE );
+ break;
+
+ case Teleport:
+ view->teleport( TRUE );
+ break;
+
+ case Brake:
+ view->brake( TRUE );
+ break;
+
+ default:
+ event->ignore();
+ return;
+ }
+ event->accept();
+}
+
+void KAstTopLevel::keyReleaseEvent( QKeyEvent *event )
+{
+ if ( event->isAutoRepeat() || !actions.contains( event->key() ) )
+ {
+ event->ignore();
+ return;
+ }
+
+ Action a = actions[ event->key() ];
+
+ switch ( a )
+ {
+ case RotateLeft:
+ view->rotateLeft( FALSE );
+ break;
+
+ case RotateRight:
+ view->rotateRight( FALSE );
+ break;
+
+ case Thrust:
+ view->thrust( FALSE );
+ break;
+
+ case Shoot:
+ view->shoot( FALSE );
+ break;
+
+ case Brake:
+ view->brake( FALSE );
+ break;
+
+ case Shield:
+ view->setShield( FALSE );
+ break;
+
+ case Teleport:
+ view->teleport( FALSE );
+ break;
+
+ case Launch:
+ if ( waitShip )
+ {
+ view->newShip();
+ waitShip = FALSE;
+ view->hideText();
+ }
+ else
+ {
+ event->ignore();
+ return;
+ }
+ break;
+
+ case NewGame:
+ slotNewGame();
+ break;
+/*
+ case Pause:
+ {
+ view->pause( TRUE );
+ QMessageBox::information( this,
+ tr("KAsteroids is paused"),
+ tr("Paused") );
+ view->pause( FALSE );
+ }
+ break;
+*/
+ default:
+ event->ignore();
+ return;
+ }
+
+ event->accept();
+}
+
+void KAstTopLevel::showEvent( QShowEvent *e )
+{
+ QMainWindow::showEvent( e );
+ view->pause( FALSE );
+ setFocus();
+}
+
+void KAstTopLevel::hideEvent( QHideEvent *e )
+{
+ QMainWindow::hideEvent( e );
+ view->pause( TRUE );
+}
+
+void KAstTopLevel::focusInEvent( QFocusEvent * )
+{
+ view->pause( FALSE );
+ setFocus();
+}
+
+void KAstTopLevel::focusOutEvent( QFocusEvent * )
+{
+ view->pause( TRUE );
+}
+
+void KAstTopLevel::slotNewGame()
+{
+ shipsRemain = 3;
+ score = 0;
+ scoreLCD->display( 0 );
+ level = 0;
+ levelLCD->display( level+1 );
+ shipsLCD->display( shipsRemain-1 );
+ view->newGame();
+ view->setRockSpeed( levels[0].rockSpeed );
+ view->addRocks( levels[0].nrocks );
+ view->newShip();
+ waitShip = FALSE;
+ view->hideText();
+ isPaused = FALSE;
+}
+
+void KAstTopLevel::slotShipKilled()
+{
+ shipsRemain--;
+ shipsLCD->display( shipsRemain-1 );
+
+ playSound( "ShipDestroyed" );
+
+ if ( shipsRemain > 0 )
+ {
+ waitShip = TRUE;
+ view->showText( tr( "Ship Destroyed.\nPress Launch/Home key."), yellow );
+ }
+ else
+ {
+ view->endGame();
+ doStats();
+ }
+}
+
+void KAstTopLevel::slotRockHit( int size )
+{
+ switch ( size )
+ {
+ case 0:
+ score += 10;
+ break;
+
+ case 1:
+ score += 20;
+ break;
+
+ default:
+ score += 40;
+ }
+
+ playSound( "RockDestroyed" );
+
+ scoreLCD->display( score );
+}
+
+void KAstTopLevel::slotRocksRemoved()
+{
+ level++;
+
+ if ( level >= MAX_LEVELS )
+ level = MAX_LEVELS - 1;
+
+ view->setRockSpeed( levels[level-1].rockSpeed );
+ view->addRocks( levels[level-1].nrocks );
+
+ levelLCD->display( level+1 );
+}
+
+void KAstTopLevel::doStats()
+{
+ QString r( "0.00" );
+ if ( view->shots() )
+ r = QString::number( (double)view->hits() / view->shots() * 100.0,
+ 'g', 2 );
+
+ view->showText( tr( "Game Over.\nPress Calendar for a new game." ), yellow, FALSE );
+}
+
+void KAstTopLevel::slotUpdateVitals()
+{
+ brakesLCD->display( view->brakeCount() );
+ shieldLCD->display( view->shieldCount() );
+ shootLCD->display( view->shootCount() );
+// teleportsLCD->display( view->teleportCount() );
+ powerMeter->setValue( view->power() );
+}
diff --git a/noncore/games/qasteroids/toplevel.h b/noncore/games/qasteroids/toplevel.h
new file mode 100644
index 0000000..4e1ac9c
--- a/dev/null
+++ b/noncore/games/qasteroids/toplevel.h
@@ -0,0 +1,99 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#ifndef __KAST_TOPLEVEL_H__
+#define __KAST_TOPLEVEL_H__
+
+#include <qmainwindow.h>
+#include <qdict.h>
+#include <qmap.h>
+
+#include "view.h"
+
+
+class KALedMeter;
+class QLCDNumber;
+
+class KAstTopLevel : public QMainWindow
+{
+ Q_OBJECT
+public:
+ KAstTopLevel( QWidget *parent=0, const char *name=0 );
+ virtual ~KAstTopLevel();
+
+private:
+ void playSound( const char *snd );
+ void readSoundMapping();
+ void doStats();
+
+protected:
+ virtual void showEvent( QShowEvent * );
+ virtual void hideEvent( QHideEvent * );
+ virtual void keyPressEvent( QKeyEvent *event );
+ virtual void keyReleaseEvent( QKeyEvent *event );
+ virtual void focusInEvent( QFocusEvent *event );
+ virtual void focusOutEvent( QFocusEvent *event );
+
+private slots:
+ void slotNewGame();
+
+ void slotShipKilled();
+ void slotRockHit( int size );
+ void slotRocksRemoved();
+
+ void slotUpdateVitals();
+
+private:
+ KAsteroidsView *view;
+ QLCDNumber *scoreLCD;
+ QLCDNumber *levelLCD;
+ QLCDNumber *shipsLCD;
+
+ QLCDNumber *teleportsLCD;
+// QLCDNumber *bombsLCD;
+ QLCDNumber *brakesLCD;
+ QLCDNumber *shieldLCD;
+ QLCDNumber *shootLCD;
+ KALedMeter *powerMeter;
+
+ bool sound;
+ QDict<QString> soundDict;
+
+ // waiting for user to press Enter to launch a ship
+ bool waitShip;
+ bool isPaused;
+
+ int shipsRemain;
+ int score;
+ int level;
+ bool showHiscores;
+
+ enum Action { Launch, Thrust, RotateLeft, RotateRight, Shoot, Teleport,
+ Brake, Shield, Pause, NewGame };
+
+ QMap<int,Action> actions;
+};
+
+#endif
+
diff --git a/noncore/games/qasteroids/view.cpp b/noncore/games/qasteroids/view.cpp
new file mode 100644
index 0000000..ef08343
--- a/dev/null
+++ b/noncore/games/qasteroids/view.cpp
@@ -0,0 +1,884 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#include "view.h"
+
+#include <qpe/resource.h>
+
+#include <qapplication.h>
+#include <qkeycode.h>
+#include <qaccel.h>
+
+#include <stdlib.h>
+#include <math.h>
+
+#define IMG_BACKGROUND "qasteroids/bg.png"
+
+#define REFRESH_DELAY 33
+#define SHIP_SPEED 0.3
+#define MISSILE_SPEED 10.0
+#define SHIP_STEPS 64
+#define ROTATE_RATE 2
+#define SHIELD_ON_COST 1
+#define SHIELD_HIT_COST 30
+#define BRAKE_ON_COST 4
+
+#define MAX_ROCK_SPEED 2.5
+#define MAX_POWERUP_SPEED 1.5
+#define MAX_SHIP_SPEED 8
+#define MAX_BRAKES 5
+#define MAX_SHIELDS 5
+#define MAX_FIREPOWER 5
+
+#define TEXT_SPEED 4
+
+#define PI_X_2 6.283185307
+#ifndef M_PI
+#define M_PI 3.141592654
+#endif
+
+struct
+{
+ int id;
+ const char *path;
+ int frames;
+}
+kas_animations [] =
+{
+// { ID_ROCK_LARGE, "rock1/rock1\%1.png", 32 },
+ { ID_ROCK_MEDIUM, "rock2/rock2\%1.png", 32 },
+ { ID_ROCK_SMALL, "rock3/rock3\%1.png", 32 },
+ { ID_SHIP, "ship/ship\%1.png", 32 },
+ { ID_MISSILE, "missile/missile.png", 1 },
+ { ID_BIT, "bits/bits\%1.png", 16 },
+ { ID_EXHAUST, "exhaust/exhaust.png", 1 },
+ { ID_ENERGY_POWERUP, "powerups/energy.png", 1 },
+// { ID_TELEPORT_POWERUP, "powerups/teleport%1.png", 12 },
+ { ID_BRAKE_POWERUP, "powerups/brake.png", 1 },
+ { ID_SHIELD_POWERUP, "powerups/shield.png", 1 },
+ { ID_SHOOT_POWERUP, "powerups/shoot.png", 1 },
+ { ID_SHIELD, "shield/shield\%1.png", 6 },
+ { 0, 0, 0 }
+};
+
+
+
+KAsteroidsView::KAsteroidsView( QWidget *parent, const char *name )
+ : QWidget( parent, name ),
+ field(200, 200),
+ view(&field,this)
+{
+ view.setVScrollBarMode( QScrollView::AlwaysOff );
+ view.setHScrollBarMode( QScrollView::AlwaysOff );
+ rocks.setAutoDelete( TRUE );
+ missiles.setAutoDelete( TRUE );
+ bits.setAutoDelete( TRUE );
+ powerups.setAutoDelete( TRUE );
+ exhaust.setAutoDelete( TRUE );
+
+ QPixmap pm( Resource::loadPixmap(IMG_BACKGROUND) );
+ field.setBackgroundPixmap( pm );
+
+ textSprite = new QCanvasText( &field );
+ QFont font( "helvetica", 14 );
+ textSprite->setFont( font );
+
+ shield = 0;
+ shieldOn = FALSE;
+ refreshRate = REFRESH_DELAY;
+
+ readSprites();
+
+ shieldTimer = new QTimer( this );
+ connect( shieldTimer, SIGNAL(timeout()), this, SLOT(hideShield()) );
+ mTimerId = -1;
+
+ shipPower = MAX_POWER_LEVEL;
+ vitalsChanged = TRUE;
+ can_destroy_powerups = FALSE;
+
+ mPaused = TRUE;
+}
+
+// - - -
+
+KAsteroidsView::~KAsteroidsView()
+{
+}
+
+// - - -
+
+void KAsteroidsView::reset()
+{
+ rocks.clear();
+ missiles.clear();
+ bits.clear();
+ powerups.clear();
+ exhaust.clear();
+
+ shotsFired = 0;
+ shotsHit = 0;
+
+ rockSpeed = 1.0;
+ powerupSpeed = 1.0;
+ mFrameNum = 0;
+ mPaused = FALSE;
+
+ ship->hide();
+ shield->hide();
+/*
+ if ( mTimerId >= 0 ) {
+ killTimer( mTimerId );
+ mTimerId = -1;
+ }
+*/
+}
+
+// - --
+
+void KAsteroidsView::newGame()
+{
+ if ( shieldOn )
+ {
+ shield->hide();
+ shieldOn = FALSE;
+ }
+ reset();
+ if ( mTimerId < 0 )
+ mTimerId = startTimer( REFRESH_DELAY );
+ emit updateVitals();
+}
+
+// - - -
+
+void KAsteroidsView::endGame()
+{
+}
+
+void KAsteroidsView::pause( bool p )
+{
+ if ( !mPaused && p ) {
+ if ( mTimerId >= 0 ) {
+ killTimer( mTimerId );
+ mTimerId = -1;
+ }
+ } else if ( mPaused && !p )
+ mTimerId = startTimer( REFRESH_DELAY );
+ mPaused = p;
+}
+
+// - - -
+
+void KAsteroidsView::newShip()
+{
+ ship->move( field.width()/2, field.height()/2, 0 );
+ shield->move( field.width()/2, field.height()/2, 0 );
+ ship->setVelocity( 0.0, 0.0 );
+ shipDx = 0;
+ shipDy = 0;
+ shipAngle = 0;
+ rotateL = FALSE;
+ rotateR = FALSE;
+ thrustShip = FALSE;
+ shootShip = FALSE;
+ brakeShip = FALSE;
+ teleportShip = FALSE;
+ shieldOn = TRUE;
+ shootDelay = 0;
+ shipPower = MAX_POWER_LEVEL;
+ rotateRate = ROTATE_RATE;
+ rotateSlow = 0;
+
+ mBrakeCount = 0;
+ mTeleportCount = 0;
+ mShootCount = 0;
+
+ ship->show();
+ shield->show();
+ mShieldCount = 1; // just in case the ship appears on a rock.
+ shieldTimer->start( 1000, TRUE );
+}
+
+void KAsteroidsView::setShield( bool s )
+{
+ if ( shieldTimer->isActive() && !s ) {
+ shieldTimer->stop();
+ hideShield();
+ } else {
+ shieldOn = s && mShieldCount;
+ }
+}
+
+void KAsteroidsView::brake( bool b )
+{
+ if ( mBrakeCount )
+ {
+ if ( brakeShip && !b )
+ {
+ rotateL = FALSE;
+ rotateR = FALSE;
+ thrustShip = FALSE;
+ rotateRate = ROTATE_RATE;
+ }
+
+ brakeShip = b;
+ }
+}
+
+// - - -
+
+void KAsteroidsView::readSprites()
+{
+ QString sprites_prefix = Resource::findPixmap( IMG_BACKGROUND );
+ int sep = sprites_prefix.findRev( "/" );
+
+ sprites_prefix.truncate( sep );
+
+ int i = 0;
+ while ( kas_animations[i].id )
+ {
+ animation.insert( kas_animations[i].id,
+ new QCanvasPixmapArray( sprites_prefix + "/" + kas_animations[i].path,
+ kas_animations[i].frames ) );
+ i++;
+ }
+
+ ship = new QCanvasSprite( animation[ID_SHIP], &field );
+ ship->hide();
+
+ shield = new KShield( animation[ID_SHIELD], &field );
+ shield->hide();
+}
+
+// - - -
+
+void KAsteroidsView::addRocks( int num )
+{
+ for ( int i = 0; i < num; i++ )
+ {
+ KRock *rock = new KRock( animation[ID_ROCK_MEDIUM], &field,
+ ID_ROCK_MEDIUM, randInt(2), randInt(2) ? -1 : 1 );
+ double dx = (2.0 - randDouble()*4.0) * rockSpeed;
+ double dy = (2.0 - randDouble()*4.0) * rockSpeed;
+ rock->setVelocity( dx, dy );
+ rock->setFrame( randInt( rock->frameCount() ) );
+ if ( dx > 0 )
+ {
+ if ( dy > 0 )
+ rock->move( 5, 5, 0 );
+ else
+ rock->move( 5, field.height() - 25, 0 );
+ }
+ else
+ {
+ if ( dy > 0 )
+ rock->move( field.width() - 25, 5, 0 );
+ else
+ rock->move( field.width() - 25, field.height() - 25, 0 );
+ }
+ rock->show( );
+ rocks.append( rock );
+ }
+}
+
+// - - -
+
+void KAsteroidsView::showText( const QString &text, const QColor &color, bool scroll )
+{
+ textSprite->setTextFlags( AlignLeft | AlignVCenter );
+ textSprite->setText( text );
+ textSprite->setColor( color );
+
+ if ( scroll ) {
+ textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2,
+ -textSprite->boundingRect().height() );
+ textDy = TEXT_SPEED;
+ } else {
+ textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2,
+ (field.height()-textSprite->boundingRect().height()) / 2 );
+ textDy = 0;
+ }
+ textSprite->show();
+}
+
+// - - -
+
+void KAsteroidsView::hideText()
+{
+ textDy = -TEXT_SPEED;
+}
+
+// - - -
+
+void KAsteroidsView::resizeEvent(QResizeEvent* event)
+{
+ QWidget::resizeEvent(event);
+ field.resize(width()-4, height()-4);
+ view.resize(width(),height());
+}
+
+// - - -
+
+void KAsteroidsView::timerEvent( QTimerEvent * )
+{
+ field.advance();
+
+ QCanvasSprite *rock;
+
+ // move rocks forward
+ for ( rock = rocks.first(); rock; rock = rocks.next() ) {
+ ((KRock *)rock)->nextFrame();
+ wrapSprite( rock );
+ }
+
+ wrapSprite( ship );
+
+ // check for missile collision with rocks.
+ processMissiles();
+
+ // these are generated when a ship explodes
+ for ( KBit *bit = bits.first(); bit; bit = bits.next() )
+ {
+ if ( bit->expired() )
+ {
+ bits.removeRef( bit );
+ }
+ else
+ {
+ bit->growOlder();
+ bit->setFrame( ( bit->frame()+1 ) % bit->frameCount() );
+ }
+ }
+
+ for ( KExhaust *e = exhaust.first(); e; e = exhaust.next() )
+ exhaust.removeRef( e );
+
+ // move / rotate ship.
+ // check for collision with a rock.
+ processShip();
+
+ // move powerups and check for collision with player and missiles
+ processPowerups();
+
+ if ( textSprite->visible() )
+ {
+ if ( textDy < 0 &&
+ textSprite->boundingRect().y() <= -textSprite->boundingRect().height() ) {
+ textSprite->hide();
+ } else {
+ textSprite->moveBy( 0, textDy );
+ }
+ if ( textSprite->boundingRect().y() > (field.height()-textSprite->boundingRect().height())/2 )
+ textDy = 0;
+ }
+
+ if ( vitalsChanged && !(mFrameNum % 10) ) {
+ emit updateVitals();
+ vitalsChanged = FALSE;
+ }
+
+ mFrameNum++;
+}
+
+void KAsteroidsView::wrapSprite( QCanvasItem *s )
+{
+ int x = int(s->x() + s->boundingRect().width() / 2);
+ int y = int(s->y() + s->boundingRect().height() / 2);
+
+ if ( x > field.width() )
+ s->move( s->x() - field.width(), s->y() );
+ else if ( x < 0 )
+ s->move( field.width() + s->x(), s->y() );
+
+ if ( y > field.height() )
+ s->move( s->x(), s->y() - field.height() );
+ else if ( y < 0 )
+ s->move( s->x(), field.height() + s->y() );
+}
+
+// - - -
+
+void KAsteroidsView::rockHit( QCanvasItem *hit )
+{
+ KPowerup *nPup = 0;
+ int rnd = static_cast<int>(randDouble()*30.0) % 30;
+ switch( rnd )
+ {
+ case 4:
+ case 5:
+ nPup = new KPowerup( animation[ID_ENERGY_POWERUP], &field,
+ ID_ENERGY_POWERUP );
+ break;
+ case 10:
+// nPup = new KPowerup( animation[ID_TELEPORT_POWERUP], &field,
+// ID_TELEPORT_POWERUP );
+ break;
+ case 15:
+ nPup = new KPowerup( animation[ID_BRAKE_POWERUP], &field,
+ ID_BRAKE_POWERUP );
+ break;
+ case 20:
+ nPup = new KPowerup( animation[ID_SHIELD_POWERUP], &field,
+ ID_SHIELD_POWERUP );
+ break;
+ case 24:
+ case 25:
+ nPup = new KPowerup( animation[ID_SHOOT_POWERUP], &field,
+ ID_SHOOT_POWERUP );
+ break;
+ }
+ if ( nPup )
+ {
+ double r = 0.5 - randDouble();
+ nPup->move( hit->x(), hit->y(), 0 );
+ nPup->setVelocity( hit->xVelocity() + r, hit->yVelocity() + r );
+ nPup->show( );
+ powerups.append( nPup );
+ }
+
+ if ( hit->rtti() == ID_ROCK_LARGE || hit->rtti() == ID_ROCK_MEDIUM )
+ {
+ // break into smaller rocks
+ double addx[4] = { 1.0, 1.0, -1.0, -1.0 };
+ double addy[4] = { -1.0, 1.0, -1.0, 1.0 };
+
+ double dx = hit->xVelocity();
+ double dy = hit->yVelocity();
+
+ double maxRockSpeed = MAX_ROCK_SPEED * rockSpeed;
+ if ( dx > maxRockSpeed )
+ dx = maxRockSpeed;
+ else if ( dx < -maxRockSpeed )
+ dx = -maxRockSpeed;
+ if ( dy > maxRockSpeed )
+ dy = maxRockSpeed;
+ else if ( dy < -maxRockSpeed )
+ dy = -maxRockSpeed;
+
+ QCanvasSprite *nrock;
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ double r = rockSpeed/2 - randDouble()*rockSpeed;
+ if ( hit->rtti() == ID_ROCK_LARGE )
+ {
+ nrock = new KRock( animation[ID_ROCK_MEDIUM], &field,
+ ID_ROCK_MEDIUM, randInt(2), randInt(2) ? -1 : 1 );
+ emit rockHit( 0 );
+ }
+ else
+ {
+ nrock = new KRock( animation[ID_ROCK_SMALL], &field,
+ ID_ROCK_SMALL, randInt(2), randInt(2) ? -1 : 1 );
+ emit rockHit( 1 );
+ }
+
+ nrock->move( hit->x(), hit->y(), 0 );
+ nrock->setVelocity( dx+addx[i]*rockSpeed+r, dy+addy[i]*rockSpeed+r );
+ nrock->setFrame( randInt( nrock->frameCount() ) );
+ nrock->show( );
+ rocks.append( nrock );
+ }
+ }
+ else if ( hit->rtti() == ID_ROCK_SMALL )
+ emit rockHit( 2 );
+ rocks.removeRef( (QCanvasSprite *)hit );
+ if ( rocks.count() == 0 )
+ emit rocksRemoved();
+}
+
+void KAsteroidsView::reducePower( int val )
+{
+ shipPower -= val;
+ if ( shipPower <= 0 )
+ {
+ shipPower = 0;
+ thrustShip = FALSE;
+ if ( shieldOn )
+ {
+ shieldOn = FALSE;
+ shield->hide();
+ }
+ }
+ vitalsChanged = TRUE;
+}
+
+void KAsteroidsView::addExhaust( double x, double y, double dx,
+ double dy, int count )
+{
+ for ( int i = 0; i < count; i++ )
+ {
+ KExhaust *e = new KExhaust( animation[ID_EXHAUST], &field );
+ e->move( x + 2 - randDouble()*4, y + 2 - randDouble()*4 );
+ e->setVelocity( dx, dy );
+ e->show( );
+ exhaust.append( e );
+ }
+}
+
+void KAsteroidsView::processMissiles()
+{
+ KMissile *missile;
+
+ // if a missile has hit a rock, remove missile and break rock into smaller
+ // rocks or remove completely.
+ QPtrListIterator<KMissile> it(missiles);
+
+ for ( ; it.current(); ++it )
+ {
+ missile = it.current();
+ missile->growOlder();
+
+ if ( missile->expired() )
+ {
+ missiles.removeRef( missile );
+ continue;
+ }
+
+ wrapSprite( missile );
+
+ QCanvasItemList hits = missile->collisions( TRUE );
+ QCanvasItemList::Iterator hit;
+ for ( hit = hits.begin(); hit != hits.end(); ++hit )
+ {
+ if ( (*hit)->rtti() >= ID_ROCK_LARGE &&
+ (*hit)->rtti() <= ID_ROCK_SMALL )
+ {
+ shotsHit++;
+ rockHit( *hit );
+ missiles.removeRef( missile );
+ break;
+ }
+ }
+ }
+}
+
+// - - -
+
+void KAsteroidsView::processShip()
+{
+ if ( ship->visible() )
+ {
+ if ( shieldOn )
+ {
+ shield->show();
+ reducePower( SHIELD_ON_COST );
+ static int sf = 0;
+ sf++;
+
+ if ( sf % 2 )
+ shield->setFrame( (shield->frame()+1) % shield->frameCount() );
+ shield->move( ship->x() - 5, ship->y() - 5 );
+
+ QCanvasItemList hits = shield->collisions( TRUE );
+ QCanvasItemList::Iterator it;
+ for ( it = hits.begin(); it != hits.end(); ++it )
+ {
+ if ( (*it)->rtti() >= ID_ROCK_LARGE &&
+ (*it)->rtti() <= ID_ROCK_SMALL )
+ {
+ int factor;
+ switch ( (*it)->rtti() )
+ {
+ case ID_ROCK_LARGE:
+ factor = 3;
+ break;
+
+ case ID_ROCK_MEDIUM:
+ factor = 2;
+ break;
+
+ default:
+ factor = 1;
+ }
+
+ if ( factor > mShieldCount )
+ {
+ // shield not strong enough
+ shieldOn = FALSE;
+ break;
+ }
+ rockHit( *it );
+ // the more shields we have the less costly
+ reducePower( factor * (SHIELD_HIT_COST - mShieldCount*2) );
+ }
+ }
+ }
+
+ if ( !shieldOn )
+ {
+ shield->hide();
+ QCanvasItemList hits = ship->collisions( TRUE );
+ QCanvasItemList::Iterator it;
+ for ( it = hits.begin(); it != hits.end(); ++it )
+ {
+ if ( (*it)->rtti() >= ID_ROCK_LARGE &&
+ (*it)->rtti() <= ID_ROCK_SMALL )
+ {
+ KBit *bit;
+ for ( int i = 0; i < 8; i++ )
+ {
+ bit = new KBit( animation[ID_BIT], &field );
+ bit->move( ship->x() + 5 - randDouble() * 10,
+ ship->y() + 5 - randDouble() * 10,
+ randInt(bit->frameCount()) );
+ bit->setVelocity( 1-randDouble()*2,
+ 1-randDouble()*2 );
+ bit->setDeath( 60 + randInt(60) );
+ bit->show( );
+ bits.append( bit );
+ }
+ ship->hide();
+ shield->hide();
+ emit shipKilled();
+ break;
+ }
+ }
+ }
+
+
+ if ( rotateSlow )
+ rotateSlow--;
+
+ if ( rotateL )
+ {
+ shipAngle -= rotateSlow ? 1 : rotateRate;
+ if ( shipAngle < 0 )
+ shipAngle += SHIP_STEPS;
+ }
+
+ if ( rotateR )
+ {
+ shipAngle += rotateSlow ? 1 : rotateRate;
+ if ( shipAngle >= SHIP_STEPS )
+ shipAngle -= SHIP_STEPS;
+ }
+
+ double angle = shipAngle * PI_X_2 / SHIP_STEPS;
+ double cosangle = cos( angle );
+ double sinangle = sin( angle );
+
+ if ( brakeShip )
+ {
+ thrustShip = FALSE;
+ rotateL = FALSE;
+ rotateR = FALSE;
+ rotateRate = ROTATE_RATE;
+ if ( fabs(shipDx) < 2.5 && fabs(shipDy) < 2.5 )
+ {
+ shipDx = 0.0;
+ shipDy = 0.0;
+ ship->setVelocity( shipDx, shipDy );
+ brakeShip = FALSE;
+ }
+ else
+ {
+ double motionAngle = atan2( -shipDy, -shipDx );
+ if ( angle > M_PI )
+ angle -= PI_X_2;
+ double angleDiff = angle - motionAngle;
+ if ( angleDiff > M_PI )
+ angleDiff = PI_X_2 - angleDiff;
+ else if ( angleDiff < -M_PI )
+ angleDiff = PI_X_2 + angleDiff;
+ double fdiff = fabs( angleDiff );
+ if ( fdiff > 0.08 )
+ {
+ if ( angleDiff > 0 )
+ rotateL = TRUE;
+ else if ( angleDiff < 0 )
+ rotateR = TRUE;
+ if ( fdiff > 0.6 )
+ rotateRate = mBrakeCount + 1;
+ else if ( fdiff > 0.4 )
+ rotateRate = 2;
+ else
+ rotateRate = 1;
+
+ if ( rotateRate > 5 )
+ rotateRate = 5;
+ }
+ else if ( fabs(shipDx) > 1 || fabs(shipDy) > 1 )
+ {
+ thrustShip = TRUE;
+ // we'll make braking a bit faster
+ shipDx += cosangle/6 * (mBrakeCount - 1);
+ shipDy += sinangle/6 * (mBrakeCount - 1);
+ reducePower( BRAKE_ON_COST );
+ addExhaust( ship->x() + 10 - cosangle*11,
+ ship->y() + 10 - sinangle*11,
+ shipDx-cosangle, shipDy-sinangle,
+ mBrakeCount+1 );
+ }
+ }
+ }
+
+ if ( thrustShip )
+ {
+ // The ship has a terminal velocity, but trying to go faster
+ // still uses fuel (can go faster diagonally - don't care).
+ double thrustx = cosangle/8;
+ double thrusty = sinangle/8;
+ if ( fabs(shipDx + thrustx) < MAX_SHIP_SPEED )
+ shipDx += thrustx;
+ if ( fabs(shipDy + thrusty) < MAX_SHIP_SPEED )
+ shipDy += thrusty;
+ ship->setVelocity( shipDx, shipDy );
+ reducePower( 1 );
+ addExhaust( ship->x() + 10 - cosangle*10,
+ ship->y() + 10 - sinangle*10,
+ shipDx-cosangle, shipDy-sinangle, 3 );
+ }
+
+ ship->setFrame( shipAngle >> 1 );
+
+ if ( shootShip )
+ {
+ if ( !shootDelay && (int)missiles.count() < mShootCount + 2 )
+ {
+ KMissile *missile = new KMissile( animation[ID_MISSILE], &field );
+ missile->move( 11+ship->x()+cosangle*11,
+ 11+ship->y()+sinangle*11, 0 );
+ missile->setVelocity( shipDx + cosangle*MISSILE_SPEED,
+ shipDy + sinangle*MISSILE_SPEED );
+ missile->show( );
+ missiles.append( missile );
+ shotsFired++;
+ reducePower( 1 );
+
+ shootDelay = 5;
+ }
+
+ if ( shootDelay )
+ shootDelay--;
+ }
+
+ if ( teleportShip )
+ {
+ int ra = rand() % 10;
+ if( ra == 0 )
+ ra += rand() % 20;
+ int xra = ra * 60 + ( (rand() % 20) * (rand() % 20) );
+ int yra = ra * 50 - ( (rand() % 20) * (rand() % 20) );
+ ship->move( xra, yra );
+ }
+
+ vitalsChanged = TRUE;
+ }
+}
+
+// - - -
+
+void KAsteroidsView::processPowerups()
+{
+ if ( !powerups.isEmpty() )
+ {
+ // if player gets the powerup remove it from the screen, if option
+ // "Can destroy powerups" is enabled and a missile hits the powerup
+ // destroy it
+
+ KPowerup *pup;
+ QPtrListIterator<KPowerup> it( powerups );
+
+ for( ; it.current(); ++it )
+ {
+ pup = it.current();
+ pup->growOlder();
+
+ if( pup->expired() )
+ {
+ powerups.removeRef( pup );
+ continue;
+ }
+
+ wrapSprite( pup );
+
+ QCanvasItemList hits = pup->collisions( TRUE );
+ QCanvasItemList::Iterator it;
+ for ( it = hits.begin(); it != hits.end(); ++it )
+ {
+ if ( (*it) == ship )
+ {
+ switch( pup->rtti() )
+ {
+ case ID_ENERGY_POWERUP:
+ shipPower += 150;
+ if ( shipPower > MAX_POWER_LEVEL )
+ shipPower = MAX_POWER_LEVEL;
+ break;
+ case ID_TELEPORT_POWERUP:
+ mTeleportCount++;
+ break;
+ case ID_BRAKE_POWERUP:
+ if ( mBrakeCount < MAX_BRAKES )
+ mBrakeCount++;
+ break;
+ case ID_SHIELD_POWERUP:
+ if ( mShieldCount < MAX_SHIELDS )
+ mShieldCount++;
+ break;
+ case ID_SHOOT_POWERUP:
+ if ( mShootCount < MAX_FIREPOWER )
+ mShootCount++;
+ break;
+ }
+
+ powerups.removeRef( pup );
+ vitalsChanged = TRUE;
+ }
+ else if ( (*it) == shield )
+ {
+ powerups.removeRef( pup );
+ }
+ else if ( (*it)->rtti() == ID_MISSILE )
+ {
+ if ( can_destroy_powerups )
+ {
+ powerups.removeRef( pup );
+ }
+ }
+ }
+ }
+ } // -- if( powerups.isEmpty() )
+}
+
+// - - -
+
+void KAsteroidsView::hideShield()
+{
+ shield->hide();
+ mShieldCount = 0;
+ shieldOn = FALSE;
+}
+
+double KAsteroidsView::randDouble()
+{
+ int v = rand();
+ return (double)v / (double)RAND_MAX;
+}
+
+int KAsteroidsView::randInt( int range )
+{
+ return rand() % range;
+}
diff --git a/noncore/games/qasteroids/view.h b/noncore/games/qasteroids/view.h
new file mode 100644
index 0000000..0a7902b
--- a/dev/null
+++ b/noncore/games/qasteroids/view.h
@@ -0,0 +1,156 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************//*
+ * KAsteroids - Copyright (c) Martin R. Jones 1997
+ *
+ * Part of the KDE project
+ */
+
+#ifndef __AST_VIEW_H__
+#define __AST_VIEW_H__
+
+#include <qwidget.h>
+#include <qlist.h>
+#include <qintdict.h>
+#include <qtimer.h>
+#include <qcanvas.h>
+#include "sprites.h"
+
+#define QPtrList QList
+#define QPtrListIterator QListIterator
+
+#define MAX_POWER_LEVEL 1000
+
+class KAsteroidsView : public QWidget
+{
+ Q_OBJECT
+public:
+ KAsteroidsView( QWidget *parent = 0, const char *name = 0 );
+ virtual ~KAsteroidsView();
+
+ int refreshRate;
+
+ void reset();
+ void setRockSpeed( double rs ) { rockSpeed = rs; }
+ void addRocks( int num );
+ void newGame();
+ void endGame();
+ void newShip();
+
+ void rotateLeft( bool r ) { rotateL = r; rotateSlow = 5; }
+ void rotateRight( bool r ) { rotateR = r; rotateSlow = 5; }
+ void thrust( bool t ) { thrustShip = t && shipPower > 0; }
+ void shoot( bool s ) { shootShip = s; shootDelay = 0; }
+ void setShield( bool s );
+ void teleport( bool te) { teleportShip = te && mTeleportCount; }
+ void brake( bool b );
+ void pause( bool p);
+
+ void showText( const QString &text, const QColor &color, bool scroll=TRUE );
+ void hideText();
+
+ int shots() const { return shotsFired; }
+ int hits() const { return shotsHit; }
+ int power() const { return shipPower; }
+
+ int teleportCount() const { return mTeleportCount; }
+ int brakeCount() const { return mBrakeCount; }
+ int shieldCount() const { return mShieldCount; }
+ int shootCount() const { return mShootCount; }
+
+signals:
+ void shipKilled();
+ void rockHit( int size );
+ void rocksRemoved();
+ void updateVitals();
+
+private slots:
+ void hideShield();
+
+protected:
+ void readSprites();
+ void wrapSprite( QCanvasItem * );
+ void rockHit( QCanvasItem * );
+ void reducePower( int val );
+ void addExhaust( double x, double y, double dx, double dy, int count );
+ void processMissiles();
+ void processShip();
+ void processPowerups();
+ void processShield();
+ double randDouble();
+ int randInt( int range );
+
+ virtual void resizeEvent( QResizeEvent *event );
+ virtual void timerEvent( QTimerEvent * );
+
+private:
+ QCanvas field;
+ QCanvasView view;
+ QIntDict<QCanvasPixmapArray> animation;
+ QPtrList<QCanvasSprite> rocks;
+ QPtrList<KMissile> missiles;
+ QPtrList<KBit> bits;
+ QPtrList<KExhaust> exhaust;
+ QPtrList<KPowerup> powerups;
+ KShield *shield;
+ QCanvasSprite *ship;
+ QCanvasText *textSprite;
+
+ bool rotateL;
+ bool rotateR;
+ bool thrustShip;
+ bool shootShip;
+ bool teleportShip;
+ bool brakeShip;
+ bool pauseShip;
+ bool shieldOn;
+
+ bool vitalsChanged;
+
+ int shipAngle;
+ int rotateSlow;
+ int rotateRate;
+ int shipPower;
+
+ int shotsFired;
+ int shotsHit;
+ int shootDelay;
+
+ int mBrakeCount;
+ int mShieldCount;
+ int mTeleportCount;
+ int mShootCount;
+
+ double shipDx;
+ double shipDy;
+
+ int textDy;
+ int mFrameNum;
+ bool mPaused;
+ int mTimerId;
+
+ double rockSpeed;
+ double powerupSpeed;
+
+ bool can_destroy_powerups;
+
+ QTimer *shieldTimer;
+};
+
+#endif
diff --git a/noncore/games/snake/.cvsignore b/noncore/games/snake/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/games/snake/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/games/snake/Makefile.in b/noncore/games/snake/Makefile.in
new file mode 100644
index 0000000..8179b6f
--- a/dev/null
+++ b/noncore/games/snake/Makefile.in
@@ -0,0 +1,159 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = snake
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = snake.h \
+ target.h \
+ obstacle.h \
+ interface.h \
+ codes.h
+SOURCES = snake.cpp \
+ target.cpp \
+ obstacle.cpp \
+ interface.cpp \
+ main.cpp
+OBJECTS = snake.o \
+ target.o \
+ obstacle.o \
+ interface.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_snake.cpp \
+ moc_interface.cpp
+OBJMOC = moc_snake.o \
+ moc_interface.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake snake.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+snake.o: snake.cpp \
+ snake.h \
+ target.h \
+ codes.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+target.o: target.cpp \
+ target.h \
+ codes.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+obstacle.o: obstacle.cpp \
+ obstacle.h \
+ codes.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+interface.o: interface.cpp \
+ interface.h \
+ snake.h \
+ target.h \
+ obstacle.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+main.o: main.cpp \
+ interface.h \
+ snake.h \
+ target.h \
+ obstacle.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_snake.o: moc_snake.cpp \
+ snake.h
+
+moc_interface.o: moc_interface.cpp \
+ interface.h \
+ snake.h \
+ target.h \
+ obstacle.h
+
+moc_snake.cpp: snake.h
+ $(MOC) snake.h -o moc_snake.cpp
+
+moc_interface.cpp: interface.h
+ $(MOC) interface.h -o moc_interface.cpp
+
+
diff --git a/noncore/games/snake/codes.h b/noncore/games/snake/codes.h
new file mode 100644
index 0000000..3b5e4d0
--- a/dev/null
+++ b/noncore/games/snake/codes.h
@@ -0,0 +1,20 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/const int target_rtti = 1500;
+const int obstacle_rtti = 1600;
diff --git a/noncore/games/snake/interface.cpp b/noncore/games/snake/interface.cpp
new file mode 100644
index 0000000..c9b4931
--- a/dev/null
+++ b/noncore/games/snake/interface.cpp
@@ -0,0 +1,224 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "interface.h"
+
+#include <qpe/resource.h>
+
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qstyle.h>
+#include <qapplication.h>
+#include <qmessagebox.h>
+
+SnakeGame::SnakeGame(QWidget* parent, const char* name, WFlags f) :
+ QMainWindow(parent,name,f),
+ canvas(232, 258)
+{
+ setCaption( tr("Snake") );
+ QPixmap bg = Resource::loadPixmap("grass");
+ canvas.setBackgroundPixmap(bg);
+ canvas.setUpdatePeriod(100);
+ snake = 0;
+
+ cv = new QCanvasView(&canvas, this);
+
+ pauseTimer = new QTimer(this);
+ connect(pauseTimer, SIGNAL(timeout()), this, SLOT(wait()) );
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar* toolbar = new QPEToolBar( this);
+ toolbar->setHorizontalStretchable( TRUE );
+
+ QPixmap newicon = Resource::loadPixmap("ksnake");
+ setIcon(newicon);
+ (void)new QToolButton(newicon, tr("New Game"), 0,
+ this, SLOT(newGame()), toolbar, "New Game");
+
+ scorelabel = new QLabel(toolbar);
+ showScore(0);
+ scorelabel->setBackgroundMode( PaletteButton );
+ scorelabel->setAlignment( AlignRight | AlignVCenter | ExpandTabs );
+ toolbar->setStretchableWidget( scorelabel );
+
+ setFocusPolicy(StrongFocus);
+
+ setCentralWidget(cv);
+
+ welcomescreen();
+ gamestopped = true;
+ waitover = true;
+}
+
+SnakeGame::~SnakeGame()
+{
+ delete snake;
+}
+
+void SnakeGame::resizeEvent(QResizeEvent *)
+{
+ QSize s = centralWidget()->size();
+ int fw = style().defaultFrameWidth();
+ canvas.resize( s.width() - fw - 2, s.height() - fw - 2);
+}
+
+void SnakeGame::welcomescreen()
+{
+ QCanvasText* title = new QCanvasText(tr("SNAKE!"), &canvas);
+ title->setColor(yellow);
+ title->setFont( QFont("times", 18, QFont::Bold) );
+ int w = title->boundingRect().width();
+ title->move(canvas.width()/2 -w/2, canvas.height()/2-110);
+ title->show();
+ QCanvasPixmapArray* titlearray = new QCanvasPixmapArray(Resource::findPixmap("title"));
+ QCanvasSprite* titlepic = new QCanvasSprite(titlearray, &canvas);
+ titlepic->move(canvas.width()/2 - 33, canvas.height()/2-85);
+ titlepic->show();
+ QCanvasText* instr = new QCanvasText(tr("Use the arrow keys to guide the\n"
+ "snake to eat the mouse. You must not\n"
+ "crash into the walls, edges or its tail."),
+ &canvas);
+ w = instr->boundingRect().width();
+ instr->move(canvas.width()/2-w/2, canvas.height()/2-20);
+ instr->setColor(white);
+ instr->show();
+ QCanvasText* cont = new QCanvasText(tr("Press Any Key To Start"), &canvas);
+ w = cont->boundingRect().width();
+ cont->move(canvas.width()/2-w/2, canvas.height()/2+80);
+ cont->setColor(yellow);
+ cont->show();
+
+}
+
+void SnakeGame::newGame()
+{
+ clear();
+ snake = new Snake(&canvas);
+ connect(snake, SIGNAL(dead()), this, SLOT(gameOver()) );
+ connect(snake, SIGNAL(targethit()), this, SLOT(levelUp()) );
+ connect(snake, SIGNAL(scorechanged()), this, SLOT(scoreInc()) );
+ connect(this, SIGNAL(moveFaster()), snake, SLOT(increaseSpeed()) );
+ last = 0;
+ targetamount = 1;
+ notargets = 1;
+ level = 1;
+ stage = 1;
+ showScore(0);
+ gamestopped = false;
+ waitover = true;
+ int x = canvas.width()/2 - 70;
+ x = x - x % 16;
+ int y = canvas.height()-50;
+ y = y - y % 16;
+ (void)new Obstacle(&canvas, x, 32);
+ (void)new Obstacle(&canvas, x, y);
+ createTargets();
+}
+
+
+void SnakeGame::showScore(int score)
+{
+ scorelabel->setText(tr(" Score : %1 ").arg(score) );
+}
+
+
+void SnakeGame::scoreInc()
+{
+ showScore( snake->getScore() );
+}
+
+void SnakeGame::levelUp()
+{
+ notargets--;
+ if (notargets == 0) {
+ stage++;
+ if (stage == 3) {
+ level++;
+ emit moveFaster();
+ targetamount++;
+ stage = 0;
+ }
+ createTargets();
+ }
+}
+
+void SnakeGame::createTargets()
+{
+ for (int i = 0; i < targetamount; i++)
+ (void)new Target(&canvas);
+ notargets = targetamount;
+}
+
+void SnakeGame::clear()
+{
+ delete snake;
+ snake = 0;
+ QCanvasItemList l = canvas.allItems();
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ delete *it;
+ }
+}
+
+void SnakeGame::gameOver()
+{
+ int score = snake->getScore();
+ QString scoreoutput="";
+ scoreoutput.setNum(score);
+ QCanvasText* gameover = new QCanvasText(tr("GAME OVER!\n Your Score: %1").arg( scoreoutput), &canvas);
+
+ gameover->setZ(100);
+ gameover->setColor(yellow);
+ gameover->setFont( QFont("times", 18, QFont::Bold) );
+ int w = gameover->boundingRect().width();
+ gameover->move(canvas.width()/2 -w/2, canvas.height()/2 -50);
+ gameover->show();
+ gamestopped = true;
+ waitover = false;
+ pauseTimer->start(2500);
+}
+
+void SnakeGame::wait()
+{
+ waitover = true;
+ pauseTimer->stop();
+ QCanvasText* cont = new QCanvasText(tr("Press Any Key to Begin a New Game."),
+ &canvas);
+ cont->setZ(100);
+ cont->setColor(white);
+ int w = cont->boundingRect().width();
+ cont->move(canvas.width()/2 -w/2, canvas.height()/2);
+ cont->show();
+}
+
+void SnakeGame::keyPressEvent(QKeyEvent* event)
+{
+ if (gamestopped) {
+ if (waitover)
+ newGame();
+ else
+ return;
+ }
+ else {
+ int newkey = event->key();
+ snake->go(newkey);
+ }
+}
+
diff --git a/noncore/games/snake/interface.h b/noncore/games/snake/interface.h
new file mode 100644
index 0000000..30c7f84
--- a/dev/null
+++ b/noncore/games/snake/interface.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qmainwindow.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+
+#include "snake.h"
+#include "target.h"
+#include "obstacle.h"
+
+// class QCanvas;
+
+class SnakeGame : public QMainWindow {
+ Q_OBJECT
+
+public:
+ SnakeGame(QWidget* parent=0, const char* name=0, WFlags f=0);
+ ~SnakeGame();
+
+ void clear();
+ void createTargets();
+ void welcomescreen();
+
+protected:
+ virtual void keyPressEvent(QKeyEvent*);
+ virtual void resizeEvent(QResizeEvent *e);
+
+signals:
+ void moveFaster();
+
+private slots:
+ void newGame();
+ void gameOver();
+ void wait();
+ void levelUp();
+ void scoreInc();
+
+private:
+ void showScore(int);
+ QCanvasView* cv;
+ QLabel* scorelabel;
+ QCanvas canvas;
+ QTimer* pauseTimer;
+ Snake* snake;
+ int last;
+ int level;
+ int stage;
+ int targetamount;
+ int notargets;
+ bool waitover;
+ bool gamestopped;
+};
diff --git a/noncore/games/snake/main.cpp b/noncore/games/snake/main.cpp
new file mode 100644
index 0000000..90a93b7
--- a/dev/null
+++ b/noncore/games/snake/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "interface.h"
+
+#include <qpe/qpeapplication.h>
+
+
+int main(int argc, char **argv)
+{
+ QPEApplication app(argc,argv);
+
+ SnakeGame* m = new SnakeGame;
+ QPEApplication::setInputMethodHint( m, QPEApplication::AlwaysOff );
+ app.showMainWidget(m);
+
+ return app.exec();
+}
diff --git a/noncore/games/snake/obstacle.cpp b/noncore/games/snake/obstacle.cpp
new file mode 100644
index 0000000..2d07fe7
--- a/dev/null
+++ b/noncore/games/snake/obstacle.cpp
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "obstacle.h"
+#include "codes.h"
+
+#include <qpe/resource.h>
+
+Obstacle::Obstacle(QCanvas* canvas, int x, int y)
+ : QCanvasSprite(0, canvas)
+{
+ newObstacle(x, y);
+}
+
+void Obstacle::newObstacle(int x, int y)
+{
+ QCanvasPixmapArray* obstaclearray = new QCanvasPixmapArray(Resource::findPixmap("snake/wall.png"));
+
+ setSequence(obstaclearray);
+
+ move(x, y);
+
+ show();
+ canvas()->update();
+}
+
+int Obstacle::rtti() const
+{
+ return obstacle_rtti;
+}
+
+Obstacle::~Obstacle()
+{
+}
diff --git a/noncore/games/snake/obstacle.h b/noncore/games/snake/obstacle.h
new file mode 100644
index 0000000..838917f
--- a/dev/null
+++ b/noncore/games/snake/obstacle.h
@@ -0,0 +1,30 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qcanvas.h>
+
+class Obstacle : public QCanvasSprite
+{
+
+public:
+ Obstacle(QCanvas*, int x, int y);
+ ~Obstacle();
+ void newObstacle(int x, int y);
+ int rtti() const;
+};
diff --git a/noncore/games/snake/qpe-snake.control b/noncore/games/snake/qpe-snake.control
new file mode 100644
index 0000000..489e642
--- a/dev/null
+++ b/noncore/games/snake/qpe-snake.control
@@ -0,0 +1,9 @@
+Files: bin/snake apps/Games/snake.desktop pics/snake
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: control the snake
+ A game for the Qtopia environment.
diff --git a/noncore/games/snake/snake.cpp b/noncore/games/snake/snake.cpp
new file mode 100644
index 0000000..9f19841
--- a/dev/null
+++ b/noncore/games/snake/snake.cpp
@@ -0,0 +1,246 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "snake.h"
+#include "target.h"
+#include "codes.h"
+
+#include <qpe/resource.h>
+
+#include <qregexp.h>
+
+static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } };
+
+Snake::Snake(QCanvas* c)
+{
+ canvas = c;
+ score = 0;
+ snakelist.setAutoDelete(true);
+ autoMoveTimer = new QTimer(this);
+ connect( autoMoveTimer, SIGNAL(timeout()), this, SLOT(moveSnake()) );
+ createSnake();
+}
+
+void Snake::createSnake()
+{
+ snakeparts = new QCanvasPixmapArray();
+ QString s0 = Resource::findPixmap("snake/s0001");
+ s0.replace(QRegExp("0001"),"%1");
+ snakeparts->readPixmaps(s0, 15);
+
+ grow = 0;
+ last = Key_Right;
+
+ QCanvasSprite* head = new QCanvasSprite(snakeparts, canvas );
+ head->setFrame(7);
+ snakelist.insert(0, head);
+ head->show();
+ head->move(34, 16);
+
+ QCanvasSprite* body = new QCanvasSprite(snakeparts, canvas );
+ body->setFrame(6);
+ snakelist.append( body );
+ body->show();
+ body->move(18, 16);
+
+ QCanvasSprite* end = new QCanvasSprite(snakeparts, canvas );
+ end->setFrame(11);
+ snakelist.append( end );
+ end->show();
+ end->move(2, 16);
+
+ currentdir = right;
+ speed = 250;
+ autoMoveTimer->start(speed);
+ moveSnake();
+}
+
+void Snake::increaseSpeed()
+{
+ if (speed > 150)
+ speed = speed - 5;
+ autoMoveTimer->start(speed);
+}
+
+void Snake::go(int newkey)
+{
+ // check key is a direction
+ if (!( (newkey == Key_Up) || (newkey == Key_Left) ||
+ (newkey == Key_Right) || (newkey == Key_Down) ))
+ return;
+ // check move is possible
+ if ( ((currentdir == left) && ((newkey == Key_Right) || (newkey == Key_Left)) ) ||
+ ((currentdir == right) && ((newkey == Key_Left) || (newkey == Key_Right)) ) ||
+ ((currentdir == up) && ((newkey == Key_Down) || (newkey == Key_Up)) ) ||
+ ((currentdir == down) && ((newkey == Key_Up) || (newkey == Key_Down)) ) )
+ return;
+ else {
+ Snake::changeHead(newkey);
+ Snake::moveSnake();
+ }
+}
+
+void Snake::move(Direction dir)
+{
+ autoMoveTimer->start(speed);
+ int x = 0;
+ int y = 0;
+ newdir = dir;
+ switch (dir) {
+ case right: x = 16; break;
+ case left: x = -16; break;
+ case down: y = 16; break;
+ case up: y = -16; break;
+ }
+ int index = lookUpPiece(currentdir, newdir);
+ QCanvasSprite* sprite = new QCanvasSprite(snakeparts, canvas );
+ sprite->setFrame(index);
+ snakelist.insert(1, sprite);
+ sprite->move(snakelist.first()->x(), snakelist.first()->y() );
+
+ snakelist.first()->moveBy(x, y);
+ if (grow <= 0)
+ changeTail();
+ else
+ grow--;
+ sprite->show();
+
+ currentdir = dir;
+}
+
+void Snake::changeTail()
+{
+ snakelist.removeLast();
+
+ double lastx = snakelist.last()->x();
+ double prevx = snakelist.prev()->x();
+ int index = 0;
+
+ if ( prevx == lastx ) { //vertical
+ if ( snakelist.prev()->y() > snakelist.last()->y() )
+ index = 13;
+ else
+ index = 14;
+ } else { //horizontal
+ if (snakelist.prev()->x() > snakelist.last()->x() )
+ index = 11;
+ else
+ index = 12;
+ }
+
+ snakelist.last()->setFrame(index);
+}
+
+void Snake::changeHead(int lastkey)
+{
+ int index = 0;
+ last = lastkey;
+
+ switch (last)
+ {
+ case Key_Up: index = 10; break;
+ case Key_Left: index = 8; break;
+ case Key_Right: index = 7; break;
+ case Key_Down: index = 9; break;
+ }
+
+ if (index) {
+ snakelist.first()->setFrame(index);
+ }
+}
+
+// returns an integer corresponding to a particular type of snake piece
+int Snake::lookUpPiece(Direction currentdir, Direction newdir)
+{
+ return Piecekey[currentdir][newdir];
+}
+
+void Snake::extendSnake()
+{
+ grow++;
+}
+
+void Snake::moveSnake()
+{
+ switch (last)
+ {
+ case Key_Up: move(up); break;
+ case Key_Left: move(left); break;
+ case Key_Right: move(right); break;
+ case Key_Down: move(down); break;
+ }
+ detectCrash();
+}
+
+void Snake::detectCrash()
+{
+ QCanvasSprite* head = snakelist.first();
+ QCanvasItem* item;
+ QCanvasItemList l=head->collisions(FALSE);
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ // check if snake hit target
+ if ( (item->rtti()== 1500 ) && (item->collidesWith(head)) ) {
+ Target* target = (Target*) item;
+ target->done();
+ emit targethit();
+ extendSnake();
+ setScore(5);
+ return;
+ }
+ // check if snake hit obstacles
+ if ( (item->rtti()==1600) && (item->collidesWith(head)) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+ }
+ //check if snake hit itself
+ for (uint i = 3; i < snakelist.count(); i++) {
+ if (head->collidesWith(snakelist.at(i)) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+ }
+ //check if snake hit edge
+ if ( (head->x() > canvas->width()-5) || (head->y() > canvas->height()-10)
+ || (head->x() <2) || (head->y() <-5) ) {
+ emit dead();
+ autoMoveTimer->stop();
+ return;
+ }
+}
+
+void Snake::setScore(int amount)
+{
+ score = score + amount;
+ emit scorechanged();
+}
+
+int Snake::getScore()
+{
+ return score;
+}
+
+Snake::~Snake()
+{
+ autoMoveTimer->stop();
+}
diff --git a/noncore/games/snake/snake.h b/noncore/games/snake/snake.h
new file mode 100644
index 0000000..5725343
--- a/dev/null
+++ b/noncore/games/snake/snake.h
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qcanvas.h>
+#include <qtimer.h>
+
+class Snake : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Direction{ left, right, up, down};
+
+ Snake(QCanvas*);
+ ~Snake();
+ void go(int newkey);
+ void move(Direction dir);
+ void changeHead(int last);
+ void changeTail();
+ void detectCrash();
+ void createSnake();
+ void extendSnake();
+ int lookUpPiece(Direction currentdir, Direction newdir);
+ void setScore(int amount);
+ int getScore();
+
+signals:
+ void dead();
+ void targethit();
+ void scorechanged();
+
+private slots:
+ void moveSnake();
+ void increaseSpeed();
+
+private:
+ QCanvasPixmapArray* snakeparts;
+ QList<QCanvasSprite>snakelist;
+ QTimer* autoMoveTimer;
+ QCanvas* canvas;
+ int grow;
+ int last;
+ int speed;
+ int score;
+ Direction currentdir;
+ Direction newdir;
+};
+
diff --git a/noncore/games/snake/snake.pro b/noncore/games/snake/snake.pro
new file mode 100644
index 0000000..6dacdbd
--- a/dev/null
+++ b/noncore/games/snake/snake.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = snake.h target.h obstacle.h interface.h codes.h
+SOURCES = snake.cpp target.cpp obstacle.cpp interface.cpp main.cpp
+TARGET = snake
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/snake.ts
diff --git a/noncore/games/snake/target.cpp b/noncore/games/snake/target.cpp
new file mode 100644
index 0000000..a09af69
--- a/dev/null
+++ b/noncore/games/snake/target.cpp
@@ -0,0 +1,77 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "target.h"
+#include "codes.h"
+
+#include <qpe/resource.h>
+
+#include <stdlib.h>
+
+Target::Target(QCanvas* canvas)
+ : QCanvasSprite(0, canvas)
+{
+ mouse = new QCanvasPixmapArray(Resource::findPixmap("snake/mouse"));
+ setSequence(mouse);
+ newTarget();
+}
+
+void Target::newTarget()
+{
+ static bool first_time = TRUE;
+ if (first_time) {
+ first_time = FALSE;
+ QTime midnight(0, 0, 0);
+ srand(midnight.secsTo(QTime::currentTime()) );
+ }
+ do {
+ int x = rand() % (canvas()->width()-10);
+ x = x - (x % 16) + 2;
+ int y = rand() % (canvas()->height()-10);
+ y = y - (y % 16) + 2;
+ move(x, y);
+ } while (onTop());
+ show();
+}
+
+bool Target::onTop()
+{
+ QCanvasItem* item;
+ QCanvasItemList l= canvas()->allItems(); //collisions(FALSE);
+ for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ item = *it;
+ if (item != this && item->collidesWith(this)) return true;
+ }
+ return false;
+}
+
+void Target::done()
+{
+ delete this;
+}
+
+int Target::rtti() const
+{
+ return target_rtti;
+}
+
+Target::~Target()
+{
+}
diff --git a/noncore/games/snake/target.h b/noncore/games/snake/target.h
new file mode 100644
index 0000000..a6da37c
--- a/dev/null
+++ b/noncore/games/snake/target.h
@@ -0,0 +1,37 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qcanvas.h>
+#include <qdatetime.h>
+
+class Target : public QCanvasSprite
+{
+
+public:
+ Target(QCanvas*);
+ ~Target();
+ void newTarget();
+ void done();
+ void createMouse();
+ bool onTop();
+ int rtti() const;
+
+private:
+ QCanvasPixmapArray* mouse;
+};
diff --git a/noncore/games/solitaire/.cvsignore b/noncore/games/solitaire/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/games/solitaire/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/games/solitaire/Makefile.in b/noncore/games/solitaire/Makefile.in
new file mode 100644
index 0000000..3c50345
--- a/dev/null
+++ b/noncore/games/solitaire/Makefile.in
@@ -0,0 +1,235 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = patience
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = canvascard.h \
+ canvasshapes.h \
+ cardgame.h \
+ cardgamelayout.h \
+ cardpile.h \
+ card.h \
+ carddeck.h \
+ canvascardgame.h \
+ freecellcardgame.h \
+ patiencecardgame.h \
+ canvascardwindow.h
+SOURCES = canvascard.cpp \
+ canvasshapes.cpp \
+ cardgame.cpp \
+ cardgamelayout.cpp \
+ cardpile.cpp \
+ card.cpp \
+ carddeck.cpp \
+ canvascardgame.cpp \
+ freecellcardgame.cpp \
+ patiencecardgame.cpp \
+ canvascardwindow.cpp \
+ main.cpp
+OBJECTS = canvascard.o \
+ canvasshapes.o \
+ cardgame.o \
+ cardgamelayout.o \
+ cardpile.o \
+ card.o \
+ carddeck.o \
+ canvascardgame.o \
+ freecellcardgame.o \
+ patiencecardgame.o \
+ canvascardwindow.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_canvascardwindow.cpp
+OBJMOC = moc_canvascardwindow.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake solitaire.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=patience
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+canvascard.o: canvascard.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+canvasshapes.o: canvasshapes.cpp \
+ canvasshapes.h
+
+cardgame.o: cardgame.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h
+
+cardgamelayout.o: cardgamelayout.cpp \
+ cardgamelayout.h \
+ cardpile.h
+
+cardpile.o: cardpile.cpp \
+ cardpile.h \
+ card.h \
+ $(QPEDIR)/include/qpe/config.h
+
+card.o: card.cpp \
+ card.h \
+ $(QPEDIR)/include/qpe/config.h
+
+carddeck.o: carddeck.cpp \
+ card.h \
+ carddeck.h
+
+canvascardgame.o: canvascardgame.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ canvascardgame.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+freecellcardgame.o: freecellcardgame.cpp \
+ freecellcardgame.h \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+patiencecardgame.o: patiencecardgame.cpp \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+canvascardwindow.o: canvascardwindow.cpp \
+ canvascardwindow.h \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ freecellcardgame.h
+
+main.o: main.cpp \
+ canvascardwindow.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_canvascardwindow.o: moc_canvascardwindow.cpp \
+ canvascardwindow.h
+
+moc_canvascardwindow.cpp: canvascardwindow.h
+ $(MOC) canvascardwindow.h -o moc_canvascardwindow.cpp
+
+
diff --git a/noncore/games/solitaire/canvascard.cpp b/noncore/games/solitaire/canvascard.cpp
new file mode 100644
index 0000000..ae3c859
--- a/dev/null
+++ b/noncore/games/solitaire/canvascard.cpp
@@ -0,0 +1,282 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardgame.h"
+#include "canvascard.h"
+
+#include <qpe/resource.h>
+
+#include <qpainter.h>
+#include <qimage.h>
+#include <qpaintdevice.h>
+#include <qbitmap.h>
+
+#include <math.h>
+
+#if defined( QT_QWS_CASSIOPEIA )
+#define SLOW_HARDWARE
+#endif
+
+// Seems to be fast enough to me even without Transformations in the library
+//#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ )
+//#define SLOW_HARDWARE
+//#endif
+
+
+QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap)
+{
+#ifdef QT_NO_TRANSFORMATIONS
+ int w = srcBitmap->width();
+ int h = srcBitmap->height();
+ QBitmap *dstBitmap = new QBitmap( w, h );
+ // ### this is very poorly implemented and probably could be much faster
+ for (int i = 0; i < w; i++)
+ for (int j = 0; j < h; j++)
+ bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 );
+ return dstBitmap;
+#else
+ QWMatrix m;
+ m.rotate( 180.0 );
+ return new QBitmap( srcBitmap->xForm( m ) );
+#endif
+}
+
+
+QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY)
+{
+#ifdef QT_NO_TRANSFORMATIONS
+ int w = srcPixmap->width();
+ int h = srcPixmap->height();
+ int newW = (int)(w * scaleX);
+ int newH = (int)(h * scaleY);
+ QPixmap *dstPixmap = new QPixmap( newW, newH );
+ // ### this is very poorly implemented and probably could be much faster
+ for (int i = 0; i < newW; i++) {
+ int srcX = w * i / newW;
+ if (newH == h) {
+ // Optimise for scaleing in the X-axis only
+ bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h );
+ } else {
+ for (int j = 0; j < newH; j++) {
+ int srcY = h * j / newH;
+ bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 );
+ }
+ }
+ }
+ return dstPixmap;
+#else
+ QWMatrix s;
+ s.scale( scaleX, scaleY );
+ return new QPixmap( srcPixmap->xForm( s ) );
+#endif
+}
+
+
+// Initialise static member variables to NULL
+QPixmap *CanvasCard::cardsFaces = NULL;
+QPixmap *CanvasCard::cardsBacks = NULL;
+QBitmap *CanvasCard::cardsChars = NULL;
+QBitmap *CanvasCard::cardsSuits = NULL;
+QBitmap *CanvasCard::cardsCharsUpsideDown = NULL;
+QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL;
+
+
+CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) :
+ Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0)
+{
+ if ( !cardsFaces ) {
+ cardsFaces = new QPixmap( Resource::loadPixmap( "cards/card_face" ) );
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) );
+ cardsChars = new QBitmap( Resource::loadBitmap( "cards/card_chars" ) );
+ cardsSuits = new QBitmap( Resource::loadBitmap( "cards/card_suits" ) );
+ cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars );
+ cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits );
+ }
+ xOff = cardsFaces->width() / 2;
+ yOff = cardsFaces->height() / 2;
+ setSize( cardsFaces->width(), cardsFaces->height() );
+ setPen( NoPen );
+ flipping = FALSE;
+}
+
+
+void CanvasCard::setCardBack(int b)
+{
+ if ( cardBack != b ) {
+
+ cardBack = b;
+
+ if ( cardsBacks )
+ delete cardsBacks;
+
+ switch (cardBack) {
+ case 0:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); break;
+ case 1:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0002" ) ); break;
+ case 2:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0003" ) ); break;
+ case 3:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0004" ) ); break;
+ case 4:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0005" ) ); break;
+ }
+
+ if ( !isFacing() )
+ redraw();
+ }
+}
+
+
+void CanvasCard::draw(QPainter &painter)
+{
+ int ix = (int)x(), iy = (int)y();
+
+ QPainter *p = &painter;
+ QPixmap *unscaledCard = NULL;
+
+ if ((scaleX <= 0.98) || (scaleY <= 0.98))
+ {
+ p = new QPainter();
+ unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() );
+ p->begin(unscaledCard);
+ ix = 0;
+ iy = 0;
+ }
+
+ if ( isFacing() ) {
+
+/*
+ // Now add the joker and card backs to the list of pixmaps
+ QPixmap *CardsBack = new QPixmap( Resource::loadPixmap( "cards/card_joker.png" ) );
+ QPoint *newBackHotspot = new QPoint( 0, 0 );
+ pixmaps->append((const QPixmap *)CardsBack);
+ hotspots->append((const QPoint *)newBackHotspot);
+*/
+
+ int w = cardsFaces->width(), h = cardsFaces->height();
+
+// p->setBrush( NoBrush );
+ p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) );
+
+ if ( isRed() == TRUE )
+ p->setPen( QColor( 0xFF, 0, 0 ) );
+ else
+ p->setPen( QColor( 0, 0, 0 ) );
+
+ p->drawPixmap( ix + 0, iy + 0, *cardsFaces );
+ p->drawPixmap( ix + 4, iy + 4, *cardsChars, 7*(getValue()-1), 0, 7, 7 );
+ p->drawPixmap( ix + 12, iy + 4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 );
+ p->drawPixmap( ix + w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 );
+ p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 );
+
+ } else {
+
+ p->drawPixmap( ix, iy, *cardsBacks );
+
+ }
+
+ if (p != &painter)
+ {
+ p->end();
+ QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY );
+ int xoff = scaledCard->width() / 2;
+ int yoff = scaledCard->height() / 2;
+ painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard );
+ delete p;
+ delete unscaledCard;
+ delete scaledCard;
+ }
+}
+
+
+static const double flipLift = 1.5;
+
+
+void CanvasCard::flipTo(int x2, int y2, int steps)
+{
+ flipSteps = steps;
+
+#ifdef SLOW_HARDWARE
+ move(x2,y2);
+ Card::flipTo(x2,y2,steps);
+#else
+ int x1 = (int)x();
+ int y1 = (int)y();
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+
+ flipping = TRUE;
+ destX = x2;
+ destY = y2;
+ animSteps = flipSteps;
+ setVelocity(dx/animSteps, dy/animSteps-flipLift);
+ setAnimated(TRUE);
+#endif
+}
+
+
+void CanvasCard::advance(int stage)
+{
+ if ( stage==1 ) {
+ if ( animSteps-- <= 0 ) {
+ scaleX = 1.0;
+ scaleY = 1.0;
+ flipping = FALSE;
+ setVelocity(0,0);
+ setAnimated(FALSE);
+ move(destX,destY); // exact
+ } else {
+ if ( flipping ) {
+ if ( animSteps > flipSteps / 2 ) {
+ // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0
+ scaleX = ((double)animSteps/flipSteps-0.5)*2;
+ } else {
+ // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1
+ scaleX = 1-((double)animSteps/flipSteps)*2;
+ }
+ if ( animSteps == flipSteps / 2-1 ) {
+ setYVelocity(yVelocity()+flipLift*2);
+ setFace( !isFacing() );
+ }
+ }
+ }
+ }
+ QCanvasRectangle::advance(stage);
+}
+
+
+void CanvasCard::animatedMove(int x2, int y2, int steps)
+{
+ destX = x2;
+ destY = y2;
+
+ double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
+
+ // Ensure a good speed
+ while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
+ steps--;
+
+ setAnimated(TRUE);
+ setVelocity(dx/steps, dy/steps);
+
+ animSteps = steps;
+}
+
diff --git a/noncore/games/solitaire/canvascard.h b/noncore/games/solitaire/canvascard.h
new file mode 100644
index 0000000..cd9691f
--- a/dev/null
+++ b/noncore/games/solitaire/canvascard.h
@@ -0,0 +1,82 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_H
+#define CANVAS_CARD_H
+
+
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qpixmap.h>
+#include <qpoint.h>
+#include <qcanvas.h>
+#include "cardgame.h"
+
+
+// ### Just made the number up, is that what you do???
+static const int canvasCardId = 2434321;
+
+
+class CanvasCard : public Card, public QCanvasRectangle
+{
+public:
+ CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas );
+ virtual ~CanvasCard() { canvas()->removeItem(this); }
+
+ int rtti () const { return canvasCardId; }
+ void move(QPoint p) { QCanvasItem::move( p.x(), p.y() ); }
+ void move(int x, int y) { QCanvasItem::move( x, y ); }
+ void animatedMove(int x, int y, int steps = 10);
+ void animatedMove() { animatedMove(savedX, savedY); }
+ void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
+ void moveToPile(int p) { Q_UNUSED(p); }
+ void setCardBack(int b);
+
+ /*virtual*/ void flipTo(int x, int y, int steps = 8);
+ /*virtual*/ void setPos( int x, int y, int z ) { setX( x ); setY( y ); setZ( z ); }
+ /*virtual*/ void showCard(void) { show(); }
+ /*virtual*/ void redraw(void) { hide(); show(); }
+ /*virtual*/ void draw(QPainter &p);
+
+ void advance(int stage);
+
+protected:
+ /*virtual*/ void flip(void) { redraw(); }
+
+private:
+ int destX, destY;
+ int animSteps;
+ int flipSteps;
+ bool flipping;
+ int savedX, savedY;
+ int cardBack;
+ int oldCardBack;
+ double scaleX, scaleY;
+ int xOff, yOff;
+ static QPixmap *cardsFaces;
+ static QPixmap *cardsBacks;
+ static QBitmap *cardsChars;
+ static QBitmap *cardsSuits;
+ static QBitmap *cardsCharsUpsideDown;
+ static QBitmap *cardsSuitsUpsideDown;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/canvascardgame.cpp b/noncore/games/solitaire/canvascardgame.cpp
new file mode 100644
index 0000000..32635a0
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardgame.cpp
@@ -0,0 +1,380 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardgame.h"
+#include "canvasshapes.h"
+#include "canvascard.h"
+#include "canvascardgame.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qpe/qpemenubar.h>
+#include <qpainter.h>
+
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+#include <math.h>
+
+
+extern int highestZ;
+
+
+class CanvasCardPile : public QCanvasRectangle
+{
+public:
+ CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) {
+ pile = new QPixmap( 0, 0 );
+ pileHeight = 0;
+ firstCard = NULL;
+ }
+
+ void addCard( CanvasCard *card );
+ void advance(int stage);
+ void animatedMove() { animatedMove(savedX, savedY); }
+ void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
+ void animatedMove(int x2, int y2, int steps = 7 );
+
+protected:
+ virtual void draw( QPainter& p );
+
+private:
+ CanvasCardGame *parent;
+ QPixmap *pile;
+ QImage tempImage32;
+ CanvasCard *firstCard;
+ int pileHeight;
+ int destX, destY;
+ int savedX, savedY;
+ int animSteps;
+};
+
+
+void CanvasCardPile::addCard( CanvasCard *card )
+{
+ if ( !firstCard )
+ firstCard = card;
+
+ int height = 36 + pileHeight * 13;
+ setSize( 23, height );
+ pile->resize( 23, height );
+ QPainter p( pile );
+ p.translate( -card->x(), -card->y() + pileHeight * 13 );
+ card->draw( p );
+ pileHeight++;
+
+ QImage tempImage;
+ tempImage = *pile;
+ tempImage32 = tempImage.convertDepth( 32 );
+ tempImage32.setAlphaBuffer( TRUE );
+ for ( int i = 0; i < tempImage32.width(); i++ )
+ for ( int j = 0; j < tempImage32.height(); j++ ) {
+ QRgb col = tempImage32.pixel( i, j );
+ int a = 255-j*220/tempImage32.height();
+ QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a );
+ tempImage32.setPixel( i, j, alpha );
+ }
+
+ QRgb alpha = qRgba( 0, 0, 0, 0 );
+ tempImage32.setPixel( 1, 0, alpha );
+ tempImage32.setPixel( 0, 0, alpha );
+ tempImage32.setPixel( 0, 1, alpha );
+
+ tempImage32.setPixel( 21, 0, alpha );
+ tempImage32.setPixel( 22, 0, alpha );
+ tempImage32.setPixel( 22, 1, alpha );
+ height--;
+ tempImage32.setPixel( 1, height, alpha );
+ tempImage32.setPixel( 0, height - 1, alpha );
+ tempImage32.setPixel( 0, height, alpha );
+
+ tempImage32.setPixel( 21, height, alpha );
+ tempImage32.setPixel( 22, height, alpha );
+ tempImage32.setPixel( 22, height - 1, alpha );
+}
+
+
+void CanvasCardPile::advance(int stage)
+{
+ if ( stage==1 ) {
+ if ( animSteps-- <= 0 ) {
+ CanvasCard *item = firstCard;
+ while (item) {
+ item->show();
+ item = (CanvasCard *)item->getCardPile()->cardInfront(item);
+ }
+ setVelocity(0,0);
+ setAnimated(FALSE);
+ parent->cancelMoving();
+ hide();
+ move(destX,destY); // exact
+ }
+ }
+ QCanvasRectangle::advance(stage);
+}
+
+
+void CanvasCardPile::animatedMove(int x2, int y2, int steps = 7 )
+{
+ destX = x2;
+ destY = y2;
+
+ double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
+
+ // Ensure a good speed
+ while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
+ steps--;
+
+ setAnimated(TRUE);
+ setVelocity(dx/steps, dy/steps);
+
+ animSteps = steps;
+}
+
+
+void CanvasCardPile::draw( QPainter& p )
+{
+ int ix = (int)x(), iy = (int)y();
+ p.drawImage( ix, iy, tempImage32 );
+}
+
+
+CanvasCardGame::~CanvasCardGame() {
+ // the deletion stuff should be fixed now and only deletes
+ // items created by this CardGame. I haven't verified there are zero
+ // memory leaks yet
+ if ( alphaCardPile )
+ delete alphaCardPile;
+}
+
+
+void CanvasCardGame::gameWon() {
+
+ srand(time(NULL));
+
+ QCanvasItemList list = canvas()->allItems();
+ QCanvasItemList::Iterator it = list.begin();
+
+ for (; it != list.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ // disperse the cards everywhere
+ int x = 300 - rand() % 1000;
+ int y = 300 + rand() % 200;
+ ((CanvasCard *)*it)->animatedMove( x, y, 50 );
+ }
+ }
+}
+
+
+void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) {
+
+ if ( moving )
+ return;
+
+ QCanvasItemList l = canvas()->collisions( e->pos() );
+
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ if ( (*it)->rtti() == canvasCardId ) {
+
+ moving = (CanvasCard *)*it;
+
+ if ( moving->animated() )
+ return;
+
+ cardXOff = (int)(e->pos().x() - moving->x());
+ cardYOff = (int)(e->pos().y() - moving->y());
+
+ if ( !mousePressCard( moving, e->pos() ) ) {
+ CanvasCard *card = moving;
+
+ if ( alphaCardPile )
+ delete alphaCardPile;
+
+ alphaCardPile = new CanvasCardPile( this, canvas() );
+ alphaCardPile->move( card->x(), card->y() );
+ alphaCardPile->savePos();
+ alphaCardPile->show();
+
+ while (card) {
+ alphaCardPile->addCard( card );
+ card->hide();
+ card = (CanvasCard *)card->getCardPile()->cardInfront(card);
+ }
+
+ alphaCardPile->setZ( INT_MAX );
+
+ moved = TRUE;
+ } else {
+ if ( alphaCardPile )
+ alphaCardPile->hide();
+ }
+ return;
+ }
+ }
+
+ mousePress( e->pos() );
+}
+
+/*
+//
+// Should have some intelligent way to make double clicking on a
+// card send it to the most appropriate pile
+//
+void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) {
+ QCanvasItemList l = canvas()->collisions( e->pos() );
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ CanvasCard *card = (CanvasCard *)*it;
+
+ if ( card->animated() )
+ return;
+
+ if ( card->getCardPile()->isAllowedToBeMoved(card) ) {
+ if (card->getCardPile()->cardInfront(card) == NULL) {
+ CardPile *pile = first();
+ if (pile && pile->isAllowedOnTop(card)) {
+ // move card to this pile
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+*/
+
+void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) {
+
+ QPoint p = e->pos();
+
+ if ( moving ) {
+
+ moved = TRUE;
+
+ if (moving->isFacing() != TRUE)
+ return;
+
+ int tx = (int)p.x() - cardXOff;
+ int ty = (int)p.y() - cardYOff;
+
+ if (snapOn == TRUE) {
+ CardPile *pile = closestPile( tx, ty, 50 );
+ if ( pile && pile->isAllowedOnTop( moving ) ) {
+ QPoint p = pile->getHypertheticalNextCardPos();
+ if ( alphaCardPile )
+ alphaCardPile->move( p.x(), p.y() );
+ return;
+ }
+ }
+
+ if ( alphaCardPile )
+ alphaCardPile->move( tx, ty );
+ }
+
+}
+
+
+void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ QPoint p = e->pos();
+
+ Q_UNUSED(p);
+
+ if ( moving ) {
+
+ CanvasCard *item = moving;
+
+ if ( item->animated() )
+ return;
+
+ if ( alphaCardPile )
+ if ( moved ) {
+
+ CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30);
+
+ if (pile && pile->isAllowedOnTop(item)) {
+ CardPile *oldPile = item->getCardPile();
+ Card *c = NULL;
+ if ( oldPile != pile) {
+ while ( item ) {
+ item->show();
+ if ( oldPile ) {
+ c = oldPile->cardInfront(item);
+ oldPile->removeCard(item);
+ }
+ pile->addCardToTop(item);
+ item->setCardPile(pile);
+ //item->move( pile->getCardPos(item) );
+ QPoint p = pile->getCardPos(item);
+ item->setPos( p.x(), p.y(), highestZ );
+ highestZ++;
+
+ if (item->getValue() == king && haveWeWon()) {
+ alphaCardPile->hide();
+ gameWon();
+ moving = NULL;
+ return;
+ }
+
+ if (oldPile) {
+ item = (CanvasCard *)c;
+ } else {
+ item = NULL;
+ }
+ }
+ alphaCardPile->hide();
+ moving = NULL;
+ return;
+ }
+ }
+
+ alphaCardPile->animatedMove();
+ }
+ }
+
+ moved = FALSE;
+}
+
+
+void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ )
+{
+ cfg.setGroup( name );
+ int numberOfCards = cfg.readNumEntry("NumberOfCards", 0);
+ Card *card = NULL;
+ for ( int i = 0; i < numberOfCards; i++ ) {
+ QString cardStr;
+ cardStr.sprintf( "%i", i );
+ int val = cfg.readNumEntry( "Card" + cardStr );
+ bool facing = cfg.readBoolEntry( "CardFacing" + cardStr );
+ card = cards[ val ];
+ card->setFace(facing);
+ pile->addCardToTop(card);
+ card->setCardPile(pile);
+ QPoint p = pile->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+}
+
+
diff --git a/noncore/games/solitaire/canvascardgame.h b/noncore/games/solitaire/canvascardgame.h
new file mode 100644
index 0000000..4d32014
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardgame.h
@@ -0,0 +1,95 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_GAME_H
+#define CANVAS_CARD_GAME_H
+
+#include "cardgame.h"
+#include "canvasshapes.h"
+#include "canvascard.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qpe/qpemenubar.h>
+#include <qpainter.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+
+class CanvasCardPile;
+
+
+class CanvasCardGame : public QCanvasView, public CardGame
+{
+public:
+ CanvasCardGame(QCanvas &c, bool snap, QWidget *parent = 0, const char *name = 0, WFlags f = 0) :
+ QCanvasView( &c, parent, name, f ),
+ moved(FALSE),
+ moving(NULL),
+ alphaCardPile( NULL ),
+ cardXOff(0), cardYOff(0),
+ snapOn(snap),
+ numberToDraw(1) { }
+
+ virtual ~CanvasCardGame();
+
+ virtual Card *newCard( eValue v, eSuit s, bool f ) {
+ return new CanvasCard( v, s, f, canvas() );
+ }
+
+ virtual void readConfig( Config& cfg ) { Q_UNUSED( cfg ); }
+ virtual void writeConfig( Config& cfg ) { Q_UNUSED( cfg ); }
+
+ virtual void gameWon();
+ virtual bool haveWeWon() { return FALSE; }
+
+ virtual bool mousePressCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); return FALSE; }
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+
+ void cancelMoving() { moving = NULL; }
+ void toggleSnap() { snapOn = (snapOn == TRUE) ? FALSE : TRUE; }
+ void toggleCardsDrawn() { numberToDraw = (numberToDraw == 1) ? 3 : 1; }
+ int cardsDrawn() { return numberToDraw; }
+ void setNumberToDraw(int numToDraw) { this->numberToDraw = numToDraw; }
+
+ void readPile( Config& cfg, CardPile *pile, QString name, int& highestZ );
+
+protected:
+ void contentsMousePressEvent(QMouseEvent *e);
+ void contentsMouseReleaseEvent(QMouseEvent *e);
+ void contentsMouseMoveEvent(QMouseEvent *e);
+
+protected:
+ // Mouse event state variables
+ bool moved;
+ CanvasCard *moving;
+ CanvasCardPile *alphaCardPile;
+ int cardXOff, cardYOff;
+
+private:
+ bool snapOn;
+ int numberToDraw;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/canvascardwindow.cpp b/noncore/games/solitaire/canvascardwindow.cpp
new file mode 100644
index 0000000..4c365a5
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardwindow.cpp
@@ -0,0 +1,227 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "canvascardwindow.h"
+#include "patiencecardgame.h"
+#include "freecellcardgame.h"
+
+#include <qpe/resource.h>
+
+#include <qmainwindow.h>
+#include <qpopupmenu.h>
+#include <qstyle.h>
+
+
+CanvasCardWindow::CanvasCardWindow(QWidget* parent, const char* name, WFlags f) :
+ QMainWindow(parent, name, f), canvas(230, 260), snapOn(TRUE), cardBack(4), gameType(0),
+ cardGame(NULL)
+{
+ setIcon( Resource::loadPixmap( "cards" ) );
+
+ // Create Playing Area for Games
+ if ( QPixmap::defaultDepth() < 12 ) {
+// canvas.setBackgroundColor(QColor(0x51, 0x74, 0x6B));
+// canvas.setBackgroundColor(QColor(0x20, 0xb0, 0x50));
+ canvas.setBackgroundColor(QColor(0x08, 0x98, 0x2D));
+ } else {
+ QPixmap bg;
+ bg.convertFromImage( Resource::loadImage( "table_pattern" ), ThresholdDither );
+ canvas.setBackgroundPixmap(bg);
+ }
+
+#if defined( QT_QWS_CASSIOPEIA )
+ canvas.setAdvancePeriod(70);
+#else
+ canvas.setAdvancePeriod(30);
+#endif
+
+
+#ifdef _PATIENCE_USE_ACCELS_
+ QPEMenuBar* menu = menuBar();
+
+ QPopupMenu* file = new QPopupMenu;
+ file->insertItem(tr("Patience"), this, SLOT(initPatience()), CTRL+Key_F);
+ file->insertItem(tr("Freecell"), this, SLOT(initFreecell()), CTRL+Key_F);
+ menu->insertItem(tr("&Game"), file);
+
+ menu->insertSeparator();
+
+ settings = new QPopupMenu;
+ settings->insertItem(tr("&Change Card Backs"), this, SLOT(changeCardBacks()), Key_F2);
+ snap_id = settings->insertItem(tr("&Snap To Position"), this, SLOT(snapToggle()), Key_F3);
+ settings->setCheckable(TRUE);
+ menu->insertItem(tr("&Settings"),settings);
+
+ menu->insertSeparator();
+
+ QPopupMenu* help = new QPopupMenu;
+ help->insertItem(tr("&About"), this, SLOT(help()), Key_F1);
+ help->setItemChecked(dbf_id, TRUE);
+ menu->insertItem(tr("&Help"),help);
+#else
+ QMenuBar* menu = menuBar();
+
+ QPopupMenu* file = new QPopupMenu;
+ file->insertItem(tr("Patience"), this, SLOT(initPatience()));
+ file->insertItem(tr("Freecell"), this, SLOT(initFreecell()));
+ menu->insertItem(tr("Play"), file);
+
+ menu->insertSeparator();
+
+ settings = new QPopupMenu;
+ settings->setCheckable(TRUE);
+ settings->insertItem(tr("Change Card Backs"), this, SLOT(changeCardBacks()));
+ snap_id = settings->insertItem(tr("Snap To Position"), this, SLOT(snapToggle()));
+ QString m;
+
+ drawId = settings->insertItem(tr("Turn One Card"), this, SLOT(drawnToggle()));
+ menu->insertItem(tr("Settings"),settings);
+
+#endif
+
+ menu->show();
+
+ Config cfg( "Patience" );
+ cfg.setGroup( "GlobalSettings" );
+ snapOn = cfg.readBoolEntry( "SnapOn", TRUE);
+ settings->setItemChecked(snap_id, snapOn);
+ gameType = cfg.readNumEntry( "GameType", -1 );
+ drawThree = cfg.readBoolEntry( "DrawThree", TRUE);
+ if ( gameType == 0 ) {
+ cardGame = new PatienceCardGame( &canvas, snapOn, this );
+ cardGame->setNumberToDraw(drawThree ? 3 : 1);
+ setCaption(tr("Patience"));
+ setCentralWidget(cardGame);
+ cardGame->readConfig( cfg );
+ setCardBacks();
+ } else if ( gameType == 1 ) {
+ cardGame = new FreecellCardGame( &canvas, snapOn, this );
+ setCaption(tr("Freecell"));
+ setCentralWidget(cardGame);
+ //cardGame->newGame(); // Until we know how to handle reading freecell config
+ cardGame->readConfig( cfg );
+ setCardBacks();
+ } else {
+ // Probably there isn't a config file or it is broken
+ // Start a new game
+ initPatience();
+ }
+
+ updateDraw();
+}
+
+
+CanvasCardWindow::~CanvasCardWindow()
+{
+ if (cardGame) {
+ Config cfg("Patience");
+ cfg.setGroup( "GlobalSettings" );
+ cfg.writeEntry( "GameType", gameType );
+ cfg.writeEntry( "SnapOn", snapOn );
+ cfg.writeEntry( "DrawThree", drawThree);
+ cardGame->writeConfig( cfg );
+ delete cardGame;
+ }
+}
+
+
+void CanvasCardWindow::resizeEvent(QResizeEvent *)
+{
+ QSize s = centralWidget()->size();
+ int fw = style().defaultFrameWidth();
+ canvas.resize( s.width() - fw - 2, s.height() - fw - 2);
+}
+
+
+void CanvasCardWindow::initPatience()
+{
+ // Create New Game
+ if ( cardGame )
+ delete cardGame;
+ cardGame = new PatienceCardGame( &canvas, snapOn, this );
+ cardGame->setNumberToDraw(drawThree ? 3 : 1);
+ gameType = 0;
+ setCaption(tr("Patience"));
+ setCentralWidget(cardGame);
+ cardGame->newGame();
+ setCardBacks();
+ updateDraw();
+}
+
+
+void CanvasCardWindow::initFreecell()
+{
+ // Create New Game
+ if ( cardGame ) {
+ delete cardGame;
+ }
+ cardGame = new FreecellCardGame( &canvas, snapOn, this );
+ gameType = 1;
+ setCaption(tr("Freecell"));
+ setCentralWidget(cardGame);
+ cardGame->newGame();
+ setCardBacks();
+}
+
+
+void CanvasCardWindow::snapToggle()
+{
+ snapOn = !snapOn;
+ settings->setItemChecked(snap_id, snapOn);
+ cardGame->toggleSnap();
+}
+
+
+void CanvasCardWindow::drawnToggle()
+{
+ cardGame->toggleCardsDrawn();
+ updateDraw();
+}
+
+void CanvasCardWindow::updateDraw() {
+ if(cardGame->cardsDrawn() == 3)
+ settings->changeItem(drawId, tr("Turn One Card"));
+ else
+ settings->changeItem(drawId, tr("Turn Three Cards"));
+}
+
+
+void CanvasCardWindow::setCardBacks()
+{
+ QCanvasItemList l = canvas.allItems();
+
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId )
+ ((CanvasCard *)(*it))->setCardBack( cardBack );
+ }
+}
+
+
+void CanvasCardWindow::changeCardBacks()
+{
+ cardBack++;
+
+ if (cardBack == 5)
+ cardBack = 0;
+
+ setCardBacks();
+}
+
+
diff --git a/noncore/games/solitaire/canvascardwindow.h b/noncore/games/solitaire/canvascardwindow.h
new file mode 100644
index 0000000..b75d40a
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardwindow.h
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_WINDOW_H
+#define CANVAS_CARD_WINDOW_H
+
+
+#include <qmainwindow.h>
+#include <qcanvas.h>
+
+
+class CanvasCardGame;
+class QPopupMenu;
+
+
+class CanvasCardWindow : public QMainWindow {
+ Q_OBJECT
+
+public:
+ CanvasCardWindow(QWidget* parent=0, const char* name=0, WFlags f=0);
+ virtual ~CanvasCardWindow();
+
+public slots:
+ void setCardBacks();
+ void changeCardBacks();
+ void snapToggle();
+ void drawnToggle();
+
+private slots:
+ void initFreecell();
+ void initPatience();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+
+ void updateDraw();
+private:
+ QCanvas canvas;
+ bool snapOn;
+ bool drawThree;
+ int drawId;
+ int cardBack;
+ int gameType;
+ CanvasCardGame *cardGame;
+
+ QPopupMenu* options;
+ QPopupMenu* settings;
+ int dbf_id;
+ int snap_id;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/canvasshapes.cpp b/noncore/games/solitaire/canvasshapes.cpp
new file mode 100644
index 0000000..28d0b4e
--- a/dev/null
+++ b/noncore/games/solitaire/canvasshapes.cpp
@@ -0,0 +1,92 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpainter.h>
+#include <qcanvas.h>
+#include "canvasshapes.h"
+
+
+CanvasRoundRect::CanvasRoundRect(int x, int y, QCanvas *canvas) :
+ QCanvasRectangle( x, y, 23, 36, canvas)
+{
+ setZ(0);
+ show();
+}
+
+
+void CanvasRoundRect::redraw()
+{
+ hide();
+ show();
+}
+
+
+void CanvasRoundRect::drawShape(QPainter &p)
+{
+ p.drawRoundRect( (int)x(), (int)y(), 23, 36);
+}
+
+
+CanvasCircleOrCross::CanvasCircleOrCross(int x, int y, QCanvas *canvas) :
+ QCanvasRectangle( x, y, 21, 21, canvas), circleShape(TRUE)
+{
+ show();
+}
+
+
+void CanvasCircleOrCross::redraw()
+{
+ hide();
+ show();
+}
+
+
+void CanvasCircleOrCross::setCircle()
+{
+ circleShape = TRUE;
+ redraw();
+}
+
+
+void CanvasCircleOrCross::setCross()
+{
+ circleShape = FALSE;
+ redraw();
+}
+
+
+void CanvasCircleOrCross::drawShape(QPainter &p)
+{
+ int x1 = (int)x(), y1 = (int)y();
+ // Green circle
+ if (circleShape == TRUE) {
+ p.setPen( QPen( QColor(0x10, 0xE0, 0x10), 1 ) );
+ p.drawEllipse( x1 - 1, y1 - 1, 21, 21);
+ p.drawEllipse( x1 - 1, y1 - 0, 21, 19);
+ p.drawEllipse( x1 + 0, y1 + 0, 19, 19);
+ p.drawEllipse( x1 + 1, y1 + 0, 17, 19);
+ p.drawEllipse( x1 + 1, y1 + 1, 17, 17);
+ // Red cross
+ } else {
+ p.setPen( QPen( QColor(0xE0, 0x10, 0x10), 5 ) );
+ p.drawLine( x1, y1, x1 + 20, y1 + 20);
+ p.drawLine( x1 + 20, y1, x1, y1 + 20);
+ }
+}
+
diff --git a/noncore/games/solitaire/canvasshapes.h b/noncore/games/solitaire/canvasshapes.h
new file mode 100644
index 0000000..72acf6b
--- a/dev/null
+++ b/noncore/games/solitaire/canvasshapes.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_SHAPES_H
+#define CANVAS_SHAPES_H
+
+
+#include <qcanvas.h>
+
+
+class QPainter;
+
+
+class CanvasRoundRect : QCanvasRectangle
+{
+public:
+ CanvasRoundRect(int x, int y, QCanvas *canvas);
+ void redraw();
+protected:
+ void drawShape(QPainter &p);
+};
+
+
+class CanvasCircleOrCross : QCanvasRectangle
+{
+public:
+ CanvasCircleOrCross(int x, int y, QCanvas *canvas);
+ void redraw();
+ void setCircle();
+ void setCross();
+protected:
+ void drawShape(QPainter &p);
+private:
+ bool circleShape;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/card.cpp b/noncore/games/solitaire/card.cpp
new file mode 100644
index 0000000..609e280
--- a/dev/null
+++ b/noncore/games/solitaire/card.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "card.h"
+
+#include <qpe/config.h>
+
+#include <qpoint.h>
+#include <qlist.h>
+
+/*
+Card( eValue v, eSuit s, bool f ) :
+ val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { }
+virtual ~Card() { }
+eValue getValue() { return val; }
+eSuit getSuit() { return suit; }
+CardPile *getCardPile() { return cardPile; }
+bool isFacing() { return faceUp; }
+bool isShowing() { return showing; }
+bool isRed() { return ((suit == diamonds) || (suit == hearts)); }
+int getX(void) { return ix; }
+int getY(void) { return iy; }
+int getZ(void) { return iz; }
+void setCardPile(CardPile *p) { cardPile = p; }
+void setFace(bool f) { faceUp = f; }
+void flip(void) { flipTo(getX(), getY()); }
+virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; }
+virtual void move(int x, int y) { ix = x; iy = y; }
+virtual void move(QPoint p) { ix = p.x(); iy = p.y(); }
+virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); }
+virtual void showCard(void) { showing = TRUE; }
+virtual void hideCard(void) { showing = FALSE; }
+virtual void redraw(void) { }
+*/
+
+
diff --git a/noncore/games/solitaire/card.h b/noncore/games/solitaire/card.h
new file mode 100644
index 0000000..eb30d30
--- a/dev/null
+++ b/noncore/games/solitaire/card.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_H
+#define CARD_H
+
+
+#include <qpoint.h>
+
+
+class CardPile;
+
+
+enum eSuit {
+ jokerSuit = 0, clubs, spades, diamonds, hearts
+};
+
+
+enum eValue {
+ jokerVal = 0, ace, two, three, four, five,
+ six, seven, eight, nine, ten, jack, queen, king
+};
+
+
+class Card
+{
+public:
+ Card( eValue v, eSuit s, bool f ) :
+ val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { }
+ virtual ~Card() { }
+
+ eValue getValue() { return val; }
+ eSuit getSuit() { return suit; }
+
+ void setCardPile(CardPile *p) { cardPile = p; }
+ CardPile *getCardPile() { return cardPile; }
+
+ void setFace(bool f) { faceUp = f; /* flip(); */ }
+ bool isFacing() { return faceUp; }
+
+ bool isShowing() { return showing; }
+ bool isRed() { return ((suit == diamonds) || (suit == hearts)); }
+
+ int getX(void) { return ix; }
+ int getY(void) { return iy; }
+ int getZ(void) { return iz; }
+ void flip(void) { flipTo(getX(), getY()); }
+
+ virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; }
+ virtual void move(int x, int y) { ix = x; iy = y; }
+ virtual void move(QPoint p) { ix = p.x(); iy = p.y(); }
+ virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); }
+ virtual void showCard(void) { showing = TRUE; }
+ virtual void hideCard(void) { showing = FALSE; }
+protected:
+ virtual void redraw(void) { }
+private:
+ eValue val;
+ eSuit suit;
+ bool faceUp;
+ bool showing;
+ int ix, iy, iz;
+ CardPile *cardPile;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/carddeck.cpp b/noncore/games/solitaire/carddeck.cpp
new file mode 100644
index 0000000..87c043a
--- a/dev/null
+++ b/noncore/games/solitaire/carddeck.cpp
@@ -0,0 +1,81 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdlib.h>
+#include <time.h>
+#include "card.h"
+#include "carddeck.h"
+
+
+CardDeck::CardDeck(int jokers) : numberOfJokers(jokers), deckCreated(FALSE)
+{
+ cards = new (Card *)[getNumberOfCards()];
+}
+
+
+CardDeck::~CardDeck()
+{
+ for (int i = 0; i < getNumberOfCards(); i++)
+ delete cards[i];
+ delete cards;
+}
+
+
+void CardDeck::createDeck()
+{
+ if (!deckCreated) {
+ for (int i = 0; i < 52; i++)
+ cards[i] = newCard( (eValue)((i % 13) + 1), (eSuit)((i / 13) + 1), FALSE );
+ for (int i = 0; i < getNumberOfJokers(); i++)
+ cards[52 + i] = newCard( jokerVal, jokerSuit, FALSE );
+ deckCreated = TRUE;
+ }
+}
+
+
+void CardDeck::shuffle()
+{
+ srand(time(NULL));
+ for (int i = 0; i < getNumberOfCards(); i++) {
+ int index = rand() % getNumberOfCards();
+ Card *tmpCard = cards[i];
+ cards[i] = cards[index];
+ cards[index] = tmpCard;
+ }
+}
+
+
+int CardDeck::getNumberOfCards()
+{
+ return 52 + getNumberOfJokers();
+}
+
+
+int CardDeck::getNumberOfJokers()
+{
+ return numberOfJokers;
+}
+
+
+Card *CardDeck::newCard( eValue v, eSuit s, bool f )
+{
+ return new Card(v, s, f);
+}
+
+
diff --git a/noncore/games/solitaire/carddeck.h b/noncore/games/solitaire/carddeck.h
new file mode 100644
index 0000000..9ad35a9
--- a/dev/null
+++ b/noncore/games/solitaire/carddeck.h
@@ -0,0 +1,49 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_DECK_H
+#define CARD_DECK_H
+
+
+class Card;
+
+
+class CardDeck
+{
+public:
+ CardDeck(int jokers = 0);
+ virtual ~CardDeck();
+
+ void createDeck();
+ void shuffle();
+ int getNumberOfCards();
+ int getNumberOfJokers();
+
+ virtual Card *newCard( eValue v, eSuit s, bool f );
+ virtual void deal() { }
+
+ Card **cards;
+private:
+ int numberOfJokers;
+ bool deckCreated;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardgame.cpp b/noncore/games/solitaire/cardgame.cpp
new file mode 100644
index 0000000..b19aeef
--- a/dev/null
+++ b/noncore/games/solitaire/cardgame.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "cardgame.h"
+
+
+void CardGame::newGame()
+{
+ // Create Cards
+ createDeck();
+
+ // Shuffle Cards
+ shuffle();
+
+ // Deal Cards
+ deal();
+}
+
+
diff --git a/noncore/games/solitaire/cardgame.h b/noncore/games/solitaire/cardgame.h
new file mode 100644
index 0000000..dd7efab
--- a/dev/null
+++ b/noncore/games/solitaire/cardgame.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_GAME_H
+#define CARD_GAME_H
+
+
+#include <qpoint.h>
+#include "card.h"
+#include "cardpile.h"
+#include "carddeck.h"
+#include "cardgamelayout.h"
+
+
+class CardGame : public CardGameLayout, public CardDeck
+{
+public:
+ CardGame(int numOfJokers = 0) : CardGameLayout(), CardDeck(numOfJokers) { }
+ virtual ~CardGame() { }
+ virtual void newGame();
+ virtual void mousePress(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseMove(QPoint p) { Q_UNUSED(p); }
+private:
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardgamelayout.cpp b/noncore/games/solitaire/cardgamelayout.cpp
new file mode 100644
index 0000000..1ceee8d
--- a/dev/null
+++ b/noncore/games/solitaire/cardgamelayout.cpp
@@ -0,0 +1,61 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "cardgamelayout.h"
+
+
+CardGameLayout::~CardGameLayout()
+{
+ // Should I just do setAutoDelete( TRUE ); ?
+ for (CardPile *p = first(); p != NULL; p = next())
+ delete p;
+}
+
+
+CardPile *CardGameLayout::closestPile(int x, int y, int maxDistance)
+{
+ int closestDistance = maxDistance * maxDistance;
+ CardPile *closestPile = NULL;
+
+ for (CardPile *p = first(); p != NULL; p = next()) {
+ int d = p->distanceFromNextPos(x, y);
+ if (d < closestDistance) {
+ closestDistance = d;
+ closestPile = p;
+ }
+ }
+
+ return closestPile;
+}
+
+
+void CardGameLayout::beginDealing()
+{
+ for (CardPile *p = first(); p != NULL; p = next())
+ p->beginDealing();
+}
+
+
+void CardGameLayout::endDealing()
+{
+ for (CardPile *p = first(); p != NULL; p = next())
+ p->endDealing();
+}
+
+
diff --git a/noncore/games/solitaire/cardgamelayout.h b/noncore/games/solitaire/cardgamelayout.h
new file mode 100644
index 0000000..bb36e6b
--- a/dev/null
+++ b/noncore/games/solitaire/cardgamelayout.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_GAME_LAYOUT_H
+#define CARD_GAME_LAYOUT_H
+
+
+#include <qlist.h>
+#include "cardpile.h"
+
+
+class CardGameLayout : public QList<CardPile>
+{
+public:
+ CardGameLayout() { }
+ virtual ~CardGameLayout();
+
+ void addCardPile(CardPile *pile) { append((const CardPile *)pile); }
+ CardPile *closestPile(int x, int y, int maxDistance);
+ void beginDealing();
+ void endDealing();
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardpile.cpp b/noncore/games/solitaire/cardpile.cpp
new file mode 100644
index 0000000..0b738d2
--- a/dev/null
+++ b/noncore/games/solitaire/cardpile.cpp
@@ -0,0 +1,114 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardpile.h"
+#include "card.h"
+
+#include <qpe/config.h>
+#include <qpoint.h>
+
+#include <qlist.h>
+
+
+CardPile::CardPile(int x, int y) : pileX(x), pileY(y), dealing(FALSE) {
+ pileWidth = 0;
+ pileHeight = 0;
+ pileNextX = pileX;
+ pileNextY = pileY;
+ pileCenterX = x + pileWidth / 2;
+ pileCenterY = y + pileHeight / 2;
+ pileRadius = (pileWidth > pileHeight) ? pileWidth : pileHeight;
+}
+
+
+int CardPile::distanceFromPile(int x, int y) {
+ return (pileCenterX-x)*(pileCenterX-x)+(pileCenterY-y)*(pileCenterY-y);
+}
+
+
+int CardPile::distanceFromNextPos(int x, int y) {
+ return (pileNextX-x)*(pileNextX-x)+(pileNextY-y)*(pileNextY-y);
+}
+
+
+Card *CardPile::cardInfront(Card *c) {
+ CardPile *p = c->getCardPile();
+ if (p) {
+ p->at(p->find(c));
+ return p->next();
+ } else {
+ return NULL;
+ }
+}
+
+
+bool CardPile::kingOnTop() {
+ Card *top = cardOnTop();
+ return top && top->getValue() == king;
+}
+
+
+bool CardPile::addCardToTop(Card *c) {
+ if (dealing || isAllowedOnTop(c)) {
+ append((const Card *)c);
+ cardAddedToTop(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool CardPile::addCardToBottom(Card *c) {
+ if (dealing || isAllowedOnBottom(c)) {
+ prepend((const Card *)c);
+ cardAddedToBottom(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool CardPile::removeCard(Card *c) {
+ if (dealing || isAllowedToBeMoved(c)) {
+ take(find(c));
+ cardRemoved(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void CardPile::writeConfig( Config& cfg, QString name ) {
+ int numberOfCards = 0;
+ cfg.setGroup( name );
+ Card *card = cardOnBottom();
+ while ( card ) {
+ QString cardStr;
+ cardStr.sprintf( "%i", numberOfCards );
+ int val = (int)card->getValue() - 1 + ( (int)card->getSuit() - 1 ) * 13;
+ cfg.writeEntry( "Card" + cardStr, val );
+ cfg.writeEntry( "CardFacing" + cardStr, card->isFacing() );
+ card = cardInfront( card );
+ numberOfCards++;
+ }
+ cfg.writeEntry("NumberOfCards", numberOfCards);
+}
+
+
diff --git a/noncore/games/solitaire/cardpile.h b/noncore/games/solitaire/cardpile.h
new file mode 100644
index 0000000..c515bbc
--- a/dev/null
+++ b/noncore/games/solitaire/cardpile.h
@@ -0,0 +1,101 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_PILE_H
+#define CARD_PILE_H
+
+
+#include <qpoint.h>
+#include <qlist.h>
+
+
+enum ePileStackingType {
+ pileCascades = 0, pileStacks, pileCascadesOrStacks
+};
+
+
+enum ePileFaceingType {
+ pileFaceUp = 0, pileFaceDown, pileFaceUpOrDown
+};
+
+
+class Card;
+class Config;
+
+
+class CardPile : public QList<Card>
+{
+public:
+ CardPile(int x, int y);
+ virtual ~CardPile() { }
+
+ int getX() { return pileX; }
+ int getY() { return pileY; }
+ int getNextX() { return pileNextX; }
+ int getNextY() { return pileNextY; }
+ int getWidth() { return pileWidth; }
+ int getHeight() { return pileHeight; }
+
+ void setX(int x) { pileX = x; }
+ void setY(int y) { pileY = y; }
+ void setNextX(int x) { pileNextX = x; }
+ void setNextY(int y) { pileNextY = y; }
+ void setWidth(int width) { pileWidth = width; }
+ void setHeight(int height) { pileHeight = height; }
+
+ void beginDealing() { dealing = TRUE; }
+ void endDealing() { dealing = FALSE; }
+ bool isDealing() { return dealing; }
+
+ int distanceFromPile(int x, int y);
+ int distanceFromNextPos(int x, int y);
+
+ Card *cardOnTop() { return getLast(); }
+ Card *cardOnBottom() { return getFirst(); }
+ Card *cardInfront(Card *c);
+ bool kingOnTop();
+
+ bool addCardToTop(Card *c);
+ bool addCardToBottom(Card *c);
+ bool removeCard(Card *c);
+
+ virtual void cardAddedToTop(Card *) { }
+ virtual void cardAddedToBottom(Card *) { }
+ virtual void cardRemoved(Card *) { }
+ virtual bool isAllowedOnTop(Card *) { return FALSE; }
+ virtual bool isAllowedOnBottom(Card *) { return FALSE; }
+ virtual bool isAllowedToBeMoved(Card *) { return FALSE; }
+ virtual QPoint getCardPos(Card *) { return QPoint(pileX, pileY); }
+ virtual QPoint getHypertheticalNextCardPos() { return QPoint(pileX, pileY); }
+
+ void writeConfig( Config& cfg, QString name );
+
+protected:
+ int pileX, pileY;
+ int pileNextX, pileNextY;
+ int pileWidth, pileHeight;
+ int pileCenterX, pileCenterY;
+ int pileRadius;
+private:
+ bool dealing;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/freecellcardgame.cpp b/noncore/games/solitaire/freecellcardgame.cpp
new file mode 100644
index 0000000..e82afd4
--- a/dev/null
+++ b/noncore/games/solitaire/freecellcardgame.cpp
@@ -0,0 +1,137 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "freecellcardgame.h"
+
+
+extern int highestZ;
+int numberOfFreeCells = 4;
+
+
+FreecellCardGame::FreecellCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent)
+{
+ numberOfFreeCells = 4;
+ highestZ = 0;
+
+ for (int i = 0; i < 4; i++) {
+ freecellPiles[i] = new FreecellFreecellPile( 5 + i * 28, 10, canvas() );
+ addCardPile(freecellPiles[i]);
+ }
+ for (int i = 0; i < 4; i++) {
+ discardPiles[i] = new FreecellDiscardPile( 125 + i * 28, 10, canvas() );
+ addCardPile(discardPiles[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ workingPiles[i] = new FreecellWorkingPile( 10 + i * 28, 50, canvas() );
+ addCardPile(workingPiles[i]);
+ }
+}
+
+
+void FreecellCardGame::deal(void)
+{
+ highestZ = 1;
+
+ beginDealing();
+
+ for (int i = 0; i < 52; i++) {
+ Card *card = cards[i];
+ card->setFace( TRUE );
+ card->setPos( 0, 0, highestZ );
+ card->setCardPile( workingPiles[i%8] );
+ workingPiles[i%8]->addCardToTop( card );
+ card->move( workingPiles[i%8]->getCardPos( card ) );
+ card->showCard();
+ highestZ++;
+ }
+
+ endDealing();
+}
+
+
+bool FreecellCardGame::mousePressCard( Card *c, QPoint p )
+{
+ Q_UNUSED(p);
+
+ if ( !c->getCardPile()->isAllowedToBeMoved(c) ) {
+ moving = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void FreecellCardGame::readConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+
+ // Create Cards, but don't shuffle or deal them yet
+ createDeck();
+
+ // Move the cards to their piles (deal them to their previous places)
+ beginDealing();
+
+ highestZ = 1;
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "FreeCellPile%i", k );
+ readPile( cfg, freecellPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", k );
+ readPile( cfg, discardPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 8; k++) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", k );
+ readPile( cfg, workingPiles[k], pile, highestZ );
+ }
+
+ highestZ++;
+
+ endDealing();
+}
+
+
+void FreecellCardGame::writeConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "FreeCellPile%i", i );
+ freecellPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", i );
+ discardPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 8; i++ ) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", i );
+ workingPiles[i]->writeConfig( cfg, pile );
+ }
+}
+
+
diff --git a/noncore/games/solitaire/freecellcardgame.h b/noncore/games/solitaire/freecellcardgame.h
new file mode 100644
index 0000000..f1b09ab
--- a/dev/null
+++ b/noncore/games/solitaire/freecellcardgame.h
@@ -0,0 +1,152 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef FREECELL_CARD_GAME_H
+#define FREECELL_CARD_GAME_H
+
+
+#include "patiencecardgame.h"
+
+
+extern int numberOfFreeCells;
+
+
+class FreecellDiscardPile : public PatienceDiscardPile
+{
+public:
+ FreecellDiscardPile(int x, int y, QCanvas *canvas) :
+ PatienceDiscardPile(x, y, canvas) { }
+
+};
+
+
+class FreecellWorkingPile : public PatienceWorkingPile
+{
+public:
+ FreecellWorkingPile(int x, int y, QCanvas *canvas) :
+ PatienceWorkingPile(x, y, canvas) { }
+
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( cardOnBottom() == NULL ) {
+ int numberOfCardsBeingMoved = 0;
+ Card *tempCard = card;
+
+ while ((tempCard != NULL)) {
+ numberOfCardsBeingMoved++;
+ tempCard = cardInfront(tempCard);
+ }
+
+ if (numberOfCardsBeingMoved > numberOfFreeCells)
+ return FALSE;
+ }
+
+ if ( card->isFacing() &&
+ cardOnTop() == NULL )
+ return TRUE;
+ return PatienceWorkingPile::isAllowedOnTop( card );
+ }
+
+ virtual bool isAllowedToBeMoved(Card *card) {
+ int nextExpectedValue = (int)card->getValue();
+ bool nextExpectedColor = card->isRed();
+ int numberOfCardsBeingMoved = 0;
+
+ while ((card != NULL)) {
+ numberOfCardsBeingMoved++;
+ if ( (int)card->getValue() != nextExpectedValue )
+ return FALSE;
+ if ( card->isRed() != nextExpectedColor )
+ return FALSE;
+ nextExpectedValue--;;
+ nextExpectedColor = !nextExpectedColor;
+ card = cardInfront(card);
+ }
+
+ if (numberOfCardsBeingMoved <= (numberOfFreeCells + 1))
+ return TRUE;
+
+ return FALSE;
+ }
+ virtual void cardRemoved(Card *card) {
+ if ( !isDealing() && !cardOnTop() )
+ numberOfFreeCells++;
+ PatienceWorkingPile::cardRemoved( card );
+ }
+ virtual void cardAddedToTop(Card *card) {
+ if ( !isDealing() && cardOnBottom() == card )
+ numberOfFreeCells--;
+ PatienceWorkingPile::cardAddedToTop( card );
+ }
+};
+
+
+class FreecellFreecellPile : public CardPile, public CanvasRoundRect
+{
+public:
+ FreecellFreecellPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( ( cardOnTop() == NULL ) && ( card->getCardPile()->cardInfront(card) == NULL ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ return TRUE;
+ }
+ virtual void cardAddedToTop(Card *card) {
+ Q_UNUSED(card);
+ numberOfFreeCells--;
+ }
+ virtual void cardRemoved(Card *card) {
+ Q_UNUSED(card);
+ numberOfFreeCells++;
+ }
+};
+
+
+class FreecellCardGame : public CanvasCardGame
+{
+public:
+ FreecellCardGame(QCanvas *c, bool snap, QWidget *parent = 0);
+ virtual void deal(void);
+ virtual bool haveWeWon() {
+ return ( discardPiles[0]->kingOnTop() &&
+ discardPiles[1]->kingOnTop() &&
+ discardPiles[2]->kingOnTop() &&
+ discardPiles[3]->kingOnTop() );
+ }
+ virtual void mousePress(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+// virtual void mouseMove(QPoint p);
+ virtual bool mousePressCard(Card *card, QPoint p);
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+ void readConfig( Config& cfg );
+ void writeConfig( Config& cfg );
+ bool snapOn;
+private:
+ FreecellFreecellPile *freecellPiles[8];
+ FreecellWorkingPile *workingPiles[8];
+ FreecellDiscardPile *discardPiles[4];
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/main.cpp b/noncore/games/solitaire/main.cpp
new file mode 100644
index 0000000..f81aa3c
--- a/dev/null
+++ b/noncore/games/solitaire/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "canvascardwindow.h"
+
+#include <qpe/qpeapplication.h>
+
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ CanvasCardWindow m;
+ m.setCaption( CanvasCardWindow::tr("Patience") );
+ a.showMainWidget( &m );
+
+ return a.exec();
+}
+
diff --git a/noncore/games/solitaire/patiencecardgame.cpp b/noncore/games/solitaire/patiencecardgame.cpp
new file mode 100644
index 0000000..5a9326a
--- a/dev/null
+++ b/noncore/games/solitaire/patiencecardgame.cpp
@@ -0,0 +1,234 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "patiencecardgame.h"
+
+
+int highestZ = 0;
+
+
+PatienceCardGame::PatienceCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent)
+{
+ numberOfTimesThroughDeck = 0;
+ highestZ = 0;
+
+ circleCross = new CanvasCircleOrCross( 7, 18, canvas() );
+ rectangle = new CanvasRoundRect( 35, 10, canvas() );
+
+ for (int i = 0; i < 4; i++) {
+ discardPiles[i] = new PatienceDiscardPile( 110 + i * 30, 10, canvas() );
+ addCardPile(discardPiles[i]);
+ }
+ for (int i = 0; i < 7; i++) {
+ workingPiles[i] = new PatienceWorkingPile( 10 + i * 30, 50, canvas() );
+ addCardPile(workingPiles[i]);
+ }
+ faceDownDealingPile = new PatienceFaceDownDeck( 5, 10, canvas() );
+ faceUpDealingPile = new PatienceFaceUpDeck( 35, 10, canvas() );
+}
+
+
+PatienceCardGame::~PatienceCardGame()
+{
+ delete circleCross;
+ delete rectangle;
+ delete faceDownDealingPile;
+ delete faceUpDealingPile;
+}
+
+
+void PatienceCardGame::deal(void)
+{
+ highestZ = 1;
+ int t = 0;
+
+ beginDealing();
+
+ for (int i = 0; i < 7; i++) {
+ cards[t]->setFace(TRUE);
+ for (int k = i; k < 7; k++, t++) {
+ Card *card = cards[t];
+ workingPiles[k]->addCardToTop(card);
+ card->setCardPile( workingPiles[k] );
+ QPoint p = workingPiles[k]->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+ }
+
+ for ( ; t < 52; t++) {
+ Card *card = cards[t];
+ faceDownDealingPile->addCardToTop(card);
+ card->setCardPile( faceDownDealingPile );
+ QPoint p = faceDownDealingPile->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+
+ endDealing();
+}
+
+
+void PatienceCardGame::readConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+
+ // Do we have a config file to read in?
+ if ( !cfg.hasKey("numberOfTimesThroughDeck") ) {
+ // if not, create a new game
+ newGame();
+ return;
+ }
+ // We have a config file, lets read it in and use it
+
+ // Create Cards, but don't shuffle or deal them yet
+ createDeck();
+
+ // How many times through the deck have we been
+ numberOfTimesThroughDeck = cfg.readNumEntry("NumberOfTimesThroughDeck");
+
+ // restore state to the circle/cross under the dealing pile
+ if ( canTurnOverDeck() )
+ circleCross->setCircle();
+ else
+ circleCross->setCross();
+
+ // Move the cards to their piles (deal them to their previous places)
+ beginDealing();
+
+ highestZ = 1;
+
+ for (int k = 0; k < 7; k++) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", k );
+ readPile( cfg, workingPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", k );
+ readPile( cfg, discardPiles[k], pile, highestZ );
+ }
+
+ readPile( cfg, faceDownDealingPile, "FaceDownDealingPile", highestZ );
+ readPile( cfg, faceUpDealingPile, "FaceUpDealingPile", highestZ );
+
+ highestZ++;
+
+ endDealing();
+}
+
+
+void PatienceCardGame::writeConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+ cfg.writeEntry("numberOfTimesThroughDeck", numberOfTimesThroughDeck);
+
+ for ( int i = 0; i < 7; i++ ) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", i );
+ workingPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", i );
+ discardPiles[i]->writeConfig( cfg, pile );
+ }
+ faceDownDealingPile->writeConfig( cfg, "FaceDownDealingPile" );
+ faceUpDealingPile->writeConfig( cfg, "FaceUpDealingPile" );
+}
+
+
+bool PatienceCardGame::mousePressCard( Card *card, QPoint p )
+{
+ Q_UNUSED(p);
+
+ CanvasCard *item = (CanvasCard *)card;
+ if (item->isFacing() != TRUE) {
+ // From facedown stack
+ if ((item->x() == 5) && ((int)item->y() == 10)) {
+ item->setZ(highestZ);
+ highestZ++;
+
+ // Added Code
+ faceDownDealingPile->removeCard(item);
+ faceUpDealingPile->addCardToTop(item);
+ item->setCardPile( faceUpDealingPile );
+
+ item->flipTo( 35, (int)item->y() );
+ }
+ moving = NULL;
+ moved = FALSE;
+
+ // move two other cards if we flip three at a time
+ int flipped = 1;
+ QCanvasItemList l = canvas()->collisions( p );
+ for (QCanvasItemList::Iterator it = l.begin(); (it != l.end()) && (flipped != cardsDrawn()); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ CanvasCard *item = (CanvasCard *)*it;
+ if (item->animated())
+ continue;
+ item->setZ(highestZ);
+ highestZ++;
+ flipped++;
+
+ // Added Code
+ faceDownDealingPile->removeCard(item);
+ faceUpDealingPile->addCardToTop(item);
+ item->setCardPile( faceUpDealingPile );
+
+ item->flipTo( 35, (int)item->y(), 8 * flipped );
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void PatienceCardGame::mousePress(QPoint p)
+{
+ if ( canTurnOverDeck() &&
+ (p.x() > 5) && (p.x() < 28) &&
+ (p.y() > 10) && (p.y() < 46) ) {
+
+ beginDealing();
+ Card *card = faceUpDealingPile->cardOnTop();
+ while ( card ) {
+ card->setPos( 5, 10, highestZ );
+ card->setFace( FALSE );
+ faceUpDealingPile->removeCard( card );
+ faceDownDealingPile->addCardToTop( card );
+ card->setCardPile( faceDownDealingPile );
+ card = faceUpDealingPile->cardOnTop();
+ highestZ++;
+ }
+ endDealing();
+
+ throughDeck();
+
+ moved = TRUE;
+ }
+}
+
+
diff --git a/noncore/games/solitaire/patiencecardgame.h b/noncore/games/solitaire/patiencecardgame.h
new file mode 100644
index 0000000..c4f6c48
--- a/dev/null
+++ b/noncore/games/solitaire/patiencecardgame.h
@@ -0,0 +1,206 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef PATIENCE_CARD_GAME_H
+#define PATIENCE_CARD_GAME_H
+
+
+#include <qpopupmenu.h>
+#include <qmainwindow.h>
+#include <qintdict.h>
+#include <qcanvas.h>
+// #include "canvascardshapes.h"
+// #include "canvascard.h"
+#include "canvascardgame.h"
+
+
+class PatienceFaceDownDeck : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceFaceDownDeck(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ Q_UNUSED(card);
+ // Need to check it is from the faceUpDealingPile
+ return TRUE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ //if ( ( !card->isFacing() ) && ( card == cardOnTop() ) )
+ if ( card == cardOnTop() )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceFaceUpDeck : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceFaceUpDeck(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ Q_UNUSED(card);
+ // Need to check it is from the faceDownDealingPile
+ return TRUE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ //if ( ( card->isFacing() ) && ( card == cardOnTop() ) )
+ if ( card == cardOnTop() )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceDiscardPile : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceDiscardPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( card->isFacing() && ( card->getCardPile()->cardInfront(card) == NULL ) &&
+ ( ( ( cardOnTop() == NULL ) && ( card->getValue() == ace ) ) ||
+ ( ( cardOnTop() != NULL ) &&
+ ( (int)card->getValue() == (int)cardOnTop()->getValue() + 1 ) &&
+ ( card->getSuit() == cardOnTop()->getSuit() ) ) ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ if ( card->isFacing() && ( card == cardOnTop() ) )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceWorkingPile : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceWorkingPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas), top(x, y) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( card->isFacing() &&
+ ( ( ( cardOnTop() == NULL ) && (card->getValue() == king) ) ||
+ ( ( cardOnTop() != NULL ) &&
+ ( (int)card->getValue() + 1 == (int)cardOnTop()->getValue() ) &&
+ ( card->isRed() != cardOnTop()->isRed() ) ) ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ if ( card->isFacing() )
+ return TRUE;
+ return FALSE;
+ }
+ virtual void cardAddedToTop(Card *card) {
+ Q_UNUSED(card);
+ top = getCardPos(NULL);
+ setNextX( top.x() );
+ setNextY( top.y() );
+ }
+ virtual void cardRemoved(Card *card) {
+ Q_UNUSED(card);
+
+ Card *newTopCard = cardOnTop();
+
+ if ( !newTopCard ) {
+ top = QPoint( pileX, pileY );
+ setNextX( pileX );
+ setNextY( pileY );
+ return;
+ } else {
+ top = getCardPos(NULL);
+ if ( newTopCard->isFacing() == FALSE ) {
+ // correct the position taking in to account the card is not
+ // yet flipped, but will become flipped
+ top = QPoint( top.x() - 1, top.y() - 3 );
+ newTopCard->flipTo( top.x(), top.y() );
+ top = QPoint( top.x(), top.y() + 13 );
+ }
+ setNextX( top.x() );
+ setNextY( top.y() );
+ }
+ }
+ virtual QPoint getCardPos(Card *c) {
+ int x = pileX, y = pileY;
+ Card *card = cardOnBottom();
+ while ((card != c) && (card != NULL)) {
+ if (card->isFacing()) {
+ y += 13;
+ } else {
+ x += 1;
+ y += 3;
+ }
+ card = cardInfront(card);
+ }
+ return QPoint( x, y );
+ }
+ virtual QPoint getHypertheticalNextCardPos(void) {
+ return top;
+ // return QPoint( getNextX(), getNextY() );
+ }
+private:
+ QPoint top;
+
+};
+
+
+class PatienceCardGame : public CanvasCardGame
+{
+public:
+ PatienceCardGame(QCanvas *c, bool snap, QWidget *parent = 0);
+ virtual ~PatienceCardGame();
+ virtual void deal(void);
+ virtual bool haveWeWon() {
+ return ( discardPiles[0]->kingOnTop() &&
+ discardPiles[1]->kingOnTop() &&
+ discardPiles[2]->kingOnTop() &&
+ discardPiles[3]->kingOnTop() );;
+ }
+ virtual void mousePress(QPoint p);
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+// virtual void mouseMove(QPoint p);
+ virtual bool mousePressCard(Card *card, QPoint p);
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+ bool canTurnOverDeck(void) { return (numberOfTimesThroughDeck != 3); }
+ void throughDeck(void) {
+ numberOfTimesThroughDeck++;
+ if (numberOfTimesThroughDeck == 3)
+ circleCross->setCross();
+ }
+ bool snapOn;
+ virtual void writeConfig( Config& cfg );
+ virtual void readConfig( Config& cfg );
+private:
+ CanvasCircleOrCross *circleCross;
+ CanvasRoundRect *rectangle;
+ PatienceWorkingPile *workingPiles[7];
+ PatienceDiscardPile *discardPiles[4];
+ PatienceFaceDownDeck *faceDownDealingPile;
+ PatienceFaceUpDeck *faceUpDealingPile;
+ int numberOfTimesThroughDeck;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/qpe-solitaire.control b/noncore/games/solitaire/qpe-solitaire.control
new file mode 100644
index 0000000..71abb0c
--- a/dev/null
+++ b/noncore/games/solitaire/qpe-solitaire.control
@@ -0,0 +1,9 @@
+Files: bin/patience apps/Games/patience.desktop pics/cards
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: solitaire card games
+ A solitaire game for the Qtopia environment.
diff --git a/noncore/games/solitaire/solitaire.pro b/noncore/games/solitaire/solitaire.pro
new file mode 100755
index 0000000..8617cab
--- a/dev/null
+++ b/noncore/games/solitaire/solitaire.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = canvascard.h canvasshapes.h cardgame.h cardgamelayout.h cardpile.h card.h carddeck.h canvascardgame.h freecellcardgame.h patiencecardgame.h canvascardwindow.h
+
+SOURCES = canvascard.cpp canvasshapes.cpp cardgame.cpp cardgamelayout.cpp cardpile.cpp card.cpp carddeck.cpp canvascardgame.cpp freecellcardgame.cpp patiencecardgame.cpp canvascardwindow.cpp main.cpp
+
+TARGET = patience
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+REQUIRES = patience
+
+TRANSLATIONS = ../i18n/de/patience.ts
diff --git a/noncore/games/tetrix/.cvsignore b/noncore/games/tetrix/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/games/tetrix/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/games/tetrix/Makefile.in b/noncore/games/tetrix/Makefile.in
new file mode 100644
index 0000000..3a74fdc
--- a/dev/null
+++ b/noncore/games/tetrix/Makefile.in
@@ -0,0 +1,157 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = tetrix
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = minefield.h \
+ gtetrix.h \
+ qtetrix.h \
+ qtetrixb.h \
+ tpiece.h
+SOURCES = main.cpp \
+ gtetrix.cpp \
+ qtetrix.cpp \
+ qtetrixb.cpp \
+ tpiece.cpp
+OBJECTS = main.o \
+ gtetrix.o \
+ qtetrix.o \
+ qtetrixb.o \
+ tpiece.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_qtetrix.cpp \
+ moc_qtetrixb.cpp
+OBJMOC = moc_qtetrix.o \
+ moc_qtetrixb.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake tetrix.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ qtetrix.h \
+ qtetrixb.h \
+ gtetrix.h \
+ tpiece.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+gtetrix.o: gtetrix.cpp \
+ gtetrix.h \
+ tpiece.h
+
+qtetrix.o: qtetrix.cpp \
+ qtetrix.h \
+ qtetrixb.h \
+ gtetrix.h \
+ tpiece.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+qtetrixb.o: qtetrixb.cpp \
+ qtetrixb.h \
+ gtetrix.h \
+ tpiece.h \
+ qtetrix.h
+
+tpiece.o: tpiece.cpp \
+ tpiece.h
+
+moc_qtetrix.o: moc_qtetrix.cpp \
+ qtetrix.h \
+ qtetrixb.h \
+ gtetrix.h \
+ tpiece.h
+
+moc_qtetrixb.o: moc_qtetrixb.cpp \
+ qtetrixb.h \
+ gtetrix.h \
+ tpiece.h
+
+moc_qtetrix.cpp: qtetrix.h
+ $(MOC) qtetrix.h -o moc_qtetrix.cpp
+
+moc_qtetrixb.cpp: qtetrixb.h
+ $(MOC) qtetrixb.h -o moc_qtetrixb.cpp
+
+
diff --git a/noncore/games/tetrix/gtetrix.cpp b/noncore/games/tetrix/gtetrix.cpp
new file mode 100644
index 0000000..d1f38b1
--- a/dev/null
+++ b/noncore/games/tetrix/gtetrix.cpp
@@ -0,0 +1,514 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "gtetrix.h"
+
+#include <string.h>
+
+GenericTetrix::GenericTetrix(int boardWidth,int boardHeight)
+{
+ int i,j;
+
+ width = boardWidth;
+ height = boardHeight;
+ boardPtr = new int[height*width]; // Note the order, this makes it easier
+ // to remove full lines.
+ for(i = 0 ; i < height ; i++)
+ for(j = 0 ; j < width ; j++)
+ board(j,i) = 0;
+ currentLine = -1; // -1 if no falling piece.
+ currentPos = 0;
+ showNext = 0; // FALSE
+ nLinesRemoved = 0;
+ nPiecesDropped = 0;
+ score = 0;
+ level = 1;
+ gameID = 0;
+ nClearLines = height;
+}
+
+GenericTetrix::~GenericTetrix()
+{
+ delete[] boardPtr;
+}
+
+
+void GenericTetrix::clearBoard(int fillRandomLines)
+{
+ int i,j;
+
+ if (fillRandomLines >= height)
+ fillRandomLines = height - 1;
+
+ erasePiece();
+ for(i = height - nClearLines - 1 ; i >= fillRandomLines ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0) {
+ draw(j,i,0);
+ board(j,i) = 0;
+ }
+ if (fillRandomLines != 0)
+ for (i = 0 ; i < fillRandomLines ; i++) {
+ fillRandom(i);
+ }
+ nClearLines = height - fillRandomLines;
+}
+
+void GenericTetrix::showBoard()
+{
+ int i,j;
+
+ showPiece();
+ for(i = height - nClearLines - 1 ; i >= 0 ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0)
+ draw(j,i,board(j,i));
+}
+
+void GenericTetrix::hideBoard()
+{
+ int i,j;
+
+ erasePiece();
+ for(i = height - nClearLines - 1 ; i >= 0 ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0)
+ draw(j,i,0);
+}
+
+void GenericTetrix::startGame(int gameType,int fillRandomLines)
+{
+ gameID = gameType;
+ clearBoard(fillRandomLines);
+ nLinesRemoved = 0;
+ updateRemoved(nLinesRemoved);
+ nClearLines = height;
+ nPiecesDropped = 0;
+ score = 0;
+ updateScore(score);
+ level = 1;
+ updateLevel(level);
+ newPiece();
+}
+
+void GenericTetrix::revealNextPiece(int revealIt)
+{
+ if (showNext == revealIt)
+ return;
+ showNext = revealIt;
+ if (!showNext)
+ eraseNextPiece();
+ else
+ showNextPiece();
+}
+
+void GenericTetrix::updateBoard(int x1,int y1,int x2, int y2,
+ int dontUpdateBlanks)
+{
+ int i,j;
+ int tmp;
+
+ if (x1 > x2) {
+ tmp = x2;
+ x2 = x1;
+ x1 = tmp;
+ }
+ if (y1 > y2) {
+ tmp = y2;
+ y2 = y1;
+ y1 = tmp;
+ }
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 >= width)
+ x2 = width - 1;
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 >= height)
+ y2 = height - 1;
+ for(i = y1 ; i <= y2 ; i++)
+ for(j = x1 ; j <= x2 ; j++)
+ if (!dontUpdateBlanks || board(j,height - i - 1) != 0)
+ draw(j,height - i - 1,board(j,height - i - 1));
+ showPiece(); // Remember to update piece correctly!!!!
+}
+
+
+void GenericTetrix::fillRandom(int line)
+{
+ int i,j;
+ int holes;
+
+ for(i = 0 ; i < width ; i++)
+ board(i,line) = TetrixPiece::randomValue(7);
+ holes = 0;
+ for(i = 0 ; i < width ; i++)
+ if (board(i,line) == 0) // Count holes in the line.
+ holes++;
+ if (holes == 0) // Full line, make a random hole:
+ board(TetrixPiece::randomValue(width),line) = 0;
+ if (holes == width) // Empty line, make a random square:
+ board(TetrixPiece::randomValue(width),line) =
+ TetrixPiece::randomValue(6) + 1;
+ for(j = 0 ; j < width ; j++)
+ draw(j,i,board(j,i));
+}
+
+void GenericTetrix::moveLeft(int steps)
+{
+ while(steps) {
+ if (!canMoveTo(currentPos - 1,currentLine))
+ return;
+ moveTo(currentPos - 1,currentLine);
+ steps--;
+ }
+}
+
+void GenericTetrix::moveRight(int steps)
+{
+ while(steps) {
+ if (!canMoveTo(currentPos + 1,currentLine))
+ return;
+ moveTo(currentPos + 1,currentLine);
+ steps--;
+ }
+}
+
+void GenericTetrix::rotateLeft()
+{
+ TetrixPiece tmp(currentPiece);
+
+ tmp.rotateLeft();
+ if (!canPosition(tmp))
+ return;
+ position(tmp);
+ currentPiece = tmp;
+}
+
+void GenericTetrix::rotateRight()
+{
+ TetrixPiece tmp(currentPiece);
+
+ tmp.rotateRight();
+ if (!canPosition(tmp))
+ return;
+ position(tmp);
+ currentPiece = tmp;
+}
+
+void GenericTetrix::dropDown()
+{
+ if (currentLine == -1)
+ return;
+
+ int dropHeight = 0;
+ int newLine = currentLine;
+ while(newLine) {
+ if (!canMoveTo(currentPos,newLine - 1))
+ break;
+ newLine--;
+ dropHeight++;
+ }
+ if (dropHeight != 0)
+ moveTo(currentPos,newLine);
+ internalPieceDropped(dropHeight);
+}
+
+void GenericTetrix::oneLineDown()
+{
+ if (currentLine == -1)
+ return;
+ if (canMoveTo(currentPos,currentLine - 1)) {
+ moveTo(currentPos,currentLine - 1);
+ } else {
+ internalPieceDropped(0);
+ }
+}
+
+void GenericTetrix::newPiece()
+{
+ currentPiece = nextPiece;
+ if (showNext)
+ eraseNextPiece();
+ nextPiece.setRandomType();
+ if (showNext)
+ showNextPiece();
+ currentLine = height - 1 + currentPiece.getMinY();
+ currentPos = width/2 + 1;
+ if (!canMoveTo(currentPos,currentLine)) {
+ currentLine = -1;
+ gameOver();
+ } else {
+ showPiece();
+ }
+}
+
+void GenericTetrix::removePiece()
+{
+ erasePiece();
+ currentLine = -1;
+}
+
+void GenericTetrix::drawNextSquare(int,int,int)
+{
+
+}
+
+void GenericTetrix::pieceDropped(int)
+{
+ newPiece();
+}
+
+void GenericTetrix::updateRemoved(int)
+{
+}
+
+void GenericTetrix::updateScore(int)
+{
+}
+
+void GenericTetrix::updateLevel(int)
+{
+}
+
+void GenericTetrix::removeFullLines()
+{
+ int i,j,k;
+ int nFullLines;
+
+ for(i = 0 ; i < height - nClearLines ; i++) {
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) == 0)
+ break;
+ if (j == width) {
+ nFullLines = 1;
+ for(k = i + 1 ; k < height - nClearLines ; k++) {
+ for(j = 0 ; j < width ; j++)
+ if (board(j,k) == 0)
+ break;
+ if (j == width) {
+ nFullLines++;
+ } else {
+ for(j = 0 ; j < width ; j++) {
+ if (board(j,k - nFullLines) != board(j,k)) {
+ board(j,k - nFullLines) = board(j,k);
+ draw( j,k - nFullLines,
+ board(j,k - nFullLines));
+ }
+ }
+ }
+ }
+ nClearLines = nClearLines + nFullLines;
+ nLinesRemoved = nLinesRemoved + nFullLines;
+ updateRemoved(nLinesRemoved);
+ score = score + 10*nFullLines; // updateScore must be
+ // called by caller!
+ for (i = height - nClearLines ;
+ i < height - nClearLines + nFullLines ;
+ i++)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0) {
+ draw(j,i,0);
+ board(j,i) = 0;
+ }
+ }
+ }
+}
+
+void GenericTetrix::showPiece()
+{
+ int x,y;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ draw(currentPos + x,currentLine - y,currentPiece.getType());
+ }
+}
+
+void GenericTetrix::erasePiece()
+{
+ int x,y;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ draw(currentPos + x,currentLine - y,0);
+ }
+}
+
+void GenericTetrix::internalPieceDropped(int dropHeight)
+{
+ gluePiece();
+ nPiecesDropped++;
+ if (nPiecesDropped % 25 == 0) {
+ level++;
+ updateLevel(level);
+ }
+ score = score + 7 + dropHeight;
+ removeFullLines();
+ updateScore(score);
+ pieceDropped(dropHeight);
+}
+
+void GenericTetrix::gluePiece()
+{
+ int x,y;
+ int min;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ board(currentPos + x,currentLine - y) = currentPiece.getType();
+ }
+ min = currentPiece.getMinY();
+ if (currentLine - min >= height - nClearLines)
+ nClearLines = height - currentLine + min - 1;
+}
+
+void GenericTetrix::showNextPiece(int erase)
+{
+ int x,y;
+ int minX = nextPiece.getMinX();
+ int minY = nextPiece.getMinY();
+ int maxX = nextPiece.getMaxX();
+ int maxY = nextPiece.getMaxY();
+
+ int xOffset = (3 - (maxX - minX))/2;
+ int yOffset = (3 - (maxY - minY))/2;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ nextPiece.getCoord(i,x,y);
+ if (erase)
+ drawNextSquare(x + xOffset - minX,
+ y + yOffset - minY,0);
+ else
+ drawNextSquare(x + xOffset - minX,
+ y + yOffset - minY,nextPiece.getType());
+ }
+}
+
+int GenericTetrix::canPosition(TetrixPiece &piece)
+{
+ if (currentLine == -1)
+ return 0;
+
+ int x,y;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ piece.getCoord(i,x,y);
+ x = currentPos + x;
+ y = currentLine - y; // Board and pieces have inverted y-coord. systems.
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ return 0; // Outside board, cannot put piece here.
+ if (board(x,y) != 0)
+ return 0; // Over a non-zero square, cannot put piece here.
+ }
+ return 1; // Inside board and no non-zero squares underneath.
+
+}
+
+int GenericTetrix::canMoveTo(int xPosition,int line)
+{
+ if (currentLine == -1)
+ return 0;
+
+ int x,y;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ x = xPosition + x;
+ y = line - y; // Board and pieces have inverted y-coord. systems.
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ return 0; // Outside board, cannot put piece here.
+ if (board(x,y) != 0)
+ return 0; // Over a non-zero square, cannot put piece here.
+ }
+ return 1; // Inside board and no non-zero squares underneath.
+}
+
+void GenericTetrix::moveTo(int xPosition,int line)
+{
+ if (currentLine == -1)
+ return;
+ optimizedMove(xPosition,line,currentPiece);
+ currentPos = xPosition;
+ currentLine = line;
+}
+
+void GenericTetrix::position(TetrixPiece &piece)
+{
+ if (currentLine == -1)
+ return;
+
+ optimizedMove(currentPos,currentLine,piece);
+}
+
+void GenericTetrix::optimizedMove(int newPos, int newLine,
+ TetrixPiece &newPiece)
+{
+ int updates [8][3];
+ int nUpdates;
+ int value;
+ int x,y;
+ int i,j;
+
+ for(i = 0 ; i < 4 ; i++) { // Put the erasing coords into updates
+ currentPiece.getCoord(i,x,y);
+ updates[i][0] = currentPos + x;
+ updates[i][1] = currentLine - y;
+ updates[i][2] = 0;
+ }
+ nUpdates = 4;
+ for(i = 0 ; i < 4 ; i++) { // Any drawing coord same as an erasing one?
+ newPiece.getCoord(i,x,y);
+ x = newPos + x;
+ y = newLine - y;
+ for (j = 0 ; j < 4 ; j++)
+ if (updates[j][0] == x && updates[j][1] == y) { // Same coord,
+ // don't have to erase
+ if (currentPiece.getType() == newPiece.getType())
+ updates[j][2] = -1; // Correct on screen, no update!
+ else
+ updates[j][2] = newPiece.getType();
+ break;
+ }
+ if (j == 4) { // This coord does not overlap an erasing one
+ updates[nUpdates][0] = x;
+ updates[nUpdates][1] = y;
+ updates[nUpdates][2] = newPiece.getType();
+ nUpdates++;
+ }
+ }
+ for (i = 0 ; i < nUpdates ; i++) { // Do the updating
+ x = updates[i][0];
+ y = updates[i][1];
+ value = updates[i][2];
+ if (value != -1) // Only update if new value != current
+ draw(x,y,value);
+ }
+}
diff --git a/noncore/games/tetrix/gtetrix.h b/noncore/games/tetrix/gtetrix.h
new file mode 100644
index 0000000..520dd89
--- a/dev/null
+++ b/noncore/games/tetrix/gtetrix.h
@@ -0,0 +1,104 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#ifndef GTETRIX_H
+#define GTETRIX_H
+
+#include "tpiece.h"
+
+
+class GenericTetrix
+{
+public:
+ GenericTetrix(int boardWidth = 10,int boardHeight = 22);
+ virtual ~GenericTetrix();
+
+ void clearBoard(int fillRandomLines = 0);
+ void revealNextPiece(int revealIt);
+ void updateBoard(int x1,int y1,int x2,int y2,int dontUpdateBlanks = 0);
+ void updateNext(){if (showNext) showNextPiece();}
+ void hideBoard();
+ void showBoard();
+ void fillRandom(int line);
+
+ void moveLeft(int steps = 1);
+ void moveRight(int steps = 1);
+ void rotateLeft();
+ void rotateRight();
+ void dropDown();
+ void oneLineDown();
+ void newPiece();
+ void removePiece();
+
+ int noOfClearLines() {return nClearLines;}
+ int getLinesRemoved() {return nLinesRemoved;}
+ int getPiecesDropped() {return nPiecesDropped;}
+ int getScore() {return score;}
+ int getLevel() {return level;}
+ int boardHeight() {return height;}
+ int boardWidth() {return width;}
+
+ virtual void drawSquare(int x,int y,int value) = 0;
+ virtual void gameOver() = 0;
+
+ virtual void startGame(int gameType = 0,int fillRandomLines = 0);
+ virtual void drawNextSquare(int x,int y,int value);
+ virtual void pieceDropped(int dropHeight);
+ virtual void updateRemoved(int noOfLines);
+ virtual void updateScore(int newScore);
+ virtual void updateLevel(int newLevel);
+
+private:
+ void draw(int x, int y, int value){drawSquare(x,height - y,value);}
+ void removeFullLines();
+ void removeLine(int line);
+ void showPiece();
+ void erasePiece();
+ void internalPieceDropped(int dropHeight);
+ void gluePiece();
+ void showNextPiece(int erase = 0);
+ void eraseNextPiece(){showNextPiece(1);};
+ int canPosition(TetrixPiece &piece); // Returns a boolean value.
+ int canMoveTo(int xPosition, int line); // Returns a boolean value.
+ void moveTo(int xPosition,int line);
+ void position(TetrixPiece &piece);
+ void optimizedMove(int newPos, int newLine,TetrixPiece &newPiece);
+
+ int &board(int x,int y){return boardPtr[width*y + x];}
+
+ TetrixPiece currentPiece;
+ TetrixPiece nextPiece;
+ int currentLine;
+ int currentPos;
+ int showNext; // Boolean variable.
+ int nLinesRemoved;
+ int nPiecesDropped;
+ int score;
+ int level;
+ int gameID;
+ int nClearLines;
+ int width;
+ int height;
+ int *boardPtr;
+};
+
+
+#endif
diff --git a/noncore/games/tetrix/main.cpp b/noncore/games/tetrix/main.cpp
new file mode 100644
index 0000000..e36d52d
--- a/dev/null
+++ b/noncore/games/tetrix/main.cpp
@@ -0,0 +1,33 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qtetrix.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a(argc,argv);
+
+ QTetrix *tetrix = new QTetrix;
+ a.showMainWidget(tetrix);
+
+ return a.exec();
+}
diff --git a/noncore/games/tetrix/qpe-tetrix.control b/noncore/games/tetrix/qpe-tetrix.control
new file mode 100644
index 0000000..46dfdf5
--- a/dev/null
+++ b/noncore/games/tetrix/qpe-tetrix.control
@@ -0,0 +1,10 @@
+Files: bin/tetrix apps/Games/tetrix.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: control falling blocks
+ A game for the Qtopia environment.
diff --git a/noncore/games/tetrix/qtetrix.cpp b/noncore/games/tetrix/qtetrix.cpp
new file mode 100644
index 0000000..f649894
--- a/dev/null
+++ b/noncore/games/tetrix/qtetrix.cpp
@@ -0,0 +1,170 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "qtetrix.h"
+
+#include <qpe/resource.h>
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qdatetime.h>
+#include <qlayout.h>
+
+
+
+void drawTetrixButton( QPainter *p, int x, int y, int w, int h,
+ const QColor *color )
+{
+ QColor fc;
+ if ( color ) {
+ QPointArray a;
+ a.setPoints( 3, x,y+h-1, x,y, x+w-1,y );
+ p->setPen( color->light() );
+ p->drawPolyline( a );
+ a.setPoints( 3, x+1,y+h-1, x+w-1,y+h-1, x+w-1,y+1 );
+ p->setPen( color->dark() );
+ p->drawPolyline( a );
+ x++;
+ y++;
+ w -= 2;
+ h -= 2;
+ fc = *color;
+ }
+ else
+ fc = p->backgroundColor();
+ p->fillRect( x, y, w, h, fc );
+}
+
+
+ShowNextPiece::ShowNextPiece( QWidget *parent, const char *name )
+ : QFrame( parent, name )
+{
+ setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ xOffset = -1; // -1 until first resizeEvent.
+}
+
+void ShowNextPiece::resizeEvent( QResizeEvent *e )
+{
+ QSize sz = e->size();
+ blockWidth = (sz.width() - 3)/5;
+ blockHeight = (sz.height() - 3)/6;
+ xOffset = (sz.width() - 3)/5;
+ yOffset = (sz.height() - 3)/6;
+}
+
+
+void ShowNextPiece::paintEvent( QPaintEvent * )
+{
+ QPainter p( this );
+ drawFrame( &p );
+ p.end(); // explicit end() so any slots can paint too
+ emit update();
+}
+
+
+void ShowNextPiece::drawNextSquare(int x, int y,QColor *color)
+{
+ if (xOffset == -1) // Before first resizeEvent?
+ return;
+
+ QPainter paint;
+ paint.begin(this);
+ drawTetrixButton( &paint, xOffset+x*blockWidth, yOffset+y*blockHeight,
+ blockWidth, blockHeight, color );
+ paint.end();
+}
+
+
+QTetrix::QTetrix( QWidget *parent, const char *name, WFlags f )
+ : QMainWindow( parent, name, f )
+{
+ setIcon( Resource::loadPixmap( "tetrix_icon" ) );
+ setCaption( tr("Tetrix" ) );
+
+ QTime t = QTime::currentTime();
+ TetrixPiece::setRandomSeed( (((double)t.hour())+t.minute()+t.second())/
+ (24+60+60) );
+
+ QWidget *gameArea = new QWidget( this );
+ setCentralWidget( gameArea );
+
+ QGridLayout *gl = new QGridLayout( gameArea, 5, 3, 8 );
+
+ QLabel *l;
+ l = new QLabel( tr("Next"), gameArea );
+ gl->addWidget( l, 0, 0 );
+ showNext = new ShowNextPiece(gameArea);
+ showNext->setBackgroundColor(QColor(0,0,0));
+ gl->addWidget( showNext, 0, 1 );
+
+ l = new QLabel( tr("Score"), gameArea );
+ gl->addWidget( l, 1, 0 );
+ showScore = new QLabel(gameArea);
+ gl->addWidget( showScore, 1, 1 );
+ l = new QLabel( tr("Level"), gameArea );
+ gl->addWidget( l, 2, 0 );
+ showLevel = new QLabel(gameArea);
+ gl->addWidget( showLevel, 2, 1 );
+ l = new QLabel( tr("Removed"), gameArea );
+ gl->addWidget( l, 3, 0 );
+ showLines = new QLabel(gameArea);
+ gl->addWidget( showLines, 3, 1 );
+
+ board = new QTetrixBoard(gameArea);
+ board->setBackgroundColor(QColor(0,0,0));
+ board->setFixedWidth( 124 );
+ gl->addMultiCellWidget( board, 0, 4, 2, 2 );
+ gl->addColSpacing( 2, 100 );
+ gl->addColSpacing( 1, 35 );
+ gl->addRowSpacing( 0, 35 );
+
+ QPushButton *pb = new QPushButton( tr("Start"), gameArea );
+ pb->setFocusPolicy( NoFocus );
+ connect( pb, SIGNAL( clicked() ), board, SLOT( start() ) );
+ gl->addMultiCellWidget( pb, 4, 4, 0, 1 );
+
+ connect( board, SIGNAL(gameOverSignal()), SLOT(gameOver()) );
+ connect( board, SIGNAL(drawNextSquareSignal(int,int,QColor*)), showNext,
+ SLOT(drawNextSquare(int,int,QColor*)) );
+ connect( showNext, SIGNAL(update()), board, SLOT(updateNext()) );
+ connect( board, SIGNAL(updateScoreSignal(int)), showScore,
+ SLOT(setNum(int)) );
+ connect( board, SIGNAL(updateLevelSignal(int)), showLevel,
+ SLOT(setNum(int)));
+ connect( board, SIGNAL(updateRemovedSignal(int)), showLines,
+ SLOT(setNum(int)));
+
+ showScore->setNum( 0 );
+ showLevel->setNum( 0 );
+ showLines->setNum( 0 );
+ board->revealNextPiece(TRUE);
+ board->setFocusPolicy( StrongFocus );
+}
+
+void QTetrix::gameOver()
+{
+}
+
+
+void QTetrix::quit()
+{
+ close();
+}
diff --git a/noncore/games/tetrix/qtetrix.h b/noncore/games/tetrix/qtetrix.h
new file mode 100644
index 0000000..b6e058a
--- a/dev/null
+++ b/noncore/games/tetrix/qtetrix.h
@@ -0,0 +1,78 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#ifndef QTETRIX_H
+#define QTETRIX_H
+
+#include "qtetrixb.h"
+#include <qframe.h>
+#include <qlcdnumber.h>
+#include <qpushbutton.h>
+#include <qpainter.h>
+#include <qmainwindow.h>
+
+class QLabel;
+
+class ShowNextPiece : public QFrame
+{
+ Q_OBJECT
+ friend class QTetrix;
+public:
+ ShowNextPiece( QWidget *parent=0, const char *name=0 );
+public slots:
+ void drawNextSquare( int x, int y,QColor *color );
+signals:
+ void update();
+private:
+ void paintEvent( QPaintEvent * );
+ void resizeEvent( QResizeEvent * );
+
+ int blockWidth,blockHeight;
+ int xOffset,yOffset;
+};
+
+
+class QTetrix : public QMainWindow
+{
+ Q_OBJECT
+public:
+ QTetrix( QWidget *parent=0, const char *name=0, WFlags f=0 );
+ void startGame() { board->startGame(); }
+
+public slots:
+ void gameOver();
+ void quit();
+private:
+ void keyPressEvent( QKeyEvent *e ) { board->keyPressEvent(e); }
+
+ QTetrixBoard *board;
+ ShowNextPiece *showNext;
+ QLabel *showScore;
+ QLabel *showLevel;
+ QLabel *showLines;
+};
+
+
+void drawTetrixButton( QPainter *, int x, int y, int w, int h,
+ const QColor *color );
+
+
+#endif
diff --git a/noncore/games/tetrix/qtetrixb.cpp b/noncore/games/tetrix/qtetrixb.cpp
new file mode 100644
index 0000000..521f171
--- a/dev/null
+++ b/noncore/games/tetrix/qtetrixb.cpp
@@ -0,0 +1,251 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "qtetrixb.h"
+#include "qtetrix.h"
+#include <qtimer.h>
+#include <qkeycode.h>
+#include <qpainter.h>
+
+const int waitAfterLineTime = 500;
+
+QTetrixBoard::QTetrixBoard( QWidget *p, const char *name )
+ : QFrame( p, name )
+{
+ setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ paint = 0;
+ timer = new QTimer(this);
+ connect( timer, SIGNAL(timeout()), SLOT(timeout()) );
+
+ colors[0].setRgb(200,100,100);
+ colors[1].setRgb(100,200,100);
+ colors[2].setRgb(100,100,200);
+ colors[3].setRgb(200,200,100);
+ colors[4].setRgb(200,100,200);
+ colors[5].setRgb(100,200,200);
+ colors[6].setRgb(218,170, 0);
+
+ xOffset = -1; // -1 until a resizeEvent is received.
+ blockWidth = 20;
+ yOffset = 30;
+ blockHeight = 20;
+ noGame = TRUE;
+ isPaused = FALSE;
+ waitingAfterLine = FALSE;
+ updateTimeoutTime(); // Sets timeoutTime
+}
+
+void QTetrixBoard::startGame(int gameType,int fillRandomLines)
+{
+ if ( isPaused )
+ return; // ignore if game is paused
+ noGame = FALSE;
+ GenericTetrix::startGame( gameType, fillRandomLines );
+ // Note that the timer is started by updateLevel!
+}
+
+
+void QTetrixBoard::pause()
+{
+ if ( noGame ) // game not active
+ return;
+ isPaused = !isPaused;
+ if ( isPaused ) {
+ timer->stop();
+ hideBoard();
+ }
+ else
+ timer->start(timeoutTime);
+ update();
+}
+
+
+void QTetrixBoard::drawSquare(int x,int y,int value)
+{
+ if (xOffset == -1) // Before first resizeEvent?
+ return;
+
+ const int X = xOffset + x*blockWidth;
+ const int Y = yOffset + (y - 1)*blockHeight;
+
+ bool localPainter = paint == 0;
+ QPainter *p;
+ if ( localPainter )
+ p = new QPainter( this );
+ else
+ p = paint;
+ drawTetrixButton( p, X, Y, blockWidth, blockHeight,
+ value == 0 ? 0 : &colors[value-1] );
+ /*
+ if ( value != 0 ) {
+ QColor tc, bc;
+ tc = colors[value-1].light();
+ bc = colors[value-1].dark();
+ p->drawShadePanel( X, Y, blockWidth, blockHeight,
+ tc, bc, 1, colors[value-1], TRUE );
+ }
+ else
+ p->fillRect( X, Y, blockWidth, blockHeight, backgroundColor() );
+ */
+ if ( localPainter )
+ delete p;
+}
+
+void QTetrixBoard::drawNextSquare( int x, int y, int value )
+{
+ if ( value == 0 )
+ emit drawNextSquareSignal (x, y, 0 );
+ else
+ emit drawNextSquareSignal( x, y, &colors[value-1] );
+}
+
+void QTetrixBoard::updateRemoved( int noOfLines )
+{
+ if ( noOfLines > 0 ) {
+ timer->stop();
+ timer->start( waitAfterLineTime );
+ waitingAfterLine = TRUE;
+ }
+ emit updateRemovedSignal( noOfLines );
+}
+
+void QTetrixBoard::updateScore( int newScore )
+{
+ emit updateScoreSignal( newScore );
+}
+
+void QTetrixBoard::updateLevel( int newLevel )
+{
+ timer->stop();
+ updateTimeoutTime();
+ timer->start( timeoutTime );
+ emit updateLevelSignal( newLevel );
+}
+
+void QTetrixBoard::pieceDropped(int)
+{
+ if ( waitingAfterLine ) // give player a break if a line has been removed
+ return;
+ newPiece();
+}
+
+void QTetrixBoard::gameOver()
+{
+ timer->stop();
+ noGame = TRUE;
+ emit gameOverSignal();
+}
+
+void QTetrixBoard::timeout()
+{
+ if ( waitingAfterLine ) {
+ timer->stop();
+ waitingAfterLine = FALSE;
+ newPiece();
+ timer->start( timeoutTime );
+ } else {
+ oneLineDown();
+ }
+}
+
+void QTetrixBoard::drawContents( QPainter *p )
+{
+ const char *text = "Press \"Pause\"";
+ QRect r = contentsRect();
+ paint = p; // set widget painter
+ if ( isPaused ) {
+ p->drawText( r, AlignCenter | AlignVCenter, text );
+ return;
+ }
+ int x1,y1,x2,y2;
+ x1 = (r.left() - xOffset) / blockWidth;
+ if (x1 < 0)
+ x1 = 0;
+ if (x1 >= boardWidth())
+ x1 = boardWidth() - 1;
+
+ x2 = (r.right() - xOffset) / blockWidth;
+ if (x2 < 0)
+ x2 = 0;
+ if (x2 >= boardWidth())
+ x2 = boardWidth() - 1;
+
+ y1 = (r.top() - yOffset) / blockHeight;
+ if (y1 < 0)
+ y1 = 0;
+ if (y1 >= boardHeight())
+ y1 = boardHeight() - 1;
+
+ y2 = (r.bottom() - yOffset) / blockHeight;
+ if (y2 < 0)
+ y2 = 0;
+ if (y2 >= boardHeight())
+ y2 = boardHeight() - 1;
+
+ updateBoard( x1, y1, x2, y2, TRUE );
+ paint = 0; // reset widget painter
+ return;
+}
+
+void QTetrixBoard::resizeEvent(QResizeEvent *e)
+{
+ QSize sz = e->size();
+ blockWidth = (sz.width() - 2)/10;
+ blockHeight = (sz.height() - 2)/22;
+ xOffset = 1;
+ //yOffset = 1;
+ yOffset = (sz.height() - 2) - (blockHeight *22);
+}
+
+void QTetrixBoard::keyPressEvent( QKeyEvent *e )
+{
+ if ( noGame || isPaused || waitingAfterLine )
+ return;
+ switch( e->key() ) {
+ case Key_Left :
+ moveLeft();
+ break;
+ case Key_Right :
+ moveRight();
+ break;
+ case Key_Down :
+// rotateRight();
+ dropDown();
+ break;
+ case Key_Up :
+ rotateLeft();
+ break;
+ case Key_Space :
+ dropDown();
+ break;
+ case Key_D :
+ oneLineDown();
+ break;
+ default:
+ return;
+ }
+ e->accept();
+}
+
+void QTetrixBoard::updateTimeoutTime()
+{
+ timeoutTime = 1000/(1 + getLevel());
+}
diff --git a/noncore/games/tetrix/qtetrixb.h b/noncore/games/tetrix/qtetrixb.h
new file mode 100644
index 0000000..4134a84
--- a/dev/null
+++ b/noncore/games/tetrix/qtetrixb.h
@@ -0,0 +1,80 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#ifndef QTETRIXB_H
+#define QTETRIXB_H
+
+#include "gtetrix.h"
+#include <qframe.h>
+
+class QTimer;
+
+class QTetrixBoard : public QFrame, public GenericTetrix
+{
+ Q_OBJECT
+public:
+ QTetrixBoard( QWidget *parent=0, const char *name=0 );
+
+ void gameOver();
+ void startGame(int gameType = 0,int fillRandomLines = 0);
+
+public slots:
+ void timeout();
+ void updateNext() { GenericTetrix::updateNext(); }
+ void key(QKeyEvent *e) { keyPressEvent(e); }
+ void start() { startGame(); }
+ void pause();
+
+signals:
+ void gameOverSignal();
+ void drawNextSquareSignal(int x,int y,QColor *color1);
+ void updateRemovedSignal(int noOfLines);
+ void updateScoreSignal(int score);
+ void updateLevelSignal(int level);
+
+public: // until we have keyboard focus, should be protected
+ void keyPressEvent( QKeyEvent * );
+
+private:
+ void drawContents( QPainter * );
+ void resizeEvent( QResizeEvent * );
+ void drawSquare(int x,int y,int value);
+ void drawNextSquare(int x,int y,int value);
+ void updateRemoved(int noOfLines);
+ void updateScore(int newScore);
+ void updateLevel(int newLlevel);
+ void pieceDropped(int dropHeight);
+ void updateTimeoutTime();
+
+ QTimer *timer;
+
+ int xOffset,yOffset;
+ int blockWidth,blockHeight;
+ int timeoutTime;
+ bool noGame;
+ bool isPaused;
+ bool waitingAfterLine;
+
+ QColor colors[7];
+ QPainter *paint;
+};
+
+#endif
diff --git a/noncore/games/tetrix/tetrix.pro b/noncore/games/tetrix/tetrix.pro
new file mode 100644
index 0000000..1160585
--- a/dev/null
+++ b/noncore/games/tetrix/tetrix.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = ../bin
+HEADERS = minefield.h \
+ gtetrix.h \
+ qtetrix.h \
+ qtetrixb.h \
+ tpiece.h
+SOURCES = main.cpp \
+ gtetrix.cpp \
+ qtetrix.cpp \
+ qtetrixb.cpp \
+ tpiece.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
diff --git a/noncore/games/tetrix/tpiece.cpp b/noncore/games/tetrix/tpiece.cpp
new file mode 100644
index 0000000..fe8b766
--- a/dev/null
+++ b/noncore/games/tetrix/tpiece.cpp
@@ -0,0 +1,201 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "tpiece.h"
+#include "qstring.h"
+#include <stdlib.h>
+#include <time.h>
+
+void TetrixPiece::rotateLeft()
+{
+ if ( pieceType == 5 ) // don't rotate square piece type
+ return;
+ int tmp;
+ for (int i = 0 ; i < 4 ; i++) {
+ tmp = getXCoord(i);
+ setXCoord(i,getYCoord(i));
+ setYCoord(i,-tmp);
+ }
+}
+
+void TetrixPiece::rotateRight()
+{
+ if ( pieceType == 5 ) // don't rotate square piece type
+ return;
+ int tmp;
+ for (int i = 0 ; i < 4 ; i++) {
+ tmp = getXCoord(i);
+ setXCoord(i,-getYCoord(i));
+ setYCoord(i,tmp);
+ }
+}
+
+int TetrixPiece::getMinX()
+{
+ int tmp = coordinates[0][0];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp > coordinates[i][0])
+ tmp = coordinates[i][0];
+ return tmp;
+}
+
+int TetrixPiece::getMaxX()
+{
+ int tmp = coordinates[0][0];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp < coordinates[i][0])
+ tmp = coordinates[i][0];
+ return tmp;
+
+}
+
+int TetrixPiece::getMinY()
+{
+ int tmp = coordinates[0][1];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp > coordinates[i][1])
+ tmp = coordinates[i][1];
+ return tmp;
+}
+
+int TetrixPiece::getMaxY()
+{
+ int tmp = coordinates[0][1];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp < coordinates[i][1])
+ tmp = coordinates[i][1];
+ return tmp;
+}
+
+void TetrixPiece::initialize(int type)
+{
+ static int pieceTypes[7][4][2] = {{{ 0,-1},
+ { 0, 0},
+ {-1, 0},
+ {-1, 1}},
+
+ {{ 0,-1},
+ { 0, 0},
+ { 1, 0},
+ { 1, 1}},
+
+ {{ 0,-1},
+ { 0, 0},
+ { 0, 1},
+ { 0, 2}},
+
+ {{-1, 0},
+ { 0, 0},
+ { 1, 0},
+ { 0, 1}},
+
+ {{ 0, 0},
+ { 1, 0},
+ { 0, 1},
+ { 1, 1}},
+
+ {{-1,-1},
+ { 0,-1},
+ { 0, 0},
+ { 0, 1}},
+
+ {{ 1,-1},
+ { 0,-1},
+ { 0, 0},
+ { 0, 1}}};
+ if (type < 1 || type > 7)
+ type = 1;
+ pieceType = type;
+ for(int i = 0 ; i < 4 ; i++) {
+ coordinates[i][0] = pieceTypes[type - 1][i][0];
+ coordinates[i][1] = pieceTypes[type - 1][i][1];
+ }
+}
+
+
+/*
+ * Sigh, oh beautiful nostalgia! This random algorithm has
+ * been taken from the book "Adventures with your pocket calculator"
+ * and I used it in my first implemented and machine-
+ * run program of any size to speak of. Imagine how hungry I
+ * was after having programmed BASIC on paper for
+ * half a year?!!?!?!?!?!? The first program I typed in was a
+ * slot machine game and was made in BASIC on a SHARP
+ * PC-1211 with 1,47 KB RAM (one point four seven kilobytes) and
+ * a one-line LCD-display (I think it had 32 characters) in the
+ * year of our lord 1981. The man I had bought the machine from worked
+ * as a COBOL programmer and was amazed and impressed
+ * when I demonstrated the program 2 days after I had
+ * bought the machine, quote: "Gees, I have been looking so long
+ * for a "random" command in that BASIC, what is it called?"
+ * Oh, how I still get a thrill out of the thought of the
+ * explanation I then gave him...
+ */
+
+/*
+ * Sukk, aa vakre nostalgi! Denne random algoritmen er
+ * tatt fra boka "Adventures with your pocket calculator"
+ * og den brukte jeg i mitt foerste implementerte og maskin-
+ * kjoerte program av nevneverdig stoerrelse. Tror du jeg var
+ * noe sulten etter aa ha programmert BASIC paa papir i et
+ * halvt aar?!!?!?!?!?!? Programmet jeg tasta inn foerst var et
+ * "enarmet banditt" spill og ble laget i BASIC paa en SHARP
+ * PC-1211 med 1,47 KB RAM (en komma foertisju kilobyte) og
+ * et en-linjers LCD-display (tror det hadde 32 karakterer) i det
+ * herrens aar 1981. Mannen jeg kjoepte maskinen av jobbet til
+ * daglig med COBOL programmering og var forbloeffet og imponert
+ * da jeg demonstrerte programmet 2 dager etter at jeg hadde
+ * kjoept maskinen, sitat: "Joess, jeg som har leita saa lenge
+ * etter en random kommando i den BASICen, hva var det den
+ * het?" Aa, jeg frydes ennaa ved tanken paa forklaringen jeg
+ * deretter ga ham...
+ */
+
+double TetrixPiece::randomSeed = 0.33333;
+
+void TetrixPiece::setRandomSeed(double seed)
+{
+#ifdef __MIPSEL__
+ srand( clock() );
+#else
+ QCString buffer;
+ if (seed < 0)
+ seed = - seed;
+ if (seed >= 1)
+ seed = seed - (double) ((int) seed);
+ buffer.sprintf("%1.5f",(float) seed);
+ for (int i = 0 ; i < 5 ; i++)
+ if ((buffer[i + 2] - '0') % 2 == 0)
+ buffer[i + 2]++;
+ randomSeed = atof(buffer);
+#endif
+}
+
+int TetrixPiece::randomValue(int maxPlusOne)
+{
+#ifdef __MIPSEL__
+ return rand() % maxPlusOne;
+#else
+ randomSeed = randomSeed*147;
+ randomSeed = randomSeed - (double) ((int) randomSeed);
+ return (int) (randomSeed*maxPlusOne);
+#endif
+}
diff --git a/noncore/games/tetrix/tpiece.h b/noncore/games/tetrix/tpiece.h
new file mode 100644
index 0000000..9c1c629
--- a/dev/null
+++ b/noncore/games/tetrix/tpiece.h
@@ -0,0 +1,62 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#ifndef TPIECE_H
+#define TPIECE_H
+
+class TetrixPiece
+{
+public:
+ TetrixPiece() {setRandomType();}
+ TetrixPiece(int type) {initialize(type % 7 + 1);}
+
+ void setRandomType() {initialize(randomValue(7) + 1);}
+
+ void rotateLeft();
+ void rotateRight();
+
+ int getType() {return pieceType;}
+ int getXCoord(int index) {return coordinates[index][0];}
+ int getYCoord(int index) {return coordinates[index][1];}
+ void getCoord(int index,int &x,int&y){x = coordinates[index][0];
+ y = coordinates[index][1];}
+ int getMinX();
+ int getMaxX();
+ int getMinY();
+ int getMaxY();
+
+ static void setRandomSeed(double seed);
+ static int randomValue(int maxPlusOne);
+
+private:
+ void setXCoord(int index,int value) {coordinates[index][0] = value;}
+ void setYCoord(int index,int value) {coordinates[index][1] = value;}
+ void setCoords(int index,int x,int y){coordinates[index][0] = x;
+ coordinates[index][1] = y;}
+ void initialize(int type);
+
+ int pieceType;
+ int coordinates[4][2];
+
+ static double randomSeed;
+};
+
+#endif
diff --git a/noncore/games/wordgame/.cvsignore b/noncore/games/wordgame/.cvsignore
new file mode 100644
index 0000000..d498858
--- a/dev/null
+++ b/noncore/games/wordgame/.cvsignore
@@ -0,0 +1,6 @@
+moc_*
+Makefile
+newgamebase.h
+rulesbase.h
+newgamebase.cpp
+rulesbase.cpp
diff --git a/noncore/games/wordgame/Makefile.in b/noncore/games/wordgame/Makefile.in
new file mode 100644
index 0000000..5627414
--- a/dev/null
+++ b/noncore/games/wordgame/Makefile.in
@@ -0,0 +1,168 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = wordgame
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = wordgame.h
+SOURCES = main.cpp \
+ wordgame.cpp
+OBJECTS = main.o \
+ wordgame.o \
+ newgamebase.o \
+ rulesbase.o
+INTERFACES = newgamebase.ui \
+ rulesbase.ui
+UICDECLS = newgamebase.h \
+ rulesbase.h
+UICIMPLS = newgamebase.cpp \
+ rulesbase.cpp
+SRCMOC = moc_wordgame.cpp \
+ moc_newgamebase.cpp \
+ moc_rulesbase.cpp
+OBJMOC = moc_wordgame.o \
+ moc_newgamebase.o \
+ moc_rulesbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake wordgame.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+wordgame.o: wordgame.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/filemanager.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+newgamebase.h: newgamebase.ui
+ $(UIC) newgamebase.ui -o $(INTERFACE_DECL_PATH)/newgamebase.h
+
+newgamebase.cpp: newgamebase.ui
+ $(UIC) newgamebase.ui -i newgamebase.h -o newgamebase.cpp
+
+rulesbase.h: rulesbase.ui
+ $(UIC) rulesbase.ui -o $(INTERFACE_DECL_PATH)/rulesbase.h
+
+rulesbase.cpp: rulesbase.ui
+ $(UIC) rulesbase.ui -i rulesbase.h -o rulesbase.cpp
+
+newgamebase.o: newgamebase.cpp
+
+rulesbase.o: rulesbase.cpp
+
+moc_wordgame.o: moc_wordgame.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h
+
+moc_newgamebase.o: moc_newgamebase.cpp \
+ newgamebase.h
+
+moc_rulesbase.o: moc_rulesbase.cpp \
+ rulesbase.h
+
+moc_wordgame.cpp: wordgame.h
+ $(MOC) wordgame.h -o moc_wordgame.cpp
+
+moc_newgamebase.cpp: newgamebase.h
+ $(MOC) newgamebase.h -o moc_newgamebase.cpp
+
+moc_rulesbase.cpp: rulesbase.h
+ $(MOC) rulesbase.h -o moc_rulesbase.cpp
+
+
diff --git a/noncore/games/wordgame/calcdist b/noncore/games/wordgame/calcdist
new file mode 100755
index 0000000..faf31f1
--- a/dev/null
+++ b/noncore/games/wordgame/calcdist
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+# Usage: cat dictionaries | grep -v '[^a-z]' | calcdist n score
+#
+# Given a lot of words, find an appropriate distribution
+# into n tiles with tile values proportional to the square root
+# of the ratio of score to the tile's frequency.
+
+$n = shift;
+$score = shift;
+
+while (<>) {
+ chomp;
+ for $c ( split "", $_ ) {
+ $freq{$c}++;
+ $t++;
+ }
+}
+
+for $c ( sort { $freq{$a} <=> $freq{$b} } keys %freq ) {
+ #print "$c: $freq{$c}\n";
+ $need = int($freq{$c}*$n/$t+0.5) || 1;
+ $value = int(sqrt($score/($freq{$c}*$n/$t))+0.5) || 1;
+ $t -= $freq{$c};
+ $n -= $need;
+ print "$need $c $value\n";
+}
diff --git a/noncore/games/wordgame/main.cpp b/noncore/games/wordgame/main.cpp
new file mode 100644
index 0000000..cd4600e
--- a/dev/null
+++ b/noncore/games/wordgame/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "wordgame.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ WordGame mw;
+ //QPEApplication::setInputMethodHint( &mw, QPEApplication::AlwaysOff );
+ a.showMainWidget(&mw);
+
+ return a.exec();
+}
diff --git a/noncore/games/wordgame/newgamebase.ui b/noncore/games/wordgame/newgamebase.ui
new file mode 100644
index 0000000..3b6570b
--- a/dev/null
+++ b/noncore/games/wordgame/newgamebase.ui
@@ -0,0 +1,337 @@
+<!DOCTYPE UI><UI>
+<class>NewGameBase</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form1</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>290</width>
+ <height>443</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>8</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Players</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player0</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player1</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player2</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player3</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player4</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player5</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox2</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Rules</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>rules</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonOk</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Start</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>default</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/noncore/games/wordgame/qpe-wordgame.control b/noncore/games/wordgame/qpe-wordgame.control
new file mode 100644
index 0000000..2293f52
--- a/dev/null
+++ b/noncore/games/wordgame/qpe-wordgame.control
@@ -0,0 +1,10 @@
+Files: bin/wordgame apps/Games/wordgame.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Crossword game
+ A crossword game for the Qtopia environment.
+ Play against the computer or human opponents.
diff --git a/noncore/games/wordgame/rulesbase.ui b/noncore/games/wordgame/rulesbase.ui
new file mode 100644
index 0000000..31cc402
--- a/dev/null
+++ b/noncore/games/wordgame/rulesbase.ui
@@ -0,0 +1,274 @@
+<!DOCTYPE UI><UI>
+<class>RulesBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RulesBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>283</width>
+ <height>264</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Game Rules</string>
+ </property>
+ <property stdset="1">
+ <name>sizeGripEnabled</name>
+ <bool>false</bool>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Name:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>gamename</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Board</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Size:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>width</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>15</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>3</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>height</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>15</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>3</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>editboard</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Edit...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QTable</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tiletable</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonDelete</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Delete</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonOk</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;OK</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>default</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Cancel</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>RulesBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>RulesBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp
new file mode 100644
index 0000000..ca4352d
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.cpp
@@ -0,0 +1,1476 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "wordgame.h"
+
+#include <qpe/applnk.h>
+#include <qpe/global.h>
+#include <qpe/filemanager.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include <qcombobox.h>
+#include <qdatetime.h>
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qiconset.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qvbox.h>
+#include <qwidgetstack.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+enum RuleEffects {
+ Multiplier=15,
+ MultiplyAll=64,
+ Start=128
+};
+
+static const int rack_tiles=7;
+
+const char* sampleWGR=
+ "wordgame_shapes\n"
+ "15 15\n"
+ "400001040100004\n"
+ "030000000000030\n"
+ "002002000200200\n"
+ "000300020003000\n"
+ "000020000020000\n"
+ "102001000100201\n"
+ "000000202000000\n"
+ "400200050002004\n"
+ "000000202000000\n"
+ "102001000100201\n"
+ "000020000020000\n"
+ "000300020003000\n"
+ "002002000200200\n"
+ "030000000000030\n"
+ "400001040100004\n"
+ "1 2 3 66 67 194 100 0\n"
+ "1 j 8\n"
+ "1 q 7\n"
+ "1 x 6\n"
+ "1 z 6\n"
+ "1 w 4\n"
+ "1 k 4\n"
+ "1 v 3\n"
+ "1 f 3\n"
+ "2 y 3\n"
+ "2 h 2\n"
+ "2 b 2\n"
+ "2 m 2\n"
+ "3 p 2\n"
+ "3 g 2\n"
+ "3 u 2\n"
+ "4 d 2\n"
+ "4 c 2\n"
+ "5 l 1\n"
+ "5 o 1\n"
+ "7 t 1\n"
+ "7 n 1\n"
+ "7 a 1\n"
+ "7 r 1\n"
+ "8 s 1\n"
+ "8 i 1\n"
+ "11 e 1\n"
+ "0\n";
+
+WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) :
+ QMainWindow(parent, name, fl)
+{
+ setIcon( Resource::loadPixmap( "wordgame" ) );
+ setCaption( tr("Word Game") );
+
+ setToolBarsMovable( FALSE );
+ vbox = new QVBox(this);
+
+ setCentralWidget(vbox);
+ toolbar = new QPEToolBar(this);
+ addToolBar(toolbar, Bottom);
+ reset = new QToolButton(Resource::loadPixmap("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar);
+ done = new QToolButton(Resource::loadPixmap("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar);
+ scoreinfo = new ScoreInfo(toolbar);
+ scoreinfo->setFont(QFont("Helvetica",10));
+ new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar);
+ toolbar->setStretchableWidget(scoreinfo);
+
+ cpu = 0;
+ board = 0;
+ bag = 0;
+ racks = 0;
+
+ aiheart = new QTimer(this);
+ connect(aiheart, SIGNAL(timeout()), this, SLOT(think()));
+
+ readConfig();
+}
+
+WordGame::~WordGame()
+{
+ writeConfig();
+}
+
+void WordGame::writeConfig()
+{
+ Config cfg("WordGame");
+ cfg.setGroup("Game");
+ cfg.writeEntry("NameList",namelist,';');
+ cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1);
+ if ( !gameover ) {
+ cfg.writeEntry("Rules",rules);
+ bag->writeConfig(cfg);
+ board->writeConfig(cfg);
+ scoreinfo->writeConfig(cfg);
+ }
+ for (int p=0; p<nplayers; p++) {
+ cfg.setGroup("Player"+QString::number(p+1));
+ if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg);
+ }
+}
+
+void WordGame::readConfig()
+{
+ Config cfg("WordGame");
+ cfg.setGroup("Game");
+ int currentplayer = cfg.readNumEntry("CurrentPlayer",0);
+ QStringList pnames = cfg.readListEntry("NameList",';');
+ if ( currentplayer ) {
+ gameover = FALSE;
+ rules = cfg.readEntry("Rules");
+ if ( rules.find("x-wordgamerules") >= 0 ) {
+ // rules files moved
+ rules = "Sample.rules";
+ }
+ if ( loadRules(rules) ) {
+ startGame(pnames);
+ bag->readConfig(cfg);
+ board->readConfig(cfg);
+ scoreinfo->readConfig(cfg);
+ for (int p=0; p<nplayers; p++) {
+ cfg.setGroup("Player"+QString::number(p+1));
+ rack(p)->readConfig(cfg);
+ }
+ player=currentplayer-1;
+ readyRack(player);
+ return;
+ }
+ }
+ // fall-back
+ openGameSelector(pnames);
+}
+
+void WordGame::openGameSelector(const QStringList& initnames)
+{
+ toolbar->hide();
+ gameover = FALSE;
+
+ delete board;
+ board = 0;
+ delete racks;
+ racks = 0;
+
+ delete cpu;
+ cpu = 0;
+
+ newgame = new NewGame(vbox);
+
+ //Rules rules(this);
+ //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules()));
+ //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets()));
+ struct passwd* n = getpwuid(getuid());
+ QString playername = n ? n->pw_name : "";
+ if ( playername.isEmpty() ) {
+ playername = "Player";
+ }
+ newgame->player0->changeItem(playername,0);
+ newgame->player1->setCurrentItem(1);
+ newgame->updateRuleSets();
+ newgame->show();
+
+ connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame()));
+}
+
+void WordGame::startGame()
+{
+ rules = newgame->ruleslist[newgame->rules->currentItem()];
+ if ( loadRules(rules) ) {
+ QStringList names;
+ names.append(newgame->player0->currentText());
+ names.append(newgame->player1->currentText());
+ names.append(newgame->player2->currentText());
+ names.append(newgame->player3->currentText());
+ names.append(newgame->player4->currentText());
+ names.append(newgame->player5->currentText());
+ delete newgame;
+ startGame(names);
+ } else {
+ // error...
+ delete newgame;
+ close();
+ }
+}
+
+void WordGame::startGame(const QStringList& playerlist)
+{
+ toolbar->show();
+ racks = new QWidgetStack(vbox);
+ namelist.clear();
+ nplayers=0;
+ for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it)
+ addPlayer(*it);
+ scoreinfo->init(namelist);
+
+ if ( nplayers ) {
+ player=0;
+ readyRack(player);
+ }
+
+ board->show();
+ racks->show();
+}
+
+bool WordGame::loadRules(const QString &name)
+{
+ QString filename = Global::applicationFileName( "wordgame", name );
+ QFile file( filename );
+ if ( !file.open( IO_ReadOnly ) )
+ return FALSE;
+
+ QTextStream ts( &file );
+
+ QString title = name;
+ title.truncate( title.length() - 6 );
+ setCaption( title );
+
+ QString shapepixmap;
+ ts >> shapepixmap;
+ int htiles,vtiles;
+ ts >> htiles >> vtiles;
+
+ if ( htiles < 3 || vtiles < 3 )
+ return FALSE;
+
+ QPixmap bgshapes = Resource::loadPixmap(shapepixmap);
+ QString rule_shapes;
+ for (int i=0; i<vtiles; i++) {
+ QString line;
+ ts >> line;
+ rule_shapes += line;
+ }
+ static int rule_effects[12];
+ int re=0,e;
+ ts >> e;
+ while ( e && re < 10 ) {
+ rule_effects[re] = e;
+ if ( re++ < 10 ) ts >> e;
+ }
+ rule_effects[re++] = 100; // default bonus
+ board = new Board(bgshapes, htiles, vtiles, vbox);
+ board->setRules(rule_shapes, rule_effects);
+ connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int)));
+
+ bag = new Bag;
+
+ int count;
+ ts >> count;
+ while ( count ) {
+ QString text;
+ int value;
+ ts >> text >> value;
+ if ( text == "_" )
+ text = "";
+
+ Tile t(text, value);
+ for (int n=count; n--; )
+ bag->add(t);
+
+ ts >> count;
+ }
+
+ return TRUE;
+}
+
+
+NewGame::NewGame(QWidget* parent) :
+ NewGameBase(parent)
+{
+}
+
+void NewGame::updateRuleSets()
+{
+ rules->clear();
+
+ QString rulesDir = Global::applicationFileName( "wordgame", "" );
+ QDir dir( rulesDir, "*.rules" );
+ ruleslist = dir.entryList();
+ if ( ruleslist.isEmpty() ) {
+ // Provide a sample
+ QFile file( rulesDir + "Sample.rules" );
+ if ( file.open( IO_WriteOnly ) ) {
+ file.writeBlock( sampleWGR, strlen(sampleWGR) );
+ file.close();
+ updateRuleSets();
+ }
+ return;
+ }
+ int newest=0;
+ int newest_age=INT_MAX;
+ QDateTime now = QDateTime::currentDateTime();
+ QStringList::Iterator it;
+ for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) {
+ QFileInfo fi((*it));
+ int age = fi.lastModified().secsTo(now);
+ QString name = *it;
+ name.truncate( name.length()-6 ); // remove extension
+ rules->insertItem( name );
+ if ( age < newest_age ) {
+ newest_age = age;
+ newest = rules->count()-1;
+ }
+ }
+ rules->setCurrentItem(newest);
+}
+
+Rules::Rules(QWidget* parent) :
+ RulesBase(parent,0,TRUE)
+{
+}
+
+void Rules::editRules()
+{
+ if ( exec() ) {
+ // ### create a new set of rules
+ emit rulesChanged();
+ }
+}
+
+void Rules::deleteRuleSet()
+{
+ // ### delete existing rule set
+ emit rulesChanged();
+}
+
+void WordGame::addPlayer(const QString& name)
+{
+ if ( !name.isEmpty() ) {
+ int colon = name.find(':');
+ int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0;
+ addPlayer(name,cpu);
+ }
+}
+
+void WordGame::addPlayer(const QString& name, int cpu)
+{
+ Rack* r = new Rack(rack_tiles,racks);
+ r->setPlayerName(name);
+ r->setComputerization(cpu);
+ racks->addWidget(r, nplayers);
+ refillRack(nplayers);
+ namelist.append(name);
+
+ ++nplayers;
+}
+
+void WordGame::nextPlayer()
+{
+ if ( !refillRack(player) ) {
+ endGame();
+ } else {
+ player = (player+1)%nplayers;
+ scoreinfo->setBoldOne(player);
+ readyRack(player);
+ }
+}
+
+bool WordGame::mayEndGame()
+{
+ int out=-1;
+ int i;
+ for (i=0; i<nplayers; i++)
+ if ( !rack(i)->count() )
+ out = i;
+ if ( out<0 ) {
+ if ( QMessageBox::warning(this,tr("End game"),
+ tr("Do you want to end the game early?"),
+ tr("Yes"), tr("No") )!=0 )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void WordGame::endGame()
+{
+ if ( gameover ) {
+ close();
+ return;
+ }
+
+ if ( !mayEndGame() )
+ return;
+ int out=-1;
+ int totalleft=0;
+ int i;
+ for (i=0; i<nplayers; i++) {
+ Rack* r = rack(i);
+ int c = r->count();
+ if ( c ) {
+ int lose=0;
+ for ( int j=0; j<c; j++ )
+ lose += r->tileRef(j)->value();
+ totalleft += lose;
+ scoreinfo->addScore(i,-lose);
+ } else {
+ out = i;
+ }
+ }
+ int highest=0;
+ int winner=0;
+ for (i=0; i<nplayers; i++) {
+ int s = scoreinfo->playerScore(i);
+ if ( s > highest ) {
+ highest = s;
+ winner = i;
+ }
+ }
+ if ( out >= 0 )
+ scoreinfo->addScore(out,totalleft);
+ scoreinfo->setBoldOne(winner);
+ gameover = TRUE;
+ done->setEnabled(TRUE);
+ reset->setEnabled(FALSE);
+}
+
+void WordGame::endTurn()
+{
+ if ( gameover ) {
+ openGameSelector(namelist);
+ } else {
+ if ( board->checkTurn() ) {
+ if ( board->turnScore() >= 0 ) {
+ scoreinfo->addScore(player,board->turnScore());
+ board->finalizeTurn();
+ } else {
+ QApplication::beep();
+ }
+ nextPlayer();
+ }
+ }
+}
+
+void WordGame::resetTurn()
+{
+ board->resetRack();
+}
+
+void WordGame::passTurn()
+{
+ // ######## trade?
+ nextPlayer();
+}
+
+bool WordGame::refillRack(int i)
+{
+ Rack* r = rack(i);
+ while ( !bag->isEmpty() && !r->isFull() ) {
+ r->addTile(bag->takeRandom());
+ }
+ return r->count() != 0;
+}
+
+void WordGame::readyRack(int i)
+{
+ Rack* r = rack(i);
+ racks->raiseWidget(i);
+ board->setCurrentRack(r);
+
+ done->setEnabled( !r->computerized() );
+ reset->setEnabled( !r->computerized() );
+
+ if ( r->computerized() ) {
+ cpu = new ComputerPlayer(board, r);
+ aiheart->start(0);
+ }
+}
+
+Rack* WordGame::rack(int i) const
+{
+ return (Rack*)racks->widget(i);
+}
+
+void WordGame::think()
+{
+ if ( !cpu->step() ) {
+ delete cpu;
+ cpu = 0;
+ aiheart->stop();
+ if ( board->turnScore() < 0 )
+ passTurn();
+ else
+ endTurn();
+ }
+}
+
+ComputerPlayer::ComputerPlayer(Board* b, Rack* r) :
+ board(b), rack(r), best(new const Tile*[rack_tiles]),
+ best_blankvalues(new Tile[rack_tiles])
+{
+ best_score = -1;
+ across=FALSE;
+ dict=0;
+}
+
+ComputerPlayer::~ComputerPlayer()
+{
+ delete [] best;
+ delete [] best_blankvalues;
+}
+
+bool ComputerPlayer::step()
+{
+ const QDawg::Node* root = dict ? Global::dawg("WordGame").root()
+ : Global::fixedDawg().root();
+ QPoint d = across ? QPoint(1,0) : QPoint(0,1);
+ const Tile* tiles[99]; // ### max board size
+ uchar nletter[4095]; // QDawg only handles 0..4095
+ memset(nletter,0,4096);
+ for (int i=0; i<rack->count(); i++) {
+ const Tile* r = rack->tileRef(i);
+ if ( r->isBlank() )
+ nletter[0]++;
+ else
+ nletter[r->text()[0].unicode()]++;
+ }
+ Tile blankvalues[99]; // ### max blanks
+ findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0);
+ if ( ++current.rx() == board->xTiles() ) {
+ current.rx() = 0;
+ if ( ++current.ry() == board->yTiles() ) {
+ if ( across ) {
+ if ( dict == 1 ) {
+ if ( best_score >= 0 ) {
+ rack->arrangeTiles(best,best_n);
+ rack->setBlanks(best_blankvalues);
+ board->scoreTurn(best_start, best_n, best_dir);
+ board->showTurn();
+ }
+ return FALSE;
+ }
+ dict++;
+ across = FALSE;
+ current = QPoint(0,0);
+ } else {
+ across = TRUE;
+ current = QPoint(0,0);
+ }
+ }
+ }
+ return TRUE;
+}
+
+void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused)
+{
+ if ( !node )
+ return;
+ QChar l = node->letter();
+ const Tile* cur = board->tile(at);
+ if ( cur ) {
+ if ( cur->text()[0] == l ) {
+ bool nextok = board->contains(at+d);
+ if ( node->isWord() && n && (!nextok || !board->tile(at+d)) )
+ noteChoice(tiles,n,d,blankvalues,blused);
+ if ( nextok )
+ findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
+ // #### text()[1]...
+ }
+ } else {
+ if ( nletter[l.unicode()] || nletter[0] ) {
+ int rc = rack->count();
+ ulong msk = 1;
+ for ( int x=0; x<rc; x++ ) {
+ if ( !(used&msk) ) {
+ const Tile* t = rack->tileRef(x);
+ if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s
+ bool nextok = board->contains(at+d);
+ tiles[n++] = t;
+ if ( t->isBlank() )
+ blankvalues[blused++] = Tile(l,0);
+ if ( node->isWord() && (!nextok || !board->tile(at+d)) )
+ noteChoice(tiles,n,d,blankvalues,blused);
+ used |= msk; // mark
+ nletter[t->text()[0].unicode()]--;
+ if ( nextok )
+ findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
+ n--;
+ nletter[t->text()[0].unicode()]++;
+ if ( t->isBlank() ) {
+ // keep looking
+ blused--;
+ used &= ~msk; // unmark
+ } else {
+ break;
+ }
+ }
+ }
+ msk <<= 1;
+ }
+ }
+ // #### text()[1]...
+ }
+ findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused);
+}
+
+void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused)
+{
+ int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0);
+/*
+if (s>0 || current==QPoint(5,1)){
+QString st;
+for ( int i=0; i<n; i++ )
+ st += tiles[i]->text();
+qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s);
+}
+*/
+ if ( s > best_score ) {
+ int i;
+ for ( i=0; i<n; i++ )
+ best[i] = tiles[i];
+ for ( i=0; i<blused; i++ )
+ best_blankvalues[i] = blankvalues[i];
+ best_n = n;
+ best_blused = blused;
+ best_score = s;
+ best_dir = d;
+ best_start = current;
+ }
+}
+
+int TileItem::smallWidth()
+{
+ return 16;
+}
+
+int TileItem::smallHeight()
+{
+ return 16;
+}
+
+int TileItem::bigWidth()
+{
+ return 22;
+}
+
+int TileItem::bigHeight()
+{
+ return 22;
+}
+
+void TileItem::setState( State state )
+{
+ hide();
+ s = state;
+ show(); // ### use update() in Qt 3.0
+}
+
+void TileItem::setTile(const Tile& tile)
+{
+ hide();
+ t = tile;
+ show(); // ### use update() in Qt 3.0
+}
+
+void TileItem::setBig(bool b)
+{
+ big = b;
+}
+
+void TileItem::drawShape(QPainter& p)
+{
+ static QFont value_font("heletica",8);
+ static QFont big_font("smoothtimes",17);
+ static QFont small_font("smoothtimes",10);
+
+ QRect area(x(),y(),width(),height());
+ p.setBrush(s == Floating ? yellow/*lightGray*/ : white);
+ p.drawRect(area);
+ if ( big ) {
+ p.setFont(value_font);
+ QString n = QString::number(t.value());
+ int w = p.fontMetrics().width('1');
+ int h = p.fontMetrics().height();
+ w *= n.length();
+ QRect valuearea(x()+width()-w-2,y()+height()-h+1,w,h);
+ p.drawText(valuearea,AlignCenter,n);
+ p.setFont(big_font);
+ area = QRect(x(),y(),width()-2,height()-1);
+ } else {
+ p.setFont(small_font);
+ area = QRect(x(),y()+2,width(),height()-2);
+ }
+ if ( t.value() == 0 )
+ p.setPen(darkGray);
+ p.drawText(area,AlignCenter,t.text().upper());
+}
+
+Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) :
+ QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()),
+ parent)
+{
+ grid = new TileItem*[w*h];
+ memset(grid,0,w*h*sizeof(TileItem*));
+ setFrameStyle(0);
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+ current_rack = 0;
+ shown_n = 0;
+}
+
+Board::~Board()
+{
+ delete canvas();
+}
+
+void Board::writeConfig(Config& cfg)
+{
+ QStringList t;
+ int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
+ for (int i=0; i<n; i++)
+ t.append( grid[i] ? grid[i]->tile().key() : QString(".") );
+ cfg.writeEntry("Board",t,';');
+}
+
+void Board::readConfig(Config& cfg)
+{
+ clear();
+ QStringList t = cfg.readListEntry("Board",';');
+ int i=0;
+ int h=canvas()->tilesHorizontally();
+ for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) {
+ if ( *it != "." ) {
+ QPoint p(i%h,i/h);
+ setTile(p,Tile(*it));
+ }
+ i++;
+ }
+ canvas()->update();
+}
+
+void Board::clear()
+{
+ int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
+ for (int i=0; i<n; i++) {
+ delete grid[i];
+ grid[i]=0;
+ }
+}
+
+
+void Board::setCurrentRack(Rack* r)
+{
+ turn_score = -1;
+ current_rack = r;
+}
+
+void Board::resetRack()
+{
+ unshowTurn();
+ canvas()->update();
+}
+
+void Board::contentsMousePressEvent(QMouseEvent* e)
+{
+ dragstart = e->pos();
+}
+
+void Board::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if ( current_rack && !current_rack->computerized() ) {
+ QPoint d = e->pos() - dragstart;
+ if ( d.x() <= 0 && d.y() <= 0 ) {
+ // None
+ resetRack();
+ } else {
+ int n;
+ QPoint start=boardPos(dragstart);
+ QPoint end=boardPos(e->pos());
+ QPoint diff=end-start;
+ QPoint dir;
+ if ( d.x() > d.y() ) {
+ n = diff.x()+1;
+ dir = QPoint(1,0);
+ } else {
+ n = diff.y()+1;
+ dir = QPoint(0,1);
+ }
+
+ unshowTurn();
+
+ // Subtract existing tiles from n
+ QPoint t = start;
+ for ( int i=n; i--; ) {
+ if ( contains(t) && tile(t) )
+ n--;
+ t += dir;
+ }
+
+ // Move start back to real start
+ while (contains(start-dir) && tile(start-dir))
+ start -= dir;
+
+ scoreTurn(start, n, dir);
+ showTurn();
+ }
+ }
+}
+
+void Board::finalizeTurn()
+{
+ int i=0;
+ QPoint at = shown_at;
+ while ( i<shown_n && contains(at) ) {
+ if ( item(at) && item(at)->state() == TileItem::Floating ) {
+ current_rack->remove(item(at)->tile());
+ setTileState(at,TileItem::Firm);
+ i++;
+ }
+ at += shown_step;
+ }
+ canvas()->update();
+}
+
+void Board::unshowTurn()
+{
+ int i=0;
+ QPoint at = shown_at;
+ while ( i<shown_n && i<current_rack->count() && contains(at) ) {
+ if ( item(at) && item(at)->state() == TileItem::Floating ) {
+ unsetTile(at);
+ i++;
+ }
+ at += shown_step;
+ }
+}
+
+void Board::showTurn()
+{
+ unshowTurn();
+ QPoint at = shown_at;
+ int i=0;
+ while ( i<shown_n && i<current_rack->count() && contains(at) ) {
+ if ( !tile(at) ) {
+ Tile t = current_rack->tile(i);
+ setTile(at,t);
+ setTileState(at,TileItem::Floating);
+ i++;
+ }
+ at += shown_step;
+ }
+ canvas()->update();
+}
+
+int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const
+{
+ int rule = rule_shape[idx(at)]-'0';
+ int effect = rule_effect[rule];
+ int mult = effect&Multiplier;
+ if ( effect & MultiplyAll ) {
+ all_mult *= mult;
+ return base;
+ } else {
+ return base * mult;
+ }
+}
+
+bool Board::isStart(const QPoint& at) const
+{
+ int rule = rule_shape[idx(at)]-'0';
+ int effect = rule_effect[rule];
+ return effect&Start;
+}
+
+bool Board::checkTurn()
+{
+ if ( current_rack->computerized() )
+ return TRUE; // computer doesn't cheat, and has already set blanks.
+
+ QPoint at = shown_at;
+ int n = shown_n;
+ QPoint d = shown_step;
+ const Tile* tiles[99];
+ Tile blankvalues[99];
+ if ( n > current_rack->count() )
+ n = current_rack->count();
+
+ QDialog check(this,0,TRUE);
+ (new QVBoxLayout(&check))->setAutoAdd(TRUE);
+
+ QHBox mw(&check);
+ new QLabel(tr("Blanks: "),&mw);
+
+ int bl=0;
+ QLineEdit* le[99];
+ for (int i=0; i<n; i++) {
+ tiles[i] = current_rack->tileRef(i);
+ if ( tiles[i]->isBlank() ) {
+ QLineEdit *l = new QLineEdit(&mw);
+ le[bl++] = l;
+ l->setMaxLength(1);
+ l->setFixedSize(l->minimumSizeHint());
+ }
+ }
+
+ QHBox btns(&check);
+ connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept()));
+ connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject()));
+
+ if ( bl ) {
+retry:
+ if ( !check.exec() ) {
+ unshowTurn();
+ canvas()->update();
+ return FALSE;
+ }
+
+ for (int b=0; b<bl; b++) {
+ QString v = le[b]->text();
+ blankvalues[b]=Tile(v,0);
+ if ( v.length() != 1 )
+ goto retry;
+ }
+ }
+
+ QStringList words;
+ unshowTurn();
+ turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words);
+ showTurn();
+ QStringList to_add;
+ for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) {
+ if ( !Global::fixedDawg().contains(*it)
+ && !Global::dawg("WordGame").contains(*it) ) {
+ switch (QMessageBox::warning(this, tr("Unknown word"),
+ tr("<p>The word \"%1\" is not in the dictionary.").arg(*it),
+ tr("Add"), tr("Ignore"), tr("Cancel")))
+ {
+ case 0:
+ // ####### add to wordgame dictionary
+ to_add.append(*it);
+ break;
+ case 1:
+ break;
+ case 2:
+ unshowTurn();
+ canvas()->update();
+ return FALSE;
+ }
+ }
+ }
+ if ( to_add.count() )
+ Global::addWords("WordGame",to_add);
+ return TRUE;
+}
+
+void Board::scoreTurn(const QPoint& at, int n, const QPoint& d)
+{
+ unshowTurn();
+ shown_at = at;
+ shown_n = n;
+ shown_step = d;
+ const Tile* tiles[99];
+ if ( n > current_rack->count() )
+ n = current_rack->count();
+ for (int i=0; i<n; i++)
+ tiles[i] = current_rack->tileRef(i);
+ turn_score = score(at,tiles,n,0,d,FALSE,0);
+ emit temporaryScore(turn_score);
+}
+
+int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const
+{
+ int total=0;
+ int totalsidetotal=0;
+
+ // words gets filled with words made
+
+ // mainword==0 ->
+ // Checks side words, but not main word
+
+ // -1 means words not in dict, or illegally positioned (eg. not connected)
+
+ // text is assumed to fit on board.
+
+ if ( words ) *words=QStringList();
+
+ QPoint otherd(d.y(), d.x());
+
+ int all_mult = 1;
+ int bl=0;
+
+ bool connected = FALSE;
+
+ QString mainword="";
+
+ if ( contains(at-d) && tile(at-d) ) {
+ return -1; // preceeding tiles
+ }
+
+ const Tile* t;
+ for (int i=0; contains(at) && ((t=tile(at)) || i<n); ) {
+ if ( t ) {
+ if ( checkdict || words ) mainword += t->text();
+ total += t->value();
+ connected = TRUE;
+ } else {
+ QString sideword;
+ QString tt;
+ if ( tiles[i]->isBlank() ) {
+ if ( blankvalue )
+ tt = blankvalue[bl++].text();
+ } else {
+ tt = tiles[i]->text();
+ }
+ sideword=tt;
+ if ( checkdict || words ) mainword += tt;
+ int side_mult = 1;
+ int tilevalue = bonussedValue(at,tiles[i]->value(),side_mult);
+ all_mult *= side_mult;
+ if ( !connected && isStart(at) )
+ connected = TRUE;
+ total += tilevalue;
+ int sidetotal = tilevalue;
+ {
+ QPoint side = at-otherd;
+
+ while ( contains(side) && (t=tile(side)) ) {
+ sidetotal += t->value();
+ sideword.prepend(t->text());
+ side -= otherd;
+ }
+ }
+ {
+ QPoint side = at+otherd;
+ while ( contains(side) && (t=tile(side)) ) {
+ sidetotal += t->value();
+ sideword.append(t->text());
+ side += otherd;
+ }
+ }
+ if ( sideword.length() > 1 ) {
+ if ( words )
+ words->append(sideword);
+ if ( checkdict && !Global::fixedDawg().contains(sideword)
+ && !Global::dawg("WordGame").contains(sideword) )
+ return -1;
+ totalsidetotal += sidetotal * side_mult;
+ connected = TRUE;
+ }
+ i++;
+ }
+ at += d;
+ }
+
+ if ( words )
+ words->append(mainword);
+ if ( checkdict && !Global::fixedDawg().contains(mainword)
+ && !Global::dawg("WordGame").contains(mainword) )
+ return -1;
+
+ if ( n == rack_tiles )
+ totalsidetotal += rack_tiles_bonus;
+
+ return connected ? totalsidetotal + total * all_mult : -1;
+}
+
+QPoint Board::boardPos(const QPoint& p) const
+{
+ return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight());
+}
+
+void Board::contentsMouseReleaseEvent(QMouseEvent*)
+{
+ if ( current_rack ) {
+ }
+}
+
+
+void Board::setRules(const QString& shapes, const int* effects)
+{
+ rule_shape=shapes; rule_effect=effects;
+ int i=0;
+ int maxre=0;
+ for (int y=0; y<yTiles(); y++) {
+ for (int x=0; x<xTiles(); x++) {
+ int re = shapes[i++]-'0';
+ if ( re > maxre ) maxre = re;
+ canvas()->setTile(x,y,re);
+ }
+ }
+ rack_tiles_bonus=effects[maxre+1];
+}
+
+void Board::unsetTile(const QPoint& p)
+{
+ delete item(p);
+ grid[idx(p)] = 0;
+}
+
+void Board::setTile(const QPoint& p, const Tile& t)
+{
+ TileItem* it=item(p);
+ if ( !it ) {
+ it = grid[idx(p)] = new TileItem(t,FALSE,canvas());
+ it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight());
+ it->show();
+ } else {
+ it->setTile(t);
+ }
+}
+
+Rack::Rack(int ntiles, QWidget* parent) : QCanvasView(
+ new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()),
+ parent),
+ item(ntiles)
+{
+ setLineWidth(1);
+ setFixedHeight(sizeHint().height());
+ n = 0;
+ for (int i=0; i<ntiles; i++)
+ item[i]=0;
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+ canvas()->setBackgroundColor(gray);
+ dragging = 0;
+}
+
+Rack::~Rack()
+{
+ clear();
+ delete canvas();
+}
+
+void Rack::clear()
+{
+ for (int i=0; i<n; i++)
+ delete item[i];
+ n=0;
+}
+
+void Rack::writeConfig(Config& cfg)
+{
+ QStringList l;
+ for (int i=0; i<n; i++)
+ l.append(tile(i).key());
+ cfg.writeEntry("Tiles",l,';');
+}
+
+void Rack::readConfig(Config& cfg)
+{
+ clear();
+ int x=0;
+ QStringList l = cfg.readListEntry("Tiles",';');
+ for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
+ TileItem *i = new TileItem(Tile(*it),TRUE,canvas());
+ i->move(x++,0);
+ i->show();
+ item[n++] = i;
+ }
+ layoutTiles();
+}
+
+static int cmp_tileitem(const void *a, const void *b)
+{
+ const TileItem* ia = *(TileItem**)a;
+ const TileItem* ib = *(TileItem**)b;
+ return int(ia->x() - ib->x());
+}
+
+void Rack::layoutTiles()
+{
+ int w = TileItem::bigWidth()+2;
+
+ if ( dragging ) dragging->moveBy(dragging_adj,0);
+ qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem);
+ if ( dragging ) dragging->moveBy(-dragging_adj,0);
+
+ for (int i=0; i<n ;i++)
+ if ( item[i] == dragging ) {
+ item[i]->setZ(1);
+ } else {
+ item[i]->move(i*w, 0);
+ item[i]->setZ(0);
+ }
+ canvas()->update();
+}
+
+void Rack::setBlanks(const Tile* bv)
+{
+ for (int j=0; j<n; j++) {
+ Tile tt = item[j]->tile();
+ if ( tt.isBlank() ) {
+ tt.setText(bv->text());
+ item[j]->setTile(tt);
+ bv++;
+ }
+ }
+}
+
+bool Rack::arrangeTiles(const Tile** s, int sn)
+{
+ bool could = TRUE;
+ for (int j=0; j<n; j++) {
+ Tile tt = item[j]->tile();
+ int f=-1;
+ for (int i=0; i<sn && f<0; i++) {
+ if (s[i] && *s[i] == tt ) {
+ s[i]=0;
+ f=i;
+ }
+ }
+ if ( f >= 0 ) {
+ item[j]->move(f-999,0);
+ } else {
+ could = FALSE;
+ }
+ }
+ layoutTiles();
+ return could;
+}
+
+void Rack::addTile(const Tile& t)
+{
+ TileItem *i = new TileItem(t,TRUE,canvas());
+ i->show();
+ item[n++] = i;
+ layoutTiles();
+}
+
+void Rack::remove(Tile t)
+{
+ for (int i=0; i<n ;i++)
+ if ( item[i]->tile() == t ) {
+ remove(i);
+ return;
+ }
+}
+
+void Rack::remove(int i)
+{
+ delete item[i];
+ n--;
+ for (;i<n;i++)
+ item[i]=item[i+1];
+ layoutTiles();
+}
+
+void Rack::resizeEvent(QResizeEvent* e)
+{
+ canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2);
+ QCanvasView::resizeEvent(e);
+}
+
+void Rack::contentsMousePressEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ QCanvasItemList list = canvas()->collisions(e->pos());
+ if (list.count()) {
+ dragging = list.first();
+ dragstart = e->pos()-QPoint(int(dragging->x()),int(dragging->y()));
+ } else {
+ dragging = 0;
+ }
+}
+
+void Rack::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ //int w = TileItem::bigWidth()+2;
+ if ( dragging ) {
+ dragging_adj = TileItem::bigWidth()/2;
+ if ( dragging->x() > e->x()-dragstart.x() )
+ dragging_adj = -dragging_adj;
+ dragging->move(e->x()-dragstart.x(),0);
+ layoutTiles();
+ }
+}
+
+void Rack::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ if ( dragging ) {
+ dragging=0;
+ layoutTiles();
+ }
+}
+
+Tile::Tile(const QString& key)
+{
+ int a=key.find('@');
+ txt = key.left(a);
+ val = key.mid(a+1).toInt();
+ blank = txt.isEmpty();
+}
+
+QString Tile::key() const
+{
+ return txt+"@"+QString::number(val);
+}
+
+Bag::Bag()
+{
+ tiles.setAutoDelete(TRUE);
+}
+
+void Bag::writeConfig(Config& cfg)
+{
+ QStringList t;
+ for (QListIterator<Tile> it(tiles); it; ++it)
+ t.append((*it)->key());
+ cfg.writeEntry("Tiles",t,';');
+}
+
+void Bag::readConfig(Config& cfg)
+{
+ tiles.clear();
+ QStringList t = cfg.readListEntry("Tiles",';');
+ for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it )
+ add(Tile(*it));
+}
+
+void Bag::add(const Tile& t)
+{
+ tiles.append(new Tile(t));
+}
+
+Tile Bag::takeRandom()
+{
+ Tile* rp = tiles.take(random()%tiles.count());
+ Tile r=*rp;
+ return r;
+}
+
+ScoreInfo::ScoreInfo( QWidget* parent, const char* name, WFlags fl ) :
+ QLabel("<P>",parent,name,fl)
+{
+ score=0;
+ msgtimer = new QTimer(this);
+ connect(msgtimer, SIGNAL(timeout()), this, SLOT(showScores()));
+ setBackgroundMode( PaletteButton );
+}
+
+ScoreInfo::~ScoreInfo()
+{
+ if ( score ) delete [] score;
+}
+
+void ScoreInfo::writeConfig(Config& cfg)
+{
+ QStringList l;
+ for (int i=0; i<(int)names.count(); i++)
+ l.append(QString::number(score[i]));
+ cfg.writeEntry("Scores",l,';');
+}
+
+void ScoreInfo::readConfig(Config& cfg)
+{
+ QStringList l = cfg.readListEntry("Scores",';');
+ int i=0;
+ for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it )
+ score[i++]=(*it).toInt();
+ showScores();
+}
+
+
+QSize ScoreInfo::sizeHint() const
+{
+ return QSize(QLabel::sizeHint().width(),fontMetrics().height());
+}
+
+void ScoreInfo::init(const QStringList& namelist)
+{
+ names = namelist;
+ if ( score ) delete [] score;
+ score = new int[names.count()];
+ memset(score,0,sizeof(int)*names.count());
+ boldone = -1;
+ showScores();
+}
+
+void ScoreInfo::addScore(int player, int change)
+{
+ score[player] += change;
+ showScores();
+}
+
+void ScoreInfo::setBoldOne(int b)
+{
+ boldone=b;
+ showScores();
+}
+
+void ScoreInfo::showScores()
+{
+ QString r="<p>";
+ int i=0;
+ //int spl=(names.count()+1)/2; // 2 lines
+ for (QStringList::ConstIterator it=names.begin(); it!=names.end(); ) {
+ if ( i==boldone ) r += "<b>";
+ QString n = *it;
+ n.replace(QRegExp(":.*"),"");
+ r += n;
+ r += ":";
+ r += QString::number(score[i]);
+ if ( i==boldone ) r += "</b>";
+
+ ++i;
+ ++it;
+ if ( it != names.end() )
+ r += " ";
+ }
+ setText(r);
+}
+
+void ScoreInfo::showTemporaryScore(int amount)
+{
+ if ( amount < 0 )
+ setText(tr("<P>Invalid move"));
+ else
+ setText(tr("<P>Score: ")+QString::number(amount));
+ msgtimer->start(3000,TRUE);
+}
+
diff --git a/noncore/games/wordgame/wordgame.h b/noncore/games/wordgame/wordgame.h
new file mode 100644
index 0000000..0ffa56a
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.h
@@ -0,0 +1,376 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef WORDGAME_H
+#define WORDGAME_H
+
+#include "newgamebase.h"
+#include "rulesbase.h"
+
+#include <qpe/qdawg.h>
+#include <qpe/applnk.h>
+
+#include <qmainwindow.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+
+class QVBox;
+class QLabel;
+class QWidgetStack;
+class QToolButton;
+class Config;
+
+class Tile {
+public:
+ Tile() {}
+
+ Tile(const Tile& t)
+ {
+ txt = t.txt;
+ val = t.val;
+ blank = t.blank;
+ }
+
+ Tile(QString text, int value)
+ {
+ txt = text;
+ val = value;
+ blank = txt.isEmpty();
+ }
+
+ Tile(const QString& key);
+
+ int value() const { return val; }
+ bool isBlank() const { return blank; }
+ QString text() const { return txt; }
+ void setText(const QString& t)
+ {
+ txt = t;
+ }
+
+ int operator==(const Tile& o) const
+ { return o.txt == txt && o.val == val && o.blank == blank; }
+ int operator!=(const Tile& o) const
+ { return !operator==(o); }
+ Tile& operator=(const Tile& o)
+ { txt=o.txt; val=o.val; blank=o.blank; return *this; }
+
+ QString key() const;
+
+private:
+ QString txt;
+ int val;
+ bool blank;
+};
+
+class Bag {
+public:
+ Bag();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ void add(const Tile&);
+ bool isEmpty() const { return tiles.isEmpty(); }
+ Tile takeRandom();
+private:
+ QList<Tile> tiles;
+};
+
+class TileItem : public QCanvasRectangle {
+public:
+ TileItem(const Tile& tile, bool b, QCanvas* c) :
+ QCanvasRectangle(0,0,
+ b?bigWidth():smallWidth(),
+ b?bigHeight():smallHeight(),c),
+ t(tile), big(b), s(Firm)
+ {
+ }
+
+ static int smallWidth();
+ static int smallHeight();
+ static int bigWidth();
+ static int bigHeight();
+
+ enum State { Firm, Floating };
+ void setState( State state );
+ State state() const { return s; }
+ const Tile& tile() const { return t; }
+ void setTile(const Tile&);
+ void setBig(bool);
+
+protected:
+ void drawShape(QPainter&);
+
+private:
+ Tile t;
+ bool big;
+ State s;
+};
+
+class Rack : public QCanvasView {
+public:
+ Rack(int ntiles, QWidget* parent);
+ ~Rack();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ bool isFull() const { return count()==max(); }
+ int max() const { return item.count(); }
+ int count() const { return n; }
+ void addTile(const Tile& t);
+ Tile tile(int i) const { return item[i]->tile(); }
+ const Tile* tileRef(int i) const { return &item[i]->tile(); }
+ void remove(int i);
+ void remove(Tile);
+ bool arrangeTiles(const Tile** s, int sn);
+ void setBlanks(const Tile*);
+
+ void setPlayerName(const QString& name) { nm = name; }
+ QString playerName() const { return nm; }
+ void setComputerization(int level) { cpu=level; }
+ bool computerized() const { return cpu>0; }
+
+protected:
+ void resizeEvent(QResizeEvent*e);
+ void contentsMousePressEvent(QMouseEvent*);
+ void contentsMouseMoveEvent(QMouseEvent*);
+ void contentsMouseReleaseEvent(QMouseEvent*);
+
+private:
+ void clear();
+ void layoutTiles();
+ int n;
+ QArray<TileItem*> item;
+ int dragging_adj;
+ QPoint dragstart;
+ QCanvasItem* dragging;
+ QString nm;
+ int cpu;
+};
+
+class Board : public QCanvasView {
+ Q_OBJECT
+public:
+ Board(QPixmap bgshapes, int w, int h, QWidget* parent);
+ ~Board();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ int xTiles() const { return canvas()->tilesHorizontally(); }
+ int yTiles() const { return canvas()->tilesVertically(); }
+
+ bool contains(const QPoint& p) const
+ { return p.x() >= 0 && p.y() >= 0
+ && p.x() < canvas()->tilesHorizontally()
+ && p.y() < canvas()->tilesVertically(); }
+ const Tile* tile(const QPoint& p) const
+ { TileItem* it=item(p); return it ? &it->tile() : 0; }
+
+ void setRules(const QString& shapes, const int* effects);
+
+ void clear();
+ void unsetTile(const QPoint& p);
+ void setTile(const QPoint& p, const Tile& t);
+
+ void setTileState(const QPoint& p, TileItem::State s)
+ {
+ TileItem* it=item(p);
+ if (it) it->setState(s);
+ }
+
+ void setCurrentRack(Rack*);
+ void resetRack();
+ void finalizeTurn();
+ void showTurn();
+ void scoreTurn(const QPoint& at, int n, const QPoint& d);
+ bool checkTurn();
+ int score(QPoint at, const Tile** tiles, int n,
+ const Tile* blankvalue,
+ const QPoint& d, bool ignoredict, QStringList* words) const;
+ int bonussedValue(const QPoint& at, int base, int& all_mult) const;
+ bool isStart(const QPoint& at) const;
+
+ int turnScore() const { return turn_score; }
+
+signals:
+ void temporaryScore(int);
+
+protected:
+ void contentsMousePressEvent(QMouseEvent*);
+ void contentsMouseMoveEvent(QMouseEvent*);
+ void contentsMouseReleaseEvent(QMouseEvent*);
+
+private:
+ int idx(const QPoint& p) const
+ { return p.x()+p.y()*canvas()->tilesHorizontally(); }
+ TileItem*& item(const QPoint& p) const
+ { return grid[idx(p)]; }
+ TileItem **grid;
+ QString rule_shape;
+ const int* rule_effect;
+ int rack_tiles_bonus;
+ Rack* current_rack;
+ QPoint boardPos(const QPoint&) const;
+ QPoint dragstart;
+ QPoint shown_at;
+ int shown_n;
+ QPoint shown_step;
+ void unshowTurn();
+ int turn_score;
+};
+
+class ComputerPlayer
+{
+ Board* board;
+ Rack* rack;
+
+ bool across;
+ int dict;
+ QPoint current;
+
+ const Tile** best;
+ int best_n;
+ Tile* best_blankvalues;
+ int best_blused;
+ int best_score;
+ QPoint best_dir;
+ QPoint best_start;
+
+public:
+ ComputerPlayer(Board* b, Rack* r);
+ ~ComputerPlayer();
+
+ bool step();
+
+private:
+ void findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar *nletter, const Tile** tiles, int n, Tile* blankvalues, int blused);
+ void noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused);
+};
+
+class ScoreInfo : public QLabel {
+ Q_OBJECT
+public:
+ ScoreInfo( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~ScoreInfo();
+
+ void init(const QStringList&);
+ void addScore(int player, int change);
+ int playerScore(int player) const { return score[player]; }
+ void setShowWinner(bool);
+ void setBoldOne(int);
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+protected:
+ QSize sizeHint() const;
+
+public slots:
+ void showTemporaryScore(int amount);
+
+private slots:
+ void showScores();
+
+private:
+ QStringList names;
+ int *score;
+ QTimer* msgtimer;
+ bool showwinner;
+ int boldone;
+};
+
+class NewGame;
+
+class WordGame : public QMainWindow {
+ Q_OBJECT
+public:
+ WordGame( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~WordGame();
+
+private slots:
+ void endTurn();
+ void resetTurn();
+ void passTurn();
+ void think();
+ void endGame();
+ void startGame();
+
+private:
+ void writeConfig();
+ void readConfig();
+
+ void startGame(const QStringList& pnames);
+ bool mayEndGame();
+ void openGameSelector(const QStringList& initnames);
+ bool loadRules(const QString& filename);
+ void addPlayer(const QString& name);
+ void addPlayer(const QString& name, int cpu);
+ void nextPlayer();
+ bool refillRack(int i);
+ void readyRack(int i);
+ Rack* rack(int i) const;
+
+ QWidgetStack *racks;
+ QToolBar* toolbar;
+ QVBox *vbox;
+ Board *board;
+ Bag *bag;
+ ScoreInfo *scoreinfo;
+ QToolButton *done;
+ QToolButton *reset;
+ QTimer* aiheart;
+ ComputerPlayer *cpu;
+ int player;
+ int nplayers;
+ QStringList namelist;
+ bool gameover;
+ QString rules;
+ NewGame* newgame;
+};
+
+class NewGame : public NewGameBase {
+ Q_OBJECT
+public:
+ NewGame(QWidget* parent);
+ QStringList ruleslist;
+
+public slots:
+ void updateRuleSets();
+};
+
+class Rules : public RulesBase {
+ Q_OBJECT
+
+public:
+ Rules(QWidget* parent);
+
+signals:
+ void rulesChanged();
+
+public slots:
+ void editRules();
+
+private:
+ void deleteRuleSet();
+};
+
+#endif // WORDGAME_H
diff --git a/noncore/games/wordgame/wordgame.pro b/noncore/games/wordgame/wordgame.pro
new file mode 100644
index 0000000..7feacf9
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = wordgame.h
+SOURCES = main.cpp \
+ wordgame.cpp
+INTERFACES = newgamebase.ui rulesbase.ui
+TARGET = wordgame
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/wordgame.ts
diff --git a/noncore/multimedia/showimg/.cvsignore b/noncore/multimedia/showimg/.cvsignore
new file mode 100644
index 0000000..f0a4beb
--- a/dev/null
+++ b/noncore/multimedia/showimg/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+moc_*
diff --git a/noncore/multimedia/showimg/Makefile.in b/noncore/multimedia/showimg/Makefile.in
new file mode 100644
index 0000000..9255b2d
--- a/dev/null
+++ b/noncore/multimedia/showimg/Makefile.in
@@ -0,0 +1,119 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = showimg
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = showimg.h
+SOURCES = main.cpp \
+ showimg.cpp
+OBJECTS = main.o \
+ showimg.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_showimg.cpp
+OBJMOC = moc_showimg.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake showimg.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=showimg
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ showimg.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+showimg.o: showimg.cpp \
+ showimg.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/fileselector.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+moc_showimg.o: moc_showimg.cpp \
+ showimg.h
+
+moc_showimg.cpp: showimg.h
+ $(MOC) showimg.h -o moc_showimg.cpp
+
+
diff --git a/noncore/multimedia/showimg/README b/noncore/multimedia/showimg/README
new file mode 100644
index 0000000..a6c9ca9
--- a/dev/null
+++ b/noncore/multimedia/showimg/README
@@ -0,0 +1,14 @@
+This example demonstrates how to read in and display images, and the
+conversion facilities available. The CuteWidget can read a file into
+a pixmap and resizes the displayed pixmap when the widget is resized.
+
+Note that the function CuteWidget::paintEvent uses the drawPixmap function
+of QPainter to display the pixmap, the bitBlt function can also be used to
+display pixmaps.
+
+If you have installed the Qt imageio extension (see extensions/imageio
+in your Qt directory), you can build using that extension.
+
+Some of the conversion options will have no effect, depending on the
+display hardware used. Generally, these are disabled.
+
diff --git a/noncore/multimedia/showimg/main.cpp b/noncore/multimedia/showimg/main.cpp
new file mode 100644
index 0000000..c28cc85
--- a/dev/null
+++ b/noncore/multimedia/showimg/main.cpp
@@ -0,0 +1,33 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "showimg.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ ImageViewer w(0, "new window", Qt::WResizeNoErase );
+ a.showMainDocumentWidget(&w);
+
+ return a.exec();
+}
diff --git a/noncore/multimedia/showimg/qpe-showimg.control b/noncore/multimedia/showimg/qpe-showimg.control
new file mode 100644
index 0000000..8189048
--- a/dev/null
+++ b/noncore/multimedia/showimg/qpe-showimg.control
@@ -0,0 +1,10 @@
+Files: bin/showimg apps/Applications/showimg.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Image Viewer
+ The image viewer for the Qtopia environment. Supports
+ Whichever formats are compiled into Qt/Embedded (eg. PNG).
diff --git a/noncore/multimedia/showimg/showimg.cpp b/noncore/multimedia/showimg/showimg.cpp
new file mode 100644
index 0000000..c56994d
--- a/dev/null
+++ b/noncore/multimedia/showimg/showimg.cpp
@@ -0,0 +1,557 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+//
+// Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com>
+//
+
+#include "showimg.h"
+
+#include <qpe/resource.h>
+#include <qpe/fileselector.h>
+#include <qpe/applnk.h>
+
+#include <qpe/qpemenubar.h>
+#include <qwidgetstack.h>
+#include <qpe/qpetoolbar.h>
+#include <qaction.h>
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qkeycode.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qtimer.h>
+
+
+ImagePane::ImagePane( QWidget *parent=0 ) : QWidget( parent )
+{
+ vb = new QVBoxLayout( this );
+
+ image = new ImageWidget( this );
+ connect(image, SIGNAL( clicked() ), this, SLOT( imageClicked() ));
+
+ vb->addWidget( image );
+
+ status = new QLabel( this );
+ status->setFixedHeight( fontMetrics().height() + 4 );
+ vb->addWidget( status );
+}
+
+void ImagePane::setPixmap( const QPixmap &pm )
+{
+ image->setPixmap( pm );
+ image->repaint( false );
+}
+
+void ImagePane::imageClicked()
+{
+ emit clicked();
+}
+
+void ImagePane::showStatus()
+{
+ delete vb;
+ vb = new QVBoxLayout( this );
+ vb->addWidget( image );
+ status->show();
+ vb->addWidget( status );
+}
+
+
+void ImagePane::hideStatus()
+{
+ delete vb;
+ vb = new QVBoxLayout( this );
+ vb->addWidget( image );
+ status->hide();
+}
+
+//===========================================================================
+/*
+ Draws the portion of the scaled pixmap that needs to be updated
+*/
+
+void ImageWidget::paintEvent( QPaintEvent *e )
+{
+ QPainter painter(this);
+
+ painter.setClipRect(e->rect());
+ painter.setBrush( black );
+ painter.drawRect( 0, 0, width(), height() );
+
+ if ( pixmap.size() != QSize( 0, 0 ) ) { // is an image loaded?
+ painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap);
+ }
+}
+
+void ImageWidget::mouseReleaseEvent(QMouseEvent *)
+{
+ emit clicked();
+}
+
+
+//===========================================================================
+
+ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags )
+ : QMainWindow( parent, name, wFlags ), filename( 0 ),
+ pickx( -1 ), picky( -1 ), clickx( -1 ), clicky( -1 ), bFromDocView( FALSE )
+{
+ setCaption( tr("Image Viewer") );
+ setIcon( Resource::loadPixmap( "ImageViewer" ) );
+
+ isFullScreen = FALSE;
+
+ setToolBarsMovable( FALSE );
+
+ toolBar = new QPEToolBar( this );
+ toolBar->setHorizontalStretchable( TRUE );
+
+ menubar = new QPEMenuBar( toolBar );
+
+ QStrList fmt = QImage::outputFormats();
+
+ QPopupMenu *edit = new QPopupMenu( menubar );
+ QPopupMenu *view = new QPopupMenu( menubar );
+
+ menubar->insertItem( "Edit", edit );
+ menubar->insertItem( "View", view );
+
+ edit->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0);
+ edit->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0);
+
+ stack = new QWidgetStack( this );
+ stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+ setCentralWidget( stack );
+
+ imagePanel = new ImagePane( stack );
+ connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView()));
+
+ fileSelector = new FileSelector("image/*", stack, "fs");
+ fileSelector->setNewVisible(FALSE);
+ fileSelector->setCloseVisible(FALSE);
+ connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) );
+ connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
+
+ toolBar = new QPEToolBar( this );
+
+ QAction *a;
+
+ a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( open() ) );
+ a->addTo( toolBar );
+
+ a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) );
+ a->addTo( toolBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0);
+ connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) );
+ a->addTo( toolBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) );
+ a->addTo( toolBar );
+ a->addTo( view);
+
+ stack->raiseWidget( fileSelector );
+
+ setMouseTracking( TRUE );
+}
+
+ImageViewer::~ImageViewer()
+{
+ delete imagePanel; // in case it is fullscreen
+}
+
+void ImageViewer::setDocument(const QString& fileref)
+{
+ delayLoad = fileref;
+ stack->raiseWidget(imagePanel);
+ QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) );
+}
+
+void ImageViewer::doDelayedLoad()
+{
+ show(delayLoad);
+}
+
+void ImageViewer::show()
+{
+ normalView();
+ QMainWindow::show();
+}
+
+void ImageViewer::show(const QString& fileref)
+{
+ bFromDocView = TRUE;
+ closeFileSelector();
+ DocLnk link(fileref);
+ if ( link.isValid() ) {
+ openFile(link);
+ } else {
+ filename = fileref;
+ updateCaption( fileref );
+ loadImage( fileref );
+ }
+}
+
+void ImageViewer::openFile( const DocLnk &file )
+{
+ closeFileSelector();
+ DocLnk link(file);
+ updateCaption( link.name() );
+ loadImage( link.file() );
+}
+
+void ImageViewer::open()
+{
+ stack->raiseWidget(fileSelector);
+}
+
+void ImageViewer::closeFileSelector()
+{
+ stack->raiseWidget(imagePanel);
+}
+
+void ImageViewer::updateCaption( QString name )
+{
+ int sep = name.findRev( '/' );
+ if ( sep >= 0 )
+ name = name.mid( sep+1 );
+ setCaption( name + tr(" - Image Viewer") );
+}
+
+/*
+ This function loads an image from a file.
+*/
+
+void ImageViewer::loadImage( const char *fileName )
+{
+ filename = fileName;
+ if ( filename ) {
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ imagePanel->statusLabel()->setText( tr("Loading image...") );
+ qApp->processEvents();
+ bool ok = image.load(filename, 0);
+ pickx = -1;
+ clickx = -1;
+ if ( ok )
+ ok = reconvertImage();
+ if ( !ok ) {
+ pm.resize(0,0); // couldn't load image
+ update();
+ }
+ QApplication::restoreOverrideCursor(); // restore original cursor
+ }
+ updateStatus();
+ imagePanel->setPixmap( pmScaled );
+ stack->raiseWidget(imagePanel);
+}
+
+bool ImageViewer::loadSelected()
+{
+ bool ok = false;
+ if ( stack->visibleWidget() == fileSelector ) {
+ const DocLnk *link = fileSelector->selected();
+ if ( link ) {
+ if ( link->file() != filename ) {
+ updateCaption( link->name() );
+ filename = link->file();
+ imagePanel->statusLabel()->setText( tr("Loading image...") );
+ qApp->processEvents();
+ ok = image.load(filename, 0);
+ if ( ok )
+ ok = reconvertImage();
+ if ( !ok )
+ pm.resize(0,0);
+ }
+ }
+ }
+ if ( !image.isNull() ) {
+ ok = true;
+ closeFileSelector();
+ }
+
+ return ok;
+}
+
+bool ImageViewer::reconvertImage()
+{
+ bool success = FALSE;
+
+ if ( image.isNull() ) return FALSE;
+
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ if ( pm.convertFromImage(image /*, conversion_flags */ ) )
+ {
+ pmScaled = QPixmap();
+ scale();
+ success = TRUE; // load successful
+ } else {
+ pm.resize(0,0); // couldn't load image
+ }
+ QApplication::restoreOverrideCursor(); // restore original cursor
+
+ return success; // TRUE if loaded OK
+}
+
+
+int ImageViewer::calcHeight()
+{
+ if ( !isFullScreen)
+ return height() - menubar->heightForWidth( width() )
+ - imagePanel->statusLabel()->height();
+ else
+ return qApp->desktop()->height();
+}
+/*
+ This functions scales the pixmap in the member variable "pm" to fit the
+ widget size and puts the resulting pixmap in the member variable "pmScaled".
+*/
+
+void ImageViewer::scale()
+{
+ int h = calcHeight();
+ if ( image.isNull() ) return;
+
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ if ( width() == pm.width() && h == pm.height() ) { // no need to scale if widget
+ pmScaled = pm; // size equals pixmap size
+ } else {
+ double hs = (double)h / (double)image.height();
+ double ws = (double)width() / (double)image.width();
+ double scaleFactor = (hs > ws) ? ws : hs;
+ int smoothW = (int)(scaleFactor * image.width());
+ int smoothH = (int)(scaleFactor * image.height());
+
+ pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) /*, conversion_flags */ );
+ }
+ QApplication::restoreOverrideCursor(); // restore original cursor
+}
+
+/*
+ The resize event handler, if a valid pixmap was loaded it will call
+ scale() to fit the pixmap to the new widget size.
+*/
+
+void ImageViewer::resizeEvent( QResizeEvent * )
+{
+ imagePanel->statusLabel()->setGeometry(0, height() - imagePanel->statusLabel()->height(),
+ width(), imagePanel->statusLabel()->height());
+
+ if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image
+ return;
+
+ int h = calcHeight();
+
+ if ( width() != pmScaled.width() || h != pmScaled.height())
+ { // if new size,
+ scale(); // scale pmScaled to window
+ updateStatus();
+ }
+ if ( image.hasAlphaBuffer() )
+ erase();
+}
+
+void ImageViewer::convertEvent( QMouseEvent* e, int& x, int& y)
+{
+ if ( pm.size() != QSize( 0, 0 ) ) {
+ int h = height() - menubar->heightForWidth( width() ) - imagePanel->statusLabel()->height();
+ int nx = e->x() * image.width() / width();
+ int ny = (e->y()-menubar->heightForWidth( width() )) * image.height() / h;
+ if (nx != x || ny != y ) {
+ x = nx;
+ y = ny;
+ updateStatus();
+ }
+ }
+}
+
+void ImageViewer::mousePressEvent( QMouseEvent *e )
+{
+ convertEvent(e, clickx, clicky);
+}
+
+void ImageViewer::mouseMoveEvent( QMouseEvent *e )
+{
+ convertEvent( e, pickx, picky );
+}
+
+void ImageViewer::hFlip()
+{
+ if ( loadSelected() )
+ setImage(image.mirror(TRUE,FALSE));
+}
+
+void ImageViewer::vFlip()
+{
+ if ( loadSelected() )
+ setImage(image.mirror(FALSE,TRUE));
+}
+
+void ImageViewer::rot180()
+{
+ if ( loadSelected() )
+ setImage(image.mirror(TRUE,TRUE));
+}
+
+void ImageViewer::rot90()
+{
+ if ( loadSelected() ) {
+ QImage oldimage, newimage;
+ uchar *oldbits, *newbits;
+ int i, j, p;
+ int w, h;
+
+ oldimage = image.convertDepth(32);
+ w = oldimage.height();
+ h = oldimage.width();
+ newimage = QImage( w, h, 32);
+
+ oldbits = oldimage.bits();
+ newbits = newimage.bits();
+
+ for (i=0; i < w ; i++)
+ for (j=0; j < h; j++)
+ for (p = 0 ; p < 4 ; p++)
+ newbits[(j * w + i) * 4 + p] = oldbits[ ((i + 1) * h - j ) * 4 + p];
+
+ setImage(newimage);
+ }
+}
+
+
+
+void ImageViewer::normalView()
+{
+ if ( !imagePanel->parentWidget() ) {
+ isFullScreen = FALSE;
+ stack->addWidget( imagePanel, 1 );
+// imagePanel->reparent(stack,0,QPoint(0,0),FALSE);
+// imagePanel->resize(width(), calcHeight());
+ scale();
+ updateStatus();
+ imagePanel->setPixmap( pmScaled );
+ imagePanel->showStatus();
+ // imagePanel->show();
+ stack->raiseWidget( imagePanel );
+ }
+}
+
+void ImageViewer::fullScreen()
+{
+ // Full-screen and rotation options
+ // contributed by Robert Wittams <robert@wittams.com>
+
+ if ( imagePanel->parentWidget() && loadSelected() ) {
+ isFullScreen = TRUE;
+ imagePanel->reparent(0,QPoint(0,0));
+ imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height());
+
+ scale();
+ updateStatus();
+ imagePanel->hideStatus();
+ imagePanel->setPixmap( pmScaled );
+ imagePanel->showFullScreen();
+ }
+}
+
+void ImageViewer::setImage(const QImage& newimage)
+{
+ image = newimage;
+ pickx = -1;
+ clickx = -1;
+ reconvertImage();
+ imagePanel->setPixmap( pmScaled );
+ updateStatus();
+}
+
+void ImageViewer::updateStatus()
+{
+ if ( pm.size() == QSize( 0, 0 ) ) {
+ if ( filename )
+ imagePanel->statusLabel()->setText( tr("Could not load image") );
+ else
+ imagePanel->statusLabel()->setText( tr("No image - select Open from File menu.") );
+ } else {
+ QString message("%1x%2");
+ message = message.arg(image.width()).arg(image.height());
+ if ( pm.size() != pmScaled.size() )
+ message += QString(" [%1x%2]").arg(pmScaled.width()).arg(pmScaled.height());
+ if (image.valid(pickx,picky)) {
+ QString moremsg;
+ moremsg.sprintf("(%d,%d)=#%0*x ",
+ pickx, picky,
+ image.hasAlphaBuffer() ? 8 : 6,
+ image.pixel(pickx,picky));
+ message += moremsg;
+ }
+ if ( image.numColors() > 0 ) {
+ if (image.valid(pickx,picky)) {
+ message += tr(", %1/%2 colors")
+ .arg(image.pixelIndex(pickx,picky))
+ .arg(image.numColors());
+ } else {
+ message += tr(", %1 colors").arg(image.numColors());
+ }
+ } else if ( image.depth() >= 16 ) {
+ message += tr(" True color");
+ }
+ if ( image.hasAlphaBuffer() ) {
+ if ( image.depth() == 8 ) {
+ int i;
+ bool alpha[256];
+ int nalpha=0;
+
+ for (i=0; i<256; i++)
+ alpha[i] = FALSE;
+
+ for (i=0; i<image.numColors(); i++) {
+ int alevel = image.color(i) >> 24;
+ if (!alpha[alevel]) {
+ alpha[alevel] = TRUE;
+ nalpha++;
+ }
+ }
+ message += tr(", %1 alpha levels").arg(nalpha);
+ } else {
+ // Too many pixels to bother counting.
+ message += tr(", 8-bit alpha channel");
+ }
+ }
+ imagePanel->statusLabel()->setText(message);
+ }
+}
+
+void ImageViewer::closeEvent( QCloseEvent *e )
+{
+ if ( stack->visibleWidget() == imagePanel && !bFromDocView ) {
+ e->ignore();
+ open();
+ } else {
+ bFromDocView = FALSE;
+ e->accept();
+ }
+}
diff --git a/noncore/multimedia/showimg/showimg.h b/noncore/multimedia/showimg/showimg.h
new file mode 100644
index 0000000..71003b1
--- a/dev/null
+++ b/noncore/multimedia/showimg/showimg.h
@@ -0,0 +1,143 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef SHOWIMG_H
+#define SHOWIMG_H
+
+#include <qwidget.h>
+#include <qmainwindow.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+
+class QMenuBar;
+class QPopupMenu;
+class QWidgetStack;
+class FileSelector;
+class DocLnk;
+
+
+class ImageWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ ImageWidget( QWidget *parent=0 ) : QWidget( parent ) { }
+ ~ImageWidget() { }
+
+ void setPixmap( const QPixmap &pm ) { pixmap = pm; }
+
+signals:
+ void clicked();
+
+protected:
+ void paintEvent( QPaintEvent * );
+ void mouseReleaseEvent(QMouseEvent* event);
+
+private:
+ QPixmap pixmap;
+};
+
+
+class ImagePane : public QWidget
+{
+ Q_OBJECT
+public:
+ ImagePane( QWidget *parent=0 );
+ ~ImagePane() { }
+
+ void showStatus();
+ void hideStatus();
+ QLabel *statusLabel() { return status; }
+ void setPixmap( const QPixmap &pm );
+
+signals:
+ void clicked();
+
+private:
+ ImageWidget *image;
+ QLabel *status;
+ QVBoxLayout *vb;
+
+private slots:
+ void imageClicked();
+};
+
+
+class ImageViewer : public QMainWindow
+{
+ Q_OBJECT
+public:
+ ImageViewer( QWidget *parent=0, const char *name=0, int wFlags=0 );
+ ~ImageViewer();
+
+ void loadImage( const char *fileName );
+ void show(const QString& fileref);
+ void show();
+
+protected:
+ void resizeEvent( QResizeEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void closeEvent( QCloseEvent * );
+
+private:
+ void updateCaption( QString name );
+ bool loadSelected();
+ void scale();
+ void convertEvent( QMouseEvent* e, int& x, int& y );
+ bool reconvertImage();
+ int calcHeight();
+ void setImage(const QImage& newimage);
+ void updateStatus();
+
+private slots:
+ void setDocument(const QString& fileref);
+ void doDelayedLoad();
+ void openFile( const DocLnk &file );
+ void open();
+ void closeFileSelector();
+ void hFlip();
+ void vFlip();
+ void rot180();
+ void rot90();
+ void normalView();
+ void fullScreen();
+
+private:
+ QString filename;
+ QString delayLoad;
+ QImage image; // the loaded image
+ QPixmap pm; // the converted pixmap
+ QPixmap pmScaled; // the scaled pixmap
+ QMenuBar *menubar;
+ ImagePane *imagePanel;
+ QToolBar *toolBar;
+ QWidgetStack *stack;
+ FileSelector *fileSelector;
+ int pickx, picky;
+ int clickx, clicky;
+ bool isFullScreen;
+ bool bFromDocView; // a flag to indicate whether or not we were
+ // launched from the document view...
+};
+
+
+#endif // SHOWIMG_H
diff --git a/noncore/multimedia/showimg/showimg.pro b/noncore/multimedia/showimg/showimg.pro
new file mode 100644
index 0000000..a372f62
--- a/dev/null
+++ b/noncore/multimedia/showimg/showimg.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = showimg.h
+
+SOURCES = main.cpp \
+ showimg.cpp
+
+TARGET = showimg
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+REQUIRES = showimg
+
+TRANSLATIONS = ../i18n/de/showimg.ts
diff --git a/noncore/settings/.cvsignore b/noncore/settings/.cvsignore
new file mode 100644
index 0000000..e3d8c4b
--- a/dev/null
+++ b/noncore/settings/.cvsignore
@@ -0,0 +1,13 @@
+moc_*
+*.moc
+Makefile
+appearancesettingsbase.h
+soundsettingsbase.h
+lightsettingsbase.h
+languagesettingsbase.cpp
+rotationsettingsbase.cpp
+appearancesettingsbase.cpp
+lightsettingsbase.cpp
+languagesettingsbase.h
+rotationsettingsbase.h
+soundsettingsbase.cpp
diff --git a/noncore/settings/language/.cvsignore b/noncore/settings/language/.cvsignore
new file mode 100644
index 0000000..30ff791
--- a/dev/null
+++ b/noncore/settings/language/.cvsignore
@@ -0,0 +1,4 @@
+moc_*
+Makefile
+languagesettingsbase.h
+languagesettingsbase.cpp
diff --git a/noncore/settings/language/Makefile.in b/noncore/settings/language/Makefile.in
new file mode 100644
index 0000000..2babf6e
--- a/dev/null
+++ b/noncore/settings/language/Makefile.in
@@ -0,0 +1,135 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = language
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = settings.h
+SOURCES = language.cpp \
+ main.cpp
+OBJECTS = language.o \
+ main.o \
+ languagesettingsbase.o
+INTERFACES = languagesettingsbase.ui
+UICDECLS = languagesettingsbase.h
+UICIMPLS = languagesettingsbase.cpp
+SRCMOC = moc_settings.cpp \
+ moc_languagesettingsbase.cpp
+OBJMOC = moc_settings.o \
+ moc_languagesettingsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake language.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+language.o: language.cpp \
+ settings.h \
+ languagesettingsbase.h
+
+main.o: main.cpp \
+ settings.h \
+ languagesettingsbase.h
+
+languagesettingsbase.h: languagesettingsbase.ui
+ $(UIC) languagesettingsbase.ui -o $(INTERFACE_DECL_PATH)/languagesettingsbase.h
+
+languagesettingsbase.cpp: languagesettingsbase.ui
+ $(UIC) languagesettingsbase.ui -i languagesettingsbase.h -o languagesettingsbase.cpp
+
+languagesettingsbase.o: languagesettingsbase.cpp \
+ languagesettingsbase.h \
+ languagesettingsbase.ui
+
+moc_settings.o: moc_settings.cpp \
+ settings.h \
+ languagesettingsbase.h
+
+moc_languagesettingsbase.o: moc_languagesettingsbase.cpp \
+ languagesettingsbase.h
+
+moc_settings.cpp: settings.h
+ $(MOC) settings.h -o moc_settings.cpp
+
+moc_languagesettingsbase.cpp: languagesettingsbase.h
+ $(MOC) languagesettingsbase.h -o moc_languagesettingsbase.cpp
+
+
diff --git a/noncore/settings/language/language.cpp b/noncore/settings/language/language.cpp
new file mode 100644
index 0000000..397d372
--- a/dev/null
+++ b/noncore/settings/language/language.cpp
@@ -0,0 +1,150 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "settings.h"
+
+#include <qpe/global.h>
+#include <qpe/fontmanager.h>
+#include <qpe/config.h>
+#include <qpe/applnk.h>
+#include <qpe/qpedialog.h>
+#include <qpe/qpeapplication.h>
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+#include <qpe/qcopenvelope_qws.h>
+#endif
+
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qtabwidget.h>
+#include <qslider.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdatastream.h>
+#include <qmessagebox.h>
+#include <qcombobox.h>
+#include <qspinbox.h>
+#include <qlistbox.h>
+#include <qdir.h>
+#if QT_VERSION >= 300
+#include <qstylefactory.h>
+#endif
+
+#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+#include <unistd.h>
+#include <linux/fb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#endif
+#include <stdlib.h>
+
+
+LanguageSettings::LanguageSettings( QWidget* parent, const char* name, WFlags fl )
+ : LanguageSettingsBase( parent, name, TRUE, fl )
+{
+ if ( FontManager::hasUnicodeFont() )
+ languages->setFont(FontManager::unicodeFont(FontManager::Proportional));
+
+ QString tfn = QPEApplication::qpeDir()+"/i18n/";
+ QDir langDir = tfn;
+ QStringList list = langDir.entryList("*", QDir::Dirs );
+
+ QStringList::Iterator it;
+
+ for( it = list.begin(); it != list.end(); ++it ) {
+ QString name = (*it);
+ QFileInfo desktopFile( tfn + "/" + name + "/.directory" );
+ if( desktopFile.exists() ) {
+ langAvail.append(name);
+ Config conf( desktopFile.filePath(), Config::File );
+ QString langName = conf.readEntry( "Name" );
+ QString ownName = conf.readEntryDirect( "Name["+name+"]" );
+ if ( ownName.isEmpty() )
+ ownName = conf.readEntryDirect( "Name" );
+ if ( !ownName.isEmpty() && ownName != langName )
+ langName = langName + " [" + ownName + "]";
+ languages->insertItem( langName );
+
+ }
+ }
+
+ dl = new QPEDialogListener(this);
+ reset();
+}
+
+LanguageSettings::~LanguageSettings()
+{
+}
+
+void LanguageSettings::accept()
+{
+ applyLanguage();
+ QDialog::accept();
+}
+
+void LanguageSettings::applyLanguage()
+{
+ QString lang = langAvail.at( languages->currentItem() );
+ setLanguage( lang );
+}
+
+
+void LanguageSettings::reject()
+{
+ reset();
+ QDialog::reject();
+}
+
+void LanguageSettings::reset()
+{
+ QString l = getenv("LANG");
+ Config config("language");
+ l = config.readEntry( "Language", l );
+ if(l.isEmpty()) l = "en";
+ actualLanguage = l;
+
+ int n = langAvail.find( l );
+ languages->setCurrentItem( n );
+}
+
+QString LanguageSettings::actualLanguage;
+
+void LanguageSettings::setLanguage(const QString& lang)
+{
+ if( lang != actualLanguage ) {
+ Config config("locale");
+ config.setGroup( "Language" );
+ config.writeEntry( "Language", lang );
+ config.write();
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ QCopEnvelope e("QPE/System","language(QString)");
+ e << lang;
+#endif
+ }
+}
+
+void LanguageSettings::done(int r)
+{
+ QDialog::done(r);
+ close();
+}
diff --git a/noncore/settings/language/language.pro b/noncore/settings/language/language.pro
new file mode 100644
index 0000000..d1f1bf0
--- a/dev/null
+++ b/noncore/settings/language/language.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = ../../bin
+HEADERS = settings.h
+SOURCES = language.cpp main.cpp
+INTERFACES = languagesettingsbase.ui
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+TARGET = language
+
+TRANSLATIONS = ../../i18n/de/language.ts
diff --git a/noncore/settings/language/languagesettingsbase.ui b/noncore/settings/language/languagesettingsbase.ui
new file mode 100644
index 0000000..62bdafa
--- a/dev/null
+++ b/noncore/settings/language/languagesettingsbase.ui
@@ -0,0 +1,51 @@
+<!DOCTYPE UI><UI>
+<class>LanguageSettingsBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LanguageSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>369</width>
+ <height>492</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Language</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Select language</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>languages</cstring>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/noncore/settings/language/main.cpp b/noncore/settings/language/main.cpp
new file mode 100644
index 0000000..a760ff3
--- a/dev/null
+++ b/noncore/settings/language/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "settings.h"
+
+#include <qpe/qpeapplication.h>
+
+
+int main(int argc, char** argv)
+{
+ QPEApplication a(argc,argv);
+
+ LanguageSettings dlg;
+
+ a.showMainWidget(&dlg);
+
+ return a.exec();
+}
+
diff --git a/noncore/settings/language/qpe-language.control b/noncore/settings/language/qpe-language.control
new file mode 100644
index 0000000..b33c947
--- a/dev/null
+++ b/noncore/settings/language/qpe-language.control
@@ -0,0 +1,9 @@
+Files: bin/language apps/Settings/Language.desktop
+Priority: optional
+Section: qpe/settings
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Language settings dialog
+ For the Qtopia environment.
diff --git a/noncore/settings/language/settings.h b/noncore/settings/language/settings.h
new file mode 100644
index 0000000..22cc987
--- a/dev/null
+++ b/noncore/settings/language/settings.h
@@ -0,0 +1,58 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+
+#include <qstrlist.h>
+#include <qasciidict.h>
+#include "languagesettingsbase.h"
+
+class QPEDialogListener;
+
+class LanguageSettings : public LanguageSettingsBase
+{
+ Q_OBJECT
+
+public:
+ LanguageSettings( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~LanguageSettings();
+
+protected:
+ void accept();
+ void reject();
+ void done(int);
+
+ QStrList langAvail;
+
+private slots:
+ void applyLanguage();
+ void reset();
+
+private:
+ static void setLanguage(const QString&);
+ static QString actualLanguage;
+
+ QPEDialogListener *dl;
+};
+
+
+#endif // SETTINGS_H
+
diff --git a/noncore/settings/sound/.cvsignore b/noncore/settings/sound/.cvsignore
new file mode 100644
index 0000000..ba1f2fe
--- a/dev/null
+++ b/noncore/settings/sound/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+moc_*
+*.moc
+soundsettingsbase.cpp
+soundsettingsbase.h
diff --git a/noncore/settings/sound/Makefile.in b/noncore/settings/sound/Makefile.in
new file mode 100644
index 0000000..1772e12
--- a/dev/null
+++ b/noncore/settings/sound/Makefile.in
@@ -0,0 +1,135 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = sound
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = soundsettings.h
+SOURCES = soundsettings.cpp \
+ main.cpp
+OBJECTS = soundsettings.o \
+ main.o \
+ soundsettingsbase.o
+INTERFACES = soundsettingsbase.ui
+UICDECLS = soundsettingsbase.h
+UICIMPLS = soundsettingsbase.cpp
+SRCMOC = moc_soundsettings.cpp \
+ moc_soundsettingsbase.cpp
+OBJMOC = moc_soundsettings.o \
+ moc_soundsettingsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake sound.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+soundsettings.o: soundsettings.cpp \
+ soundsettings.h \
+ soundsettingsbase.h
+
+main.o: main.cpp \
+ soundsettings.h \
+ soundsettingsbase.h
+
+soundsettingsbase.h: soundsettingsbase.ui
+ $(UIC) soundsettingsbase.ui -o $(INTERFACE_DECL_PATH)/soundsettingsbase.h
+
+soundsettingsbase.cpp: soundsettingsbase.ui
+ $(UIC) soundsettingsbase.ui -i soundsettingsbase.h -o soundsettingsbase.cpp
+
+soundsettingsbase.o: soundsettingsbase.cpp \
+ soundsettingsbase.h \
+ soundsettingsbase.ui
+
+moc_soundsettings.o: moc_soundsettings.cpp \
+ soundsettings.h \
+ soundsettingsbase.h
+
+moc_soundsettingsbase.o: moc_soundsettingsbase.cpp \
+ soundsettingsbase.h
+
+moc_soundsettings.cpp: soundsettings.h
+ $(MOC) soundsettings.h -o moc_soundsettings.cpp
+
+moc_soundsettingsbase.cpp: soundsettingsbase.h
+ $(MOC) soundsettingsbase.h -o moc_soundsettingsbase.cpp
+
+
diff --git a/noncore/settings/sound/main.cpp b/noncore/settings/sound/main.cpp
new file mode 100644
index 0000000..5d28a8c
--- a/dev/null
+++ b/noncore/settings/sound/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "soundsettings.h"
+
+#include <qpe/qpeapplication.h>
+
+
+int main(int argc, char** argv)
+{
+ QPEApplication a(argc,argv);
+
+ SoundSettings dlg;
+
+ a.showMainWidget(&dlg);
+
+ return a.exec();
+}
+
diff --git a/noncore/settings/sound/qpe-sound.control b/noncore/settings/sound/qpe-sound.control
new file mode 100644
index 0000000..f7f1c4f
--- a/dev/null
+++ b/noncore/settings/sound/qpe-sound.control
@@ -0,0 +1,10 @@
+Files: bin/sound apps/Settings/Sound.desktop
+Priority: optional
+Section: qpe/settings
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-1
+Depends: qpe-base ($QPE_VERSION)
+Description: Sound settings dialog
+ For the Qtopia environment.
diff --git a/noncore/settings/sound/sound.pro b/noncore/settings/sound/sound.pro
new file mode 100644
index 0000000..9028a44
--- a/dev/null
+++ b/noncore/settings/sound/sound.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = ../../bin
+HEADERS = soundsettings.h
+SOURCES = soundsettings.cpp main.cpp
+INTERFACES = soundsettingsbase.ui
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+TARGET = sound
diff --git a/noncore/settings/sound/soundsettings.cpp b/noncore/settings/sound/soundsettings.cpp
new file mode 100644
index 0000000..92281f8
--- a/dev/null
+++ b/noncore/settings/sound/soundsettings.cpp
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "soundsettings.h"
+
+#include <qpe/config.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qslider.h>
+#include <qcheckbox.h>
+
+SoundSettings::SoundSettings( QWidget* parent, const char* name, WFlags fl )
+ : SoundSettingsBase( parent, name, TRUE, fl )
+{
+ Config config( "Sound" );
+
+ config.setGroup( "System" );
+ volume->setValue(100-config.readNumEntry("Volume"));
+ touchsound->setChecked(config.readBoolEntry("Touch"));
+ keysound->setChecked(config.readBoolEntry("Key"));
+
+ connect(volume, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int)));
+}
+
+void SoundSettings::reject()
+{
+ Config config( "Sound" );
+ config.setGroup( "System" );
+ setVolume(100-config.readNumEntry("Volume"));
+
+ QDialog::reject();
+}
+
+void SoundSettings::accept()
+{
+ Config config( "Sound" );
+ config.setGroup( "System" );
+ config.writeEntry("Volume",100-volume->value());
+ config.writeEntry("Touch",touchsound->isChecked());
+ config.writeEntry("Key",keysound->isChecked());
+ setVolume(volume->value());
+ QDialog::accept();
+}
+
+void SoundSettings::setVolume(int v)
+{
+ QCopEnvelope( "QPE/System", "setVolume(int,int)" ) << 0 << 100-v;
+}
diff --git a/noncore/settings/sound/soundsettings.h b/noncore/settings/sound/soundsettings.h
new file mode 100644
index 0000000..b5c8cee
--- a/dev/null
+++ b/noncore/settings/sound/soundsettings.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SOUNDSETTINGS_H
+#define SOUNDSETTINGS_H
+
+
+#include "soundsettingsbase.h"
+
+
+class SoundSettings : public SoundSettingsBase
+{
+ Q_OBJECT
+
+public:
+ SoundSettings( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+
+protected:
+ void accept();
+ void reject();
+
+private slots:
+ void setVolume(int);
+};
+
+
+#endif // SOUNDSETTINGS_H
+
diff --git a/noncore/settings/sound/soundsettingsbase.ui b/noncore/settings/sound/soundsettingsbase.ui
new file mode 100644
index 0000000..1aa4545
--- a/dev/null
+++ b/noncore/settings/sound/soundsettingsbase.ui
@@ -0,0 +1,281 @@
+<!DOCTYPE UI><UI>
+<class>SoundSettingsBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>SoundSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>246</width>
+ <height>299</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Sound Settings</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>keysound</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Keyboard sound</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>touchsound</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Screen sound</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout10</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QSlider</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>volume</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>100</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>50</number>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>tickmarks</name>
+ <enum>Right</enum>
+ </property>
+ <property stdset="1">
+ <name>tickInterval</name>
+ <number>5</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout9</cstring>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout10_2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PixmapLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>scaledContents</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Loud</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer3_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer5_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout9_2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PixmapLabel2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ <property stdset="1">
+ <name>scaledContents</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Silent</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="409">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022630543251d2e253d856405bffcbc54103b11c856360003105719c44d4b8371f590803210638829a38b2983115c2c112a8224969808d60716868a2582c440aa94a1628960a00755a5ac8c2aa64c8118c23c6cf6c2dda787e23eb03f602af1fa17395c6aadb9008c9350cb</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="409">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022630543251d2e253d856405bffcbc54105b19c856360003103711c44d4b8371f5d000c962ca9862ca9862ca60b1440806bb0a0c80dcc444304616030924a2a983a8d423a80ed93c6cf6e2701f567f100c835a6b2e0025ab4ee4</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/settings/sysinfo/.cvsignore b/noncore/settings/sysinfo/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/settings/sysinfo/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/settings/sysinfo/Makefile.in b/noncore/settings/sysinfo/Makefile.in
new file mode 100644
index 0000000..1149304
--- a/dev/null
+++ b/noncore/settings/sysinfo/Makefile.in
@@ -0,0 +1,193 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = sysinfo
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = memory.h \
+ graph.h \
+ load.h \
+ storage.h \
+ versioninfo.h \
+ sysinfo.h
+SOURCES = main.cpp \
+ memory.cpp \
+ graph.cpp \
+ load.cpp \
+ storage.cpp \
+ versioninfo.cpp \
+ sysinfo.cpp
+OBJECTS = main.o \
+ memory.o \
+ graph.o \
+ load.o \
+ storage.o \
+ versioninfo.o \
+ sysinfo.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_memory.cpp \
+ moc_graph.cpp \
+ moc_load.cpp \
+ moc_storage.cpp \
+ moc_versioninfo.cpp \
+ moc_sysinfo.cpp
+OBJMOC = moc_memory.o \
+ moc_graph.o \
+ moc_load.o \
+ moc_storage.o \
+ moc_versioninfo.o \
+ moc_sysinfo.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake sysinfo.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ sysinfo.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+memory.o: memory.cpp \
+ graph.h \
+ memory.h
+
+graph.o: graph.cpp \
+ graph.h
+
+load.o: load.cpp \
+ load.h
+
+storage.o: storage.cpp \
+ graph.h \
+ storage.h
+
+versioninfo.o: versioninfo.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/version.h \
+ versioninfo.h
+
+sysinfo.o: sysinfo.cpp \
+ memory.h \
+ load.h \
+ storage.h \
+ versioninfo.h \
+ sysinfo.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+moc_memory.o: moc_memory.cpp \
+ memory.h
+
+moc_graph.o: moc_graph.cpp \
+ graph.h
+
+moc_load.o: moc_load.cpp \
+ load.h
+
+moc_storage.o: moc_storage.cpp \
+ storage.h
+
+moc_versioninfo.o: moc_versioninfo.cpp \
+ versioninfo.h
+
+moc_sysinfo.o: moc_sysinfo.cpp \
+ sysinfo.h
+
+moc_memory.cpp: memory.h
+ $(MOC) memory.h -o moc_memory.cpp
+
+moc_graph.cpp: graph.h
+ $(MOC) graph.h -o moc_graph.cpp
+
+moc_load.cpp: load.h
+ $(MOC) load.h -o moc_load.cpp
+
+moc_storage.cpp: storage.h
+ $(MOC) storage.h -o moc_storage.cpp
+
+moc_versioninfo.cpp: versioninfo.h
+ $(MOC) versioninfo.h -o moc_versioninfo.cpp
+
+moc_sysinfo.cpp: sysinfo.h
+ $(MOC) sysinfo.h -o moc_sysinfo.cpp
+
+
diff --git a/noncore/settings/sysinfo/graph.cpp b/noncore/settings/sysinfo/graph.cpp
new file mode 100644
index 0000000..0b02bf7
--- a/dev/null
+++ b/noncore/settings/sysinfo/graph.cpp
@@ -0,0 +1,183 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include "graph.h"
+
+void GraphData::clear()
+{
+ names.clear();
+ values.resize(0);
+}
+
+void GraphData::addItem( const QString &name, int value )
+{
+ names.append( name );
+ values.resize( values.size() + 1 );
+ values[values.size()-1] = value;
+}
+
+Graph::Graph(QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f )
+{
+}
+
+PieGraph::PieGraph(QWidget *parent, const char *name, WFlags f )
+ : Graph( parent, name, f )
+{
+}
+
+void PieGraph::drawContents( QPainter *p )
+{
+ int size = QMIN( contentsRect().width(), contentsRect().height() ) - 1;
+
+ int total = 0;
+ for ( unsigned i = 0; i < data->count(); i++ )
+ total += data->value(i);
+
+ int angle = 0;
+ for ( unsigned i = 0; i < data->count(); i++ ) {
+ int len;
+ if ( i == data->count() - 1 || !total )
+ len = 5760 - angle;
+ else
+ len = data->value(i) * 5760 / total;
+ QColor col;
+ col.setHsv( i * 360 / data->count(), 255, 255 );
+ p->setBrush( col );
+ p->drawPie ( contentsRect().x(), contentsRect().y(),
+ size, size, angle, len+32 );
+ angle += len;
+ }
+}
+
+BarGraph::BarGraph(QWidget *parent, const char *name, WFlags f )
+ : Graph( parent, name, f )
+{
+ setMinimumHeight( 10 );
+ setMaximumHeight( 45 );
+}
+
+void BarGraph::drawContents( QPainter *p )
+{
+ int h = contentsRect().height();
+ int y = contentsRect().top();
+
+ int total = 0;
+ for ( unsigned i = 0; i < data->count(); i++ )
+ total += data->value(i);
+
+ int pos = 0;
+ for ( unsigned i = 0; i < data->count(); i++ ) {
+ int len;
+ if ( i == data->count() - 1 || !total )
+ len = contentsRect().width() - pos;
+ else
+ len = data->value(i) * contentsRect().width() / total;
+ QColor col;
+ col.setHsv( i * 360 / data->count(), 255, 255 );
+ drawSegment( p, QRect(contentsRect().x() + pos, y, len, h), col );
+ pos += len;
+ }
+}
+
+void BarGraph::drawSegment( QPainter *p, const QRect &r, const QColor &c )
+{
+ if ( QPixmap::defaultDepth() > 8 ) {
+ QColor topgrad = c.light(170);
+ QColor botgrad = c.dark();
+
+ int h1, h2, s1, s2, v1, v2;
+ topgrad.hsv( &h1, &s1, &v1 );
+ botgrad.hsv( &h2, &s2, &v2 );
+ int ng = r.height();
+ for ( int j =0; j < ng; j++ ) {
+ p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1),
+ s1 + ((s2-s1)*j)/(ng-1),
+ v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
+ p->drawLine( r.x(), r.top()+j, r.x()+r.width(), r.top()+j );
+ }
+ } else {
+ p->fillRect( r.x(), r.top(), r.width(), r.height(), c );
+ }
+}
+
+
+GraphLegend::GraphLegend( QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f )
+{
+ horz = FALSE;
+}
+
+void GraphLegend::setOrientation(Orientation o)
+{
+ horz = o == Horizontal;
+}
+
+void GraphLegend::drawContents( QPainter *p )
+{
+ int total = 0;
+ for ( unsigned i = 0; i < data->count(); i++ )
+ total += data->value(i);
+
+ int tw = width()/data->count()-1;
+ int th = height()/(horz ? 1 : data->count());
+ if ( th > p->fontMetrics().height() )
+ th = p->fontMetrics().height();
+ int x = 0;
+ int y = 0;
+ for ( unsigned i = 0; i < data->count(); i++ ) {
+ QColor col;
+ col.setHsv( i * 360 / data->count(), 255, 255 );
+ p->setBrush( col );
+ p->drawRect( x+1, y+1, th - 2, th - 2 );
+ p->drawText( x+th + 1, y + p->fontMetrics().ascent()+1, data->name(i) );
+ if ( horz ) {
+ x += tw;
+ } else {
+ y += th;
+ }
+ }
+}
+
+QSize GraphLegend::sizeHint() const
+{
+ int th = fontMetrics().height() + 2;
+ int maxw = 0;
+ for ( unsigned i = 0; i < data->count(); i++ ) {
+ int w = fontMetrics().width( data->name(i) );
+ if ( w > maxw )
+ maxw = w;
+ }
+ if ( 0 && horz ) {
+ return QSize( maxw * data->count(), th );
+ } else {
+ return QSize( maxw, th * data->count() );
+ }
+}
+
+void GraphLegend::setData( const GraphData *p )
+{
+ data = p;
+ int th = fontMetrics().height();
+ setMinimumHeight( th * ( horz ? 1 : data->count() ) );
+ updateGeometry();
+}
diff --git a/noncore/settings/sysinfo/graph.h b/noncore/settings/sysinfo/graph.h
new file mode 100644
index 0000000..5a65e79
--- a/dev/null
+++ b/noncore/settings/sysinfo/graph.h
@@ -0,0 +1,89 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qframe.h>
+#include <qarray.h>
+#include <qstringlist.h>
+
+class GraphData
+{
+public:
+ void clear();
+ void addItem( const QString &name, int value );
+
+ const QString &name( int i ) const { return names[i]; }
+ int value( int i ) const { return values[i]; }
+ unsigned count() const { return values.size(); }
+
+private:
+ QStringList names;
+ QArray<int> values;
+};
+
+class Graph : public QFrame
+{
+ Q_OBJECT
+public:
+ Graph( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+ void setData( const GraphData *p ) { data = p; }
+
+protected:
+ const GraphData *data;
+};
+
+class PieGraph : public Graph
+{
+ Q_OBJECT
+public:
+ PieGraph( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+protected:
+ virtual void drawContents( QPainter *p );
+};
+
+class BarGraph : public Graph
+{
+ Q_OBJECT
+public:
+ BarGraph( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+protected:
+ virtual void drawContents( QPainter *p );
+ void drawSegment( QPainter *p, const QRect &r, const QColor &c );
+};
+
+class GraphLegend : public QFrame
+{
+ Q_OBJECT
+public:
+ GraphLegend( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+ void setData( const GraphData *p );
+ virtual QSize sizeHint() const;
+ void setOrientation(Orientation o);
+
+protected:
+ virtual void drawContents( QPainter *p );
+
+private:
+ const GraphData *data;
+ bool horz;
+};
diff --git a/noncore/settings/sysinfo/load.cpp b/noncore/settings/sysinfo/load.cpp
new file mode 100644
index 0000000..0fcfa6b
--- a/dev/null
+++ b/noncore/settings/sysinfo/load.cpp
@@ -0,0 +1,207 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <stdio.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include "load.h"
+
+LoadInfo::LoadInfo( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ QVBoxLayout *vb = new QVBoxLayout( this, 6 );
+
+ QString cpuInfo = getCpuInfo();
+ if ( !cpuInfo.isNull() )
+ vb->addWidget( new QLabel( cpuInfo, this ) );
+ vb->addWidget( new Load( this ), 100 );
+ QLabel *l = new QLabel( this );
+ l->setPixmap( makeLabel( red, tr("Application CPU usage (%)") ) );
+ vb->addWidget( l, 1 );
+ l = new QLabel( this );
+ l->setPixmap( makeLabel( green, tr("System CPU usage (%)") ) );
+ vb->addWidget( l, 1 );
+ vb->addStretch(50);
+}
+
+QPixmap LoadInfo::makeLabel( const QColor &col, const QString &text )
+{
+ int h = fontMetrics().height();
+ QPixmap pm( 20 + fontMetrics().width( text ), h );
+ QPainter p( &pm );
+ p.fillRect( pm.rect(), colorGroup().background() );
+ p.fillRect( 0, h/2-4, 18, h/2+3, black );
+ p.setPen( col );
+ p.drawLine( 2, h/2, 15, h/2 );
+ p.setPen( colorGroup().text() );
+ p.drawText( 20, fontMetrics().ascent(), text );
+
+ return pm;
+}
+
+QString LoadInfo::getCpuInfo()
+{
+ bool haveInfo = FALSE;
+ QString info = tr("Type: ");
+ QFile f( "/proc/cpuinfo" );
+ if ( f.open( IO_ReadOnly ) ) {
+ QTextStream ts( &f );
+
+ while ( !ts.atEnd() ) {
+ QString s = ts.readLine();
+ if ( s.find( "model name" ) == 0 ) {
+ info += s.mid( s.find( ':' ) + 2 );
+ haveInfo = TRUE;
+ } else if ( s.find( "cpu MHz" ) == 0 ) {
+ double mhz = s.mid( s.find( ':' ) + 2 ).toDouble();
+ info += " " + QString::number( mhz, 'f', 0 );
+ info += "MHz";
+ break;
+ } else if ( s.find( "Processor" ) == 0 ) {
+ info += s.mid( s.find( ':' ) + 2 );
+ haveInfo = TRUE;
+ break;
+#ifdef __MIPSEL__
+ } else if ( s.find( "cpu model" ) == 0 ) {
+ info += " " + s.mid( s.find( ':' ) + 2 );
+ break;
+ } else if ( s.find( "cpu" ) == 0 ) {
+ info += s.mid( s.find( ':' ) + 2 );
+ haveInfo = TRUE;
+#endif
+ }
+ }
+ }
+
+ if ( !haveInfo )
+ info = QString();
+
+ return info;
+}
+
+Load::Load( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ setMinimumHeight( 30 );
+ setBackgroundColor( black );
+ points = 100;
+ setMinimumWidth( points );
+ userLoad = new double [points];
+ systemLoad = new double [points];
+ for ( int i = 0; i < points; i++ ) {
+ userLoad[i] = 0.0;
+ systemLoad[i] = 0.0;
+ }
+ maxLoad = 1.3;
+ QTimer *timer = new QTimer( this );
+ connect( timer, SIGNAL(timeout()), SLOT(timeout()) );
+ timer->start( 2000 );
+ gettimeofday( &last, 0 );
+ first = TRUE;
+ timeout();
+}
+
+void Load::paintEvent( QPaintEvent *ev )
+{
+ QPainter p( this );
+
+ int h = height() - 5;
+
+ int mult = (int)(h / maxLoad);
+
+ p.setPen( gray );
+ p.drawLine( 0, h - mult, width(), h - mult );
+ p.drawText( 0, h - mult, "100" );
+ p.drawText( 0, h, "0" );
+
+ p.setPen( green );
+ for ( int i = 1; i < points; i++ ) {
+ int x1 = (i - 1) * width() / points;
+ int x2 = i * width() / points;
+ p.drawLine( x1, h - systemLoad[i-1] * mult,
+ x2, h - systemLoad[i] * mult );
+ }
+
+ p.setPen( red );
+ for ( int i = 1; i < points; i++ ) {
+ int x1 = (i - 1) * width() / points;
+ int x2 = i * width() / points;
+ p.drawLine( x1, h - userLoad[i-1] * mult,
+ x2, h - userLoad[i] * mult );
+ }
+}
+
+void Load::timeout()
+{
+ int user;
+ int usernice;
+ int sys;
+ int idle;
+ FILE *fp;
+ fp = fopen( "/proc/stat", "r" );
+ fscanf( fp, "cpu %d %d %d %d", &user, &usernice, &sys, &idle );
+ fclose( fp );
+ struct timeval now;
+ gettimeofday( &now, 0 );
+ int tdiff = now.tv_usec - last.tv_usec;
+ tdiff += (now.tv_sec - last.tv_sec) * 1000000;
+ tdiff /= 10000;
+
+ int udiff = user - lastUser;
+ int sdiff = sys - lastSys;
+ if ( tdiff > 0 ) {
+ double uload = (double)udiff / (double)tdiff;
+ double sload = (double)sdiff / (double)tdiff;
+ if ( !first ) {
+ for ( int i = 1; i < points; i++ ) {
+ userLoad[i-1] = userLoad[i];
+ systemLoad[i-1] = systemLoad[i];
+ }
+ userLoad[points-1] = uload;
+ systemLoad[points-1] = sload;
+// scroll( -width()/points, 0, QRect( 0, 0, width() - width()/points + 1, height() ) );
+ repaint( TRUE );
+ double ml = 1.3;
+ /*
+ for ( int i = 0; i < points; i++ ) {
+ if ( userLoad[i] > ml )
+ ml = userLoad[i];
+ }
+ */
+ if ( maxLoad != ml ) {
+ maxLoad = ml;
+ update();
+ }
+ }
+
+ last = now;
+ lastUser = user;
+ lastSys = sys;
+ first = FALSE;
+ } else if ( tdiff < 0 ) {
+ last = now;
+ }
+}
+
diff --git a/noncore/settings/sysinfo/load.h b/noncore/settings/sysinfo/load.h
new file mode 100644
index 0000000..e7f5388
--- a/dev/null
+++ b/noncore/settings/sysinfo/load.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <sys/time.h>
+#include <qwidget.h>
+
+/*
+ Little load meter
+*/
+class Load : public QWidget {
+ Q_OBJECT
+public:
+ Load( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+protected:
+ void paintEvent( QPaintEvent *ev );
+
+private slots:
+ void timeout();
+
+private:
+ int points;
+ double *userLoad;
+ double *systemLoad;
+ double maxLoad;
+ struct timeval last;
+ int lastUser;
+ int lastUsernice;
+ int lastSys;
+ int lastIdle;
+ bool first;
+};
+
+class LoadInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ LoadInfo( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+
+private:
+ QPixmap makeLabel( const QColor &col, const QString &text );
+ QString getCpuInfo();
+};
diff --git a/noncore/settings/sysinfo/main.cpp b/noncore/settings/sysinfo/main.cpp
new file mode 100644
index 0000000..6e889db
--- a/dev/null
+++ b/noncore/settings/sysinfo/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "sysinfo.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char *argv[] )
+{
+ QPEApplication a( argc, argv );
+
+ SystemInfo *si = new SystemInfo();
+ a.showMainWidget( si );
+
+ return a.exec();
+}
+
diff --git a/noncore/settings/sysinfo/memory.cpp b/noncore/settings/sysinfo/memory.cpp
new file mode 100644
index 0000000..781f0df
--- a/dev/null
+++ b/noncore/settings/sysinfo/memory.cpp
@@ -0,0 +1,94 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlayout.h>
+#include "graph.h"
+#include "memory.h"
+
+MemoryInfo::MemoryInfo( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ QVBoxLayout *vb = new QVBoxLayout( this, 5 );
+
+ totalMem = new QLabel( this );
+ vb->addWidget( totalMem );
+
+ data = new GraphData();
+// graph = new PieGraph( this );
+ graph = new BarGraph( this );
+ graph->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ vb->addWidget( graph, 1 );
+ graph->setData( data );
+
+ legend = new GraphLegend( this );
+ vb->addWidget( legend );
+ legend->setData( data );
+
+ vb->addStretch( 1 );
+ updateData();
+
+ QTimer *t = new QTimer( this );
+ connect( t, SIGNAL( timeout() ), this, SLOT( updateData() ) );
+ t->start( 5000 );
+}
+
+MemoryInfo::~MemoryInfo()
+{
+ delete data;
+}
+
+void MemoryInfo::updateData()
+{
+ QFile file( "/proc/meminfo" );
+
+ if ( file.open( IO_ReadOnly ) ) {
+ QTextStream t( &file );
+ QString dummy = t.readLine(); // title
+ t >> dummy;
+ int total, used, memfree, shared, buffers, cached;
+ t >> total;
+ total /= 1000;
+ t >> used;
+ used /= 1000;
+ t >> memfree;
+ memfree /= 1000;
+ t >> shared;
+ shared /= 1000;
+ t >> buffers;
+ buffers /= 1000;
+ t >> cached;
+ cached /= 1000;
+ int realUsed = total - ( buffers + cached + memfree );
+ data->clear();
+ data->addItem( tr("Used (%1 kB)").arg(realUsed), realUsed );
+ data->addItem( tr("Buffers (%1 kB)").arg(buffers), buffers );
+ data->addItem( tr("Cached (%1 kB)").arg(cached), cached );
+ data->addItem( tr("Free (%1 kB)").arg(memfree), memfree );
+ totalMem->setText( tr( "Total Memory: %1 kB" ).arg( total ) );
+ graph->repaint( FALSE );
+ legend->update();
+ }
+}
+
+
diff --git a/noncore/settings/sysinfo/memory.h b/noncore/settings/sysinfo/memory.h
new file mode 100644
index 0000000..696f97c
--- a/dev/null
+++ b/noncore/settings/sysinfo/memory.h
@@ -0,0 +1,48 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <qwidget.h>
+
+class GraphData;
+class Graph;
+class GraphLegend;
+class QLabel;
+
+class MemoryInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ MemoryInfo( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~MemoryInfo();
+
+private slots:
+ void updateData();
+
+private:
+ QLabel *totalMem;
+ GraphData *data;
+ Graph *graph;
+ GraphLegend *legend;
+};
+
+#endif
diff --git a/noncore/settings/sysinfo/qpe-sysinfo.control b/noncore/settings/sysinfo/qpe-sysinfo.control
new file mode 100644
index 0000000..e5ed583
--- a/dev/null
+++ b/noncore/settings/sysinfo/qpe-sysinfo.control
@@ -0,0 +1,9 @@
+Files: bin/sysinfo apps/Applications/sysinfo.desktop pics/qpe-logo.png pics/tux-logo.png
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: System Information dialog
+ For the Qtopia environment.
diff --git a/noncore/settings/sysinfo/storage.cpp b/noncore/settings/sysinfo/storage.cpp
new file mode 100644
index 0000000..4e81170
--- a/dev/null
+++ b/noncore/settings/sysinfo/storage.cpp
@@ -0,0 +1,220 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qlayout.h>
+#include "graph.h"
+#include "storage.h"
+
+#include <stdio.h>
+#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
+#include <sys/vfs.h>
+#include <mntent.h>
+#endif
+
+StorageInfo::StorageInfo( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ vb = 0;
+ disks.setAutoDelete(TRUE);
+ lines.setAutoDelete(TRUE);
+ updateMounts();
+ startTimer( 5000 );
+}
+
+void StorageInfo::timerEvent(QTimerEvent*)
+{
+ updateMounts();
+}
+
+static bool isCF(const QString& m)
+{
+ FILE* f = fopen("/var/run/stab", "r");
+ if (!f) f = fopen("/var/state/pcmcia/stab", "r");
+ if (!f) f = fopen("/var/lib/pcmcia/stab", "r");
+ if ( f ) {
+ char line[1024];
+ char devtype[80];
+ char devname[80];
+ while ( fgets( line, 1024, f ) ) {
+ // 0 ide ide-cs 0 hda 3 0
+ if ( sscanf(line,"%*d %s %*s %*s %s", devtype, devname )==2 )
+ {
+ if ( QString(devtype) == "ide" && m.find(devname)>0 ) {
+ fclose(f);
+ return TRUE;
+ }
+ }
+ }
+ fclose(f);
+ }
+ return FALSE;
+}
+
+void StorageInfo::updateMounts()
+{
+#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
+ struct mntent *me;
+ FILE *mntfp = setmntent( "/etc/mtab", "r" );
+ QStringList curdisks;
+ QStringList curfs;
+ bool rebuild = FALSE;
+ int n=0;
+ if ( mntfp ) {
+ while ( (me = getmntent( mntfp )) != 0 ) {
+ QString fs = me->mnt_fsname;
+ if ( fs.left(7)=="/dev/hd" || fs.left(7)=="/dev/sd"
+ || fs.left(8)=="/dev/mtd" || fs.left(9) == "/dev/mmcd" )
+ {
+ n++;
+ curdisks.append(fs);
+ QString d = me->mnt_dir;
+ curfs.append(d);
+ if ( !disks.find(d) )
+ rebuild = TRUE;
+ }
+ }
+ endmntent( mntfp );
+ }
+ if ( rebuild || n != (int)disks.count() ) {
+ disks.clear();
+ lines.clear();
+ delete vb;
+ vb = new QVBoxLayout( this, n > 3 ? 1 : 5 );
+ bool frst=TRUE;
+ QStringList::ConstIterator it=curdisks.begin();
+ QStringList::ConstIterator fsit=curfs.begin();
+ for (; it!=curdisks.end(); ++it, ++fsit) {
+ if ( !frst ) {
+ QFrame *f = new QFrame( this );
+ vb->addWidget(f);
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ lines.append(f);
+ f->show();
+ } frst=FALSE;
+ QString humanname=*it;
+ if ( isCF(humanname) )
+ humanname = tr("CF Card");
+ else if ( humanname == "/dev/hda1" )
+ humanname = tr("Hard Disk");
+ else if ( humanname.left(9) == "/dev/mmcd" )
+ humanname = tr("SD Card");
+ else if ( humanname.left(7) == "/dev/hd" )
+ humanname = tr("Hard Disk") + " " + humanname.mid(7);
+ else if ( humanname.left(7) == "/dev/sd" )
+ humanname = tr("SCSI Hard Disk") + " " + humanname.mid(7);
+ else if ( humanname == "/dev/mtdblock1" || humanname == "/dev/mtdblock/1" )
+ humanname = tr("Internal Storage");
+ else if ( humanname.left(14) == "/dev/mtdblock/" )
+ humanname = tr("Internal Storage") + " " + humanname.mid(14);
+ else if ( humanname.left(13) == "/dev/mtdblock" )
+ humanname = tr("Internal Storage") + " " + humanname.mid(13);
+ // etc.
+ MountInfo* mi = new MountInfo( *fsit, humanname, this );
+ vb->addWidget(mi);
+ disks.insert(*fsit,mi);
+ mi->show();
+ }
+ vb->addStretch();
+ } else {
+ // just update them
+ for (QDictIterator<MountInfo> i(disks); i.current(); ++i)
+ i.current()->updateData();
+ }
+#endif
+}
+
+
+MountInfo::MountInfo( const QString &path, const QString &ttl, QWidget *parent, const char *name )
+ : QWidget( parent, name ), title(ttl)
+{
+ fs = new FileSystem( path );
+ QVBoxLayout *vb = new QVBoxLayout( this, 3 );
+
+ totalSize = new QLabel( this );
+ vb->addWidget( totalSize );
+
+ data = new GraphData();
+ graph = new BarGraph( this );
+ graph->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ vb->addWidget( graph, 1 );
+ graph->setData( data );
+
+ legend = new GraphLegend( this );
+ legend->setOrientation(Horizontal);
+ vb->addWidget( legend );
+ legend->setData( data );
+
+ updateData();
+}
+
+MountInfo::~MountInfo()
+{
+ delete data;
+ delete fs;
+}
+
+void MountInfo::updateData()
+{
+ fs->update();
+
+ long mult = fs->blockSize() / 1024;
+ long div = 1024 / fs->blockSize();
+ if ( !mult ) mult = 1;
+ if ( !div ) div = 1;
+ long total = fs->totalBlocks() * mult / div;
+ long avail = fs->availBlocks() * mult / div;
+ long used = total - avail;
+ totalSize->setText( title + tr(" total: %1 kB").arg( total ) );
+ data->clear();
+ data->addItem( tr("Used (%1 kB)").arg(used), used );
+ data->addItem( tr("Available (%1 kB)").arg(avail), avail );
+ graph->repaint( FALSE );
+ legend->update();
+ graph->show();
+ legend->show();
+}
+
+//---------------------------------------------------------------------------
+
+FileSystem::FileSystem( const QString &p )
+ : fspath( p ), blkSize(512), totalBlks(0), availBlks(0)
+{
+ update();
+}
+
+void FileSystem::update()
+{
+#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
+ struct statfs fs;
+ if ( !statfs( fspath.latin1(), &fs ) ) {
+ blkSize = fs.f_bsize;
+ totalBlks = fs.f_blocks;
+ availBlks = fs.f_bavail;
+ } else {
+ blkSize = 0;
+ totalBlks = 0;
+ availBlks = 0;
+ }
+#endif
+}
+
diff --git a/noncore/settings/sysinfo/storage.h b/noncore/settings/sysinfo/storage.h
new file mode 100644
index 0000000..3fa5b79
--- a/dev/null
+++ b/noncore/settings/sysinfo/storage.h
@@ -0,0 +1,87 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qwidget.h>
+#include <qframe.h>
+#include <qlist.h>
+#include <qdict.h>
+
+class QLabel;
+class GraphData;
+class Graph;
+class GraphLegend;
+class FileSystem;
+class MountInfo;
+class QVBoxLayout;
+
+
+class StorageInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ StorageInfo( QWidget *parent=0, const char *name=0 );
+
+protected:
+ void timerEvent(QTimerEvent*);
+
+private:
+ void updateMounts();
+ QDict<MountInfo> disks;
+ QList<QFrame> lines;
+ QVBoxLayout *vb;
+};
+
+class MountInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ MountInfo( const QString &path, const QString &ttl, QWidget *parent=0, const char *name=0 );
+ ~MountInfo();
+
+ void updateData();
+
+private:
+ QString title;
+ FileSystem *fs;
+ QLabel *totalSize;
+ GraphData *data;
+ Graph *graph;
+ GraphLegend *legend;
+};
+
+class FileSystem
+{
+public:
+ FileSystem( const QString &p );
+
+ void update();
+
+ const QString &path() const { return fspath; }
+ long blockSize() const { return blkSize; }
+ long totalBlocks() const { return totalBlks; }
+ long availBlocks() const { return availBlks; }
+
+private:
+ QString fspath;
+ long blkSize;
+ long totalBlks;
+ long availBlks;
+};
+
+
diff --git a/noncore/settings/sysinfo/sysinfo.cpp b/noncore/settings/sysinfo/sysinfo.cpp
new file mode 100644
index 0000000..bc483aa
--- a/dev/null
+++ b/noncore/settings/sysinfo/sysinfo.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "memory.h"
+#include "load.h"
+#include "storage.h"
+//#include "graphics.h"
+#include "versioninfo.h"
+#include "sysinfo.h"
+
+
+#include <qpe/resource.h>
+
+#include <qtabwidget.h>
+#include <qlayout.h>
+
+SystemInfo::SystemInfo( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ setIcon( Resource::loadPixmap( "system_icon" ) );
+ setCaption( tr("System Info") );
+ QVBoxLayout *lay = new QVBoxLayout( this );
+ QTabWidget *tab = new QTabWidget( this );
+ lay->addWidget( tab );
+ tab->addTab( new MemoryInfo( tab ), tr("Memory") );
+#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
+ tab->addTab( new StorageInfo( tab ), tr("Storage") );
+#endif
+ tab->addTab( new LoadInfo( tab ), tr("CPU") );
+// tab->addTab( new Graphics( tab ), tr("Graphics") );
+ tab->addTab( new VersionInfo( tab ), tr("Version") );
+
+ resize( 220, 180 );
+}
+
+
diff --git a/noncore/settings/sysinfo/sysinfo.h b/noncore/settings/sysinfo/sysinfo.h
new file mode 100644
index 0000000..abbf955
--- a/dev/null
+++ b/noncore/settings/sysinfo/sysinfo.h
@@ -0,0 +1,29 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qwidget.h>
+
+class SystemInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ SystemInfo( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+};
+
diff --git a/noncore/settings/sysinfo/sysinfo.pro b/noncore/settings/sysinfo/sysinfo.pro
new file mode 100644
index 0000000..0c7d907
--- a/dev/null
+++ b/noncore/settings/sysinfo/sysinfo.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = memory.h \
+ graph.h \
+ load.h \
+ storage.h \
+ versioninfo.h \
+ sysinfo.h
+SOURCES = main.cpp \
+ memory.cpp \
+ graph.cpp \
+ load.cpp \
+ storage.cpp \
+ versioninfo.cpp \
+ sysinfo.cpp
+INTERFACES =
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TARGET = sysinfo
+
+TRANSLATIONS = ../i18n/de/sysinfo.ts
diff --git a/noncore/settings/sysinfo/versioninfo.cpp b/noncore/settings/sysinfo/versioninfo.cpp
new file mode 100644
index 0000000..d60a445
--- a/dev/null
+++ b/noncore/settings/sysinfo/versioninfo.cpp
@@ -0,0 +1,109 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/resource.h>
+#include <qpe/version.h>
+
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qimage.h>
+#include <qtimer.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlayout.h>
+#include "versioninfo.h"
+
+VersionInfo::VersionInfo( QWidget *parent, const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ setMinimumSize( 200, 150 );
+
+ QVBoxLayout *vb = new QVBoxLayout( this, 4 );
+
+ QString kernelVersionString;
+ QFile file( "/proc/version" );
+ if ( file.open( IO_ReadOnly ) ) {
+ QTextStream t( &file );
+ QString v;
+ t >> v; t >> v; t >> v;
+ v = v.left( 20 );
+ kernelVersionString = tr( "<b>Linux Kernel</b><p>Version: " ) + v + "<p>";
+ t >> v;
+ kernelVersionString += tr( "Compiled by: " ) + v;
+ file.close();
+ }
+
+ QString palmtopVersionString;
+ palmtopVersionString = tr( "<b>Qtopia</b><p>Version: " ) + QPE_VERSION + "<p>";
+#ifdef QPE_VENDOR
+ QString builder = QPE_VENDOR;
+#else
+ QString builder = "Unknown";
+#endif
+ palmtopVersionString += tr( "Compiled by: " ) + builder + "<p>";
+ palmtopVersionString += tr( "Built on: " ) + __DATE__;
+
+
+ QHBoxLayout *hb1 = new QHBoxLayout( vb );
+ hb1->setSpacing( 2 );
+
+ QLabel *palmtopLogo = new QLabel( this );
+ QImage logo1 = Resource::loadImage( "qpe-logo" );
+ logo1 = logo1.smoothScale( 50, 55 );
+ QPixmap logo1Pixmap;
+ logo1Pixmap.convertFromImage( logo1 );
+ palmtopLogo->setPixmap( logo1Pixmap );
+ palmtopLogo->setFixedSize( 60, 60 );
+ hb1->addWidget( palmtopLogo, 0, Qt::AlignTop + Qt::AlignLeft );
+
+ QLabel *palmtopVersion = new QLabel( this );
+ palmtopVersion->setText( palmtopVersionString );
+ hb1->addWidget( palmtopVersion, 1, Qt::AlignTop + Qt::AlignLeft );
+
+
+ QHBoxLayout *hb2 = new QHBoxLayout( vb );
+ hb1->setSpacing( 2 );
+
+ QLabel *linuxLogo = new QLabel( this );
+
+ // Need to do this extra qpainter code with this image becuase for some
+ // reason it doesn't alpha belnd if directly converted to a pixmap
+ QPixmap logo2Pixmap( 60, 60 );
+ QColor bgColor = colorGroup().background();
+ QPainter painter( &logo2Pixmap );
+ painter.fillRect( QRect( 0, 0, 60, 60 ), QBrush( bgColor ) );
+ QImage logo2 = Resource::loadImage( "tux-logo" );
+ logo2 = logo2.smoothScale( 40, 47 );
+ painter.drawImage( 0, 0, logo2 );
+ painter.end();
+ linuxLogo->setPixmap( logo2Pixmap );
+ linuxLogo->setFixedSize( 60, 60 );
+ hb2->addWidget( linuxLogo, 0, Qt::AlignTop + Qt::AlignLeft );
+
+ QLabel *kernelVersion = new QLabel( this );
+ kernelVersion->setText( kernelVersionString );
+ hb2->addWidget( kernelVersion, 1, Qt::AlignTop + Qt::AlignLeft );
+}
+
+VersionInfo::~VersionInfo()
+{
+}
+
diff --git a/noncore/settings/sysinfo/versioninfo.h b/noncore/settings/sysinfo/versioninfo.h
new file mode 100644
index 0000000..1b5c851
--- a/dev/null
+++ b/noncore/settings/sysinfo/versioninfo.h
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef VERSIONINFO_H
+#define VERSIONINFO_H
+
+#include <qwidget.h>
+
+class VersionInfo : public QWidget
+{
+ Q_OBJECT
+public:
+ VersionInfo( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~VersionInfo();
+};
+
+#endif
diff --git a/noncore/tools/calc2/Makefile b/noncore/tools/calc2/Makefile
new file mode 100644
index 0000000..1e31a2f
--- a/dev/null
+++ b/noncore/tools/calc2/Makefile
@@ -0,0 +1,138 @@
+#############################################################################
+# Makefile for building calc
+# Generated by tmake at 12:06, 2001/11/26
+# Project: calc
+# Template: app
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+CFLAGS = -pipe -Wall -W -O2 -DNO_DEBUG
+CXXFLAGS= -pipe -DQWS -fno-exceptions -fno-rtti -Wall -W -O2 -DNO_DEBUG
+INCPATH = -I$(QPEDIR)/include -I$(QTDIR)/include
+LINK = gcc
+LFLAGS =
+LIBS = $(SUBLIBS) -L$(QTDIR)/lib -lqpe -Wl,-export-dynamic -lqte
+MOC = $(QTDIR)/bin/moc
+UIC = $(QTDIR)/bin/uic
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = calc.h \
+ plugininterface.h \
+ instruction.h \
+ engine.h \
+ stdinstructions.h
+SOURCES = calc.cpp \
+ main.cpp \
+ engine.cpp
+OBJECTS = calc.o \
+ main.o \
+ engine.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_calc.cpp \
+ moc_engine.cpp
+OBJMOC = moc_calc.o \
+ moc_engine.o
+DIST =
+TARGET = calc
+INTERFACE_DECL_PATH = .
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(TARGET)
+
+$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC)
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake calc.pro
+
+dist:
+ $(TAR) calc.tar calc.pro $(SOURCES) $(HEADERS) $(INTERFACES) $(DIST)
+ $(GZIP) calc.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) $(TARGET)
+ -rm -f *~ core
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+####### Compile
+
+calc.o: calc.cpp \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qpeapplication.h \
+ calc.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qlibrary.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qcom.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/quuid.h \
+ engine.h \
+ instruction.h \
+ plugininterface.h
+
+main.o: main.cpp \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qpeapplication.h \
+ calc.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qlibrary.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qcom.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/quuid.h \
+ engine.h \
+ instruction.h \
+ plugininterface.h
+
+engine.o: engine.cpp \
+ engine.h \
+ instruction.h
+
+moc_calc.o: moc_calc.cpp \
+ calc.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qlibrary.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/qcom.h \
+ /home/luke/builds/2.3.2-emb/qpe/include/qpe/quuid.h \
+ engine.h \
+ instruction.h \
+ plugininterface.h
+
+moc_engine.o: moc_engine.cpp \
+ engine.h \
+ instruction.h
+
+moc_calc.cpp: calc.h
+ $(MOC) calc.h -o moc_calc.cpp
+
+moc_engine.cpp: engine.h
+ $(MOC) engine.h -o moc_engine.cpp
+
diff --git a/noncore/tools/calc2/binary/Makefile b/noncore/tools/calc2/binary/Makefile
new file mode 100644
index 0000000..93cc0d5
--- a/dev/null
+++ b/noncore/tools/calc2/binary/Makefile
@@ -0,0 +1,146 @@
+#############################################################################
+# Makefile for building libbinary.so.1.0.0
+# Generated by tmake at 12:03, 2001/11/22
+# Project: binary
+# Template: lib
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+CFLAGS = -pipe -Wall -W -O2 -fPIC -DNO_DEBUG
+CXXFLAGS= -pipe -DQWS -fno-exceptions -fno-rtti -Wall -W -O2 -fPIC -DNO_DEBUG
+INCPATH = -I$(QPEDIR)/include -I$(QPEDIR)/calc2 -I$(QTDIR)/include
+LINK = gcc
+LFLAGS = -shared -Wl,-soname,libbinary.so.1
+LIBS = $(SUBLIBS) -L$(QTDIR)/lib -lqte
+AR = ar cqs
+RANLIB =
+MOC = $(QTDIR)/bin/moc
+UIC = $(QTDIR)/bin/uic
+
+TAR = tar -cf
+GZIP = gzip -9f
+
+####### Files
+
+HEADERS = binaryimpl.h \
+ binaryfactory.h
+SOURCES = binaryimpl.cpp \
+ binaryfactory.cpp
+OBJECTS = binaryimpl.o \
+ binaryfactory.o \
+ binary.o
+INTERFACES = binary.ui
+UICDECLS = binary.h
+UICIMPLS = binary.cpp
+SRCMOC = moc_binaryimpl.cpp \
+ moc_binary.cpp
+OBJMOC = moc_binaryimpl.o \
+ moc_binary.o
+DIST =
+TARGET = libbinary.so.1.0.0
+TARGETA = $(QPEDIR)/plugins/calculator/libbinary.a
+TARGETD = libbinary.so.1.0.0
+TARGET0 = libbinary.so
+TARGET1 = libbinary.so.1
+TARGET2 = libbinary.so.1.0
+INTERFACE_DECL_PATH = .
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(QPEDIR)/plugins/calculator/libbinary.so.1.0.0
+
+$(QPEDIR)/plugins/calculator/libbinary.so.1.0.0: $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ -rm -f $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)
+ $(LINK) $(LFLAGS) -o $(TARGETD) $(OBJECTS) $(OBJMOC) $(LIBS)
+ -ln -s $(TARGET) $(TARGET0)
+ -ln -s $(TARGET) $(TARGET1)
+ -ln -s $(TARGET) $(TARGET2)
+ -rm -f $(QPEDIR)/plugins/calculator/$(TARGET)
+ -rm -f $(QPEDIR)/plugins/calculator/$(TARGET0)
+ -rm -f $(QPEDIR)/plugins/calculator/$(TARGET1)
+ -rm -f $(QPEDIR)/plugins/calculator/$(TARGET2)
+ -mv $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) $(QPEDIR)/plugins/calculator/
+
+staticlib: $(TARGETA)
+
+$(TARGETA): $(UICDECLS) $(OBJECTS) $(OBJMOC)
+ -rm -f $(TARGETA)
+ $(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake binary.pro
+
+dist:
+ $(TAR) binary.tar binary.pro $(SOURCES) $(HEADERS) $(INTERFACES) $(DIST)
+ $(GZIP) binary.tar
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) $(TARGET)
+ -rm -f $(TARGET0) $(TARGET1) $(TARGET2) $(TARGETA)
+ -rm -f *~ core
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+####### Compile
+
+binaryimpl.o: binaryimpl.cpp \
+ binaryimpl.h \
+ binary.h
+
+binaryfactory.o: binaryfactory.cpp \
+ binaryfactory.h \
+ binaryimpl.h \
+ binary.h
+
+binary.h: binary.ui
+ $(UIC) binary.ui -o $(INTERFACE_DECL_PATH)/binary.h
+
+binary.cpp: binary.ui
+ $(UIC) binary.ui -i binary.h -o binary.cpp
+
+binary.o: binary.cpp \
+ binary.h \
+ binary.ui
+
+moc_binaryimpl.o: moc_binaryimpl.cpp \
+ binaryimpl.h \
+ binary.h
+
+moc_binary.o: moc_binary.cpp \
+ binary.h
+
+moc_binaryimpl.cpp: binaryimpl.h
+ $(MOC) binaryimpl.h -o moc_binaryimpl.cpp
+
+moc_binary.cpp: binary.h
+ $(MOC) binary.h -o moc_binary.cpp
+
diff --git a/noncore/tools/calc2/binary/README b/noncore/tools/calc2/binary/README
new file mode 100644
index 0000000..4937038
--- a/dev/null
+++ b/noncore/tools/calc2/binary/README
@@ -0,0 +1 @@
+A binary interface with bitwise operations
diff --git a/noncore/tools/calc2/binary/binary.pro b/noncore/tools/calc2/binary/binary.pro
new file mode 100644
index 0000000..01ba6a4
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binary.pro
@@ -0,0 +1,16 @@
+TEMPLATE = lib
+CONFIG -= moc
+CONFIG += qt release
+
+# Input
+INTERFACES += binary.ui
+HEADERS = binaryimpl.h \
+ binaryfactory.h
+SOURCES = binaryimpl.cpp \
+ binaryfactory.cpp
+
+INCLUDEPATH += $(QPEDIR)/include \
+ $(QPEDIR)/calc2
+DEPENDPATH += $(QPEDIR)/include
+
+DESTDIR = $(QPEDIR)/plugins/calculator
diff --git a/noncore/tools/calc2/binary/binary.ui b/noncore/tools/calc2/binary/binary.ui
new file mode 100644
index 0000000..26064d1
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binary.ui
@@ -0,0 +1,177 @@
+<!DOCTYPE UI><UI>
+<class>FormBinary</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>FormBinary</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>332</width>
+ <height>114</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Binary</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB0</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB1</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>1</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBAnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>AND</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBOr</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>OR</string>
+ </property>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBNot</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>NOT</string>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBSHL</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;-</string>
+ </property>
+ </widget>
+ <widget row="0" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBXor</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>XOR</string>
+ </property>
+ </widget>
+ <widget row="1" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBSHR</cstring>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>-&gt;</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+</UI>
diff --git a/noncore/tools/calc2/binary/binaryfactory.cpp b/noncore/tools/calc2/binary/binaryfactory.cpp
new file mode 100644
index 0000000..110334f
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binaryfactory.cpp
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "binaryfactory.h"
+#include "binaryimpl.h"
+#include <engine.h>
+
+QWidget *BinaryInterface::getPlugin ( Engine *e, QWidget *parent ) {
+ if ( !input )
+ input = new FormBinaryImpl ( e, parent );
+ return input;
+}
+
+#ifndef QT_NO_COMPONENT
+QRESULT BinaryInterface::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_Calc )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( BinaryInterface )
+}
+#endif
diff --git a/noncore/tools/calc2/binary/binaryfactory.h b/noncore/tools/calc2/binary/binaryfactory.h
new file mode 100644
index 0000000..e015384
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binaryfactory.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef BINARYIMPL_H
+#define BINARYIMPL_H
+
+#include "binaryimpl.h"
+#include <plugininterface.h>
+#include <engine.h>
+
+class BinaryInterface : public CalcInterface
+{
+public:
+ BinaryInterface(){input = 0;};
+ virtual ~BinaryInterface(){};
+
+#ifndef QT_NO_COMPONENT
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+#endif
+
+ QWidget *getPlugin( Engine *, QWidget *parent );
+
+private:
+ FormBinaryImpl *input;
+ ulong ref;
+};
+
+#endif
diff --git a/noncore/tools/calc2/binary/binaryimpl.cpp b/noncore/tools/calc2/binary/binaryimpl.cpp
new file mode 100644
index 0000000..ffc56ad
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binaryimpl.cpp
@@ -0,0 +1,110 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "binaryimpl.h"
+#include <instruction.h>
+
+class iXOR : public Instruction {
+public:
+ iXOR():Instruction(){};
+ ~iXOR(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = num.i ^ acc.i;
+ return result;
+ };
+};
+class iAND : public Instruction {
+public:
+ iAND():Instruction(){};
+ ~iAND(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = num.i & acc.i;
+ return result;
+ };
+};
+class iNOT : public Instruction {
+public:
+ iNOT():Instruction(){};
+ ~iNOT(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = ~ num.i;
+ return result;
+ };
+};
+class iOR : public Instruction {
+public:
+ iOR():Instruction(){};
+ ~iOR(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = num.i | acc.i;
+ return result;
+ };
+};
+class iLSH : public Instruction {
+public:
+ iLSH():Instruction(){};
+ ~iLSH(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = num.i << 1;
+ return result;
+ };
+};
+class iRSH : public Instruction {
+public:
+ iRSH():Instruction(){};
+ ~iRSH(){};
+ Data eval(Data num) {
+ Data result;
+ result.i = num.i >> 1;
+ return result;
+ };
+};
+
+void FormBinaryImpl::val0Clicked() {
+ engine->pushValue('0');
+}
+
+void FormBinaryImpl::val1Clicked() {
+ engine->pushValue('1');
+}
+
+void FormBinaryImpl::XORClicked() {
+ engine->pushInstruction(new iXOR());
+}
+void FormBinaryImpl::ANDClicked() {
+ engine->pushInstruction(new iAND());
+}
+void FormBinaryImpl::NOTClicked() {
+ engine->immediateInstruction(new iNOT());
+}
+void FormBinaryImpl::ORClicked() {
+ engine->pushInstruction(new iOR());
+}
+void FormBinaryImpl::LSHClicked() {
+ engine->immediateInstruction(new iLSH());
+}
+void FormBinaryImpl::RSHClicked() {
+ engine->immediateInstruction(new iRSH());
+}
diff --git a/noncore/tools/calc2/binary/binaryimpl.h b/noncore/tools/calc2/binary/binaryimpl.h
new file mode 100644
index 0000000..bf9e3a7
--- a/dev/null
+++ b/noncore/tools/calc2/binary/binaryimpl.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef FORMBINARYINPUTIMPL
+#define FORMBINARYINPUTIMPL
+
+#include "binary.h"
+#include <engine.h>
+
+class FormBinaryImpl : public FormBinary {
+Q_OBJECT
+public:
+ FormBinaryImpl(Engine *e,QWidget *p) : FormBinary (p,"Binary") {
+ engine = e;
+ engine->setRepresentation(rBin);
+ };
+ ~FormBinaryImpl(){};
+private:
+ Engine *engine;
+
+private slots:
+ void val0Clicked();
+ void val1Clicked();
+
+ void XORClicked();
+ void ANDClicked();
+ void NOTClicked();
+ void ORClicked();
+
+ void LSHClicked();
+ void RSHClicked();
+};
+
+#endif
diff --git a/noncore/tools/calc2/calc.cpp b/noncore/tools/calc2/calc.cpp
new file mode 100644
index 0000000..883ab33
--- a/dev/null
+++ b/noncore/tools/calc2/calc.cpp
@@ -0,0 +1,104 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qvaluelist.h>
+#include <qpe/qpeapplication.h>
+#include <qdir.h>
+#include <qwidgetstack.h>
+
+#include "calc.h"
+#include "plugininterface.h"
+
+calc::calc (QWidget * p = 0, const char *n = 0):QWidget (p, n)
+{
+ setCaption (tr ("Calculator"));
+
+// widgets
+ LCD = new QLCDNumber (this);
+ LCD->setMaximumSize (QSize (240, 30));
+ LCD->setNumDigits(12);
+LCD->setSegmentStyle(QLCDNumber::Filled);
+ pluginWidgetStack = new QWidgetStack (this);
+
+// layout widgets
+ calculatorLayout = new QVBoxLayout (this);
+ calculatorLayout->addWidget (LCD);
+ calculatorLayout->addWidget (pluginWidgetStack);
+
+// no formatting of display for now
+ connect (&engine, SIGNAL(display (double)), LCD, SLOT(display (double)));
+ connect (&engine, SIGNAL(display (const QString &)), LCD, SLOT(display (const QString &)));
+ connect (&engine, SIGNAL(setBinMode()), LCD, SLOT(setBinMode()));
+ connect (&engine, SIGNAL(setOctMode()), LCD, SLOT(setOctMode()));
+ connect (&engine, SIGNAL(setDecMode()), LCD, SLOT(setDecMode()));
+ connect (&engine, SIGNAL(setHexMode()), LCD, SLOT(setHexMode()));
+
+#ifndef NO_PLUGINS
+// load plugins
+ QValueList < Plugin >::Iterator mit;
+ for (mit = pluginList.begin (); mit != pluginList.end (); ++mit) {
+ (*mit).interface->release ();
+ (*mit).library->unload ();
+ delete (*mit).library;
+ }
+ pluginList.clear ();
+
+ QString path = QPEApplication::qpeDir() + "/plugins/calculator";
+ QDir dir (path, "lib*.so");
+ QStringList list = dir.entryList ();
+
+ QStringList::Iterator it;
+ for (it = list.begin (); it != list.end (); ++it) {
+ CalcInterface *iface = 0;
+ QLibrary *lib = new QLibrary (path + "/" + *it);
+
+ Plugin plugin;
+ plugin.pluginWidget = 0;
+
+ if (lib->queryInterface (IID_Calc, (QUnknownInterface **) & iface) ==
+ QS_OK) {
+ plugin.library = lib;
+ plugin.interface = iface;
+ plugin.pluginWidget = plugin.interface->getPlugin(&engine,pluginWidgetStack);
+ if (plugin.pluginWidget)
+ pluginWidgetStack->addWidget (plugin.pluginWidget, pluginList.count());
+ pluginList.append (plugin);
+ } else {
+ delete lib;
+ }
+ }
+ setMode (1);
+#else
+// load simple interface
+#endif
+}
+
+calc::~calc ()
+{
+#ifndef NO_PLUGINS
+ QValueList < Plugin >::Iterator mit;
+ for (mit = pluginList.begin (); mit != pluginList.end (); ++mit) {
+ (*mit).interface->release ();
+ (*mit).library->unload ();
+ delete (*mit).library;
+ }
+#endif
+}
+
diff --git a/noncore/tools/calc2/calc.h b/noncore/tools/calc2/calc.h
new file mode 100644
index 0000000..b52356d
--- a/dev/null
+++ b/noncore/tools/calc2/calc.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef CALC_H
+#define CALC_H
+
+#ifdef QT_NO_COMPONENT
+#define NO_PLUGINS
+#endif
+
+#include <qlayout.h>
+#include <qwidgetstack.h>
+
+#ifndef NO_PLUGINS
+#include <qvaluelist.h>
+#include <qpe/qlibrary.h>
+#endif
+
+#include "engine.h"
+#include "plugininterface.h"
+
+struct Plugin {
+#ifndef NO_PLUGINS
+ QLibrary *library;
+#endif
+ QWidget *pluginWidget;
+ CalcInterface *interface;
+ QString name;
+};
+
+class calc:public QWidget {
+
+Q_OBJECT
+public:
+ calc (QWidget * p = 0, const char *n = 0);
+ ~calc ();
+
+private:
+#ifndef NO_PLUGINS
+ void loadPlugins ();
+ QValueList < Plugin > pluginList;
+#endif
+ QVBoxLayout *calculatorLayout;
+ QWidgetStack *pluginWidgetStack;
+ QLCDNumber *LCD;
+ Engine engine;
+
+public slots:
+ void setMode(int m){pluginWidgetStack->raiseWidget(m);};
+};
+
+#endif
diff --git a/noncore/tools/calc2/calc.pro b/noncore/tools/calc2/calc.pro
new file mode 100644
index 0000000..c10232a
--- a/dev/null
+++ b/noncore/tools/calc2/calc.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+CONFIG += qt release
+
+# Input
+HEADERS += calc.h plugininterface.h instruction.h engine.h stdinstructions.h
+SOURCES += calc.cpp main.cpp engine.cpp
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe -Wl,-export-dynamic
+
diff --git a/noncore/tools/calc2/engine.cpp b/noncore/tools/calc2/engine.cpp
new file mode 100644
index 0000000..a9a47c4
--- a/dev/null
+++ b/noncore/tools/calc2/engine.cpp
@@ -0,0 +1,214 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "engine.h"
+#include <qstring.h>
+#include <math.h>
+#include <qlcdnumber.h>
+
+Data Engine::evalStack (Data num, bool inbrace = FALSE)
+{
+ if (state != sError) {
+ Instruction *i;
+
+// Pop the next op from the stack
+ while (!stack.isEmpty () && (braces || !inbrace)) {
+ i = stack.pop ();
+
+// Check this ops prec vs next ops prec
+ if (!stack.isEmpty ())
+ if (i->precedence <= stack.top()->precedence)
+ i->acc = evalStack (i->acc, inbrace);
+
+// Evaluate this instruction
+ num = i->eval (num);
+
+// Error-check ( change this to work for all types )
+ if (isnan (num.dbl) || isinf (num.dbl)) {
+ qDebug ("bad result from operation");
+ state = sError;
+ clearData(&num);
+ return num;
+ }
+ }
+ }
+ return num;
+}
+
+// Plugins call this to request the stack be evaluated
+void Engine::eval ()
+{
+ num = evalStack (num);
+ if (state != sError) {
+ displayData(num);
+ state = sStart;
+ }
+// if the user didnt close all their braces, its no big deal
+ braces = 0;
+}
+
+void Engine::immediateInstruction (Instruction * i)
+{
+ if (state != sError) {
+ i->setRep(currentRep);
+ num = i->eval (num);
+ displayData(num);
+ state = sStart;
+ }
+}
+
+void Engine::pushInstruction (Instruction * i)
+{
+ if (state != sError) {
+ i->setRep(currentRep);
+ i->acc = num;
+ stack.push (i);
+ state = sStart;
+ }
+}
+
+void Engine::pushValue (char v)
+{
+ if (state == sAppend) {
+ bool ok = FALSE;
+ switch (currentRep) {
+ case rDouble:
+ displayString.append(v);
+ num.dbl=displayString.toDouble(&ok);
+ break;
+ case rFraction:
+ break;
+ default:
+ displayString.append(v);
+ num.i=displayString.toInt(&ok, calcBase());
+ };
+ if (!ok) {
+ state = sError;
+ qDebug("pushValue() - num->string conversion");
+ } else {
+ const QString constString = displayString;
+ emit(display(constString));
+ };
+
+ } else if (state == sStart) {
+ softReset();
+ displayString.truncate(0);
+ state = sAppend;
+ pushValue (v);
+ } else if (state == sError) {
+ qDebug ("in error state");
+ return;
+ }
+}
+
+void Engine::del ()
+{
+ bool ok;
+ switch (currentRep) {
+ case rDouble:
+ displayString.truncate(displayString.length());
+ num.dbl=displayString.toDouble(&ok);
+ break;
+ case rFraction:
+ qDebug("not available");
+ break;
+ default:
+ displayString.truncate(displayString.length());
+ num.i = displayString.toInt(&ok, calcBase());
+ };
+
+ if (!ok) {
+ state = sError;
+ qDebug("del() - num->string conversion");
+ } else {
+ const QString constString = displayString;
+ emit(display(constString));
+ };
+}
+
+void Engine::displayData(Data d) {
+ switch (currentRep) {
+ case rDouble:
+ displayString.setNum(d.dbl);
+ break;
+ case rFraction:
+ qDebug("fractional display not yet impl");
+ break;
+ default:
+ displayString.setNum(d.i, calcBase());
+ break;
+ };
+ const QString constString= displayString;
+ emit(display(constString));
+}
+
+// Returns the base when Rep is an integer type
+int Engine::calcBase () {
+ switch (currentRep) {
+ case rBin:
+ return 2;
+ case rOct:
+ return 8;
+ case rDec:
+ return 10;
+ case rHex:
+ return 16;
+ default:
+ state = sError;
+ qDebug("Error - attempt to calc base for non-integer");
+ return 10;
+ };
+}
+
+// Special instruction for internal use only
+class iOpenBrace:public Instruction {
+ public:
+ iOpenBrace (Engine *e):Instruction (100) {engine = e;};
+ ~iOpenBrace () {};
+
+ Data eval (Data num) {
+ engine->decBraces();
+ return num;
+ };
+ private:
+ Engine *engine;
+};
+
+void Engine::openBrace() {
+ pushInstruction(new iOpenBrace(this));
+}
+
+void Engine::closeBrace() {
+ braces++;evalStack(num,TRUE);
+}
+
+// will need to show and hide display widgets
+void Engine::setRepresentation(Representation r) {
+ currentRep = r;
+ clearData(&num);
+ clearData(&mem);
+ state = sStart;
+}
+
+void Engine::clearData(Data *d) {
+ d->i = d->fraction.numerator = d->fraction.denominator = 0;
+ d->dbl = 0;
+}
+
diff --git a/noncore/tools/calc2/engine.h b/noncore/tools/calc2/engine.h
new file mode 100644
index 0000000..15c9aa1
--- a/dev/null
+++ b/noncore/tools/calc2/engine.h
@@ -0,0 +1,111 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef ENGINE_H
+#define ENGINE_H
+
+#include <qwidget.h>
+#include <qstack.h> // Instruction stack
+#include <qstring.h> // Display
+#include "instruction.h"
+
+// Possible states
+enum State {
+ sStart, // start inputting a new number
+ sAppend, // continue inputting a number
+ sError
+};
+
+// State machine
+class Engine:public QWidget {
+
+Q_OBJECT
+public:
+ Engine (QWidget * parent = 0, const char *name = 0):QWidget (parent, name) {
+ hardReset();
+ setRepresentation(rDec);
+ };
+
+ ~Engine () { };
+
+ void immediateInstruction (Instruction *);
+ void pushInstruction (Instruction *);
+ void eval ();
+
+ void pushValue (char);
+ void del ();
+
+ void openBrace ();
+ void closeBrace ();
+
+ void softReset () { // clears the number being inputted
+ decimalPlaces = -1;
+ clearData(&num);
+ displayData(num);
+ state = sStart;
+ };
+ void hardReset () { // a "real" reset of the stack
+ stack.clear ();
+ memClear();
+ braces = 0;
+ softReset ();
+ };
+
+ void memSave () {
+ mem = num;
+ };
+ void memRecall () {
+ num = mem;
+ state = sStart;
+ displayData(num);
+ };
+ void memClear () {
+ clearData(&mem);
+ };
+
+ // rFraction will require a special display enabled here
+ void setRepresentation(Representation);
+
+ // you dont want to call this
+ void decBraces(void){ braces--; };
+
+private:
+ void displayData(Data d);
+ void clearData(Data *d);
+ int calcBase();
+ Data evalStack (Data, bool);
+ Data num,mem;
+ State state;
+ QStack < Instruction > stack;
+ Representation currentRep;
+ int braces, decimalPlaces; // count of finishing 0's in num
+ QString displayString; // saves instatiating it over and over
+
+signals:
+ void display(const QString &);
+ void display(double); // could get rid of this and
+ // use a QLabel instead.
+ void setHexMode();
+ void setBinMode();
+ void setDecMode();
+ void setOctMode();
+};
+
+#endif
diff --git a/noncore/tools/calc2/instruction.h b/noncore/tools/calc2/instruction.h
new file mode 100644
index 0000000..6077bf0
--- a/dev/null
+++ b/noncore/tools/calc2/instruction.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef INSTRUCTION_H
+#define INSTRUCTION_H
+
+/* Internal representation of data
+The first four types indicate an int,
+that is, Data.i, and are incompatible
+with the other two types.
+
+- Plugin is responsible for telling engine
+which Rep to use at any given time
+- Instructions from that plugin only
+have to handle that representation
+- Engine is responsible for error-checking
+according to its current rep and display */
+enum Representation {
+ rBin,
+ rOct,
+ rDec,
+ rHex,
+ rDouble,
+ rFraction
+};
+
+// An atom of data
+union Data {
+ int i;
+ double dbl;
+ struct Fraction {
+ int numerator, denominator;
+ } fraction;
+};
+
+// Instruction base class
+class Instruction {
+public:
+ Instruction (int p = 0) {
+ precedence = p;
+ };
+
+ virtual ~ Instruction () {};
+
+ virtual Data eval(Data) = 0;
+ void setRep(Representation r) { rep = r; };
+
+ Representation rep;
+ Data acc;
+ int precedence;
+};
+
+#endif
diff --git a/noncore/tools/calc2/main.cpp b/noncore/tools/calc2/main.cpp
new file mode 100644
index 0000000..ebfcc28
--- a/dev/null
+++ b/noncore/tools/calc2/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#include "calc.h"
+
+int main (int argc, char **argv)
+{
+ QPEApplication a (argc, argv);
+
+ calc mw;
+
+ QPEApplication::setInputMethodHint (&mw, QPEApplication::AlwaysOff);
+ mw.setCaption (calc::tr ("Calculator"));
+ a.showMainWidget (&mw);
+
+ return a.exec ();
+}
diff --git a/noncore/tools/calc2/plugininterface.h b/noncore/tools/calc2/plugininterface.h
new file mode 100644
index 0000000..df6db9d
--- a/dev/null
+++ b/noncore/tools/calc2/plugininterface.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef CALCINTERFACE_H
+#define CALCINTERFACE_H
+
+#include <qnamespace.h>
+#include <qstring.h>
+#include <qlcdnumber.h>
+#include <qpe/qcom.h>
+
+#include "engine.h"
+
+#ifndef QT_NO_COMPONENT
+// {3CE88B66-B3FD-4580-9D04-77338A31A667}
+#ifndef IID_Calc
+#define IID_Calc QUuid( 0x3ce88b66, 0xb3fd, 0x4580, 0x9d, 0x04, 0x77, 0x33, 0x8a, 0x31, 0xa6, 0x67)
+#endif
+#endif
+
+class QWidget;
+class QObject;
+
+struct CalcInterface:public QUnknownInterface {
+ virtual QWidget *getPlugin (Engine *e, QWidget * parent) = 0;
+};
+
+#endif
diff --git a/noncore/tools/calc2/simple/README b/noncore/tools/calc2/simple/README
new file mode 100644
index 0000000..37acb64
--- a/dev/null
+++ b/noncore/tools/calc2/simple/README
@@ -0,0 +1 @@
+A simple interface with no operator precedence.
diff --git a/noncore/tools/calc2/simple/simple.pro b/noncore/tools/calc2/simple/simple.pro
new file mode 100644
index 0000000..92378a6
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simple.pro
@@ -0,0 +1,14 @@
+TEMPLATE = lib
+CONFIG -= moc
+CONFIG += qt release
+
+# Input
+INTERFACES += simple.ui
+HEADERS = simpleimpl.h simplefactory.h stdinstructions.h
+SOURCES = simpleimpl.cpp simplefactory.cpp
+
+INCLUDEPATH += $(QPEDIR)/include \
+ $(QPEDIR)/calc2
+DEPENDPATH += $(QPEDIR)/include
+
+DESTDIR = $(QPEDIR)/plugins/calculator
diff --git a/noncore/tools/calc2/simple/simple.ui b/noncore/tools/calc2/simple/simple.ui
new file mode 100644
index 0000000..af12905
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simple.ui
@@ -0,0 +1,704 @@
+<!DOCTYPE UI><UI>
+<class>FormSimple</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>FormSimple</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>73</x>
+ <y>0</y>
+ <width>240</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>240</width>
+ <height>320</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>baseSize</name>
+ <size>
+ <width>240</width>
+ <height>240</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Simple</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="4" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBEval</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>160</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>=</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB5</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>5</string>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBDecimal</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>.</string>
+ </property>
+ </widget>
+ <widget row="3" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>3</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>2</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB4</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>4</string>
+ </property>
+ </widget>
+ <widget row="2" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB6</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>6</string>
+ </property>
+ </widget>
+ <widget row="3" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBMul</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>*</string>
+ </property>
+ </widget>
+ <widget row="2" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBSub</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>-</string>
+ </property>
+ </widget>
+ <widget row="1" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBAdd</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>+</string>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB9</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>9</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB7</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>7</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>1</string>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB0</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>160</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0</string>
+ </property>
+ </widget>
+ <widget row="4" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBDiv</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>/</string>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PB8</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>8</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBMPlus</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>M+</string>
+ </property>
+ </widget>
+ <widget row="0" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBCE</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>CE</string>
+ </property>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBMC</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MC</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PBMR</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>80</width>
+ <height>80</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MR</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>PB0</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val0Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB1</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val1Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB2</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val2Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB3</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val3Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB4</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val4Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB5</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val5Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB6</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val6Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB7</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val7Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB8</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val8Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PB9</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>val9Clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBSub</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>subClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBMul</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>mulClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBDiv</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>divClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBDecimal</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>decimalClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBEval</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>evalClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBMC</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>MCClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBMPlus</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>MPlusClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBMR</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>MRClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>addClicked()</slot>
+ </connection>
+ <connection>
+ <sender>PBCE</sender>
+ <signal>clicked()</signal>
+ <receiver>FormSimple</receiver>
+ <slot>CEClicked()</slot>
+ </connection>
+ <slot access="public">CEClicked()</slot>
+ <slot access="public">MCClicked()</slot>
+ <slot access="public">MPlusClicked()</slot>
+ <slot access="public">MRClicked()</slot>
+ <slot access="public">addClicked()</slot>
+ <slot access="public">decimalClicked()</slot>
+ <slot access="public">divClicked()</slot>
+ <slot access="public">evalClicked()</slot>
+ <slot access="public">mulClicked()</slot>
+ <slot access="public">subClicked()</slot>
+ <slot access="public">val0Clicked()</slot>
+ <slot access="public">val1Clicked()</slot>
+ <slot access="public">val2Clicked()</slot>
+ <slot access="public">val3Clicked()</slot>
+ <slot access="public">val4Clicked()</slot>
+ <slot access="public">val5Clicked()</slot>
+ <slot access="public">val6Clicked()</slot>
+ <slot access="public">val7Clicked()</slot>
+ <slot access="public">val8Clicked()</slot>
+ <slot access="public">val9Clicked()</slot>
+</connections>
+</UI>
diff --git a/noncore/tools/calc2/simple/simplefactory.cpp b/noncore/tools/calc2/simple/simplefactory.cpp
new file mode 100644
index 0000000..515418f
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simplefactory.cpp
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "simplefactory.h"
+#include "simpleimpl.h"
+#include <engine.h>
+
+QWidget *SimpleInterface::getPlugin ( Engine *e, QWidget *parent ) {
+ if ( !input )
+ input = new FormSimpleImpl ( e, parent );
+ return input;
+}
+
+#ifndef QT_NO_COMPONENT
+QRESULT SimpleInterface::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_Calc )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( SimpleInterface )
+}
+#endif
diff --git a/noncore/tools/calc2/simple/simplefactory.h b/noncore/tools/calc2/simple/simplefactory.h
new file mode 100644
index 0000000..e1022fd
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simplefactory.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef BINARYIMPL_H
+#define BINARYIMPL_H
+
+#include "simpleimpl.h"
+#include <plugininterface.h>
+#include <engine.h>
+
+class SimpleInterface : public CalcInterface
+{
+public:
+ SimpleInterface(){input = 0;};
+ virtual ~SimpleInterface(){};
+
+#ifndef QT_NO_COMPONENT
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+#endif
+
+ QWidget *getPlugin( Engine *, QWidget *parent );
+
+private:
+ FormSimpleImpl *input;
+ ulong ref;
+};
+
+#endif
diff --git a/noncore/tools/calc2/simple/simpleimpl.cpp b/noncore/tools/calc2/simple/simpleimpl.cpp
new file mode 100644
index 0000000..f71f000
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simpleimpl.cpp
@@ -0,0 +1,120 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpushbutton.h>
+#include <qlcdnumber.h>
+
+#include "simpleimpl.h"
+#include <stdinstructions.h>
+
+void FormSimpleImpl::CEClicked() {
+ engine->hardReset();
+}
+
+void FormSimpleImpl::MCClicked() {
+ engine->memClear();
+}
+
+void FormSimpleImpl::MRClicked() {
+ engine->memRecall();
+}
+
+void FormSimpleImpl::MPlusClicked() {
+ engine->memSave();
+}
+
+void FormSimpleImpl::evalClicked() {
+ engine->eval();
+}
+
+void FormSimpleImpl::addClicked ()
+{
+ engine->pushInstruction (new iAdd ());
+}
+
+void FormSimpleImpl::subClicked ()
+{
+ engine->pushInstruction (new iSub ());
+}
+
+void FormSimpleImpl::mulClicked ()
+{
+ engine->pushInstruction (new iMul ());
+}
+
+void FormSimpleImpl::divClicked ()
+{
+ engine->pushInstruction (new iDiv ());
+}
+
+void FormSimpleImpl::decimalClicked ()
+{
+ engine->pushValue ('.');
+}
+
+void FormSimpleImpl::val1Clicked ()
+{
+ engine->pushValue ('1');
+}
+
+void FormSimpleImpl::val2Clicked ()
+{
+ engine->pushValue ('2');
+}
+
+void FormSimpleImpl::val3Clicked ()
+{
+ engine->pushValue ('3');
+}
+
+void FormSimpleImpl::val4Clicked ()
+{
+ engine->pushValue ('4');
+}
+
+void FormSimpleImpl::val5Clicked ()
+{
+ engine->pushValue ('5');
+}
+
+void FormSimpleImpl::val6Clicked ()
+{
+ engine->pushValue ('6');
+}
+
+void FormSimpleImpl::val7Clicked ()
+{
+ engine->pushValue ('7');
+}
+
+void FormSimpleImpl::val8Clicked ()
+{
+ engine->pushValue ('8');
+}
+
+void FormSimpleImpl::val9Clicked ()
+{
+ engine->pushValue ('9');
+}
+
+void FormSimpleImpl::val0Clicked ()
+{
+ engine->pushValue ('0');
+}
diff --git a/noncore/tools/calc2/simple/simpleimpl.h b/noncore/tools/calc2/simple/simpleimpl.h
new file mode 100644
index 0000000..a2db154
--- a/dev/null
+++ b/noncore/tools/calc2/simple/simpleimpl.h
@@ -0,0 +1,65 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef STANDARDIMPL_H
+#define STANDARDIMPL_H
+
+#include <qpe/qmath.h>
+#include <qlcdnumber.h>
+
+#include "simple.h"
+#include "engine.h"
+#include "instruction.h"
+
+class FormSimpleImpl:public FormSimple {
+Q_OBJECT
+public:
+ FormSimpleImpl (Engine *e, QWidget * parent = 0, const char *name = 0)
+ :FormSimple (parent, name) {engine = e;engine->setRepresentation(rDouble);};
+
+ ~FormSimpleImpl () { };
+
+private:
+ Engine *engine;
+
+private slots:
+ void MPlusClicked();
+ void MCClicked();
+ void MRClicked();
+ void CEClicked();
+ void evalClicked();
+ void addClicked ();
+ void decimalClicked ();
+ void divClicked ();
+ void mulClicked ();
+ void subClicked ();
+ void val0Clicked ();
+ void val1Clicked ();
+ void val2Clicked ();
+ void val3Clicked ();
+ void val4Clicked ();
+ void val5Clicked ();
+ void val6Clicked ();
+ void val7Clicked ();
+ void val8Clicked ();
+ void val9Clicked ();
+};
+
+#endif
diff --git a/noncore/tools/calc2/stdinstructions.h b/noncore/tools/calc2/stdinstructions.h
new file mode 100644
index 0000000..a575968
--- a/dev/null
+++ b/noncore/tools/calc2/stdinstructions.h
@@ -0,0 +1,125 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef STDINSTRUCTION_H
+#define STDINSTRUCTION_H
+
+#include <qpe/qmath.h>
+#include "instruction.h"
+
+// Useful instructions for plugin writers
+// If you use them, take note of their precedence
+class iAdd:public Instruction {
+public:
+ iAdd ():Instruction (10) { };
+ ~iAdd () { };
+ Data eval (Data num) {
+ Data result;
+ switch (rep) {
+ case rDouble:
+ result.dbl = acc.dbl + num.dbl;
+ break;
+ default:
+ result.i = acc.i + num.i;
+ };
+ return result;
+ };
+};
+class iSub:public Instruction {
+public:
+ iSub ():Instruction (10) { };
+ ~iSub () { };
+ Data eval (Data num) {
+ Data result;
+ switch (rep) {
+ case rDouble:
+ result.dbl = acc.dbl - num.dbl;
+ break;
+ default:
+ result.i = acc.i - num.i;
+ };
+ return result;
+ };
+};
+class iMul:public Instruction {
+public:
+ iMul ():Instruction (20) { };
+ ~iMul () { };
+ Data eval (Data num) {
+ Data result;
+ switch (rep) {
+ case rDouble:
+ result.dbl = acc.dbl * num.dbl;
+ break;
+ default:
+ result.i = acc.i * num.i;
+ };
+ return result;
+ };
+};
+class iDiv:public Instruction {
+public:
+ iDiv ():Instruction (20) { };
+ ~iDiv () { };
+ Data eval (Data num) {
+ Data result;
+ switch (rep) {
+ case rDouble:
+ result.dbl = acc.dbl / num.dbl;
+ break;
+ default:
+ result.i = acc.i / num.i;
+ };
+ return result;
+ };
+};
+
+// Immediate double instructions only
+class iSin:public Instruction {
+public:
+ iSin ():Instruction () { };
+ ~iSin () { };
+ Data eval (Data num) {
+ Data result;
+ result.dbl = qSin(num.dbl);
+ return result;
+ };
+};
+class iCos:public Instruction {
+public:
+ iCos ():Instruction () { };
+ ~iCos () { };
+ Data eval (Data num) {
+ Data result;
+ result.dbl = qCos(num.dbl);
+ return result;
+ };
+};
+class iTan:public Instruction {
+public:
+ iTan ():Instruction () { };
+ ~iTan () {};
+ Data eval (Data num) {
+ Data result;
+ result.dbl = qTan(num.dbl);
+ return result;
+ };
+};
+#endif
diff --git a/noncore/tools/calculator/.cvsignore b/noncore/tools/calculator/.cvsignore
new file mode 100644
index 0000000..f5bf2df
--- a/dev/null
+++ b/noncore/tools/calculator/.cvsignore
@@ -0,0 +1,4 @@
+moc_*
+Makefile
+calculator.h
+calculator.cpp
diff --git a/noncore/tools/calculator/Makefile.in b/noncore/tools/calculator/Makefile.in
new file mode 100644
index 0000000..d62b046
--- a/dev/null
+++ b/noncore/tools/calculator/Makefile.in
@@ -0,0 +1,139 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = calculator
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = calculatorimpl.h
+SOURCES = calculatorimpl.cpp \
+ main.cpp
+OBJECTS = calculatorimpl.o \
+ main.o \
+ calculator.o
+INTERFACES = calculator.ui
+UICDECLS = calculator.h
+UICIMPLS = calculator.cpp
+SRCMOC = moc_calculatorimpl.cpp \
+ moc_calculator.cpp
+OBJMOC = moc_calculatorimpl.o \
+ moc_calculator.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake calculator.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+calculatorimpl.o: calculatorimpl.cpp \
+ calculatorimpl.h \
+ calculator.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qmath.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+main.o: main.cpp \
+ calculatorimpl.h \
+ calculator.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+calculator.h: calculator.ui
+ $(UIC) calculator.ui -o calculator.h
+
+calculator.cpp: calculator.ui
+ $(UIC) calculator.ui -i calculator.h -o calculator.cpp
+
+calculator.o: calculator.cpp \
+ calculator.h \
+ calculator.ui
+
+moc_calculatorimpl.o: moc_calculatorimpl.cpp \
+ calculatorimpl.h \
+ calculator.h
+
+moc_calculator.o: moc_calculator.cpp \
+ calculator.h
+
+moc_calculatorimpl.cpp: calculatorimpl.h
+ $(MOC) calculatorimpl.h -o moc_calculatorimpl.cpp
+
+moc_calculator.cpp: calculator.h
+ $(MOC) calculator.h -o moc_calculator.cpp
+
+
diff --git a/noncore/tools/calculator/calculator.pro b/noncore/tools/calculator/calculator.pro
new file mode 100644
index 0000000..1281fd5
--- a/dev/null
+++ b/noncore/tools/calculator/calculator.pro
@@ -0,0 +1,13 @@
+DESTDIR = $(QPEDIR)/bin
+TEMPLATE = app
+CONFIG = qt warn_on release
+HEADERS = calculatorimpl.h
+SOURCES = calculatorimpl.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES = calculator.ui
+TARGET = calculator
+
+TRANSLATIONS = ../i18n/de/calculator.ts
diff --git a/noncore/tools/calculator/calculator.ui b/noncore/tools/calculator/calculator.ui
new file mode 100644
index 0000000..e8218ab
--- a/dev/null
+++ b/noncore/tools/calculator/calculator.ui
@@ -0,0 +1,1026 @@
+<!DOCTYPE UI><UI>
+<class>Calculator</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Calculator</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>271</width>
+ <height>404</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>baseSize</name>
+ <size>
+ <width>235</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Experimental Calculator</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLCDNumber</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LCD</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>7</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>numDigits</name>
+ <number>15</number>
+ </property>
+ <property stdset="1">
+ <name>segmentStyle</name>
+ <enum>Flat</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ComboBoxFunction</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonMPlus</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>M+</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonMR</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MR</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonMC</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MC</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonCE</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>CE</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout10</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF6</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF7</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF8</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>log</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF9</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>ln</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF11</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>(</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF12</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>)</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout11</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>sin</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>cos</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>tan</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF4</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF5</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>%</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonF10</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>+/-</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout5</cstring>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="2" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>3</string>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton6</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>6</string>
+ </property>
+ </widget>
+ <widget row="3" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonEquals</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>=</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton0</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0</string>
+ </property>
+ </widget>
+ <widget row="1" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonMinus</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>-</string>
+ </property>
+ </widget>
+ <widget row="2" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonTimes</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>x</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton4</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>4</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton8</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>8</string>
+ </property>
+ </widget>
+ <widget row="3" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonDivide</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>/</string>
+ </property>
+ </widget>
+ <widget row="0" column="3" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonAdd</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>+</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>1</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButtonDecimal</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>.</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton5</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>5</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton7</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>7</string>
+ </property>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton9</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>9</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <family>adobe-helvetica</family>
+ <pointsize>24</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>2</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>ComboBoxFunction</tabstop>
+ <tabstop>PushButtonMPlus</tabstop>
+ <tabstop>PushButtonMR</tabstop>
+ <tabstop>PushButtonMC</tabstop>
+ <tabstop>PushButtonCE</tabstop>
+ <tabstop>PushButtonF6</tabstop>
+ <tabstop>PushButtonF7</tabstop>
+ <tabstop>PushButtonF8</tabstop>
+ <tabstop>PushButtonF9</tabstop>
+ <tabstop>PushButtonF11</tabstop>
+ <tabstop>PushButtonF12</tabstop>
+ <tabstop>PushButtonF1</tabstop>
+ <tabstop>PushButtonF2</tabstop>
+ <tabstop>PushButtonF3</tabstop>
+ <tabstop>PushButtonF4</tabstop>
+ <tabstop>PushButtonF5</tabstop>
+ <tabstop>PushButtonF10</tabstop>
+ <tabstop>PushButton7</tabstop>
+ <tabstop>PushButton8</tabstop>
+ <tabstop>PushButton9</tabstop>
+ <tabstop>PushButtonAdd</tabstop>
+ <tabstop>PushButton4</tabstop>
+ <tabstop>PushButton5</tabstop>
+ <tabstop>PushButton6</tabstop>
+ <tabstop>PushButtonMinus</tabstop>
+ <tabstop>PushButton1</tabstop>
+ <tabstop>PushButton2</tabstop>
+ <tabstop>PushButton3</tabstop>
+ <tabstop>PushButtonTimes</tabstop>
+ <tabstop>PushButton0</tabstop>
+ <tabstop>PushButtonDecimal</tabstop>
+ <tabstop>PushButtonEquals</tabstop>
+ <tabstop>PushButtonDivide</tabstop>
+</tabstops>
+</UI>
diff --git a/noncore/tools/calculator/calculatorimpl.cpp b/noncore/tools/calculator/calculatorimpl.cpp
new file mode 100644
index 0000000..2f7d7ce
--- a/dev/null
+++ b/noncore/tools/calculator/calculatorimpl.cpp
@@ -0,0 +1,601 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "calculatorimpl.h"
+
+#include <qpe/resource.h>
+#include <qpe/qmath.h>
+#include <qpe/qpeapplication.h>
+
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qfont.h>
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qmessagebox.h>
+#include <math.h>
+
+CalculatorImpl::CalculatorImpl( QWidget * parent, const char * name,
+ WFlags f )
+ : Calculator( parent, name, f )
+{
+ xtopowerofy = Resource::loadPixmap("xtopowerofy");
+ ythrootofx = Resource::loadPixmap("ythrootofx");
+ oneoverx = Resource::loadPixmap("oneoverx");
+
+ memMark = new QLabel( "m", LCD );
+ memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) );
+ memMark->resize( 12, 12 );
+ memMark->move( 4, 2 );
+ memMark->hide();
+ mem = 0;
+
+ PushButtonMR->setEnabled( FALSE );
+
+ current_mode = max_mode = conversion_mode_count = 0;
+ last_conversion = -1;
+
+//bgr_command.insert( PushButtonFunction);
+ bgr_command.insert( PushButtonMPlus);
+ bgr_command.insert( PushButtonMR);
+ bgr_command.insert( PushButtonMC);
+ bgr_command.insert( PushButtonCE);
+ connect( &bgr_command, SIGNAL(clicked(int) ), this, SLOT(command_buttons(int)));
+
+ bgr_digits.insert(PushButton0);
+ bgr_digits.insert(PushButton1);
+ bgr_digits.insert(PushButton2);
+ bgr_digits.insert(PushButton3);
+ bgr_digits.insert(PushButton4);
+ bgr_digits.insert(PushButton5);
+ bgr_digits.insert(PushButton6);
+ bgr_digits.insert(PushButton7);
+ bgr_digits.insert(PushButton8);
+ bgr_digits.insert(PushButton9);
+ connect( &bgr_digits, SIGNAL(clicked(int) ), this, SLOT(enterNumber(int)));
+
+
+ bgr_std.insert(PushButtonEquals);
+ bgr_std.insert(PushButtonDecimal);
+ bgr_std.insert(PushButtonAdd);
+ bgr_std.insert(PushButtonMinus);
+ bgr_std.insert(PushButtonDivide);
+ bgr_std.insert(PushButtonTimes);
+ connect( &bgr_std, SIGNAL(clicked(int) ), this, SLOT(std_buttons(int)));
+
+// change the / to a proper division signal
+ PushButtonDivide->setText(QChar(0xF7));
+
+ func_buttons[0] = PushButtonF1;
+ func_buttons[1] = PushButtonF2;
+ func_buttons[2] = PushButtonF3;
+ func_buttons[3] = PushButtonF4;
+ func_buttons[4] = PushButtonF5;
+ func_buttons[5] = PushButtonF6;
+ func_buttons[6] = PushButtonF7;
+ func_buttons[7] = PushButtonF8;
+ func_buttons[8] = PushButtonF9;
+ func_buttons[9] = PushButtonF10;
+ func_buttons[10] = PushButtonF11;
+ func_buttons[11] = PushButtonF12;
+
+ for ( int x = 0 ; x < func_button_count ; x++ ) {
+ QPushButton* tmpbutton = func_buttons[x];
+ faces << tmpbutton->text();
+ bgr_function.insert(tmpbutton);
+ }
+ connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(do_convert(int) ) );
+ connect( &bgr_function, SIGNAL(clicked(int) ) , this, SLOT(std_funcs (int) ) );
+
+ connect(ComboBoxFunction, SIGNAL(activated(int) ), this, SLOT(function_button(int) ) );
+
+ captions.append("Standard");
+ ComboBoxFunction->insertItem(captions.last());
+
+ // now add in the conversion modes
+ // when the menu gets done, these should be in a submenu
+ QString tmp = QPEApplication::qpeDir();
+ tmp += "/etc/unit_conversion.dat";
+ QFile myfile(tmp);
+ if ( !myfile.open( IO_Translate | IO_ReadOnly ) ) {
+ // QMessageBox::warning(this, "Warning", "Data file\nunit_conversion.dat\nnot found\nNo conversion\nfeatures will\nbe available");
+ // disable the f button if no conv file available
+ ComboBoxFunction->setEnabled(FALSE);
+ }
+ else {
+ QString line, line2;
+ QTextStream ts(&myfile);
+
+ // first pass, see how many conversion types there are in order to allocate for them
+ while ( ! ts.eof() ) {
+ line = ts.readLine();
+ if ( line.contains ("STARTTYPE" ) )
+ conversion_mode_count++;
+ }
+
+ entry_list = new double[conversion_mode_count*func_button_count];
+
+ myfile.close();
+ myfile.open( IO_Translate | IO_ReadOnly );
+ QTextStream ts2(&myfile);
+
+ // second pass, read in values
+ int x = 0;
+ while ( ! ts2.eof() ) {
+ line = ts2.readLine();
+ if ( line.contains("STARTTYPE") ) {
+ captions << line.remove(0,10);
+ ComboBoxFunction->insertItem(captions.last());
+ while ( !line.contains("ENDTYPE") ) {
+ line = ts2.readLine();
+ if ( line.contains("NAME") ) {
+ faces << line.remove(0,5);
+ line2 = ts2.readLine();
+ line2.remove(0,6);
+ entry_list[x] = line2.toDouble();
+ x++;
+ }
+ }
+ }
+ }
+ }
+ myfile.close();
+ clear();
+ max_mode = pre_conv_modes_count + conversion_mode_count + post_conv_modes_count - 1;
+ display_pixmap_faces();
+
+ qApp->installEventFilter( this );
+}
+
+bool CalculatorImpl::eventFilter( QObject *o, QEvent *e )
+{
+ if ( e->type() == QEvent::KeyPress && state != sError ) {
+ QKeyEvent *k = (QKeyEvent*)e;
+ if ( k->key() >= Key_0 && k->key() <= Key_9 ) {
+ enterNumber( k->key() - Key_0 );
+ return true;
+ } else {
+ switch ( k->key() ) {
+ case Key_Equal:
+ std_buttons(0);
+ return true;
+ case Key_Period:
+ std_buttons(1);
+ return true;
+ case Key_Plus:
+ std_buttons(2);
+ return true;
+ case Key_Minus:
+ std_buttons(3);
+ return true;
+ case Key_Slash:
+ std_buttons(4);
+ return true;
+ case Key_Asterisk:
+ std_buttons(5);
+ return true;
+ case Key_Percent:
+ execOp( oPercent );
+ return true;
+ case Key_ParenLeft:
+ if ( current_mode < pre_conv_modes_count )
+ execOp( oOpenBrace );
+ return true;
+ case Key_ParenRight:
+ if ( current_mode < pre_conv_modes_count )
+ execOp( oCloseBrace );
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ return Calculator::eventFilter( o, e );
+}
+
+void CalculatorImpl::do_convert(int button) {
+ if ( state == sError )
+ return;
+ if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) &&
+ button < changeable_func_button_count ) {
+ if ( last_conversion > -1 ) {
+ if( state == sNewNumber ){
+ acc = num
+ / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
+ * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) ;
+ num = acc;
+ LCD->display( acc );
+ } else {
+ state = sNewNumber;
+ num = num
+ / (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + last_conversion])
+ * (entry_list[(current_mode - pre_conv_modes_count) * func_button_count + button]) ;
+ LCD->display( num );
+ acc = num;
+ }
+ }
+ last_conversion = button;
+ }
+}
+
+
+void CalculatorImpl::function_button(int mode){
+ if ( state == sError )
+ clear();
+ // dont need the next line when using a popup menu
+ current_mode = mode;
+
+ // reset the last conv
+ last_conversion = -1;
+
+ // set the caption
+ this->setCaption( captions[current_mode] );
+
+ reset_conv();
+
+ for ( int x = 0 ; x < changeable_func_button_count ; x++ ) {
+ QPushButton* tmpbutton = func_buttons[x];
+
+ // if its a conversion , make it a toggle button
+ if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) {
+ tmpbutton->setToggleButton(TRUE);
+ } else {
+ tmpbutton->setToggleButton(FALSE);
+ }
+ tmpbutton->setText( faces[current_mode * func_button_count + x] );
+ }
+
+ if ( current_mode == 0 ) display_pixmap_faces();
+
+ if ( current_mode >= pre_conv_modes_count && current_mode <= (max_mode - post_conv_modes_count) ) {
+ bgr_function.setExclusive(TRUE);
+ } else {
+ bgr_function.setExclusive(FALSE);
+ }
+}
+
+void CalculatorImpl::display_pixmap_faces() {
+ QPushButton* tmpbutton = func_buttons[5];
+ tmpbutton->setPixmap(xtopowerofy);
+
+ tmpbutton = func_buttons[6];
+ tmpbutton->setPixmap(ythrootofx);
+
+ tmpbutton = func_buttons[3];
+ tmpbutton->setPixmap(oneoverx);
+}
+
+void CalculatorImpl::clear() {
+ acc = num = 0;
+ operationStack.clear();
+ state = sStart;
+ numDecimals = 0;
+ numOpenBraces = 0;
+ flPoint = FALSE;
+ LCD->display( 0 );
+ fake = QString::null;
+
+ reset_conv();
+}
+
+void CalculatorImpl::reset_conv() {
+ for ( int x = 0 ; x < changeable_func_button_count ; x++ ) {
+ QPushButton* tmpbutton = func_buttons[x];
+
+ // dont carry any selections into the next mode
+ if ( tmpbutton->state() == QPushButton::On ) {
+ tmpbutton->toggle();
+ }
+ }
+
+ last_conversion = -1;
+}
+
+void CalculatorImpl::std_buttons(int button)
+{
+ if ( state == sError )
+ return;
+ execOp( (Operation)(button + oSum) );
+}
+
+void CalculatorImpl::std_funcs(int button) {
+ if ( state == sError )
+ return;
+ if ( current_mode < pre_conv_modes_count ||
+ button > changeable_func_button_count-1 ) {
+ Operation op;
+ if ( button < 10 )
+ op = (Operation)(button + oSin);
+ else if ( button == 10 )
+ op = oOpenBrace;
+ else
+ op = oCloseBrace;
+ execOp( op );
+ }
+}
+
+void CalculatorImpl::execOp( Operation i )
+{
+ switch (i) {
+ // these operators only affect the current number.
+ case oDivX:
+ case oLog:
+ case oLn:
+ case oSin:
+ case oCos:
+ case oTan:
+ num = evalExpr(i);
+ break;
+
+ case oAdd:
+ case oSub: {
+ processStack( oAdd );
+ Op op( num, i );
+ operationStack.push( op );
+ break;
+ }
+ case oDiv:
+ case oMult:
+ case oRoot:
+ case oXsquared: {
+ processStack( oDiv );
+ Op op( num, i );
+ operationStack.push( op );
+ break;
+ }
+ case oChSign:
+ num = -num;
+ LCD->display(num);
+ return;
+
+ case oOpenBrace: {
+ Op op( 0, oOpenBrace );
+ operationStack.push( op );
+ numOpenBraces++;
+ state = sNewNumber;
+ return;
+ }
+ case oCloseBrace: {
+ if ( numOpenBraces == 0 )
+ return;
+ processStack( oAdd );
+ if ( operationStack.top().operation != oOpenBrace )
+ qDebug( "Calculator: internal Error" );
+ operationStack.pop();
+ state = sNewNumber;
+ numOpenBraces--;
+ break;
+ }
+
+ case oPoint:
+ flPoint = TRUE;
+ return;
+
+ case oPercent:
+ processStack( oPercent );
+ break;
+
+
+ case oSum:
+ processStack( oSum );
+ break;
+
+ default:
+ return;
+ };
+
+ if ( state == sError ) {
+ LCD->display( "Error" );
+ return;
+ } else {
+ LCD->display(num);
+ }
+ state = sNewNumber;
+ numDecimals = 0;
+ flPoint = FALSE;
+}
+
+
+void CalculatorImpl::processStack( int op )
+{
+ //dubious percent hack, since the changeable operator precedences are
+ //pretty much hardwired to be less than the non-changeable
+ bool percent = FALSE;
+ if ( op == oPercent ) {
+ percent = TRUE;
+ op = oSum;
+ }
+ while( !operationStack.isEmpty() && operationStack.top().operation >= op ) {
+ Op operation = operationStack.pop();
+ acc = operation.number;
+ if ( percent ) {
+ if ( operation.operation == oAdd || operation.operation == oSub )
+ num = acc*num/100;
+ else
+ num = num / 100;
+ }
+ num = evalExpr( operation.operation );
+ percent = FALSE;
+ }
+}
+
+
+double CalculatorImpl::evalExpr( int op ) {
+ double sum = 0;
+
+ switch( op ){
+ case oPercent: sum = num / 100.; break;
+ case oDivX:
+ if (num == 0)
+ state = sError;
+ else
+ sum = 1 / num;
+ break;
+ case oXsquared:
+ sum = pow(acc,num);
+ break;
+ case oChSign: (state == sStart) ? sum = -num : sum = -acc; break;
+ case oSub: sum = acc - num; break;
+ case oMult: sum = acc * num; break;
+ case oAdd: sum = acc + num; break;
+ case oDiv: {
+ if (num == 0) {
+ state = sError;
+ } else {
+ sum = acc / num;
+ }
+ break;
+ }
+ case oRoot:
+ /* the linux library is dumb, and can't to -x to 1/n
+ when n is odd. (even and error of course is acceptable */
+ if((acc < 0) && (int(num) == num) && (int(num) % 2 == 1 )) {
+ sum = pow(-acc, 1 / num);
+ sum = -sum;
+ } else {
+ sum = pow(acc, 1 / num);
+ }
+ break;
+ case oLog:
+ sum = log10(num);
+ break;
+ case oLn:
+ sum = log(num);
+ break;
+ case oTan: sum = qTan(num);break;
+ case oSin: sum = qSin(num);break;
+ case oCos: sum = qCos(num);break;
+ default: sum = num; break;
+ }
+
+ if ( isinf( sum ) || isnan( sum ) )
+ state = sError;
+ return sum;
+}
+
+
+void CalculatorImpl::enterNumber( int n )
+{
+ if ( state == sError )
+ return;
+ if( state == sStart ){
+ if( LCD->value() > 0 ){
+ QString s = QString::number( LCD->value(), 'g', LCD->numDigits());
+ if( s.length() > (uint)(LCD->numDigits() - 2)) return;
+
+ } else if( (int)fake.length() >= LCD->numDigits() || numDecimals >=12 ){
+ return;
+ }
+ }
+
+ if( state == sNewNumber ){
+ state = sStart;
+ acc = 0;
+ if( flPoint ){
+ numDecimals = 1;
+ num = n / pow(10, numDecimals);
+ } else
+ num = n;
+ } else if( flPoint ){
+ numDecimals++;
+ if( num < 0 ){
+ num -= n / pow(10, numDecimals);
+ } else {
+ num += n / pow(10, numDecimals);
+ }
+ } else {
+ num *= 10;
+ if( num < 0 )
+ num -= n;
+ else
+ num += n;
+ }
+
+ // We need feedback in the calc display while entering fl.point zeros.
+ // This is a small hack to display sequences like: 0.000 and 1.100
+ double integer, fraction;
+ fraction = modf( num, &integer );
+ if( flPoint ){
+ QString is, fs, zeros;
+
+ is = QString::number( integer, 'g', 13 );
+ fs = QString::number( fraction, 'g', numDecimals );
+ if( fs.contains('e') ){
+ fs = QString::number( fraction, 'f', LCD->numDigits() );
+ }
+ fs = fs.mid( 2, numDecimals );
+
+ if( (integer == 0) && (fraction == 0) )
+ fake = "0.";
+ else if( (integer != 0) && (fraction == 0) )
+ fake = is + ".";
+ else
+ fake = is + "." + fs;
+
+ zeros.fill( '0', (numDecimals - fs.length()) );
+ fake += zeros;
+ // ### This code sets LCD->value() to zero since it sets a text
+ // ### Avoid getting the current value from LCD->value() for
+ // ### calculations.
+ LCD->display( fake );
+ } else
+ LCD->display( num );
+}
+
+void CalculatorImpl::command_buttons(int i) {
+ if ( state == sError && i != 3 )
+ return;
+ switch (i) {
+ case 0: // M+
+ mem += num;
+ if( mem != 0 ){
+ memMark->show();
+ PushButtonMR->setEnabled( TRUE ); };
+ state = sNewNumber;
+ break;
+ case 1: // MR
+ acc = num = mem;
+ state = sNewNumber;
+ LCD->display( mem );
+ break;
+ case 2: // MC
+ mem = 0;
+ memMark->hide();
+ PushButtonMR->setEnabled( FALSE );
+ break;
+ case 3: // CE
+ if ( state == sStart ) {
+ // clear the entered number on the first press
+ state = sNewNumber;
+ num = acc = 0;
+ flPoint = FALSE;
+ LCD->display( 0 );
+ fake = QString::null;
+ numDecimals = 0;
+ } else {
+ clear();
+ }
+ break;
+ };
+
+}
diff --git a/noncore/tools/calculator/calculatorimpl.h b/noncore/tools/calculator/calculatorimpl.h
new file mode 100644
index 0000000..bfb726f
--- a/dev/null
+++ b/noncore/tools/calculator/calculatorimpl.h
@@ -0,0 +1,135 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CALCULATORIMPL_H
+#define CALCULATORIMPL_H
+
+
+#include <qlcdnumber.h>
+#include "calculator.h"
+#include <qpushbutton.h>
+#include <qbuttongroup.h>
+#include <qvaluestack.h>
+
+// mode x functions
+enum Operation {
+ oNop,
+ oOpenBrace,
+ oCloseBrace,
+ oSum,
+ oPoint,
+ oAdd,
+ oSub,
+ oDiv,
+ oMult,
+
+// mode 0 functions
+ oSin,
+ oCos,
+ oTan,
+ oDivX,
+ oPercent,
+ oXsquared,
+ oRoot,
+ oLog,
+ oLn,
+ oChSign
+};
+
+// states
+#define sStart 0
+#define sNewNumber 1
+#define sError 2
+
+struct Op
+{
+ Op() { number = 0; operation = oNop; }
+ Op( double num, Operation op )
+ { number = num; operation = op; }
+ double number;
+ Operation operation;
+};
+
+class QLabel;
+class CalculatorImpl : public Calculator
+{
+ Q_OBJECT
+
+public:
+ CalculatorImpl( QWidget * parent = 0, const char * name = 0,
+ WFlags f = 0 );
+
+public slots:
+ void command_buttons(int);
+ void enterNumber(int i);
+ void std_buttons(int);
+ void std_funcs(int);
+ void do_convert(int);
+ void function_button(int);
+
+protected:
+ virtual bool eventFilter( QObject *o, QEvent *e );
+
+private:
+ void clear();
+
+ void reset_conv();
+
+ void processStack( int op );
+
+ QValueStack<Op> operationStack;
+ int state;
+
+ double acc, num, mem;
+ int numDecimals;
+ bool flPoint;
+ int numOpenBraces;
+
+ void execOp( Operation i );
+ double evalExpr( int op );
+ QLabel * memMark;
+ QString fake;
+
+ // useful values for conversion stuff
+ int current_mode, max_mode, conversion_mode_count, last_conversion;
+
+ // make adding new modes easier for ourselves
+ static const int pre_conv_modes_count = 1;
+ static const int post_conv_modes_count = 0;
+
+ // an array of pointers to the func buttons
+ static const int func_button_count = 12;
+ // this is an abomination
+ static const int changeable_func_button_count = 10;
+ QPushButton* func_buttons[func_button_count];
+
+ QButtonGroup bgr_function, bgr_digits, bgr_std, bgr_command;
+ QStringList faces, captions;
+
+ // an array of doubles holding the conversion ratios
+ double* entry_list;
+
+ QPixmap xtopowerofy;
+ QPixmap ythrootofx;
+ QPixmap oneoverx;
+
+ void display_pixmap_faces(void);
+};
+
+#endif
diff --git a/noncore/tools/calculator/main.cpp b/noncore/tools/calculator/main.cpp
new file mode 100644
index 0000000..74cd5d3
--- a/dev/null
+++ b/noncore/tools/calculator/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "calculatorimpl.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ CalculatorImpl mw;
+ QPEApplication::setInputMethodHint( &mw, QPEApplication::AlwaysOff );
+ mw.setCaption( CalculatorImpl::tr("Calculator") );
+ a.showMainWidget( &mw );
+
+ return a.exec();
+}
diff --git a/noncore/tools/calculator/qpe-calculator.control b/noncore/tools/calculator/qpe-calculator.control
new file mode 100644
index 0000000..afef70b
--- a/dev/null
+++ b/noncore/tools/calculator/qpe-calculator.control
@@ -0,0 +1,10 @@
+Files: bin/calculator apps/Applications/calculator.desktop etc/unit_conversion.dat
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Calculator
+ A multi-function calculator for the Qtopia environment.
+ Includes units conversion.
diff --git a/noncore/tools/clock/.cvsignore b/noncore/tools/clock/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/noncore/tools/clock/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/noncore/tools/clock/Makefile.in b/noncore/tools/clock/Makefile.in
new file mode 100644
index 0000000..adda9e6
--- a/dev/null
+++ b/noncore/tools/clock/Makefile.in
@@ -0,0 +1,118 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = clock
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = clock.h
+SOURCES = clock.cpp \
+ main.cpp
+OBJECTS = clock.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_clock.cpp
+OBJMOC = moc_clock.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake clock.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+clock.o: clock.cpp \
+ clock.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+main.o: main.cpp \
+ clock.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_clock.o: moc_clock.cpp \
+ clock.h
+
+moc_clock.cpp: clock.h
+ $(MOC) clock.h -o moc_clock.cpp
+
+
diff --git a/noncore/tools/clock/clock.cpp b/noncore/tools/clock/clock.cpp
new file mode 100644
index 0000000..ef93e11
--- a/dev/null
+++ b/noncore/tools/clock/clock.cpp
@@ -0,0 +1,319 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "clock.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/config.h>
+#include <qpe/timestring.h>
+
+#include <qlcdnumber.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qpainter.h>
+
+#include <math.h>
+
+const double deg2rad = 0.017453292519943295769; // pi/180
+const int sw_prec = 2;
+
+static void toggleScreenSaver( bool on )
+{
+ QCopEnvelope e("QPE/System", "setScreenSaverMode(int)" );
+ e << (on ? QPEApplication::Enable: QPEApplication::DisableSuspend );
+}
+
+Clock::Clock( QWidget * parent, const char * name, WFlags f )
+ : QVBox( parent, name , f )
+{
+ setSpacing( 4 );
+ setMargin( 1 );
+
+ Config config( "qpe" );
+ config.setGroup("Time");
+ ampm = config.readBoolEntry( "AMPM", TRUE );
+
+ aclock = new AnalogClock( this );
+ aclock->display( QTime::currentTime() );
+ aclock->setLineWidth( 2 );
+
+ QHBox *hb = new QHBox( this );
+ hb->setMargin( 0 );
+ QWidget *space = new QWidget( hb );
+ lcd = new QLCDNumber( hb );
+ lcd->setSegmentStyle( QLCDNumber::Flat );
+ lcd->setFrameStyle( QFrame::NoFrame );
+ lcd->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
+ lcd->setFixedHeight( 23 );
+
+ ampmLabel = new QLabel( "PM", hb );
+ ampmLabel->setFont( QFont( "Helvetica", 14, QFont::Bold ) );
+ ampmLabel->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred ) );
+ ampmLabel->setAlignment( AlignLeft | AlignBottom );
+ space = new QWidget( hb );
+
+ date = new QLabel( this );
+ date->setAlignment( AlignHCenter | AlignVCenter );
+ date->setFont( QFont( "Helvetica", 14, QFont::Bold ) );
+ date->setText( TimeString::longDateString( QDate::currentDate() ) );
+
+ QWidget *controls = new QWidget( this );
+ QGridLayout *gl = new QGridLayout( controls, 2, 2, 6, 4 );
+
+ QButtonGroup *grp = new QButtonGroup( controls );
+ grp->setRadioButtonExclusive( true );
+ grp->hide();
+
+ clockRB = new QRadioButton ( tr( "Clock" ), controls );
+ gl->addWidget( clockRB, 0, 0 );
+ grp->insert( clockRB );
+
+ swatchRB = new QRadioButton ( tr( "Stopwatch" ), controls );
+ gl->addWidget( swatchRB, 1, 0 );
+ grp->insert( swatchRB );
+
+ connect( grp, SIGNAL(clicked(int)), this, SLOT(modeSelect(int)) );
+ grp->setButton( 0 );
+
+ set = new QPushButton ( controls );
+ gl->addWidget( set, 0, 1 );
+ set->setText( tr( "Start" ) );
+ set->setEnabled( FALSE );
+ grp->insert( set );
+
+ reset = new QPushButton ( controls );
+ gl->addWidget( reset, 1, 1 );
+ reset->setText( tr( "Reset" ) );
+ reset->setEnabled( FALSE );
+ grp->insert( reset );
+
+ connect( set, SIGNAL( pressed() ), SLOT( slotSet() ) );
+ connect( reset, SIGNAL( clicked() ), SLOT( slotReset() ) );
+
+ t = new QTimer( this );
+ connect( t, SIGNAL( timeout() ), SLOT( updateClock() ) );
+ t->start( 1000 );
+
+ connect( qApp, SIGNAL( timeChanged() ), SLOT( updateClock() ) );
+
+ swatch_running = FALSE;
+ swatch_totalms = 0;
+
+ connect( qApp, SIGNAL(clockChanged(bool)), this, SLOT(changeClock(bool)) );
+
+ QTimer::singleShot( 0, this, SLOT(updateClock()) );
+ modeSelect(0);
+}
+
+Clock::~Clock()
+{
+ toggleScreenSaver( true );
+}
+
+void Clock::updateClock()
+{
+ if ( clockRB->isChecked() ) {
+ QTime tm = QDateTime::currentDateTime().time();
+ QString s;
+ if ( ampm ) {
+ int hour = tm.hour();
+ if (hour == 0)
+ hour = 12;
+ if (hour > 12)
+ hour -= 12;
+ s.sprintf( "%2d%c%02d", hour, ':', tm.minute() );
+ ampmLabel->setText( (tm.hour() >= 12) ? "PM" : "AM" );
+ ampmLabel->show();
+ } else {
+ s.sprintf( "%2d%c%02d", tm.hour(), ':', tm.minute() );
+ ampmLabel->hide();
+ }
+ lcd->display( s );
+ lcd->repaint( FALSE );
+ aclock->display( QTime::currentTime() );
+ date->setText( TimeString::longDateString( QDate::currentDate() ) );
+ } else {
+ QTime swatch_time;
+ QString lcdtext;
+ int totalms = swatch_totalms;
+ if ( swatch_running )
+ totalms += swatch_start.elapsed();
+ swatch_time = QTime(0,0,0).addMSecs(totalms);
+ QString d = swatch_running ? QString(" ")
+ : QString::number(totalms%1000+1000);
+ lcdtext = swatch_time.toString() + "." + d.right(3).left(sw_prec);
+ lcd->display( lcdtext );
+ lcd->repaint( FALSE );
+ aclock->display( swatch_time );
+ date->setText( TimeString::longDateString( QDate::currentDate() ) );
+ }
+}
+
+void Clock::changeClock( bool a )
+{
+ ampm = a;
+ updateClock();
+}
+
+void Clock::clearClock( void )
+{
+ lcd->display( QTime( 0,0,0 ).toString() );
+ aclock->display( QTime( 0,0,0 ) );
+}
+
+void Clock::slotSet()
+{
+ if ( t->isActive() ) {
+ swatch_totalms += swatch_start.elapsed();
+ set->setText( tr( "Start" ) );
+ t->stop();
+ swatch_running = FALSE;
+ toggleScreenSaver( TRUE );
+ updateClock();
+ } else {
+ swatch_start.start();
+ set->setText( tr( "Stop" ) );
+ t->start( 1000 );
+ swatch_running = TRUE;
+ // disable screensaver while stop watch is running
+ toggleScreenSaver( FALSE );
+ }
+}
+
+void Clock::slotReset()
+{
+ t->stop();
+ swatch_start.start();
+ swatch_totalms = 0;
+
+ if (swatch_running )
+ t->start(1000);
+
+ updateClock();
+}
+
+void Clock::modeSelect( int m )
+{
+ if ( m ) {
+ lcd->setNumDigits( 8+1+sw_prec );
+ lcd->setMinimumWidth( lcd->sizeHint().width() );
+ set->setEnabled( TRUE );
+ reset->setEnabled( TRUE );
+ ampmLabel->hide();
+
+ if ( !swatch_running )
+ t->stop();
+ } else {
+ lcd->setNumDigits( 5 );
+ lcd->setMinimumWidth( lcd->sizeHint().width() );
+ set->setEnabled( FALSE );
+ reset->setEnabled( FALSE );
+ t->start(1000);
+ }
+ updateClock();
+}
+
+QSizePolicy AnalogClock::sizePolicy() const
+{
+ return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
+}
+
+void AnalogClock::drawContents( QPainter *p )
+{
+ QRect r = contentsRect();
+ QPoint center( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+
+ QPoint l1( r.x() + r.width() / 2, r.y() + 2 );
+ QPoint l2( r.x() + r.width() / 2, r.y() + 8 );
+
+ QPoint h1( r.x() + r.width() / 2, r.y() + r.height() / 4 );
+ QPoint h2( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+
+ QPoint m1( r.x() + r.width() / 2, r.y() + r.height() / 8 );
+ QPoint m2( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+
+ QPoint s1( r.x() + r.width() / 2, r.y() + 8 );
+ QPoint s2( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+
+ QColor color( clear ? backgroundColor() : black );
+ QTime time = clear ? prevTime : currTime;
+
+ if ( clear && prevTime.secsTo(currTime) > 1 ) {
+ p->eraseRect( rect() );
+ return;
+ }
+
+ if ( !clear ) {
+ // draw ticks
+ p->setPen( QPen( color, 1 ) );
+ for ( int i = 0; i < 12; i++ )
+ p->drawLine( rotate( center, l1, i * 30 ), rotate( center, l2, i * 30 ) );
+ }
+
+ if ( !clear || prevTime.minute() != currTime.minute() ||
+ prevTime.hour() != currTime.hour() ) {
+ // draw hour pointer
+ h1 = rotate( center, h1, 30 * ( time.hour() % 12 ) + time.minute() / 2 );
+ h2 = rotate( center, h2, 30 * ( time.hour() % 12 ) + time.minute() / 2 );
+ p->setPen( QPen( color, 3 ) );
+ p->drawLine( h1, h2 );
+ }
+
+ if ( !clear || prevTime.minute() != currTime.minute() ) {
+ // draw minute pointer
+ m1 = rotate( center, m1, time.minute() * 6 );
+ m2 = rotate( center, m2, time.minute() * 6 );
+ p->setPen( QPen( color, 2 ) );
+ p->drawLine( m1, m2 );
+ }
+
+ // draw second pointer
+ s1 = rotate( center, s1, time.second() * 6 );
+ s2 = rotate( center, s2, time.second() * 6 );
+ p->setPen( QPen( color, 1 ) );
+ p->drawLine( s1, s2 );
+
+ if ( !clear )
+ prevTime = currTime;
+}
+
+void AnalogClock::display( const QTime& t )
+{
+ currTime = t;
+ clear = true;
+ repaint( false );
+ clear = false;
+ repaint( false );
+}
+
+QPoint AnalogClock::rotate( QPoint c, QPoint p, int a )
+{
+ double angle = deg2rad * ( - a + 180 );
+ double nx = c.x() - ( p.x() - c.x() ) * cos( angle ) -
+ ( p.y() - c.y() ) * sin( angle );
+ double ny = c.y() - ( p.y() - c.y() ) * cos( angle ) +
+ ( p.x() - c.x() ) * sin( angle );
+ return QPoint( nx, ny );
+}
diff --git a/noncore/tools/clock/clock.h b/noncore/tools/clock/clock.h
new file mode 100644
index 0000000..6dbebf7
--- a/dev/null
+++ b/noncore/tools/clock/clock.h
@@ -0,0 +1,87 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CLOCK_H
+#define CLOCK_H
+
+#include <qdatetime.h>
+#include <qvbox.h>
+
+class QLCDNumber;
+class QLabel;
+class QTimer;
+class QRadioButton;
+class QPushButton;
+
+class AnalogClock : public QFrame
+{
+ Q_OBJECT
+
+public:
+ AnalogClock( QWidget * parent = 0, const char * name = 0 )
+ : QFrame( parent, name ), clear(false) {}
+
+ QSizePolicy sizePolicy() const;
+
+ void display( const QTime& time );
+
+protected:
+ void drawContents( QPainter *p );
+
+private:
+ QPoint rotate( QPoint center, QPoint p, int angle );
+
+ QTime currTime;
+ QTime prevTime;
+ bool clear;
+};
+
+class Clock : public QVBox
+{
+ Q_OBJECT
+
+public:
+ Clock( QWidget * parent = 0, const char * name = 0, WFlags f=0 );
+ ~Clock();
+
+private slots:
+ void slotSet();
+ void slotReset();
+ void modeSelect(int);
+ void updateClock();
+ void changeClock( bool );
+
+private:
+ void clearClock();
+
+ QTimer *t;
+ QLCDNumber *lcd;
+ QLabel *date;
+ QLabel *ampmLabel;
+ QPushButton *set, *reset;
+ QRadioButton *clockRB, *swatchRB;
+ AnalogClock *aclock;
+ QTime swatch_start;
+ int swatch_totalms;
+ bool swatch_running;
+ bool ampm;
+};
+
+#endif
+
diff --git a/noncore/tools/clock/clock.pro b/noncore/tools/clock/clock.pro
new file mode 100644
index 0000000..97f4d2c
--- a/dev/null
+++ b/noncore/tools/clock/clock.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = clock.h
+SOURCES = clock.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
+TARGET = clock
+
+TRANSLATIONS = ../i18n/de/clock.ts
diff --git a/noncore/tools/clock/main.cpp b/noncore/tools/clock/main.cpp
new file mode 100644
index 0000000..cbfb73b
--- a/dev/null
+++ b/noncore/tools/clock/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "clock.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ Clock mw;
+ mw.setCaption( Clock::tr("Clock") );
+ a.showMainWidget( &mw );
+
+ return a.exec();
+}
diff --git a/noncore/tools/clock/qpe-clock.control b/noncore/tools/clock/qpe-clock.control
new file mode 100644
index 0000000..62f377f
--- a/dev/null
+++ b/noncore/tools/clock/qpe-clock.control
@@ -0,0 +1,9 @@
+Files: bin/clock apps/Applications/clock.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Clock and stop-watch
+ A simple clock and stop-watch for the Qtopia environment.
diff --git a/noncore/unsupported/filebrowser/.cvsignore b/noncore/unsupported/filebrowser/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/noncore/unsupported/filebrowser/Makefile.in b/noncore/unsupported/filebrowser/Makefile.in
new file mode 100644
index 0000000..c7238ea
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/Makefile.in
@@ -0,0 +1,136 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = filebrowser
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = inlineedit.h \
+ filebrowser.h
+SOURCES = filebrowser.cpp \
+ inlineedit.cpp \
+ main.cpp
+OBJECTS = filebrowser.o \
+ inlineedit.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_inlineedit.cpp \
+ moc_filebrowser.cpp
+OBJMOC = moc_inlineedit.o \
+ moc_filebrowser.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake filebrowser.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+filebrowser.o: filebrowser.cpp \
+ inlineedit.h \
+ filebrowser.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/mimetype.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+inlineedit.o: inlineedit.cpp \
+ inlineedit.h
+
+main.o: main.cpp \
+ filebrowser.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/mimetype.h
+
+moc_inlineedit.o: moc_inlineedit.cpp \
+ inlineedit.h
+
+moc_filebrowser.o: moc_filebrowser.cpp \
+ filebrowser.h
+
+moc_inlineedit.cpp: inlineedit.h
+ $(MOC) inlineedit.h -o moc_inlineedit.cpp
+
+moc_filebrowser.cpp: filebrowser.h
+ $(MOC) filebrowser.h -o moc_filebrowser.cpp
+
+
diff --git a/noncore/unsupported/filebrowser/filebrowser.cpp b/noncore/unsupported/filebrowser/filebrowser.cpp
new file mode 100644
index 0000000..9439bb8
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/filebrowser.cpp
@@ -0,0 +1,850 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "inlineedit.h"
+#include "filebrowser.h"
+
+#include <qpe/resource.h>
+#include <qpe/global.h>
+#include <qpe/mimetype.h>
+#include <qpe/applnk.h>
+
+#include <qcopchannel_qws.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qregexp.h>
+#include <qheader.h>
+#include <qpe/qpetoolbar.h>
+#include <qpopupmenu.h>
+#include <qpe/qpemenubar.h>
+#include <qaction.h>
+#include <qstringlist.h>
+#include <qcursor.h>
+#include <qmultilineedit.h>
+#include <qfont.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+//
+// FileItem
+//
+FileItem::FileItem( QListView * parent, const QFileInfo & fi )
+ : QListViewItem( parent ),
+ fileInfo( fi )
+{
+ QDate d = fi.lastModified().date();
+
+ setText( 0, fi.fileName() );
+ setText( 1, sizeString( fi.size() ) + " " );
+ setText( 2, QString().sprintf("%4d-%02d-%02d",d.year(), d.month(), d.day() ) );
+
+ MimeType mt(fi.filePath());
+
+ if( fi.isDir() )
+ setText( 3, "directory" );
+ else if( isLib() )
+ setText( 3, "library" );
+ else
+ setText( 3, mt.description() );
+
+ QPixmap pm;
+ if( fi.isDir() ){
+ if( !QDir( fi.filePath() ).isReadable() )
+ pm = Resource::loadPixmap( "lockedfolder" );
+ else
+ pm = Resource::loadPixmap( "folder" );
+ }
+ else if( !fi.isReadable() )
+ pm = Resource::loadPixmap( "locked" );
+ else if( isLib() )
+ pm = Resource::loadPixmap( "library" );
+ else
+ pm = mt.pixmap();
+ if ( pm.isNull() )
+ pm = Resource::loadPixmap("UnknownDocument-14");
+ setPixmap(0,pm);
+}
+
+QString FileItem::sizeString( unsigned int s )
+{
+ double size = s;
+
+ if ( size > 1024 * 1024 * 1024 )
+ return QString().sprintf( "%.1f", size / ( 1024 * 1024 * 1024 ) ) + "G";
+ else if ( size > 1024 * 1024 )
+ return QString().sprintf( "%.1f", size / ( 1024 * 1024 ) ) + "M";
+ else if ( size > 1024 )
+ return QString().sprintf( "%.1f", size / ( 1024 ) ) + "K";
+ else
+ return QString::number( size ) + "B";
+}
+
+QString FileItem::key( int column, bool ascending ) const
+{
+ QString tmp;
+
+ ascending = ascending;
+
+ if( (column == 0) && fileInfo.isDir() ){ // Sort by name
+ // We want the directories to appear at the top of the list
+ tmp = (char) 0;
+ return (tmp + text( column ).lower());
+ }
+ else if( column == 2 ) { // Sort by date
+ QDateTime epoch( QDate( 1980, 1, 1 ) );
+ tmp.sprintf( "%08d", epoch.secsTo( fileInfo.lastModified() ) );
+ return tmp;
+ }
+ else if( column == 1 ) { // Sort by size
+ return tmp.sprintf( "%08d", fileInfo.size() );
+ }
+
+ return text( column ).lower();
+}
+
+bool FileItem::isLib()
+{
+ // This is of course not foolproof
+ if( !qstrncmp("lib", fileInfo.baseName(), 3) &&
+ ( fileInfo.extension().contains( "so" ) ||
+ fileInfo.extension().contains( "a" ) ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+int FileItem::launch()
+{
+ DocLnk doc( fileInfo.filePath(), FALSE );
+ doc.execute();
+ listView()->clearSelection();
+ return 1;
+}
+
+bool FileItem::rename( const QString & name )
+{
+ QString oldpath, newpath;
+
+ if ( name.isEmpty() )
+ return FALSE;
+
+ if ( name.contains( QRegExp("[/\\$\"\'\\*\\?]") ) )
+ return FALSE;
+
+ oldpath = fileInfo.filePath();
+ newpath = fileInfo.dirPath() + "/" + name;
+
+ if ( ::rename( (const char *) oldpath, (const char *) newpath ) != 0 )
+ return FALSE;
+ else
+ return TRUE;
+}
+
+//
+// FileView
+//
+FileView::FileView( const QString & dir, QWidget * parent,
+ const char * name )
+ : QListView( parent, name ),
+ menuTimer( this ),
+ le( NULL ),
+ itemToRename( NULL )
+{
+ addColumn( "Name" );
+ addColumn( "Date" );
+ addColumn( "Size" );
+ addColumn( "Type" );
+
+ setMultiSelection( TRUE );
+ header()->hide();
+
+ setColumnWidthMode( 0, Manual );
+ setColumnWidthMode( 3, Manual );
+
+ // right align yize column
+ setColumnAlignment( 1, AlignRight );
+
+ generateDir( dir );
+
+ connect( this, SIGNAL( clicked( QListViewItem * )),
+ SLOT( itemClicked( QListViewItem * )) );
+ connect( this, SIGNAL( doubleClicked( QListViewItem * )),
+ SLOT( itemDblClicked( QListViewItem * )) );
+ connect( this, SIGNAL( selectionChanged() ), SLOT( cancelMenuTimer() ) );
+ connect( &menuTimer, SIGNAL( timeout() ), SLOT( showFileMenu() ) );
+}
+
+void FileView::resizeEvent( QResizeEvent *e )
+{
+ setColumnWidth( 0, width() - 2 * lineWidth() - 20 - columnWidth( 1 ) - columnWidth( 2 ) );
+
+ // hide type column, we use it for "sort by type" only
+ setColumnWidth( 3, 0 );
+ QListView::resizeEvent( e );
+}
+
+void FileView::updateDir()
+{
+ generateDir( currentDir );
+}
+
+void FileView::setDir( const QString & dir )
+{
+ if ( dir.startsWith( "/dev" ) ) {
+ QMessageBox::warning( this, tr( "File Manager" ),
+ tr( "Can't show /dev/ directory." ), tr( "&Ok" ) );
+ return;
+ }
+ dirHistory += currentDir;
+ generateDir( dir );
+}
+
+void FileView::generateDir( const QString & dir )
+{
+ QDir d( dir );
+
+ if( d.exists() && !d.isReadable() ) return;
+
+ currentDir = d.canonicalPath();
+
+ d.setFilter( QDir::Dirs | QDir::Files );
+ d.setSorting( QDir::Name | QDir::DirsFirst | QDir::IgnoreCase |
+ QDir::Reversed );
+
+ const QFileInfoList * list = d.entryInfoList();
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+
+ clear();
+ while( (fi = it.current()) ){
+ if( (fi->fileName() == ".") || (fi->fileName() == "..") ){
+ ++it;
+ continue;
+ }
+ (void) new FileItem( (QListView *) this, *fi );
+ ++it;
+ }
+
+ emit dirChanged();
+}
+
+void FileView::rename()
+{
+ itemToRename = (FileItem *) currentItem();
+ const QPixmap * pm;
+ int pmw;
+
+ if( itemToRename == NULL ) return;
+
+ if( ( pm = itemToRename->pixmap( 0 ) ) == NULL )
+ pmw = 0;
+ else
+ pmw = pm->width();
+
+ ensureItemVisible( itemToRename );
+ horizontalScrollBar()->setValue( 0 );
+ horizontalScrollBar()->setEnabled( FALSE );
+ verticalScrollBar()->setEnabled( FALSE );
+
+ selected = isSelected( itemToRename );
+ setSelected( itemToRename, FALSE );
+
+ if( le == NULL ){
+ le = new InlineEdit( this );
+ le->setFrame( FALSE );
+ connect( le, SIGNAL( lostFocus() ), SLOT( endRenaming() ) );
+ }
+
+ QRect r = itemRect( itemToRename );
+ r.setTop( r.top() + frameWidth() + 1 );
+ r.setLeft( r.left() + frameWidth() + pmw );
+ r.setBottom( r.bottom() + frameWidth() );
+ r.setWidth( columnWidth( 0 ) - pmw );
+
+ le->setGeometry( r );
+ le->setText( itemToRename->text( 0 ) );
+ le->selectAll();
+ le->show();
+ le->setFocus();
+}
+
+void FileView::endRenaming()
+{
+ if( le && itemToRename ){
+ le->hide();
+ setSelected( itemToRename, selected );
+
+ if( !itemToRename->rename( le->text() ) ){
+ QMessageBox::warning( this, tr( "Rename file" ),
+ tr( "Rename failed!" ), tr( "&Ok" ) );
+ } else {
+ updateDir();
+ }
+ itemToRename = NULL;
+ horizontalScrollBar()->setEnabled( TRUE );
+ verticalScrollBar()->setEnabled( TRUE );
+ }
+}
+
+void FileView::copy()
+{
+ // dont keep cut files any longer than necessary
+ // ##### a better inmplementation might be to rename the CUT file
+ // ##### to ".QPE-FILEBROWSER-MOVING" rather than copying it.
+ system ( "rm -rf /tmp/qpemoving" );
+
+ FileItem * i;
+
+ if((i = (FileItem *) firstChild()) == 0) return;
+
+ flist.clear();
+ while( i ){
+ if( i->isSelected() /*&& !i->isDir()*/ ){
+ flist += i->getFilePath();
+ }
+ i = (FileItem *) i->nextSibling();
+ }
+}
+
+void FileView::paste()
+{
+ int i, err;
+ QString cmd, dest, basename, cd = currentDir;
+
+ if(cd == "/") cd = "";
+
+ for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) {
+ basename = (*it).mid((*it).findRev("/") + 1, (*it).length());
+
+ dest = cd + "/" + basename;
+ if( QFile( dest ).exists() ){
+ i = 1;
+ dest = cd + "/Copy of " + basename;
+ while( QFile( dest ).exists() ){
+ dest.sprintf( "%s/Copy (%d) of %s", (const char *) cd, i++,
+ (const char *) basename );
+ }
+ }
+
+ //
+ // Copy a directory recursively using the "cp" command -
+ // may have to be changed
+ //
+ if( QFileInfo( (*it) ).isDir() ){
+ cmd = "/bin/cp -fpR \"" + (*it) +"\" " + "\"" + dest + "\"";
+ err = system( (const char *) cmd );
+ } else if( !copyFile( dest, (*it) ) ){
+ err = -1;
+ } else {
+ err = 0;
+ }
+
+ if ( err != 0 ) {
+ QMessageBox::warning( this, tr("Paste file"), tr("Paste failed!"),
+ tr("Ok") );
+ break;
+ } else {
+ updateDir();
+ QListViewItem * i = firstChild();
+ basename = dest.mid( dest.findRev("/") + 1, dest.length() );
+
+ while( i ){
+ if( i->text(0) == basename ){
+ setCurrentItem( i );
+ ensureItemVisible( i );
+ break;
+ }
+ i = i->nextSibling();
+ }
+ }
+ }
+}
+
+bool FileView::copyFile( const QString & dest, const QString & src )
+{
+ char bf[ 50000 ];
+ int bytesRead;
+ bool success = TRUE;
+ struct stat status;
+
+ QFile s( src );
+ QFile d( dest );
+
+ if( s.open( IO_ReadOnly | IO_Raw ) &&
+ d.open( IO_WriteOnly | IO_Raw ) )
+ {
+ while( (bytesRead = s.readBlock( bf, sizeof( bf ) )) ==
+ sizeof( bf ) )
+ {
+ if( d.writeBlock( bf, sizeof( bf ) ) != sizeof( bf ) ){
+ success = FALSE;
+ break;
+ }
+ }
+ if( success && (bytesRead > 0) ){
+ d.writeBlock( bf, bytesRead );
+ }
+ } else {
+ success = FALSE;
+ }
+
+ // Set file permissions
+ if( stat( (const char *) src, &status ) == 0 ){
+ chmod( (const char *) dest, status.st_mode );
+ }
+
+ return success;
+}
+
+void FileView::cut()
+{
+ int err;
+ // ##### a better inmplementation might be to rename the CUT file
+ // ##### to ".QPE-FILEBROWSER-MOVING" rather than copying it.
+ QString cmd, dest, basename, cd = "/tmp/qpemoving";
+ QStringList newflist;
+ newflist.clear();
+
+ cmd = "rm -rf " + cd;
+ system ( (const char *) cmd );
+ cmd = "mkdir " + cd;
+ system( (const char *) cmd );
+
+// get the names of the files to cut
+ FileItem * item;
+
+ if((item = (FileItem *) firstChild()) == 0) return;
+
+ flist.clear();
+ while( item ){
+ if( item->isSelected() /*&& !item->isDir()*/ ){
+ flist += item->getFilePath();
+ }
+ item = (FileItem *) item->nextSibling();
+ }
+
+// move these files into a tmp dir
+ for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) {
+ basename = (*it).mid((*it).findRev("/") + 1, (*it).length());
+
+ dest = cd + "/" + basename;
+
+ newflist += dest;
+
+ cmd = "/bin/mv -f \"" + (*it) +"\" " + "\"" + dest + "\"";
+ err = system( (const char *) cmd );
+
+ if ( err != 0 ) {
+ QMessageBox::warning( this, tr("Cut file"), tr("Cut failed!"),
+ tr("Ok") );
+ break;
+ } else {
+ updateDir();
+ QListViewItem * im = firstChild();
+ basename = dest.mid( dest.findRev("/") + 1, dest.length() );
+
+ while( im ){
+ if( im->text(0) == basename ){
+ setCurrentItem( im );
+ ensureItemVisible( im );
+ break;
+ }
+ im = im->nextSibling();
+ }
+ }
+ }
+
+ // update the filelist to point to tmp dir so paste works nicely
+ flist = newflist;
+}
+
+void FileView::del()
+{
+ FileItem * i;
+ QStringList fl;
+ QString cmd;
+ int err;
+
+ if((i = (FileItem *) firstChild()) == 0) return;
+
+ while( i ){
+ if( i->isSelected() ){
+ fl += i->getFilePath();
+ }
+ i = (FileItem *) i->nextSibling();
+ }
+ if( fl.count() < 1 ) return;
+
+ if( QMessageBox::warning( this, tr("Delete"), tr("Are you sure?"),
+ tr("Yes"), tr("No") ) == 0)
+ {
+ //
+ // Dependant upon the "rm" command - will probably have to be replaced
+ //
+ for ( QStringList::Iterator it = fl.begin(); it != fl.end(); ++it ) {
+ cmd = "/bin/rm -rf \"" + (*it) + "\"";
+ err = system( (const char *) cmd );
+ if ( err != 0 ) {
+ QMessageBox::warning( this, tr("Delete"), tr("Delete failed!"),
+ tr("Ok") );
+ break;
+ }
+ }
+ updateDir();
+ }
+}
+
+void FileView::newFolder()
+{
+ int t = 1;
+ FileItem * i;
+ QString nd = currentDir + "/NewFolder";
+
+ while( QFile( nd ).exists() ){
+ nd.sprintf( "%s/NewFolder (%d)", (const char *) currentDir, t++ );
+ }
+
+ if( mkdir( (const char *) nd, 0777 ) != 0){
+ QMessageBox::warning( this, tr( "New folder" ),
+ tr( "Folder creation failed!" ),
+ tr( "Ok" ) );
+ return;
+ }
+ updateDir();
+
+ if((i = (FileItem *) firstChild()) == 0) return;
+
+ while( i ){
+ if( i->isDir() && ( i->getFilePath() == nd ) ){
+ setCurrentItem( i );
+ rename();
+ break;
+ }
+ i = (FileItem *) i->nextSibling();
+ }
+}
+
+void FileView::viewAsText()
+{
+ FileItem * i = (FileItem *) currentItem();
+ Global::execute( "textedit -f ", i->getFilePath() );
+}
+
+void FileView::itemClicked( QListViewItem * i)
+{
+ FileItem * t = (FileItem *) i;
+
+ if( t == NULL ) return;
+ if( t->isDir() ){
+ setDir( t->getFilePath() );
+ }
+}
+
+void FileView::itemDblClicked( QListViewItem * i)
+{
+ FileItem * t = (FileItem *) i;
+
+ if(t == NULL) return;
+ if(t->launch() == -1){
+ QMessageBox::warning( this, tr( "Launch Application" ),
+ tr( "Launch failed!" ), tr( "Ok" ) );
+ }
+}
+
+void FileView::parentDir()
+{
+ setDir( currentDir + "./.." );
+}
+
+void FileView::lastDir()
+{
+ if( dirHistory.count() == 0 ) return;
+
+ QString newDir = dirHistory.last();
+ dirHistory.remove( dirHistory.last() );
+ generateDir( newDir );
+}
+
+void FileView::contentsMousePressEvent( QMouseEvent * e )
+{
+ QListView::contentsMousePressEvent( e );
+ menuTimer.start( 750, TRUE );
+}
+
+void FileView::contentsMouseReleaseEvent( QMouseEvent * e )
+{
+ QListView::contentsMouseReleaseEvent( e );
+ menuTimer.stop();
+}
+
+void FileView::cancelMenuTimer()
+{
+ if( menuTimer.isActive() )
+ menuTimer.stop();
+}
+
+void FileView::addToDocuments()
+{
+ FileItem * i = (FileItem *) currentItem();
+ DocLnk f;
+ QString n = i->text(0);
+ n.replace(QRegExp("\\..*"),"");
+ f.setName( n );
+ f.setFile( i->getFilePath() );
+ f.writeLink();
+}
+
+void FileView::run()
+{
+ FileItem * i = (FileItem *) currentItem();
+ i->launch();
+}
+
+void FileView::showFileMenu()
+{
+ FileItem * i = (FileItem *) currentItem();
+ if ( !i )
+ return;
+
+ QPopupMenu * m = new QPopupMenu( this );
+
+ if ( !i->isDir() ) {
+ m->insertItem( tr( "Add to Documents" ), this, SLOT( addToDocuments() ) );
+ m->insertSeparator();
+ }
+
+ MimeType mt(i->getFilePath());
+ const AppLnk* app = mt.application();
+
+ if ( !i->isDir() ) {
+ if ( app )
+ m->insertItem( app->pixmap(), tr( "Open in " + app->name() ), this, SLOT( run() ) );
+ else if( i->isExecutable() )
+ m->insertItem( Resource::loadPixmap( i->text( 0 ) ), tr( "Run" ), this, SLOT( run() ) );
+
+ m->insertItem( Resource::loadPixmap( "txt" ), tr( "View as text" ),
+ this, SLOT( viewAsText() ) );
+
+ m->insertSeparator();
+ }
+
+ m->insertItem( tr( "Rename" ), this, SLOT( rename() ) );
+ m->insertItem( Resource::loadPixmap("cut"),
+ tr( "Cut" ), this, SLOT( cut() ) );
+ m->insertItem( Resource::loadPixmap("copy"),
+ tr( "Copy" ), this, SLOT( copy() ) );
+ m->insertItem( Resource::loadPixmap("paste"),
+ tr( "Paste" ), this, SLOT( paste() ) );
+ m->insertItem( tr( "Delete" ), this, SLOT( del() ) );
+ m->insertSeparator();
+ m->insertItem( tr( "Select all" ), this, SLOT( selectAll() ) );
+ m->insertItem( tr( "Deselect all" ), this, SLOT( deselectAll() ) );
+ m->popup( QCursor::pos() );
+}
+
+//
+// FileBrowser
+//
+
+FileBrowser::FileBrowser( QWidget * parent,
+ const char * name, WFlags f ) :
+ QMainWindow( parent, name, f )
+{
+ init( QDir::current().canonicalPath() );
+}
+
+FileBrowser::FileBrowser( const QString & dir, QWidget * parent,
+ const char * name, WFlags f ) :
+ QMainWindow( parent, name, f )
+{
+ init( dir );
+}
+
+void FileBrowser::init(const QString & dir)
+{
+ setCaption( tr("File Manager") );
+ setIcon( Resource::loadPixmap( "filebrowser_icon" ) );
+
+ fileView = new FileView( dir, this );
+ fileView->setAllColumnsShowFocus( TRUE );
+
+ setCentralWidget( fileView );
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar* toolBar = new QPEToolBar( this );
+ toolBar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar* menuBar = new QPEMenuBar( toolBar );
+
+ dirMenu = new QPopupMenu( this );
+ menuBar->insertItem( tr( "Dir" ), dirMenu );
+
+ sortMenu = new QPopupMenu( this );
+ menuBar->insertItem( tr( "Sort" ), sortMenu );
+ sortMenu->insertItem( tr( "by Name "), this, SLOT( sortName() ) );
+ sortMenu->insertItem( tr( "by Size "), this, SLOT( sortSize() ) );
+ sortMenu->insertItem( tr( "by Date "), this, SLOT( sortDate() ) );
+ sortMenu->insertItem( tr( "by Type "), this, SLOT( sortType() ) );
+ sortMenu->insertSeparator();
+ sortMenu->insertItem( tr( "Ascending" ), this, SLOT( updateSorting() ) );
+ sortMenu->setItemChecked( sortMenu->idAt( 5 ), TRUE );
+ sortMenu->setItemChecked( sortMenu->idAt( 0 ), TRUE );
+
+ toolBar = new QPEToolBar( this );
+
+ lastAction = new QAction( tr("Previous dir"), Resource::loadIconSet( "back" ),
+ QString::null, 0, this, 0 );
+ connect( lastAction, SIGNAL( activated() ), fileView, SLOT( lastDir() ) );
+ lastAction->addTo( toolBar );
+ lastAction->setEnabled( FALSE );
+
+ upAction = new QAction( tr("Parent dir"), Resource::loadIconSet( "up" ),
+ QString::null, 0, this, 0 );
+ connect( upAction, SIGNAL( activated() ), fileView, SLOT( parentDir() ) );
+ upAction->addTo( toolBar );
+
+ QAction *a = new QAction( tr("New folder"), Resource::loadPixmap( "newfolder" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), fileView, SLOT( newFolder() ) );
+ a->addTo( toolBar );
+
+ a = new QAction( tr("Cut"), Resource::loadPixmap( "cut" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), fileView, SLOT( cut() ) );
+ a->addTo( toolBar );
+
+ a = new QAction( tr("Copy"), Resource::loadPixmap( "copy" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), fileView, SLOT( copy() ) );
+ a->addTo( toolBar );
+
+ pasteAction = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ),
+ QString::null, 0, this, 0 );
+ connect( pasteAction, SIGNAL( activated() ), fileView, SLOT( paste() ) );
+ pasteAction->addTo( toolBar );
+
+
+ connect( fileView, SIGNAL( dirChanged() ), SLOT( updateDirMenu() ) );
+ updateDirMenu();
+
+ QCopChannel* pcmciaChannel = new QCopChannel( "QPE/Card", this );
+ connect( pcmciaChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(pcmciaMessage( const QCString &, const QByteArray &)) );
+}
+
+void FileBrowser::pcmciaMessage( const QCString &msg, const QByteArray &)
+{
+ if ( msg == "mtabChanged()" ) {
+ // ## Only really needed if current dir is on a card
+ fileView->updateDir();
+ }
+}
+
+void FileBrowser::dirSelected( int id )
+{
+ int i = 0, j;
+ QString dir;
+
+ // Bulid target dir from menu
+ while( (j = dirMenu->idAt( i )) != id ){
+ dir += dirMenu->text( j ).stripWhiteSpace();
+ if( dirMenu->text( j ) != "/" ) dir += "/";
+ i++;
+ }
+ dir += dirMenu->text( dirMenu->idAt( i ) ).stripWhiteSpace();
+
+ fileView->setDir( dir );
+}
+
+void FileBrowser::updateDirMenu()
+{
+ QString spc, cd = fileView->cd();
+ QStringList l = QStringList::split( "/", cd );
+ int i = 0;
+
+ dirMenu->clear();
+ dirMenu->insertItem( tr( "/" ), this, SLOT( dirSelected(int) ) );
+
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ spc.fill( ' ', i++);
+ dirMenu->insertItem( spc + (*it), this,
+ SLOT( dirSelected(int) ) );
+ }
+ dirMenu->setItemChecked( dirMenu->idAt( l.count() ), TRUE );
+
+ lastAction->setEnabled( fileView->history().count() != 0 );
+ upAction->setEnabled( cd != "/" );
+}
+
+void FileBrowser::sortName()
+{
+ fileView->setSorting( 0, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
+ fileView->sort();
+ sortMenu->setItemChecked( sortMenu->idAt( 0 ), TRUE );
+ sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
+}
+
+void FileBrowser::sortSize()
+{
+ fileView->setSorting( 1, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
+ fileView->sort();
+ sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 1 ), TRUE );
+ sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
+}
+
+void FileBrowser::sortDate()
+{
+ fileView->setSorting( 2, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
+ fileView->sort();
+ sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 2 ), TRUE );
+ sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
+}
+
+void FileBrowser::sortType()
+{
+ fileView->setSorting( 3, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
+ fileView->sort();
+ sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
+ sortMenu->setItemChecked( sortMenu->idAt( 3 ), TRUE );
+}
+
+void FileBrowser::updateSorting()
+{
+ sortMenu->setItemChecked( sortMenu->idAt( 5 ), !sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
+
+ if ( sortMenu->isItemChecked( sortMenu->idAt( 0 ) ) )
+ sortName();
+ else if ( sortMenu->isItemChecked( sortMenu->idAt( 1 ) ) )
+ sortSize();
+ else if ( sortMenu->isItemChecked( sortMenu->idAt( 2 ) ) )
+ sortDate();
+ else
+ sortType();
+}
diff --git a/noncore/unsupported/filebrowser/filebrowser.h b/noncore/unsupported/filebrowser/filebrowser.h
new file mode 100644
index 0000000..2e9e444
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/filebrowser.h
@@ -0,0 +1,141 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef FILEBROWSER_H
+#define FILEBROWSER_H
+
+#include <qlistview.h>
+#include <qmainwindow.h>
+#include <qfileinfo.h>
+#include <qaction.h>
+#include <qtimer.h>
+#include <qstringlist.h>
+
+class InlineEdit;
+
+class FileItem : public QListViewItem
+{
+public:
+ FileItem( QListView * parent, const QFileInfo & fi );
+
+ QString key( int column, bool ascending = TRUE ) const;
+ QString getFilePath(){ return fileInfo.filePath(); }
+ QString getFileName(){ return fileInfo.fileName(); }
+ bool isDir(){ return fileInfo.isDir(); }
+ bool isExecutable(){ return fileInfo.isExecutable(); }
+ bool isLib();
+ int launch();
+ bool rename( const QString & name );
+private:
+ QString sizeString( unsigned int size );
+ QFileInfo fileInfo;
+};
+
+
+class FileView : public QListView
+{
+ Q_OBJECT
+
+public:
+ FileView( const QString & dir, QWidget * parent = 0,
+ const char * name = 0 );
+ void setDir( const QString & dir );
+ QString cd(){ return currentDir; }
+ QStringList history() const { return dirHistory; }
+
+public slots:
+ void updateDir();
+ void parentDir();
+ void lastDir();
+
+ void rename();
+ void copy();
+ void paste();
+ void del();
+ void cut();
+ void newFolder();
+ void viewAsText();
+
+protected:
+ void generateDir( const QString & dir );
+ void resizeEvent( QResizeEvent* );
+ void contentsMousePressEvent( QMouseEvent * e );
+ void contentsMouseReleaseEvent( QMouseEvent * e );
+
+protected slots:
+ void itemClicked( QListViewItem * i );
+ void itemDblClicked( QListViewItem * i );
+ void showFileMenu();
+ void cancelMenuTimer();
+ void selectAll(){ QListView::selectAll( TRUE ); }
+ void deselectAll(){ QListView::selectAll( FALSE ); }
+ void addToDocuments();
+ void run();
+ void endRenaming();
+
+private:
+ QString currentDir;
+ QStringList dirHistory, flist;
+ QTimer menuTimer;
+ InlineEdit * le;
+ FileItem * itemToRename;
+ bool selected;
+
+ bool copyFile( const QString & dest, const QString & src );
+
+signals:
+ void dirChanged();
+ void textViewActivated( QWidget * w );
+ void textViewDeactivated();
+};
+
+class FileBrowser : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ FileBrowser( QWidget * parent = 0,
+ const char * name = 0, WFlags f = 0 );
+ FileBrowser( const QString & dir, QWidget * parent = 0,
+ const char * name = 0, WFlags f = 0 );
+private:
+ void init(const QString & dir);
+ QString fileToCopy;
+ QPopupMenu * dirMenu, * sortMenu;
+ FileView * fileView;
+ QAction * pasteAction;
+ QAction *lastAction;
+ QAction *upAction;
+
+ bool copyFile( const QString & dest, const QString & src );
+
+private slots:
+ void pcmciaMessage( const QCString &msg, const QByteArray &);
+
+ void sortName();
+ void sortDate();
+ void sortSize();
+ void sortType();
+ void updateSorting();
+
+ void updateDirMenu();
+ void dirSelected( int id );
+};
+
+#endif
diff --git a/noncore/unsupported/filebrowser/filebrowser.pro b/noncore/unsupported/filebrowser/filebrowser.pro
new file mode 100644
index 0000000..34df79a
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/filebrowser.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = inlineedit.h \
+ filebrowser.h
+SOURCES = filebrowser.cpp \
+ inlineedit.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
diff --git a/noncore/unsupported/filebrowser/inlineedit.cpp b/noncore/unsupported/filebrowser/inlineedit.cpp
new file mode 100644
index 0000000..47c500a
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/inlineedit.cpp
@@ -0,0 +1,30 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "inlineedit.h"
+
+InlineEdit::InlineEdit( QWidget * parent, const char * name )
+ : QLineEdit( parent, name )
+{
+}
+
+void InlineEdit::focusOutEvent( QFocusEvent * )
+{
+ emit lostFocus();
+}
diff --git a/noncore/unsupported/filebrowser/inlineedit.h b/noncore/unsupported/filebrowser/inlineedit.h
new file mode 100644
index 0000000..3fbfdd6
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/inlineedit.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef INLINEEDIT_H
+#define INLINEEDIT_H
+
+#include <qlineedit.h>
+
+class InlineEdit : public QLineEdit
+{
+ Q_OBJECT
+
+public:
+ InlineEdit( QWidget * parent = 0, const char * name = 0 );
+
+signals:
+ void lostFocus();
+
+protected:
+ void focusOutEvent( QFocusEvent * );
+};
+
+#endif
diff --git a/noncore/unsupported/filebrowser/main.cpp b/noncore/unsupported/filebrowser/main.cpp
new file mode 100644
index 0000000..7304786
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/main.cpp
@@ -0,0 +1,41 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "filebrowser.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/mimetype.h>
+
+#include <qmainwindow.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ MimeType::updateApplications();
+ FileBrowser mw( QDir::current().canonicalPath() );
+ mw.resize( 240, 320 );
+ mw.setCaption( FileBrowser::tr("File Manager") );
+ a.showMainWidget( &mw );
+
+ return a.exec();
+}
diff --git a/noncore/unsupported/filebrowser/qpe-filebrowser.control b/noncore/unsupported/filebrowser/qpe-filebrowser.control
new file mode 100644
index 0000000..c55fe6a
--- a/dev/null
+++ b/noncore/unsupported/filebrowser/qpe-filebrowser.control
@@ -0,0 +1,9 @@
+Files: bin/filebrowser apps/Applications/filebrowser.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Browse the file system
+ The filebrowser for the Qtopia environment.
diff --git a/noncore/unsupported/oipkg/.cvsignore b/noncore/unsupported/oipkg/.cvsignore
new file mode 100644
index 0000000..3791def
--- a/dev/null
+++ b/noncore/unsupported/oipkg/.cvsignore
@@ -0,0 +1,10 @@
+Makefile
+moc_*
+pkfind.cpp
+pkfind.h
+pksettings.cpp
+pksettings.h
+pkdesc.cpp
+pkdesc.h
+packagemanagerbase.cpp
+packagemanagerbase.h
diff --git a/noncore/unsupported/oipkg/Makefile.in b/noncore/unsupported/oipkg/Makefile.in
new file mode 100644
index 0000000..8dd7edb
--- a/dev/null
+++ b/noncore/unsupported/oipkg/Makefile.in
@@ -0,0 +1,203 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = qipkg
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = packagemanager.h
+SOURCES = packagemanager.cpp \
+ main.cpp
+OBJECTS = packagemanager.o \
+ main.o \
+ packagemanagerbase.o \
+ pkdesc.o \
+ pkfind.o \
+ pksettings.o
+INTERFACES = packagemanagerbase.ui \
+ pkdesc.ui \
+ pkfind.ui \
+ pksettings.ui
+UICDECLS = packagemanagerbase.h \
+ pkdesc.h \
+ pkfind.h \
+ pksettings.h
+UICIMPLS = packagemanagerbase.cpp \
+ pkdesc.cpp \
+ pkfind.cpp \
+ pksettings.cpp
+SRCMOC = moc_packagemanager.cpp \
+ moc_packagemanagerbase.cpp \
+ moc_pkdesc.cpp \
+ moc_pkfind.cpp \
+ moc_pksettings.cpp
+OBJMOC = moc_packagemanager.o \
+ moc_packagemanagerbase.o \
+ moc_pkdesc.o \
+ moc_pkfind.o \
+ moc_pksettings.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake qipkg.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+packagemanager.o: packagemanager.cpp \
+ packagemanager.h \
+ packagemanagerbase.h \
+ pkdesc.h \
+ pkfind.h \
+ pksettings.h \
+ $(QPEDIR)/include/qpe/process.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/applnk.h
+
+main.o: main.cpp \
+ packagemanager.h \
+ packagemanagerbase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+packagemanagerbase.h: packagemanagerbase.ui
+ $(UIC) packagemanagerbase.ui -o $(INTERFACE_DECL_PATH)/packagemanagerbase.h
+
+packagemanagerbase.cpp: packagemanagerbase.ui
+ $(UIC) packagemanagerbase.ui -i packagemanagerbase.h -o packagemanagerbase.cpp
+
+pkdesc.h: pkdesc.ui
+ $(UIC) pkdesc.ui -o $(INTERFACE_DECL_PATH)/pkdesc.h
+
+pkdesc.cpp: pkdesc.ui
+ $(UIC) pkdesc.ui -i pkdesc.h -o pkdesc.cpp
+
+pkfind.h: pkfind.ui
+ $(UIC) pkfind.ui -o $(INTERFACE_DECL_PATH)/pkfind.h
+
+pkfind.cpp: pkfind.ui
+ $(UIC) pkfind.ui -i pkfind.h -o pkfind.cpp
+
+pksettings.h: pksettings.ui
+ $(UIC) pksettings.ui -o $(INTERFACE_DECL_PATH)/pksettings.h
+
+pksettings.cpp: pksettings.ui
+ $(UIC) pksettings.ui -i pksettings.h -o pksettings.cpp
+
+packagemanagerbase.o: packagemanagerbase.cpp
+
+pkdesc.o: pkdesc.cpp
+
+pkfind.o: pkfind.cpp
+
+pksettings.o: pksettings.cpp
+
+moc_packagemanager.o: moc_packagemanager.cpp \
+ packagemanager.h \
+ packagemanagerbase.h
+
+moc_packagemanagerbase.o: moc_packagemanagerbase.cpp \
+ packagemanagerbase.h
+
+moc_pkdesc.o: moc_pkdesc.cpp \
+ pkdesc.h
+
+moc_pkfind.o: moc_pkfind.cpp \
+ pkfind.h
+
+moc_pksettings.o: moc_pksettings.cpp \
+ pksettings.h
+
+moc_packagemanager.cpp: packagemanager.h
+ $(MOC) packagemanager.h -o moc_packagemanager.cpp
+
+moc_packagemanagerbase.cpp: packagemanagerbase.h
+ $(MOC) packagemanagerbase.h -o moc_packagemanagerbase.cpp
+
+moc_pkdesc.cpp: pkdesc.h
+ $(MOC) pkdesc.h -o moc_pkdesc.cpp
+
+moc_pkfind.cpp: pkfind.h
+ $(MOC) pkfind.h -o moc_pkfind.cpp
+
+moc_pksettings.cpp: pksettings.h
+ $(MOC) pksettings.h -o moc_pksettings.cpp
+
+
diff --git a/noncore/unsupported/oipkg/ipkg/available b/noncore/unsupported/oipkg/ipkg/available
new file mode 100644
index 0000000..a9a8ddc
--- a/dev/null
+++ b/noncore/unsupported/oipkg/ipkg/available
@@ -0,0 +1,2256 @@
+Package: ae
+Priority: optional
+Section: editors
+Installed-Size: 144
+Debian-Maintainer: Dale Scheetz (Dwarf #1) <dwarf@polaris.net>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 962-30
+Depends: libc6 (>= 2.2.1-2), slang1 (>> 1.3.0-0)
+Filename: ./ae_962-30_arm.ipk
+Size: 15635
+MD5Sum: 96f0a0a9e1c3edede3fbdd605fc4a2bb
+Description: Anthony's Editor -- a tiny full-screen editor
+ ae is a tiny full-screen text editor with both modal (vi-like)
+ and modeless (emacs-like) modes, determined by an ae.rc config file.
+
+Package: apmd
+Priority: extra
+Section: admin
+Installed-Size: 284
+Debian-Maintainer: Avery Pennarun <apenwarr@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 3.0final-1
+Depends: libc6 (>= 2.1.2), xlib6g (>= 3.3-5), xlib6g (>= 3.3.6)
+Filename: ./apmd_3.0final-1_arm.ipk
+Size: 6863
+MD5Sum: 3dcb9b6ae51b923058f0a167c7dcb680
+Description: Utilities for Advanced Power Management (APM) on laptops
+ On laptop computers, the Advanced Power Management (APM) support
+ provides access to battery status information and may help you to
+ conserve battery power, depending on your laptop and the APM
+ implementation. The apmd program also lets you run arbitrary programs
+ when APM events happen (for example, you can eject PCMCIA devices when
+ you suspend, or change hard drive timeouts when you connect the battery).
+ .
+ This package contains apmd(8), a daemon for logging and acting on APM
+ events, apm(1), a client that prints /proc/apm, xapm(1x), an X11 utility
+ that displays a little graph, on_ac_power(1), a program for shell scripts
+ to determine if wall power is connected, and tailf(1) which follows the
+ growth of a log file without writing to disk.
+ .
+ The Debian default kernel does *not* contain APM support, because it causes
+ problems on some computers. So, you need to recompile your kernel
+ and enable APM support during configuration; the corresponding questions
+ are in the 'Character devices' section.
+ .
+
+Package: ash
+Essential: yes
+Priority: required
+Section: shells
+Installed-Size: 152
+Debian-Maintainer: Herbert Xu <herbert@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 0.3.7-16
+Pre-Depends: libc6 (>= 2.2.1-2)
+Filename: ./ash_0.3.7-16_arm.ipk
+Size: 51495
+MD5Sum: 1d1f163c5655cee3c62c053b818aadb2
+Description: NetBSD /bin/sh
+ "ash" is a POSIX compliant shell that is much smaller than "bash".
+ We take advantage of that by making it the shell on the installation
+ root floppy, where space is at a premium.
+ .
+ It can be usefully installed as /bin/sh (because it executes scripts
+ somewhat faster than "bash"), or as the default shell either of root
+ or of a second user with a userid of 0 (because it depends on fewer
+ libraries, and is therefore less likely to be affected by an upgrade
+ problem or a disk failure). It is also useful for checking that a
+ script uses only POSIX syntax.
+ .
+ "bash" is a better shell for most users, since it has some nice
+ features absent from "ash", and is a required part of the system.
+
+Package: bash
+Version: 2.03-6
+Section: base
+Priority: required
+Architecture: arm
+Pre-Depends: libc6 (>= 2.1.2), libncurses5
+Depends: base-files (>= 2.1.12)
+Installed-Size: 748
+Debian-Maintainer: Matthias Klose <doko@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./bash_2.03-6_arm.ipk
+Size: 224887
+MD5Sum: 07f98861afc6d22427dd35700b342c68
+Description: The GNU Bourne Again SHell
+ Bash is an sh-compatible command language interpreter that executes
+ commands read from the standard input or from a file. Bash also
+ incorporates useful features from the Korn and C shells (ksh and csh).
+ .
+ Bash is ultimately intended to be a conformant implementation of the
+ IEEE Posix Shell and Tools specification (IEEE Working Group 1003.2).
+
+Package: blackbox
+Priority: optional
+Version: 0.1
+Architecture: arm
+Maintainer: Alexander Guy <a7r@handhelds.org>
+Depends: libc6, xlibs, libfreetype6, libstdc++2.10-glibc2.2, libxft, libxrender
+Filename: ./blackbox_0.1_arm.ipk
+Size: 145909
+MD5Sum: 02648d34fdbe00260fcb692abc9e7705
+Description: blackbox window manager
+
+Package: checkers
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs, libfreetype6, libstdc++2.10-glibc2.2, libfltk1
+Filename: ./checkers_0.0_arm.ipk
+Size: 20117
+MD5Sum: 45d08b5ead7c474711e77efcce6bff12
+Description: Play checkers against the computer
+
+Package: cpu-scale-2.4.3-rmk1-np2
+Priority: standard
+Version: 2.4.3rmk1np2
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: modutils
+Filename: ./cpu-scale-2.4.3-rmk1-np2_2.4.3rmk1np2_arm.ipk
+Size: 4068
+MD5Sum: d1b1f8bcfa511ef0a966b8435a61d69b
+Description: support for scaling the speed of the SA-1110 processor
+ This package contains a kernel module which will allow the speed of
+ the SA-1110 processor to be adjusted via /proc/scale
+
+Package: debianutils
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 172
+Debian-Maintainer: Guy Maor <maor@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.15
+Replaces: miscutils, cron (<=3.0pl1-31), debian-utils, tetex-bin (<< 1.0.6-1.1)
+Pre-Depends: libc6 (>= 2.1.97)
+Conflicts: debian-utils
+Filename: ./debianutils_1.15_arm.ipk
+Size: 9430
+MD5Sum: ce83af3644fd050fcd97988dc7074184
+Description: Miscellaneous utilities specific to Debian.
+ Debianutils includes installkernel mkboot mktemp readlink run-parts savelog
+ sensible-editor sensible-pager tempfile which.
+
+Package: dev-files
+Essential: yes
+Version: 0.4
+Priority: required
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./dev-files_0.4_arm.ipk
+Size: 2880
+MD5Sum: d4848a628a22fe664f35da48a56e98f4
+Description: devices files for /dev directory
+ This package contains a collection of devices files for /dev. I'm
+ not sure who came up with the list -- I just grabbed it from
+ familiar v0.4 bleeding. Perhaps we'll want to switch to devfs in
+ the kernel and eliminate this package?
+
+Package: diff
+Priority: optional
+Section: base
+Installed-Size: 276
+Debian-Maintainer: Santiago Vila <sanvila@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.7-24
+Pre-Depends: libc6 (>= 2.2.1-2)
+Filename: ./diff_2.7-24_arm.ipk
+Size: 35043
+MD5Sum: b016146c47582743d57144d13d5cb14c
+Description: File comparison utilities
+ `diff' shows differences between two files, or each corresponding file
+ in two directories.
+ .
+ The set of differences produced by `diff' can be used to distribute
+ updates to text files (such as program source code) to other people.
+ This method is especially useful when the differences are small compared
+ to the complete files. Given `diff' output, the `patch' program can
+ update, or "patch", a copy of the file.
+
+Package: dosfstools
+Priority: optional
+Section: otherosfs
+Installed-Size: 126
+Debian-Maintainer: Roman Hodek <roman@hodek.net>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.8-1
+Replaces: mkdosfs
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: mkdosfs
+Filename: ./dosfstools_2.8-1_arm.ipk
+Size: 14197
+MD5Sum: 8fe452f8337b43071f1fa9558b24ac0b
+Description: Utilities to create and check MS-DOS FAT filesystems
+ Inside of this package there are two utilities to create and to
+ check MS-DOS FAT filesystems on either harddisks or floppies under
+ Linux. This version uses the enhanced boot sector/superblock
+ format of DOS 3.3+ as well as provides a default dummy boot sector
+ code.
+
+Package: e2fsprogs
+Priority: required
+Section: base
+Installed-Size: 584
+Debian-Maintainer: Yann Dirson <dirson@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.19-4
+Replaces: e2fslibsg, ss2g, comerr2g
+Provides: libcomerr2, libss2, libext2fs2, libe2p2, libuuid1, e2fslibsg
+Pre-Depends: libc6 (>= 2.2.1-2)
+Suggests: gpart, parted
+Conflicts: e2fslibsg, dump (<< 0.4b4-4), quota (<< 1.55-8.1)
+Filename: ./e2fsprogs_1.19-4_arm.ipk
+Size: 135371
+MD5Sum: b61f3677ee894669d066d244969da387
+Description: The EXT2 file system utilities and libraries.
+ EXT2 stands for "Extended Filesystem", version 2. It's the main
+ filesystem type used for hard disks on Debian and other Linux systems.
+ .
+ This package contains programs for creating, checking, and maintaining EXT2
+ filesystems, and the generic `fsck' wrapper.
+
+Package: familiar-base
+Essential: yes
+Priority: required
+Version: 0.10
+Architecture: arm
+Maintainer: Alexander Guy <a7r@handhelds.org>
+Depends: sysvinit (>= 2.72)
+Pre-Depends: libc6 (>= 2.1.97)
+Filename: ./familiar-base_0.10_arm.ipk
+Size: 16749
+MD5Sum: f8da9c14594bbf9fd5350b5df072cfbd
+Description: essential files for a familiar installation
+ This package is a bit of a catch-all for files that need to be
+ installed with familiar, (I made this package from everything that
+ was still left over after I split off the rest of the files from
+ familiar v0.4 bleeding into their own packages) . Much of what it is
+ here is simply emty directories that must exist. Also, there are
+ some files here which may be created by scripts in Debian that we
+ are not yet runnging. There are probably several files here that
+ should move to other packages.
+
+Package: familiar-postinst
+Priority: optional
+Version: 0.1
+Architecture: arm
+Maintainer: Alexander Guy <a7r@handhelds.org>
+Depends: wget, ntpdate
+Filename: ./familiar-postinst_0.1_arm.ipk
+Size: 1022
+MD5Sum: f246e2efdcd8c798426e394426e327c1
+Description: A collection of shell scripts to do postinstall polishing.
+ These scripts download some of Microsoft's core True-Type Fonts,
+ as well as sync the handheld's time against a public NTP server.
+
+Package: fileutils
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 1892
+Debian-Maintainer: Michael Stone <mstone@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 4.0.43-1
+Replaces: color-ls, util-linux (<= 2.7.1-1)
+Pre-Depends: libc6 (>= 2.2.1-2)
+Conflicts: color-ls
+Filename: ./fileutils_4.0.43-1_arm.ipk
+Size: 244849
+MD5Sum: 96584322c797c44b0dc2171973b406c3
+Description: GNU file management utilities.
+ The utilities: chgrp chmod chown cp dd df dir dircolors du install ln
+ ls mkdir mkfifo mknod mv rm rmdir shred touch vdir sync.
+
+Package: fscrib
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs, libxaw7
+Filename: ./fscrib_0.0_arm.ipk
+Size: 120261
+MD5Sum: 916dd41f2ed4b0fe3b4ea08d3a80633e
+Description: Full-screen character recognition
+
+Package: fstroke
+Priority: optional
+Version: 0.2-fam1
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs, libxaw7
+Filename: ./fstroke_0.2-fam1_arm.ipk
+Size: 16248
+MD5Sum: f4fba9d28f724936cca622f374ce9347
+Description: Full-screen modeless character recognizer
+
+Package: ftp
+Version: 0.10-3.1
+Section: net
+Priority: standard
+Architecture: arm
+Depends: libc6 (>= 2.1.2), libncurses5, libreadline4 (>= 4.1)
+Replaces: netstd
+Installed-Size: 156
+Debian-Maintainer: Herbert Xu <herbert@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./ftp_0.10-3.1_arm.ipk
+Size: 33962
+MD5Sum: d8c10c5d6d03be0b84964c885927e077
+Description: The FTP client.
+ ftp is the user interface to the ARPANET standard File Transfer Protocol.
+ The program allows a user to transfer files to and from a remote network
+ site.
+Source: netkit-ftp
+
+Package: gdk-imlib1
+Priority: optional
+Section: libs
+Installed-Size: 372
+Debian-Maintainer: Ossama Othman <ossama@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: imlib
+Version: 1.9.8.1-2
+Replaces: gdk-imlib-nonfree1, libgdk-imlib-nonfree1, libgdk-imlib1
+Provides: gdk-imlib, libgdk-imlib1
+Depends: imlib-base (>= 1.9.8.1-2), libc6 (>= 2.1.97), libglib1.2 (>= 1.2.0), libjpeg62, libpng2, libtiff3g, libungif3g (>= 3.0-2) | giflib3g (>= 3.0-5.2), zlib1g (>= 1:1.1.3)
+Suggests: imlib-progs, imagemagick, netpbm, libjpeg-progs
+Conflicts: gdk-imlib-nonfree1, libgdk-imlib-nonfree1, libgdk-imlib1
+Filename: ./gdk-imlib1_1.9.8.1-2_arm.ipk
+Size: 62912
+MD5Sum: 38e2feac77d8a95288de100ed3109454
+Description: Gdk-Imlib is an imaging library for use with gtk
+ Gdk-Imlib is a low-level gdk interface for gtk programmers. It allows easier
+ access to many graphics formats and can write to them as well.
+
+Package: grep
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 488
+Debian-Maintainer: Wichert Akkerman <wakkerma@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.4.2-1
+Provides: rgrep
+Pre-Depends: libc6 (>= 2.1.2)
+Conflicts: rgrep
+Filename: ./grep_2.4.2-1_arm.ipk
+Size: 119438
+MD5Sum: 67fa4cb756f951fda7b7a5d4da2ab523
+Description: GNU grep, egrep and fgrep.
+ The GNU family of grep utilities may be the "fastest grep in the west".
+ GNU grep is based on a fast lazy-state deterministic matcher (about
+ twice as fast as stock Unix egrep) hybridized with a Boyer-Moore-Gosper
+ search for a fixed string that eliminates impossible text from being
+ considered by the full regexp matcher without necessarily having to
+ look at every character. The result is typically many times faster
+ than Unix grep or egrep. (Regular expressions containing backreferencing
+ will run more slowly, however.)
+
+Package: gzip
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 130
+Debian-Maintainer: Bdale Garbee <bdale@gag.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.2.4-33
+Depends: debianutils (>= 1.6)
+Pre-Depends: libc6 (>= 2.1)
+Filename: ./gzip_1.2.4-33_arm.ipk
+Size: 30103
+MD5Sum: e98844d058d1909781782abea0182887
+Description: The GNU compression utility.
+ This is the standard GNU file compression utility, which is also the default
+ compression tool for Debian. It typically operates on files with names
+ ending in '.gz'.
+ .
+ This package can also decompress '.Z' files created with 'compress'.
+
+Package: h3600-utils
+Priority: standard
+Version: 0.4
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6
+Filename: ./h3600-utils_0.4_arm.ipk
+Size: 2736
+MD5Sum: 5071017b84fb30c7ae33e3da97dfad80
+Description: utilities for controlling hardware on Compaq iPAQ H3600 series computers
+ This package contains programs for controlling the backlight (sic)
+ as well as the leds on the Compaq iPAQ H3600 series of handheld
+ computers.
+
+Package: hostname
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 37
+Debian-Maintainer: Adam Heath <doogie@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.07
+Pre-Depends: libc6 (>= 2.1)
+Filename: ./hostname_2.07_arm.ipk
+Size: 5277
+MD5Sum: 2e3ed84ee965ed6bb7619b443b228d63
+Description: A utility to set/show the host name or domain name
+ The hostname command can be used to either set or display
+ the current host or domain name of the system. This name is
+ used by many of the networking programs to identify the machine.
+ The domain name is also used by NIS/YP.
+
+Package: ifupdown
+Priority: important
+Section: base
+Installed-Size: 168
+Debian-Maintainer: Anthony Towns <ajt@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 0.6.4-3
+Replaces: netbase (<< 4.00)
+Depends: net-tools, libc6 (>= 2.1.2)
+Suggests: iproute
+Filename: ./ifupdown_0.6.4-3_arm.ipk
+Size: 11654
+MD5Sum: 7d60dcafa9a3526aca1fa566024e6e42
+Description: High level tools to configure network interfaces
+ This package provides the tools ifup and ifdown which may be used to
+ configure (or, respectively, deconfigure) network interfaces, based on
+ the file /etc/network/interfaces.
+
+Package: intimateboot
+Priority: optional
+Section: extras
+Installed-Size: 40960
+Debian-Maintainer: Nicolás Lichtmaier <nick@debian.org>
+Maintainer: James Conner <jim@secret.org.uk>
+Architecture: arm
+Version: 050301
+Depends: reiserfs-module (= 2.4.1-rmk1-np1 )
+Filename: ./intimateboot_050301_arm.ipk
+Size: 2518
+MD5Sum: 92532bfa8875aae0746d6901192b3cd2
+Description: This package provides the necessary boot scripts to optionally make the intimate distribution boot up. If a valid boot image for intimate is not found, then the system will boot Familiar from flash as normal. The package provides an additional linuxrc script, which may be run as an alternative to the normal one. It also provides devfs support via a small script. Booting via microdrive or NFS is supported, but you must preconfigure NFS paths etc before starting. IMPORTANT : You will need to change the linuxargs in the bootloader after installing this package. This is done by entering... 'set linuxargs "noinited devfs=mount root=/dev/mtdblock3 init=/linuxrc.intimate console=ttySA0"' and 'params save' at the boot> prompt.
+
+
+Package: ion-nasty-hacks
+Priority: optional
+Version: 200102160-fam1
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs
+Filename: ./ion-nasty-hacks_200102160-fam1_arm.ipk
+Size: 58518
+MD5Sum: 79a39fcb686adf83942ad50ad32845f4
+Description: a text-editorish, keyboard/stylus friendly window manager
+
+Package: ipkg
+Essential: yes
+Priority: required
+Version: 0.4-fam1
+Architecture: all
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: shellutils, textutils, sed, grep, gzip, tar, wget
+Filename: ./ipkg_0.4-fam1_all.ipk
+Size: 5306
+MD5Sum: 6502942cc864d29cf005925a168747cd
+Description: Lightweight package management system
+
+Package: irda-common
+Version: 0.9.14-3
+Section: misc
+Priority: optional
+Architecture: arm
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: irda-utils
+Replaces: irda-utils
+Installed-Size: 100
+Debian-Maintainer: NOKUBI Takatsugu <knok@daionet.gr.jp>
+Maintainer: Alexander Guy <a7r@andern.org>
+Source: irda-utils
+Filename: ./irda-common_0.9.14-3_arm.ipk
+Size: 5259
+MD5Sum: d41a70d88dbf47b63bf601cbe176b121
+Description: IrDA management utilities
+ IrDA management utilities for Linux.
+ This package contains irmanager and irattach.
+
+Package: irda-modules-2.4.3-rmk2-np1
+Priority: extra
+Maintainer: Alexander Guy <a7r@andern.org>
+Depends: kernel-modules-2.4.3-rmk2-np1
+Version: fam3
+Architecture: arm
+Filename: ./irda-modules-2.4.3-rmk2-np1_fam3_arm.ipk
+Size: 194859
+MD5Sum: 7af6f1d272eb0cb135162fb9f9bb2c76
+Description: IrDA kernel modules
+ The entire suite of kernel modules required to use both SIR and FIR
+ IrDA. This includes IrCOMM, and IrLAN support.
+
+Package: iv
+Essential: yes
+Priority: required
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Provides: vi
+Depends: libc6
+Filename: ./iv_0.0_arm.ipk
+Size: 8364
+MD5Sum: 9cf155930e6db23ddece8705df27d99d
+Description: Lightweight reimplementation of vi <attribution?>
+
+Package: kernel-modules-2.4.3-rmk2-np1
+Essential: yes
+Priority: required
+Version: fam3
+Architecture: arm
+Maintainer: Alexander Guy <a7r@andern.org>
+Depends: modutils
+Filename: ./kernel-modules-2.4.3-rmk2-np1_fam3_arm.ipk
+Size: 585458
+MD5Sum: 2cd52706ce0157337664414bc6e75943
+Description: kernel modules for kernel 2.4.3-rmk2-np1
+ This package contains almost all of the kernel modules that might be
+ useful within familiar. Eventually I would like to split many of
+ these modules off into their own packages that would have dependency
+ links from the programs that need them. For example, e2fsprogs could
+ depend on e2fs-kernel-modules or something like that. I have already
+ split off cpu-scale and the pcmcia modules into their own packages.
+
+Package: less
+Version: 346-7
+Section: text
+Priority: standard
+Architecture: arm
+Depends: libc6 (>= 2.1.2), libncurses5, debianutils (>= 1.8)
+Installed-Size: 163
+Debian-Maintainer: Thomas Schoepf <schoepf@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./less_346-7_arm.ipk
+Size: 41734
+MD5Sum: 617280f25bba9c4b03e631af7cd969b2
+Description: A file pager program, similar to more(1)
+ Less is a program similar to more (1), but which allows backward
+ movement in the file as well as forward movement. Also, less does not
+ have to read the entire input file before starting, so with large input
+ files it starts up faster than text editors like vi (1). Less uses
+ termcap (or terminfo on some systems), so it can run on a variety of
+ terminals. There is even limited support for hardcopy terminals.
+ .
+ Homepage: http://www.flash.net/~marknu/less/
+
+Package: libc6
+Priority: required
+Section: base
+Installed-Size: 13104
+Debian-Maintainer: Ben Collins <bcollins@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: glibc
+Version: 2.2.2-1
+Replaces: ldso (<= 1.9.11-9), timezone, timezones, gconv-modules, libtricks
+Provides: gconv-modules, glibc2.2
+Suggests: locales, glibc-doc
+Conflicts: libdb2 (= 2:2.7.7-2.1), timezone, timezones, gconv-modules, libtricks, libc6-doc
+Filename: ./libc6_2.2.2-1_arm.ipk
+Size: 1100492
+MD5Sum: 4944634b673b732d4a9fc8ec87a1447c
+Description: GNU C Library: Shared libraries and Timezone data
+ Contains the standard libraries that are used by nearly all programs on
+ the system. This package includes shared versions of the standard C library
+ and the standard math library, as well as many others.
+ Timezone data is also included.
+
+Package: libdb2
+Priority: optional
+Section: libs
+Installed-Size: 388
+Debian-Maintainer: Ben Collins <bcollins@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Source: db
+Version: 2:2.7.7-3
+Architecture: arm
+Replaces: libdb2.6, lib-bdb2
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: lib-bdb2
+Filename: ./libdb2_2.7.7-3_arm.ipk
+Size: 138089
+MD5Sum: ed771a8cdf8225b98db3c61b39a05d07
+Description: The Berkeley database routines (run-time files).
+ libdb2 is a library for manipulating database files, developed at
+ Berkeley and extended by Sleepycat Software Inc.
+ This is the stable version, also commercially supported.
+ .
+ It supports three kinds of file formats:
+ * btree. A representation of a sorted, balanced tree structure.
+ * hashed. An extensible, dynamic hashing scheme.
+ * UNIX file oriented. A byte stream file with fixed or variable
+ length records.
+ Other core database services:
+ * page cache management for fast access, clean page allocation.
+ * lock with multiple reader/writer granularity.
+ * nested transaction support with logging and rollback recovery
+ (two phase commit).
+ * Large set of utility, to dump/load/restore data and examine log.
+
+Package: libfltk1
+Priority: optional
+Section: libs
+Installed-Size: 370
+Debian-Maintainer: Fabrizio Polacco <fpolacco@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: fltk
+Version: 1.0.9-1.1
+Depends: libc6 (>= 2.2.1-2), libgl1, libstdc++2.10-glibc2.2, xlibs (>= 4.0.1-11)
+Filename: ./libfltk1_1.0.9-1.1_arm.ipk
+Size: 186802
+MD5Sum: 59c552236fc0e89fd4fb7474d6fbfe0a
+Description: The Fast Light Toolkit, a GUI toolkit inspired by libForms
+ This is a very nice LGPL'd graphic user interface toolkit originally based on
+ libForms. Programs written using libForms will hopefully be ported to libfltk
+ in the future and will need this package to run.
+
+Package: libfreetype6
+Priority: optional
+Section: libs
+Installed-Size: 396
+Debian-Maintainer: Anthony Fok <foka@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: freetype
+Version: 2.0.1.20010317-1
+Replaces: freetype0, freetype1
+Depends: libc6 (>= 2.2.1-2)
+Suggests: libfreetype6-dev
+Conflicts: freetype
+Filename: ./libfreetype6_2.0.1.20010317-1_arm.ipk
+Size: 106977
+MD5Sum: 639030e1e406cc87c44db49a70de9f34
+Description: FreeType 2 font engine, shared library files.
+ The FreeType project is a team of volunteers who develop free,
+ portable and high-quality software solutions for digital typography.
+ They specifically target embedded systems and focus on bringing small,
+ efficient and ubiquitous products.
+ .
+ The FreeType 2 library is their new software font engine. It has been
+ designed to provide the following important features:
+ * A universal and simple API to manage font files
+ * Support for several font formats through loadable modules
+ * High-quality anti-aliasing
+ * High portability & performance
+ .
+ Supported font formats include:
+ * TrueType files (.ttf) and collections (.ttc)
+ * Type 1 font files both in ASCII (.pfa) or binary (.pfb) format
+ * Type 1 Multiple Master fonts. The FreeType 2 API also provides
+ routines to manage design instances easily
+ * Type 1 CID-keyed fonts
+ * OpenType/CFF (.otf) fonts
+ * CFF/Type 2 fonts
+ * Adobe CEF fonts (.cef), used to embed fonts in SVG documents with
+ the Adobe SVG viewer plugin.
+ * Windows FNT/FON bitmap fonts
+ .
+ This package contains the files needed to run programs that use the
+ FreeType 2 library.
+ .
+ Home Page: http://www.freetype.org/
+ Authors: David Turner <david.turner@freetype.org>
+ Robert Wilhelm <robert.wilhelm@freetype.org>
+ Werner Lemberg <werner.lemberg@freetype.org>
+
+Package: libglade0
+Priority: optional
+Section: libs
+Installed-Size: 164
+Debian-Maintainer: Paolo Molaro <lupus@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libglade
+Version: 0.16-2
+Depends: libc6 (>= 2.2.1-2), libglib1.2 (>= 1.2.0), libgtk1.2 (>= 1.2.8-3), libxml1, xlibs (>= 4.0.1-11), zlib1g (>= 1:1.1.3)
+Filename: ./libglade0_0.16-2_arm.ipk
+Size: 35028
+MD5Sum: 26211c69d51e1f8abd45022eaadb25b1
+Description: Library to load .glade files at runtime.
+ This library allows you to load user interfaces in your program, which are
+ stored externally. This allows alteration of the interface without
+ recompilation of the program.
+ .
+ The interfaces can also be edited with GLADE.
+
+Package: libglib1.2
+Priority: optional
+Section: libs
+Installed-Size: 264
+Debian-Maintainer: Ben Gertzfield <che@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: glib1.2
+Version: 1.2.10-1
+Replaces: libgtk-doc
+Depends: libc6 (>= 2.2.1-2)
+Suggests: libgtk1.2
+Filename: ./libglib1.2_1.2.10-1_arm.ipk
+Size: 68147
+MD5Sum: 1fe1ad635bc78331c9e3ae27406ddc12
+Description: The GLib library of C routines
+ GLib is a library containing many useful C routines for things such
+ as trees, hashes, and lists. GLib was previously distributed with
+ the GTK+ toolkit, but has been split off as of the developers' version
+ 1.1.0.
+ .
+ You do not need to install this package if you have libgtk1 (note 1,
+ not 1.1 or 1.2) installed. libgtk1 included libglib in it. libgtk1.1
+ and libgtk1.2, however, do need libglib1.1 to be installed separately.
+
+Package: libgtk1.2
+Priority: optional
+Section: libs
+Installed-Size: 2184
+Debian-Maintainer: Ben Gertzfield <che@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: gtk+1.2
+Version: 1.2.10-1
+Replaces: libgtk1.1.5, libgtk1.1.6, libgtk1.1.9, libgtk1.1.11, libgtk1.1.12, libgtk1.1.13, libgtk1.1.14, libgtk1.1.15, libgtk1.1.16
+Depends: libc6 (>= 2.2.1-2), libglib1.2 (>= 1.2.0), xlibs (>= 4.0.1-11)
+Pre-Depends: dpkg (>= 1.6.8)
+Conflicts: libgtk-dev (<< 1:1.0.2)
+Filename: ./libgtk1.2_1.2.10-1_arm.ipk
+Size: 602094
+MD5Sum: b0ff676813a80f1017876b125bb9bad0
+Description: The GIMP Toolkit set of widgets for X
+ The GIMP Toolkit is a freely available set of widgets for X.
+ GTK is easy to use, and has been implemented in such projects as
+ The GNU Image Manipulation Program (The GIMP), GNOME, a GNU
+ desktop set of utilities for X, and gzilla, a GNU web-browser.
+
+Package: libjpeg62
+Priority: optional
+Section: libs
+Installed-Size: 204
+Debian-Maintainer: Mark Mickan <mmickan@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libjpeg6b
+Version: 6b-1.3
+Replaces: libjpeg6b
+Provides: libjpeg6b
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: libjpeg6b
+Filename: ./libjpeg62_6b-1.3_arm.ipk
+Size: 64434
+MD5Sum: 2cabfc091e7755c93a3d78b2dff48f0f
+Description: The Independent JPEG Group's JPEG runtime library [libc6]
+ This package contains the shared library.
+
+Package: libncurses5
+Version: 5.0-6.0potato1
+Section: base
+Priority: required
+Architecture: arm
+Depends: libc6 (>= 2.1.2), ncurses-base
+Installed-Size: 427
+Debian-Maintainer: Joel Klecker <ncurses-maint@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./libncurses5_5.0-6.0potato1_arm.ipk
+Size: 101390
+MD5Sum: 6f1a19d05c5f8d312efb33e05318d714
+Description: Shared libraries for terminal handling
+ This package contains the shared libraries necessary to run programs
+ compiled with ncurses.
+Source: ncurses
+
+Package: libpam0g
+Priority: required
+Section: base
+Installed-Size: 152
+Debian-Maintainer: Sam Hartman <hartmans@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: pam
+Version: 0.72-21
+Replaces: libpam0g-util
+Depends: libc6 (>= 2.2.1-2), libpam-runtime
+Suggests: libpam-doc
+Conflicts: libpam0 (<= 0.56-2), libpam
+Filename: ./libpam0g_0.72-21_arm.ipk
+Size: 18191
+MD5Sum: 21196b782a3327aa39382825db2d64f1
+Description: Pluggable Authentication Modules library
+ Contains the C shared library for Linux-PAM, a suite of shared
+ libraries that enable the local system administrator to choose how
+ applications authenticate users. In other words, without rewriting
+ or recompiling a PAM-aware application, it is possible to switch
+ between the authentication mechanism(s) it uses. One may entirely
+ upgrade the local authentication system without touching the
+ applications themselves.
+
+Package: libpam-modules
+Priority: required
+Section: base
+Installed-Size: 472
+Debian-Maintainer: Sam Hartman <hartmans@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: pam
+Version: 0.72-21
+Replaces: libpam0g-util
+Provides: libpam-motd, libpam-mkhomedir
+Depends: libc6 (>= 2.2.1-2), libcap1, libdb3 (>= 3.2.9-1), libpam0g (>= 0.72-1)
+Conflicts: libpam0g-modules (= 0.66-1), libpam-motd, libpam-mkhomedir, suidmanager (<< 0.50)
+Filename: ./libpam-modules_0.72-21_arm.ipk
+Size: 20438
+MD5Sum: 23a98606804b0600dcc81ff26ad5772f
+Description: Pluggable Authentication Modules for PAM
+ This package completes the set of modules for PAM. It includes the
+ the pam_unix_*.so module as well as some specialty modules.
+
+Package: libpam-runtime
+Priority: required
+Section: base
+Installed-Size: 132
+Debian-Maintainer: Sam Hartman <hartmans@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: pam
+Version: 0.72-21
+Replaces: libpam0g-util, libpam0g-dev
+Conflicts: libpam0g-util, libpam0g (<< 0.66-0)
+Filename: ./libpam-runtime_0.72-21_arm.ipk
+Size: 2495
+MD5Sum: 183d85691a48163576f7b62e8cc43184
+Description: Runtime support for the PAM library
+ Contains the base setup for libpam
+
+Package: libpng2
+Priority: standard
+Section: libs
+Installed-Size: 288
+Debian-Maintainer: Philippe Troin <phil@fifi.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libpng
+Version: 1.0.8-1
+Depends: libc6 (>= 2.1.2), libz1
+Filename: ./libpng2_1.0.8-1_arm.ipk
+Size: 74734
+MD5Sum: ef8044db7824d9e486c6d9fb1c677168
+Description: PNG library - runtime
+ libpng is a library implementing an interface for reading and writing
+ PNG (Portable Network Graphics) format files.
+ .
+ This library is more recent than libpng0g, and you should use it rather
+ than libpng0g (which is for legacy packages).
+
+Package: libpopt0
+Priority: important
+Section: base
+Installed-Size: 92
+Debian-Maintainer: Joseph Carter <knghtbrd@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: popt
+Version: 1.5-0.1
+Replaces: popt
+Depends: libc6 (>= 2.1.2)
+Conflicts: popt, libpopt-dev (<= 1.4-1)
+Filename: ./libpopt0_1.5-0.1_arm.ipk
+Size: 11129
+MD5Sum: 9a43286e1b181448f36a1939d4cea530
+Description: lib for parsing cmdline parameters
+ Popt was heavily influenced by the getopt() and getopt_long() functions,
+ but it allows more powerful argument expansion. It can parse arbitrary
+ argv[] style arrays and automatically set variables based on command
+ line arguments. It also allows command line arguments to be aliased via
+ configuration files and includes utility functions for parsing arbitrary
+ strings into argv[] arrays using shell-like rules.
+ .
+ This package contains the runtime library and locale data.
+
+Package: libreadline4
+Version: 4.1-1
+Section: base
+Priority: required
+Architecture: arm
+Depends: libc6 (>= 2.1.2), libncurses5
+Installed-Size: 260
+Debian-Maintainer: Matthias Klose <doko@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Filename: ./libreadline4_4.1-1_arm.ipk
+Size: 67959
+MD5Sum: bb6ad084c0b2b9b6251f43d5ddd2e28e
+Description: GNU readline and history libraries, run-time libraries.
+ The GNU readline library aids in the consistency of user interface
+ across discrete programs that need to provide a command line
+ interface.
+ .
+ The GNU history library provides a consistent user interface for
+ recalling lines of previously typed input.
+Source: readline4
+
+Package: libssl0.9.6
+Priority: optional
+Section: non-us/main
+Installed-Size: 1062
+Debian-Maintainer: Christoph Martin <christoph.martin@uni-mainz.de>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: openssl
+Version: 0.9.6a-1
+Replaces: libssl, libssl096
+Provides: libssl096
+Depends: libc6 (>= 2.2.1-2), libssl0.9.6
+Conflicts: ssleay (<< 0.9.2b), libssl, openssl (<< 0.9.6-2), libssl096, libssl096-dev (<< 0.9.6-2)
+Filename: ./libssl0.9.6_0.9.6a-1_arm.ipk
+Size: 309622
+MD5Sum: d1d6d8f48a48eb86f22e89f1a7f8dc06
+Description: SSL shared libraries
+ libssl and libcrypto shared libraries needed by programs like
+ apache-ssl, telnet-ssl and openssh.
+ .
+ It is part of the OpenSSL implementation of SSL.
+
+Package: libstdc++2.10-glibc2.2
+Priority: required
+Section: base
+Installed-Size: 328
+Debian-Maintainer: Debian GCC maintainers <gcc@packages.debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: gcc-2.95 (2.95.4.ds1-0.010407)
+Version: 1:2.95.4-0.010407
+Depends: libc6 (>= 2.2.1-2)
+Filename: ./libstdc++2.10-glibc2.2_2.95.4-0.010407_arm.ipk
+Size: 161222
+MD5Sum: 3d5c530f551cb14aaaccfcb2c221741f
+Description: The GNU stdc++ library
+ NOTE: This is not a final release, but taken from the CVS gcc-2_95-branch
+ (dated 20010407).
+ .
+ This package contains an additional runtime library for C++ programs
+ built with the GNU compiler.
+
+Package: libungif3g
+Priority: optional
+Section: graphics
+Installed-Size: 88
+Debian-Maintainer: Adam Heath <doogie@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libungif
+Version: 3.0-3
+Replaces: giflib3g
+Provides: giflib3g
+Depends: libc6 (>= 2.1.2), xlib6g (>= 3.3.6)
+Conflicts: libgif3g, libgif2, giflib3g
+Filename: ./libungif3g_3.0-3_arm.ipk
+Size: 16148
+MD5Sum: 65985228c87656161d3bdcfb1771185e
+Description: shared library for GIF images (runtime lib)
+ This is a shared library for working with GIF images.
+ .
+ The libungif library is a specially modified version of giflib which
+ is free of the Unisys LZW patent. It can read all GIFs, but only
+ write uncompressed GIFs. If you need to be able to write compressed
+ GIFs, you can install the non-free giflib packages instead (which may
+ not be available on CD).
+
+Package: libwrap0
+Priority: important
+Section: base
+Installed-Size: 136
+Debian-Maintainer: Anthony Towns <ajt@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: tcp-wrappers
+Version: 7.6-7
+Depends: libc6 (>= 2.1.2)
+Recommends: tcpd
+Conflicts: netbase (<< 3.16-1)
+Filename: ./libwrap0_7.6-7_arm.ipk
+Size: 13202
+MD5Sum: 18fd9d5e2f2e30652ee460aa1e97a5b1
+Description: Wietse Venema's TCP wrappers library
+ Wietse Venema's network logger, also known as TCPD or LOG_TCP.
+ .
+ These programs log the client host name of incoming telnet,
+ ftp, rsh, rlogin, finger etc. requests. Security options are:
+ access control per host, domain and/or service; detection of
+ host name spoofing or host address spoofing; booby traps to
+ implement an early-warning system.
+
+Package: libxaw6
+Priority: optional
+Section: libs
+Installed-Size: 372
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: xfree86
+Version: 4.0.2-13
+Replaces: xlib6g (<< 4.0)
+Depends: libc6 (>= 2.2.1-2), xlibs (>= 4.0.1-11)
+Conflicts: xlib6g (<< 4.0)
+Filename: ./libxaw6_4.0.2-13_arm.ipk
+Size: 125255
+MD5Sum: e5b9dbfc091f69133156ae0c53e80f43
+Description: X Athena widget set library (version 6)
+ Xaw is a widget set based on the the Xt (X Toolkit Intrinsics) library.
+ It provides a set of graphical user-interface elements ("widgets") such as
+ menus, scrollbars, dialog boxes, text-input areas, and so forth. The X
+ clients distributed with the X Window System itself, as well as many
+ others, use the Athena widget set.
+ .
+ The version of the Athena widgets in this package corresponds to the
+ X11R6.4 release of the X Window System. XFree86 has made significant
+ enhancements to the Athena widget set; their version can be found in the
+ libxaw7 package.
+
+Package: libxaw7
+Priority: optional
+Section: libs
+Installed-Size: 484
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: xfree86
+Version: 4.0.2-13
+Depends: libc6 (>= 2.2.1-2), xlibs (>= 4.0.1-11)
+Filename: ./libxaw7_4.0.2-13_arm.ipk
+Size: 176321
+MD5Sum: 19b82bde7d895cf3227e5e5aa20c4222
+Description: X Athena widget set library
+ Xaw is a widget set based on the the Xt (X Toolkit Intrinsics) library.
+ It provides a set of graphical user-interface elements ("widgets") such as
+ menus, scrollbars, dialog boxes, text-input areas, and so forth. The X
+ clients distributed with the X Window System itself, as well as many
+ others, use the Athena widget set.
+ .
+ XFree86 has made a number of major improvements to the Athena widget set,
+ resulting in version 7 -- this version features widgets customizable in
+ appearance and event handling (a.k.a. "themes"); an extensible image
+ loader (currently supports bitmaps, gradients, and pixmaps); numerous
+ enhancements to the Text widget, text source and text sink objects; and
+ multiple-column support in the SimpleMenu widget.
+ .
+ The older Athena widget library corresponding to version X11R6.4 of the X
+ Window System can be found in the libxaw6 package.
+
+Package: libxft
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6
+Filename: ./libxft_0.0_arm.ipk
+Size: 44433
+MD5Sum: 5c9660cd2b8f1317a6ce677b094708ff
+Description: libxft <needs better description here>
+
+Package: libxml1
+Priority: optional
+Section: libs
+Installed-Size: 480
+Debian-Maintainer: Fredrik Hallenberg <hallon@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libxml
+Version: 1:1.8.11-1
+Replaces: libxml0
+Provides: libxml0
+Depends: libc6 (>= 2.1.97), zlib1g (>= 1:1.1.3)
+Conflicts: libxml0
+Filename: ./libxml1_1.8.11-1_arm.ipk
+Size: 122515
+MD5Sum: ffc5f30c0e229aec973ba2dedf8bf38a
+Description: GNOME XML library
+ XML is a metalanguage to let you design your own markup language.
+ A regular markup language defines a way to describe information in
+ a certain class of documents (eg HTML). XML lets you define your
+ own customized markup languages for many classes of document. It
+ can do this because it's written in SGML, the international standard
+ metalanguage for markup languages.
+
+Package: libxmltok1
+Priority: optional
+Section: libs
+Installed-Size: 176
+Debian-Maintainer: Ardo van Rangelrooij <ardo@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: libxmltok
+Version: 1.1-5
+Depends: libc6 (>= 2.1.97)
+Filename: ./libxmltok1_1.1-5_arm.ipk
+Size: 36765
+MD5Sum: 2669363932f3538598690504e8bd843b
+Description: XML Parser Toolkit, runtime libraries
+ Libraries for XML parsing in C, which contains the shared libraries,
+ libxmltok and libxmlparser. These libraries are being used, for
+ instance, for XML support to Netscape 5 and the Perl module,
+ XML::Parser.
+ .
+ Author: James Clark <jjc@jclark.com>
+ Homepage: http://www.jclark.com/xml/expat.html
+
+Package: libxrender
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6
+Filename: ./libxrender_0.0_arm.ipk
+Size: 7748
+MD5Sum: ddc4cf38278e868247db1daf82d3390d
+Description: X rendering extension
+
+Package: loadmeter
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs
+Filename: ./loadmeter_0.0_arm.ipk
+Size: 17294
+MD5Sum: 68863f7c94238b4902722e9555a40f52
+Description: graphical CPU load montitoring
+
+Package: login
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 312
+Debian-Maintainer: Ben Collins <bcollins@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: shadow
+Version: 20000902-3.1
+Replaces: shadow-login, shadow-passwd, shellutils (<< 2.0-2)
+Depends: libpam-modules (>= 0.72-5)
+Pre-Depends: libc6 (>= 2.2.1-2), libpam0g (>= 0.72-1)
+Conflicts: shadow-login, pam-apps, secure-su, suidregister (<< 0.50)
+Filename: ./login_20000902-3.1_arm.ipk
+Size: 24402
+MD5Sum: 7817225e43bb8e999f89c58152d23de4
+Description: System login tools
+ These tools are required to be able to login and use your system. The
+ login program invokes you user shell and enables command execution. The
+ newgrp program is used to change your effective group ID (useful for
+ workgroup type situations). The su program allows changing your effective
+ user ID (useful being able to execute commands as another user).
+ .
+ Also supplies a logout daemon that can place limits on when, from where,
+ and for how long certain users can login to the system.
+
+Package: lrzsz
+Essential: yes
+Priority: required
+Section: comm
+Installed-Size: 264
+Debian-Maintainer: Josip Rodin <jrodin@jagor.srce.hr>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 0.12.21-4
+Depends: libc6 (>= 2.2.1-2)
+Suggests: minicom
+Filename: ./lrzsz_0.12.21-4_arm.ipk
+Size: 64893
+MD5Sum: 6f1a0ea3c0bc986b96c916192fe318ab
+Description: Tools for zmodem/xmodem/ymodem file transfer
+ Lrzsz is a cosmetically modified zmodem/ymodem/xmodem package built
+ from the public-domain version of Chuck Forsberg's rzsz package.
+ .
+ These programs use error correcting protocols ({z,x,y}modem) to send
+ (sz, sx, sb) and receive (rz, rx, rb) files over a dial-in serial port
+ from a variety of programs running under various operating systems.
+
+Package: madplay
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6
+Filename: ./madplay_0.0_arm.ipk
+Size: 70830
+MD5Sum: 5ff68a920d656af9c8aaefaa1362a0f1
+Description: Fast, high-quality, fixed-point MP3 player
+
+Package: mingle
+Priority: optional
+Version: 0.1
+Architecture: arm
+Maintainer: Gareth J. Greenaway <gareth@wiked.org>
+Depends: python
+Filename: ./mingle_0.1_arm.ipk
+Size: 51136
+MD5Sum: 5954457eb75f93c38f941d283ea05f50
+Description: Mingle contact manager illustrating the use of the Familiar Framework project.
+
+Package: mixer
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs
+Filename: ./mixer_0.0_arm.ipk
+Size: 8729
+MD5Sum: 50d2997c142037603450e53c6af14bf6
+Description: control audio levels graphically
+
+Package: modutils
+Priority: required
+Section: base
+Installed-Size: 564
+Debian-Maintainer: Wichert Akkerman <wakkerma@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.4.2-1
+Replaces: manpages (<=1.15-3)
+Depends: libc6 (>= 2.1.97), sysvinit (>=2.71-2)
+Suggests: ksymoops
+Filename: ./modutils_2.4.2-1_arm.ipk
+Size: 113605
+MD5Sum: 8046533303655791c7c1a16f76224346
+Description: Linux module utilities.
+ These utilities are intended to make a Linux modular kernel
+ manageable for all users, administrators and distribution
+ maintainers.
+Origin: debian
+Bugs: debbugs://bugs.debian.org/
+
+Package: mount
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 228
+Debian-Maintainer: Adrian Bunk <bunk@fs.tum.de>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: util-linux
+Version: 2.11b-2
+Pre-Depends: libc6 (>= 2.2.1-2)
+Filename: ./mount_2.11b-2_arm.ipk
+Size: 41072
+MD5Sum: ddc0df15fb6d3aac711d0a77172df6c2
+Description: Tools for mounting and manipulating filesystems.
+ This package provides the mount(8), umount(8), swapon(8),
+ swapoff(8), and losetup(8) commands.
+
+Package: ncurses-base
+Priority: required
+Section: base
+Installed-Size: 222
+Debian-Maintainer: Daniel Jacobowitz <ncurses-maint@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: all
+Source: ncurses
+Version: 5.2.20010318-1
+Replaces: ncurses-term
+Provides: ncurses-runtime
+Conflicts: ncurses, ncurses-runtime
+Filename: ./ncurses-base_5.2.20010318-1_all.ipk
+Size: 8901
+MD5Sum: 67746347774792cff7d97adf0ff4c272
+Description: Descriptions of common terminal types
+ This package contains what should be a reasonable subset of terminal
+ definitions, including: ansi, dumb, linux, rxvt, screen, sun, vt100,
+ vt102, vt220, vt52, and xterm.
+
+Package: netbase
+Priority: important
+Section: base
+Installed-Size: 110
+Debian-Maintainer: Anthony Towns <ajt@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: all
+Version: 4.05
+Depends: net-tools | iproute, ifupdown, ipchains | ipfwadm | iptables, netkit-inetd, tcpd, netkit-ping | iputils-ping
+Suggests: debconf, ipmasqadm | ipautofw | iptables, portmap, netkit-rpc
+Conflicts: xinetd (<= 2.2.1-8), netstd (<< 3.00), nfs-user-server (<< 2.2beta47-9), nis (<= 3.6-2), rstatd (<= 3.03-3), rwalld (<= 0.16-1), rusersd (<= 0.17-1), ugidd (<< 2.2beta47-9)
+Filename: ./netbase_4.05_all.ipk
+Size: 9502
+MD5Sum: 029f1dffa57f6b23f97b08b5262dfc38
+Description: Basic TCP/IP networking system
+ This package provides the necessary infrastructure for basic TCP/IP based
+ networking.
+
+Package: netcat
+Priority: optional
+Section: net
+Installed-Size: 228
+Debian-Maintainer: Decklin Foster <decklin@red-bean.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.10-17
+Depends: libc6 (>= 2.2.1-2)
+Filename: ./netcat_1.10-17_arm.ipk
+Size: 12265
+MD5Sum: 14101b949ee963abb64de99130725c6f
+Description: TCP/IP swiss army knife
+ A simple Unix utility which reads and writes data across network
+ connections using TCP or UDP protocol. It is designed to be a reliable
+ "back-end" tool that can be used directly or easily driven by other
+ programs and scripts. At the same time it is a feature-rich network
+ debugging and exploration tool, since it can create almost any kind of
+ connection you would need and has several interesting built-in
+ capabilities.
+
+Package: netkit-ping
+Priority: important
+Section: net
+Installed-Size: 84
+Debian-Maintainer: Anthony Towns <ajt@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: netkit-base
+Version: 0.10-6.1
+Replaces: netbase (<< 4.00)
+Provides: ping
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: ping
+Filename: ./netkit-ping_0.10-6.1_arm.ipk
+Size: 10418
+MD5Sum: cdf51bd27a0e95867f1ee7ab7c328192
+Description: The ping utility from netkit
+ The ping command sends ICMP ECHO_REQUEST packets to a host in order to
+ test if the host is reachable via the network.
+
+Package: net-tools
+Priority: important
+Section: net
+Installed-Size: 676
+Debian-Maintainer: Bernd Eckenfels <ecki@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.59-1
+Replaces: netbase (<< 4.00)
+Depends: libc6 (>= 2.2.1-2)
+Filename: ./net-tools_1.59-1_arm.ipk
+Size: 100555
+MD5Sum: 5f8cd79e32b953142faed78f46dd5625
+Description: The NET-3 networking toolkit
+ This package includes the important tools for controlling the network
+ subsystem of the Linux kernel. This includes arp, ifconfig, netstat,
+ rarp, nameif and route. Additionally, this package contains utilities
+ relating to particular network hardware types (plipconfig, slattach) and
+ advanced aspects of IP configuration (iptunnel, ipmaddr).
+ .
+ In the upstream package 'hostname' and friends are included. Those are
+ not installed by this package, since there is a special "hostname*.deb".
+
+Package: ntpdate
+Priority: optional
+Section: net
+Installed-Size: 132
+Debian-Maintainer: Bdale Garbee <bdale@gag.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: ntp
+Version: 1:4.0.99g-3
+Replaces: ntp (<< 4.0.98a),xntp,xntp3
+Depends: libc6 (>= 2.2.1-2)
+Suggests: ntp
+Conflicts: ntp (<< 4.0.98a),chrony
+Filename: ./ntpdate_4.0.99g-3_arm.ipk
+Size: 22995
+MD5Sum: 628963690db28b96a036356abcee8860
+Description: The ntpdate client for setting system time from NTP servers.
+ The ntpdate client allows a system's clock to be set to match the time
+ obtained by communicating with one or more servers running the NTP protocol.
+ .
+ The use of ntpdate is optional if you're running the ntp package, it can help
+ a system obtain lock if it starts with a time that's pretty close by using
+ ntpdate before starting the daemon.
+ .
+ The ntpdate client by itself is useful for occasionally setting the time on
+ machines that are not on the net full-time, such as laptops.
+
+Package: pcmcia-cs
+Priority: extra
+Version: 0.0-fam3
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6 (>= 2.2.1-2), modutils, psmisc
+Suggests: pcmcia-modules, xlibs (>= 4.0.1-11)
+Filename: ./pcmcia-cs_0.0-fam3_arm.ipk
+Size: 57178
+MD5Sum: 123d19e3199f7598e6517efe6e2a2080
+Description: PCMCIA Card Services for Linux.
+ NOTE: I couldn't find this package in Debian/arm so I just grabbed
+ the control file from my Debian/i386 and combined it with the
+ pcmcia-cs bits from familiar v0.4 bleeding. A better solution would
+ be to rebuild the real .deb from the pcmcia-cs source.
+ .
+ PCMCIA cards are commonly used in laptops to provide expanded
+ capabilities, such as modems, increased memory, etc. Some desktop PCs
+ can accept PCMCIA cards as well, although this is rare.
+ .
+ Card Services for Linux is a complete PCMCIA support package. It
+ includes a set of client drivers for specific cards, and a card
+ manager daemon that can respond to card insertion and removal events,
+ loading and unloading drivers on demand. It supports ``hot swapping''
+ of PCMCIA cards, so cards can be inserted and ejected at any time.
+ .
+ The actual kernel modules required for this package are contained in
+ the pcmcia-modules-<kernel version> package, where <kernel version> is
+ the version of the kernel for which the modules have been compiled.
+
+Package: pcmcia-modules-2.4.3-rmk2-np1
+Priority: extra
+Maintainer: Alexander Guy <a7r@andern.org>
+Depends: kernel-modules-2.4.3-rmk2-np1, pcmcia-cs
+Version: fam3
+Architecture: arm
+Filename: ./pcmcia-modules-2.4.3-rmk2-np1_fam3_arm.ipk
+Size: 111546
+MD5Sum: 95da695ec0792cdb70b86aaf5eb48e7c
+Description: PCMCIA kernel modules
+ The full collection of PCMCIA kernel modules from pcmcia-cs. Install
+ this if you will be plugging any Compact Flash or PCMCIA cards into
+ your computer.
+ .
+ We may want to split these up into many fine-grained packages.
+
+Package: ppp
+Priority: standard
+Section: base
+Installed-Size: 764
+Debian-Maintainer: Michael Beattie <mjb@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.4.0f-1
+Replaces: ppp-pam
+Depends: libc6 (>= 2.1.2), libpam0g, libpam-modules, netbase, sysvinit (>= 2.75-4)
+Suggests: debconf
+Conflicts: ppp-pam
+Filename: ./ppp_2.4.0f-1_arm.ipk
+Size: 96430
+MD5Sum: 2bd0da8e83b6d609a4a5dc498564ce06
+Description: Point-to-Point Protocol (PPP) daemon.
+ The Point-to-Point Protocol (PPP) provides a standard way to transmit
+ datagrams over a serial link, as well as a standard way for the machines
+ at either end of the link (the "peers") to negotiate various optional
+ characteristics of the link. Using PPP, a serial link can be used to
+ transmit Internet Protocol (IP) datagrams, allowing TCP/IP connections
+ between the peers.
+ .
+ This package contains pppd with PAM support built-in, so `ppp-pam'
+ package is obsolete.
+
+Package: procps
+Priority: required
+Section: base
+Installed-Size: 484
+Debian-Maintainer: Craig Small <csmall@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1:2.0.7-4
+Replaces: watch, bsdutils (<< 2.9x-1)
+Provides: watch
+Depends: libc6 (>= 2.2.1-2), libncurses5
+Recommends: psmisc
+Conflicts: watch, libproc-dev (<< 1:1.2.6-2), w-bassman (<< 1.0-3), procps-nonfree, pgrep (<< 3.3-5)
+Filename: ./procps_2.0.7-4_arm.ipk
+Size: 46669
+MD5Sum: 374592eb63c1100ebded8c4129954cc3
+Description: The /proc file system utilities.
+ These are utilities to browse the /proc filesystem, which is not a real file
+ system but a way for the kernel to provide information about the status of
+ entries in its process table. (e.g. running, stopped or "zombie")
+ Both command line and full screen utilities are provided. Ncurses is needed
+ for the full screen utilities.
+
+Package: pump
+Priority: optional
+Section: base
+Installed-Size: 144
+Debian-Maintainer: Steve Dunham <dunham@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 0.8.3-3
+Replaces: pump-udeb
+Depends: libc6 (>= 2.1.97)
+Conflicts: dhcpcd, dhcpcd-sv, pump-udeb
+Filename: ./pump_0.8.3-3_arm.ipk
+Size: 25830
+MD5Sum: 1f0b17323498f46c111531b03df1153d
+Description: Simple DHCP/BOOTP client.
+ This is the DHCP/BOOTP client written by RedHat.
+
+Package: pyditor
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: python
+Filename: ./pyditor_0.0_arm.ipk
+Size: 1444
+MD5Sum: c7209f99c5036c9ece32918905086cc5
+Description: python-based text editor
+
+Package: python
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, libdb2
+Filename: ./python_0.0_arm.ipk
+Size: 834371
+MD5Sum: 30aaff82d29a7ed787f7d288c8743794
+Description: python of course <needs real description>
+
+Package: qiv
+Priority: extra
+Section: graphics
+Installed-Size: 86
+Debian-Maintainer: Mitch Blevins <mblevin@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.6-1
+Depends: gdk-imlib1 (>= 1.9.8.1-2), libc6 (>= 2.1.97), libglib1.2 (>= 1.2.0), libgtk1.2 (>= 1.2.8-3), xlibs (>= 4.0.1-11)
+Filename: ./qiv_1.6-1_arm.ipk
+Size: 15767
+MD5Sum: 877b1dc63c32b1f468a20a7ade4818f5
+Description: a quick image viewer for X
+ Quick Image Viewer (qiv) is a very small and pretty fast GDK/Imlib
+ image viewer. Features include zoom, maxpect, scale down, fullscreen,
+ brightness/contrast/gamma correction, slideshow, flip,
+ horizontal/vertical, rotate left/right, delete (move to .qiv-trash/),
+ jump to image x, jump forward/backward x images, filename filter and
+ you can use qiv to set your X11-Desktop background.
+
+Package: reiserfs-module
+Priority: optional
+Section: kernel
+Installed-Size: 249337
+Debian-Maintainer: Nicolás Lichtmaier <nick@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.4.3-rmk2-np1
+Depends: kernel (= 2.4.3-rmk2-np1)
+Filename: ./reiserfs-module_2.4.3-rmk2-np1_arm.ipk
+Size: 106059
+MD5Sum: f1975bedcc503d1ee66a9e627350b813
+Description: Reiserfs is a journaling filesystem. This is the kernel module for it.
+
+Package: rsync
+Priority: optional
+Section: net
+Installed-Size: 280
+Debian-Maintainer: Philip Hands <phil@hands.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.4.6-1
+Depends: libc6 (>= 2.1.2)
+Suggests: ssh
+Filename: ./rsync_2.4.6-1_arm.ipk
+Size: 74003
+MD5Sum: ce2d8f8672994f93bb03c38919fdb504
+Description: fast remote file copy program (like rcp)
+ rsync is a program that allows files to be copied to and from remote
+ machines in much the same way as rcp. It has many more options than
+ rcp, and uses the rsync remote-update protocol to greatly speedup
+ file transfers when the destination file already exists.
+ .
+ The rsync remote-update protocol allows rsync to transfer just the
+ differences between two sets of files across the network link.
+
+Package: rxvt
+Priority: optional
+Section: x11
+Installed-Size: 580
+Debian-Maintainer: Brian Mays <brian@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1:2.6.3-8-fam1
+Provides: x-terminal-emulator
+Depends: libc6 (>= 2.1.97), xlibs (>= 4.0.1-11), base-passwd (>= 2.0.3.4)
+Conflicts: suidmanager (<< 0.50)
+Filename: ./rxvt_2.6.3-8-fam1_arm.ipk
+Size: 40759
+MD5Sum: e514f9093a45e8a95db37123a193b974
+Description: VT102 terminal emulator for the X Window System
+ Rxvt is an 8-bit clean, color xterm replacement that uses significantly
+ less memory than a conventional xterm, mostly since it doesn't support
+ toolkit configurability or Tek graphics, but also since features can
+ be removed at compile-time to reflect your needs.
+ .
+ The distribution also includes rclock, the smaller/better xclock
+ replacement with appointment scheduling and xbiff functionality.
+
+Package: rxvt-aa
+Priority: optional
+Section: x11
+Installed-Size: 580
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1:2.6.3-8
+Provides: x-terminal-emulator
+Depends: libc6 (>= 2.1.97), xlibs (>= 4.0.1-11), base-passwd (>= 2.0.3.4), libxft, libxrender
+Conflicts: suidmanager (<< 0.50)
+Filename: ./rxvt-aa_2.6.3-8_arm.ipk
+Size: 42018
+MD5Sum: c042c85c082d043aa5a58d4c62c67b70
+Description: rxvt with support for anti-aliased fonts
+ This package proves an rxvt terminal with support for anti-aliased fonts.
+ .
+ Rxvt is an 8-bit clean, color xterm replacement that uses significantly
+ less memory than a conventional xterm, mostly since it doesn't support
+ toolkit configurability or Tek graphics, but also since features can
+ be removed at compile-time to reflect your needs.
+ .
+ The distribution also includes rclock, the smaller/better xclock
+ replacement with appointment scheduling and xbiff functionality.
+
+Package: screen
+Priority: optional
+Version: 3.9.8
+Architecture: arm
+Maintainer: Brian Kearns <bdkearns@bdkearns.net>
+Depends: ncurses-base, libncurses5, libc6
+Filename: ./screen_3.9.8_arm.ipk
+Size: 134749
+MD5Sum: 80b9bb7de6b30ecdeadc04f0bcda875a
+Description: Console manager
+
+Package: script-test
+Priority: optional
+Version: 0.0
+Architecture: all
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends:
+Filename: ./script-test_0.0_all.ipk
+Size: 820
+MD5Sum: ea6b272ff25bb69482a9907492b316a0
+Description: Empty test for ipkg script support
+
+Package: sed
+Priority: required
+Section: base
+Installed-Size: 180
+Debian-Maintainer: Wichert Akkerman <wakkerma@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 3.02-6
+Pre-Depends: libc6 (>= 2.1.2)
+Filename: ./sed_3.02-6_arm.ipk
+Size: 12338
+MD5Sum: c893daf6fef70813b566db8ed8c06950
+Description: The GNU sed stream editor.
+ sed reads the specified files or the standard input if no
+ files are specified, makes editing changes according to a
+ list of commands, and writes the results to the standard
+ output.
+
+Package: shellutils
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 2152
+Debian-Maintainer: Michael Stone <mstone@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.0.11-5
+Replaces: bsdutils (<= 3.0-2), util-linux (<< 2.9e-0.1)
+Pre-Depends: libc6 (>= 2.2.1-2), login | hurd
+Conflicts: login (<< 19990827-1)
+Filename: ./shellutils_2.0.11-5_arm.ipk
+Size: 123564
+MD5Sum: a9a70a1fd2e2057ed43e5a069d521d0d
+Description: The GNU shell programming utilities.
+ The utilities: basename chroot date dirname echo env expr factor false groups
+ hostid id logname nice nohup pathchk pinky printenv printf pwd seq sleep stty
+ tee test true tty uname users who whoami yes.
+
+Package: slang1
+Priority: optional
+Section: libs
+Installed-Size: 456
+Debian-Maintainer: Jim Mintha <jmintha@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: slang
+Version: 1.4.4-1
+Depends: libc6 (>= 2.2.1-2)
+Filename: ./slang1_1.4.4-1_arm.ipk
+Size: 159766
+MD5Sum: 775f054fdda315ef73afc9399612a7ad
+Description: The S-Lang programming library - runtime version.
+ S-Lang is a C programmer's library that includes routines for the rapid
+ development of sophisticated, user friendly, multi-platform applications.
+ .
+ This package contains only the shared library libslang.so.* and copyright
+ information. It is only necessary for programs that use this library (such
+ as jed and slrn). If you plan on doing development with S-Lang, you will
+ need the companion -dev package as well.
+
+
+Package: ssh
+Priority: optional
+Section: non-US
+Installed-Size: 1020
+Debian-Maintainer: Philip Hands <phil@hands.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: openssh
+Version: 1:2.5.2p2-2
+Depends: libc6 (>= 2.2.1-2), libpam0g (>= 0.72-1), libssl0.9.6, libwrap0, zlib1g (>= 1:1.1.3), libpam-modules (>= 0.72-9), libwrap0 (>= 7.6-1.1)
+Suggests: ssh-askpass, debconf, xbase-clients, dpkg (>= 1.8.3.1)
+Conflicts: ssh-nonfree, ssh-socks, ssh2, debconf (<< 0.2.17), debconf-tiny (<< 0.2.17), sftp, rsh-client (<< 0.16.1-1)
+Filename: ./ssh_2.5.2p2-2_arm.ipk
+Size: 210692
+MD5Sum: 1fe9ccb1693d36d4388758f73f041d9b
+Description: Secure rlogin/rsh/rcp replacement (OpenSSH)
+ OpenSSH is derived from OpenBSD's version of ssh, which was in turn
+ derived from ssh code from before the time when ssh's license was
+ changed to be non-free.
+ Ssh (Secure Shell) is a program for logging into a remote machine
+ and for executing commands on a remote machine.
+ It provides secure encrypted communications between two untrusted
+ hosts over an insecure network. X11 connections and arbitrary TCP/IP
+ ports can also be forwarded over the secure channel.
+ It is intended as a replacement for rlogin, rsh and rcp, and can be
+ used to provide rdist, and rsync with a secure communication channel.
+ .
+ --------------------------------------------------------------------
+ .
+ This software may be freely imported into the United States; however,
+ the United States Government may consider re-exporting it a criminal
+ offense. Thus, if you are outside the US, please retrieve this
+ software from outside the US.
+ In some countries, particularly Russia, Iraq, Pakistan, and France, it
+ may be illegal to use any encryption at all without a special permit.
+
+Package: stowaway-h3600
+Priority: optional
+Version: 1.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6
+Filename: ./stowaway-h3600_1.0_arm.ipk
+Size: 15470
+MD5Sum: 67c0f14bf6a5e523ed7a95b6fca02a79
+Description: Support for the iPAQ H3600 series Stowaway keyboard
+
+Package: sysset
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: python
+Filename: ./sysset_0.0_arm.ipk
+Size: 2878
+MD5Sum: 5124d246b5b7da481874f97fb86c859f
+Description: python utility for configuring system settings
+
+Package: sysvinit
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 207
+Debian-Maintainer: Miquel van Smoorenburg <miquels@cistron.nl>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.78-4
+Replaces: last, bsdutils (<=2.0-2)
+Depends: dpkg (>= 1.4.0.21), mount (>= 2.7i-1), util-linux (>= 2.9t-2), e2fsprogs (>= 1.15-1)
+Pre-Depends: libc6 (>= 2.1.2)
+Conflicts: last, file-rc (<= 0.4.2), kbd (<< 0.95-2), mdutils (<< 0.35-9)
+Filename: ./sysvinit_2.78-4_arm.ipk
+Size: 43771
+MD5Sum: ebf719f849e02d9bdfd66f54e129398e
+Description: System-V like init.
+ Init is the first program to run after your system is booted, and
+ continues to run as process number 1 until your system halts. Init's
+ job is to start other programs that are essential to the operation of
+ your system. All processes are descended from init. For more information,
+ see the manual page init(8).
+
+Package: tar
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 1064
+Debian-Maintainer: Bdale Garbee <bdale@gag.com>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.13.19-1
+Pre-Depends: libc6 (>= 2.1.97)
+Suggests: bzip2
+Filename: ./tar_1.13.19-1_arm.ipk
+Size: 67084
+MD5Sum: 4f93d22d8645b86b6fb49c375254045e
+Description: GNU tar
+ Tar is a program for packaging a set of files as a single archive in tar
+ format. The function it performs is conceptually similar to cpio, and to
+ things like pkzip in the DOS world. It is heavily used by the Debian package
+ management system, and is useful for performing system backups and exchanging
+ sets of files with others.
+
+Package: task-bootstrap
+Priority: optional
+Version: 0.6
+Architecture: arm
+Maintainer: Alexander Guy <a7r@handhelds.org>
+Depends: ssh, ppp, pcmcia-modules-2.4.3-rmk2-np1, wireless-tools, pump
+Filename: ./task-bootstrap_0.6_arm.ipk
+Size: 693
+MD5Sum: 1dc75245df83987c0cb26f1953d2e9ec
+Description: Everything you might need to bootstrap a minimal ipkg system.
+
+Package: task-familiar-complete
+Priority: optional
+Version: 0.5
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: apmd, checkers, cpu-scale-2.4.3-rmk2-np1, dosfstools, fscrib, h3600-utils, libglade0, libpopt0, libxaw6, libxml1, libxmltok1, loadmeter, ncurses-base, netcat, ntpdate, pcmcia-modules-2.4.3-rmk2-np1, procps, ppp, pump, pyditor, qiv, rsync, ssh, sysset, xvkbd, task-mp3-player, task-games, task-wireless, task-x
+Filename: ./task-familiar-complete_0.5_arm.ipk
+Size: 808
+MD5Sum: f117049d5863f2e70d9903f9bc83475e
+Description: Task package for a complete familiar system
+
+Package: task-games
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: checkers
+Filename: ./task-games_0.0_arm.ipk
+Size: 994
+MD5Sum: 48f5a22131a2f4aada009620b1242438
+Description: Task package for a complete familiar system
+
+Package: task-mp3-player
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: madplay, mixer
+Filename: ./task-mp3-player_0.0_arm.ipk
+Size: 667
+MD5Sum: aa5f5c85ccb22af9c4f6f677522df9e7
+Description: Task package for a complete familiar system
+
+Package: task-wireless
+Priority: optional
+Version: 0.1
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: wireless-tools, pcmcia-modules-2.4.3-rmk2-np1
+Filename: ./task-wireless_0.1_arm.ipk
+Size: 639
+MD5Sum: 988d6d2960bf165b5ed324dbfb85d674
+Description: Task package for wireless networking
+
+Package: task-x
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: xserver-tiny-h3600, xbase-clients, xfonts-base, xfonts-75dpi, xfonts-ttf, blackbox, rxvt-aa, xcalibrate
+Filename: ./task-x_0.0_arm.ipk
+Size: 739
+MD5Sum: 78d7c74c9fdac90f3b58fba7231a4ff8
+Description: Task package for a basic X system
+
+Package: textutils
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 1550
+Debian-Maintainer: Herbert Xu <herbert@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.0-3
+Replaces: bsdmainutils (<= 4.5.2), ptx
+Provides: ptx
+Pre-Depends: libc6 (>= 2.1.2)
+Conflicts: ptx
+Filename: ./textutils_2.0-3_arm.ipk
+Size: 156555
+MD5Sum: fbdac4eb344aea6287461bc8dc613add
+Description: The GNU text file processing utilities.
+ The utilities: cat cksum comm csplit cut expand fmt fold head join md5sum
+ nl od paste pr ptx sort split sum tac tail tr tsort unexpand uniq wc.
+
+Package: urlget
+Priority: optional
+Version: 0.3
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, netbase
+Filename: ./urlget_0.3_arm.ipk
+Size: 2613
+MD5Sum: 271ae2fbfd1e691d2b19d24ba1c01648
+Description: Tiny package for retrieving files via HTTP
+
+Package: util-linux
+Essential: yes
+Priority: required
+Section: base
+Installed-Size: 840
+Debian-Maintainer: Adrian Bunk <bunk@fs.tum.de>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 2.11b-2-fam2
+Replaces: miscutils, setterm, getty, fdisk
+Pre-Depends: libc6 (>= 2.2.1-2), libncurses5 (>= 5.2.20010310-1)
+Recommends: util-linux-locales
+Suggests: kbd | console-tools
+Conflicts: setterm, getty, fdisk, kbd (<< 1.05-3), console-tools (<< 1:0.2.3-21)
+Filename: ./util-linux_2.11b-2-fam2_arm.ipk
+Size: 9771
+MD5Sum: e1abcd568a156976ac95eff239dbb091
+Description: Miscellaneous system utilities.
+ A mixed bag of system utilities: arch chkdupexe cfdisk cytune dmesg
+ fdisk fsck.minix getty getopt hwclock ipcrm ipcs mcookie mkfs mkfs.minix
+ mkswap more namei pivot_root raw rdev setterm setsid tunelp whereis.
+
+Package: wget
+Priority: optional
+Section: web
+Installed-Size: 1272
+Debian-Maintainer: Nicolás Lichtmaier <nick@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 1.6-2
+Depends: libc6 (>= 2.2.1-2), netbase
+Filename: ./wget_1.6-2_arm.ipk
+Size: 62824
+MD5Sum: bbc13feb01f63a86cb6a542bf629cc77
+Description: utility to retrieve files from the WWW via HTTP and FTP
+ Wget [formerly known as Geturl] is a freely available network utility
+ to retrieve files from the World Wide Web using HTTP and FTP, the two
+ most widely used Internet protocols. It works non-interactively, thus
+ enabling work in the background, after having logged off.
+ .
+ The recursive retrieval of HTML pages, as well as FTP sites is
+ supported -- you can use Wget to make mirrors of archives and home
+ pages, or traverse the web like a WWW robot (Wget understands
+ /robots.txt).
+
+Package: wireless-tools
+Priority: optional
+Section: net
+Installed-Size: 120
+Debian-Maintainer: Björn Andersson <bjorn@lifix.fi>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Version: 20-1.1
+Depends: libc6 (>= 2.2.1-2)
+Filename: ./wireless-tools_20-1.1_arm.ipk
+Size: 17032
+MD5Sum: 695142d573351ca6e8ddffcfc77fa195
+Description: Tools for manipulating Linux Wireless Extensions
+ This package contains the Wireless tools, used to manipulate
+ the Linux Wireless Extensions. The Wireless Extension is an interface
+ allowing you to set Wireless LAN specific parameters and get the
+ specific stats.
+ .
+ The tools in this package only work with kernel versions 2.2.14
+ and above, and 2.3.24 and above.
+
+Package: xbase-clients
+Priority: optional
+Section: x11
+Installed-Size: 3916
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: xfree86
+Version: 4.0.2-13
+Replaces: xbase (<< 3.3.2.3a-2), xf86setup (<< 3.3.2.3a-9), xserver-common (<< 4.0), xmodmap, xcontrib, xpm4g-dev, xpm-bin, xsm
+Provides: xmodmap, xcontrib, xpm-bin, xsm
+Depends: debconf (>= 0.3.83), cpp, libc6 (>= 2.2.1-2), libfreetype6, libgl1, libncurses5 (>= 5.2.20010310-1), libxaw7 (>= 4.0.1-1), xlibs (>= 4.0.1-11)
+Conflicts: xbase (<< 3.3.2.3a-2), xserver-common (<< 3.3.2.3a-9), xmodmap, xaw-wrappers (<< 0.90), xfonts-100dpi (<< 3.3.3.1-3), xfonts-75dpi (<< 3.3.3.1-3), xfonts-base (<< 3.3.3.1-3), xfonts-cyrillic (<< 3.3.3.1-3), xfonts-scalable (<< 3.3.3.1-3), xfnt100 (<= 3.3.2.3a-1), xfnt75 (<= 3.3.2.3a-1), xfntbase (<= 3.3.2.3a-1), xfntcyr (<= 3.3.2.3a-1), xfntscl (<= 3.3.2.3a-1), xdm (<< 4.0), xsm, xcontrib, xpm4g-dev, xpm-bin
+Filename: ./xbase-clients_4.0.2-13_arm.ipk
+Size: 205512
+MD5Sum: 60ff8d6dfa873abf4c0d611fff7d268c
+Description: miscellaneous X clients
+ An X client is a program that interfaces with an X server (almost always
+ via the X libraries), and thus with some input and output hardware like a
+ graphics card, monitor, keyboard, and pointing device (such as a mouse).
+ .
+ This package provides a miscellaneous assortment of several dozen X
+ clients that ship with the X Window System, including:
+ - startx and xinit, which initialize X sessions from the command line;
+ - xauth, a tool for controlling access to the X session;
+ - xedit, a text editor;
+ - xbiff, a tool which tells you when you have new email;
+ - xcalc, a scientific calculator desktop accessory;
+ - xclipboard, a tool to manage cut-and-pasted text selections;
+ - xcutsel, which exchanges selection and cut buffer contents;
+ - xconsole, which monitors system console messages;
+ - xditview, a viewer for ditroff output;
+ - xeyes, a demo program in which a pair of eyes track the pointer;
+ - xfd, a tool that displays all the glyphs in a given X font;
+ - xfontsel, a tool for browsing and selecting X fonts;
+ - xhost, a very dangerous program that you should never use;
+ - xkill, a tool for terminating misbehaving X clients;
+ - xload, a monitor for the system load average;
+ - xlogo, a demo program that displays the X logo;
+ - xmag, which magnifies parts of the X screen;
+ - xman, a manual page browser;
+ - xmessage, a tool to display message or dialog boxes;
+ - xrefresh, a tool that forces a redraw of the X screen;
+ - xsetroot, a tool for tailoring the appearance of the root window;
+ - xvidtune, a tool for customizing X server modelines for your monitor;
+ - xwd, a utility for taking window dumps ("screenshots") of the X session;
+ - xwud, a viewer for window dumps created by xwd;
+ - oclock and xclock, graphical clocks;
+ - beforelight, a screen saver;
+ - bitmap, a monochrome bitmap file editor;
+ - bmtoa, a tool that converts a monochrome bitmap to ASCII text;
+ - cxpm and sxpm, tools for checking and viewing X pixmap files;
+ - iceauth, a tool for manipulating ICE protocol authorization records;
+ - xset, a tool for setting miscellaneous X server parameters;
+ - xmodmap, a utility for modifying keymaps and pointer button mappings in X;
+ - xsetmode and xsetpointer, tools for handling X Input devices;
+ - setxkbmap, xkbbell, xkbcomp, xkbevd, xkbprint, xkbvleds, and xkbwatch,
+ tools for managing the X keyboard extension (XKB);
+ - xsm, a session manager for X sessions;
+ - smproxy, a session manager proxy for X clients that do not use the X
+ session manager protocol;
+ - xgamma, a tool for querying and setting a monitor's gamma correction;
+ - appres, editres, listres, viewres, and xrdb, which query and update the
+ X resource database;
+ - Xmark, x11perf, x11perfcomp, and xieperf, tools for benchmarking
+ graphical operations under the X Window System;
+ - fstobdf, which retrieves a font in BDF format from an X font server;
+ - xcmsdb, a device color characteristic utility for the X Color Management
+ System;
+ - xstdcmap, a utility to selectively define standard colormap properties;
+ - xev, an X event displayer;
+ - xfindproxy, a tool to locate X proxy services;
+ - xlsatoms, which lists interned atoms defined on an X server;
+ - xlsclients, which lists client applications running on an X display;
+ - xlsfonts, a server font list displayer;
+ - xprop, a property displayer for X;
+ - xdpyinfo, a display information utility for X;
+ - xwininfo, a window information utility for X;
+ - glxinfo, a GLX extension information utility for X;
+ - xvinfo, an Xv extension information utility for X;
+ - ico, an X graphics demo using an animated polyhedron;
+ - dga, a demo program for the DGA extension; and
+ - xgc, an (unfinished) X graphics demo program.
+
+Package: xcalibrate
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs
+Filename: ./xcalibrate_0.0_arm.ipk
+Size: 6641
+MD5Sum: 1ff1b7f86d9ee3c4f9d261d6c69059be
+Description: calibrate the iPAQ H3600 touch screen for X
+
+Package: xfonts-75dpi
+Priority: optional
+Section: x11
+Installed-Size: 2912
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: all
+Source: xfree86
+Version: 4.0.2-13
+Replaces: xfnt75
+Provides: xfnt75
+Depends: xutils
+Suggests: xfs | xserver
+Conflicts: xfnt75, xbase-clients (<< 4.0)
+Filename: ./xfonts-75dpi_4.0.2-13_all.ipk
+Size: 173134
+MD5Sum: b99622fecd62b08624fd4c0977b61cfd
+Description: 75 dpi fonts for X
+ xfonts-75dpi provides a set of bitmapped fonts at 75 dots per inch. In most
+ cases it is desirable to have the X font server (xfs) and/or an X server
+ installed to make the fonts available to X clients.
+ .
+ This package and xfonts-100dpi provide the same set of fonts, rendered at
+ different resolutions; only one or the other is necessary, but both may be
+ installed. xfonts-75dpi may be more suitable for small monitors and/or small
+ screen resolutions (under 1024x768).
+ .
+ This package requires the xutils package to prepare the font directories
+ for use by an X server or X font server.
+
+Package: xfonts-base
+Priority: optional
+Section: x11
+Installed-Size: 7724
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: all
+Source: xfree86
+Version: 4.0.2-13
+Replaces: xfntbase, xfonts-cjk
+Provides: xfntbase, xfonts-cjk
+Depends: xutils
+Suggests: xfs, xserver
+Conflicts: xfntbase, xfonts-cjk, xbase-clients (<< 4.0)
+Filename: ./xfonts-base_4.0.2-13_all.ipk
+Size: 24879
+MD5Sum: 26837af24947d47947962450480e9258
+Description: standard fonts for X
+ xfonts-base provides a standard set of low-resolution bitmapped fonts. In
+ most cases it is desirable to have the X font server (xfs) and/or an X server
+ installed to make the fonts available to X clients.
+ .
+ If you are not using a remote font server, you must install this package if
+ you are installing an X server. It contains fonts without which X servers
+ will not work.
+ .
+ This package also provides a set of files that can be used by the X or
+ fonts server to transcode fonts from one encoding to another (e.g., KOI8-R
+ to ISO-8859-5).
+ .
+ This package requires the xutils package to prepare the font directories
+ for use by an X server or X font server.
+
+Package: xfonts-ttf
+Priority: optional
+Version: 0.0
+Architecture: all
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: xutils
+Filename: ./xfonts-ttf_0.0_all.ipk
+Size: 15567
+MD5Sum: ec6912955eda9edf873f892677fae523
+Description: free TrueType fonts to be used within X
+
+Package: xlibs
+Priority: optional
+Section: libs
+Installed-Size: 4306
+Debian-Maintainer: Branden Robinson <branden@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: xfree86
+Version: 4.0.2-13
+Replaces: xlib, xbase (<< 3.3.2.3a-2), xlib6 (<< 3.3.2.3-2), xbase-clients (<< 4.0), xlib6g (<< 4.0), xlib6g-dev (<< 4.0), xpm4g, fvwm-common, xcontrib
+Provides: libxpm4
+Depends: xfree86-common (>> 4.0), libc6 (>= 2.2.1-2), xlibs (>= 4.0.1-11)
+Conflicts: xlib, xlib6 (<< 3.3.2.3-2), xlib6g (<< 4.0), xlib6g-dev (<< 4.0), xbase-clients (<< 4.0), xpm4g
+Filename: ./xlibs_4.0.2-13_arm.ipk
+Size: 820973
+MD5Sum: ad9b6742385277d8cf63cfcdde41d4dc
+Description: X Window System client libraries
+ NOTE: I really want to break this package up into lots of little
+ packages for familiar, (mainly so we can dump things like Xt if no
+ binaries depend on them). - Carl Worth <cworth@handhelds.org>
+ .
+ The X libraries are an interface between X client programs and the
+ hardware-oriented X servers, and consist of routines to read input from the
+ keyboard and pointer, draw on the screen, etc., in an abstract manner that is
+ independent of the particular characteristics of the hardware. The X
+ libraries, and the programs that use them, communicate with X servers by
+ means of the X protocol.
+ .
+ libX11 (a.k.a. Xlib) provides the low-level functionality, dealing mostly
+ with the wire protocol and in terms of basic operations such as opening and
+ closing the X protocol connection, creating graphics contexts, drawing
+ graphics primitives such as lines, arcs, and glyphs, handling events, and so
+ forth.
+ .
+ libXpm, the X pixmap library, is a set of routines used to store and retrieve
+ X pixmaps (a data structure comprising a rectangular array of pixels) from
+ files; the xpm file format is an extension of the monochrome bitmap file
+ format in the X11 specification. (Traditionally, libXpm was maintained and
+ distributed separately from the X Window System, but XFree86 has absorbed
+ this library).
+ .
+ libXt, the X Toolkit Instrinsics, is an abstract widget library upon which
+ graphical widget libraries (such as Athena and LessTif) may be developed; the
+ Intrinsics provide a number of useful interfaces to X conventions and
+ protocols, in many cases reducing a long series of Xlib calls to just a
+ couple of Xt calls.
+ .
+ libXmu is a set of miscellaneous utility functions useful to client
+ programmers.
+ .
+ The remainder of the libraries in this package implement the client side
+ of various X protocol extensions:
+ - libICE, the Inter-Client Exchange extension;
+ - libPEX5, PEX, a 3D graphics extension now superseded by Mesa/OpenGL;
+ - libSM, the Session Management extension;
+ - libXIE, the X Image Extension;
+ - libXext, a collection of several commonly-used extensions;
+ - libXi, the X Input extension;
+ - libXp, the X Printing extension; and
+ - libXtst, the X Testing extension.
+ .
+ xlibs also contains the XKB keyboard parameter files, locale data, and a set
+ of bitmap and pixmap image files commonly used by X clients.
+
+Package: xserver-tiny-h3600
+Priority: optional
+Version: 0.2
+Architecture: arm
+Maintainer: Alexander Guy <a7r@handhelds.org>
+Depends: libc6, zlib1g, h3600-utils
+Filename: ./xserver-tiny-h3600_0.2_arm.ipk
+Size: 405916
+MD5Sum: dbbc661d81cec5a8ac402ebbfd682c4d
+Description: X server for the iPAQ H3600 display and touchscreen.
+
+Package: xvkbd
+Priority: optional
+Version: 0.0
+Architecture: arm
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: libc6, xlibs, libxaw6
+Filename: ./xvkbd_0.0_arm.ipk
+Size: 13591
+MD5Sum: 45cd39eebf02283965268bbba5436528
+Description: On-screen virtual keyboard for X
+
+Package: zlib1g
+Priority: standard
+Section: libs
+Installed-Size: 144
+Debian-Maintainer: Mark Brown <broonie@debian.org>
+Maintainer: Carl Worth <cworth@handhelds.org>
+Architecture: arm
+Source: zlib
+Version: 1:1.1.3-14
+Provides: libz1
+Depends: libc6 (>= 2.2.1-2)
+Conflicts: zlib1 (<= 1:1.0.4-7)
+Filename: ./zlib1g_1.1.3-14_arm.ipk
+Size: 28970
+MD5Sum: c7f98957d73220efb3e39ec75ac09c23
+Description: compression library - runtime
+ zlib is a library implementing the deflate compression method found
+ in gzip and pkzip. This package includes the shared library.
+
diff --git a/noncore/unsupported/oipkg/ipkg/status b/noncore/unsupported/oipkg/ipkg/status
new file mode 100644
index 0000000..ddcd5fa
--- a/dev/null
+++ b/noncore/unsupported/oipkg/ipkg/status
@@ -0,0 +1,418 @@
+Package: ash
+Status: install ok installed
+Essential: yes
+Version: 0.3.7-16
+
+Package: libc6
+Status: install ok installed
+Version: 2.2.2-1
+
+Package: debianutils
+Status: install ok installed
+Essential: yes
+Version: 1.15
+
+Package: dev-files
+Status: install ok installed
+Essential: yes
+Version: 0.4
+
+Package: dpkg
+Status: install ok installed
+Essential: yes
+Version: 1.8.3.1
+
+Package: libncurses5
+Status: install ok installed
+Version: 5.0-6.0potato1
+
+Package: libstdc++2.10-glibc2.2
+Status: install ok installed
+Version: 1:2.95.4-0.010407
+
+Package: e2fsprogs
+Status: install ok installed
+Version: 1.19-4
+
+Package: ncurses-base
+Status: install ok installed
+Conffiles: /etc/terminfo/a/ansi 6b60f35a7fb6122a53b1e74e56cba56e /etc/terminfo/d/dumb ca3b114f0727da81a9b957b553a9915d /etc/terminfo/l/linux 8d94e8037f878a0468b4a29a28e83933 /etc/terminfo/m/mach 215cacd84662e9e93e998833477da362 /etc/terminfo/m/mach-bold 2dfb5dc3b706cd29273ab25f20394ac8 /etc/terminfo/m/mach-color a4b356122e490897b411db4893c8483e /etc/terminfo/p/pcansi 8b97f1ea94e8d2942c8dcd2d943e1322 /etc/terminfo/r/rxvt 5fb0eff2f9d74b42ab9bf6532ae4b54b /etc/terminfo/r/rxvt-m fd21b1fd19f15558368fbfaca40c92ce /etc/terminfo/s/screen e6c11d68d1b4d1d754fd1024d7970251 /etc/terminfo/s/screen-w df1678735733b574d38d6dc08991b372 /etc/terminfo/s/sun c7ab8d7ab013eca15c6eb83a4c80a3d1 /etc/terminfo/v/vt100 ad245bbce8921ee045952390f57fae39 /etc/terminfo/v/vt102 c33de92a31aa93532f323d7b604f2060 /etc/terminfo/v/vt220 fb1504db6c5a5962d65c1e59ec3ee331 /etc/terminfo/v/vt52 2cfdf4dcc4a93c378d9c6bc01cb8f3c3 /etc/terminfo/x/xterm 8b85646c0ec7d05772e8893a0fe6c587 /etc/terminfo/x/xterm-color 582138668da3b0f586aeee0dab85ce64 /etc/terminfo/x/xterm-mono 894041962a58eb2c22ab75a510bfb9c8 /etc/terminfo/x/xterm-r5 edae3c5c9da23b6358a7362492fd17e8 /etc/terminfo/x/xterm-r6 ba7d833b34aa46016660e577c81644b2 /etc/terminfo/x/xterm-vt220 f7ee9373c6df206ee9b5f674a8748272 /etc/terminfo/x/xterm-xfree86 e3e10164f2a536129beeae0b1070513d
+Version: 5.2.20010318-1
+
+Package: fileutils
+Status: install ok installed
+Essential: yes
+Version: 4.0.43-1
+
+Package: grep
+Status: install ok installed
+Essential: yes
+Version: 2.4.2-1
+
+Package: gzip
+Status: install ok installed
+Essential: yes
+Version: 1.2.4-33
+
+Package: hostname
+Status: install ok installed
+Essential: yes
+Version: 2.07
+
+Package: sed
+Status: install ok installed
+Version: 3.02-6
+
+Package: urlget
+Status: install ok installed
+Version: 0.3
+
+Package: netbase
+Status: install ok installed
+Conffiles: /etc/init.d/networking e9ecbce88a3f5a296a216298e282270e /etc/protocols 9b4c76b625771acc5c8df17b3ed780bc /etc/services 1f73acd0620a72c63f34c14dff83774d
+Version: 4.05
+
+Package: ifupdown
+Status: install ok installed
+Version: 0.6.4-3
+
+Package: libpam-modules
+Status: install ok installed
+Version: 0.72-21
+
+Package: libpam0g
+Status: install ok installed
+Version: 0.72-21
+
+Package: net-tools
+Status: install ok installed
+Version: 1.59-1
+
+Package: netkit-ping
+Status: install ok installed
+Version: 0.10-6.1
+
+Package: libpam-runtime
+Status: install ok installed
+Conffiles: /etc/pam.conf c29f5bbea9887ff059b5973185c82212 /etc/pam.d/other 1ec5167fb7299a6b6b55b31c29a8b303
+Version: 0.72-21
+
+Package: modutils
+Status: install ok installed
+Conffiles: /etc/cron.daily/modutils 10fc6b90de70ffa3594d6c47ec9be935 /etc/init.d/modutils 0a8547ed5c4d6d98b729fa5a2603e7f4
+Version: 2.4.2-1
+
+Package: lrzsz
+Status: install ok installed
+Essential: yes
+Version: 0.12.21-4
+
+Package: mount
+Status: install ok installed
+Essential: yes
+Version: 2.11b-2
+
+Package: shellutils
+Status: install ok installed
+Essential: yes
+Version: 2.0.11-5
+
+Package: sysvinit
+Status: install ok installed
+Conffiles: /etc/init.d/bootmisc.sh e9418a2ae63ae39f02b3e4c32290b19d /etc/init.d/checkfs.sh 10e539a025742a6288f60651ae7613a1 /etc/init.d/checkroot.sh b73e84b9518933e9ea1195f9f707d24d /etc/init.d/halt 031ddd15603637361bca220953f21a55 /etc/init.d/hostname.sh cacd9a754d39665499db7f79dac4e212 /etc/init.d/mountall.sh ba7702a69890a12e91e7ea259c71150e /etc/init.d/reboot aff6c76c29e8daa1f7c47479024d51b2 /etc/init.d/rmnologin f84dc015574ab0e48fb0694dc70307b2 /etc/init.d/sendsigs 8c66184b264a2d86c18f34fff627b49f /etc/init.d/single 68031365ba0ce859ec96e5cc812c6d07 /etc/init.d/umountfs 1f2a624a32fee66cc5654261942aa6bb
+Essential: yes
+Version: 2.78-4
+
+Package: tar
+Status: install ok installed
+Essential: yes
+Version: 1.13.19-1
+
+Package: textutils
+Status: install ok installed
+Essential: yes
+Version: 2.0-3
+
+Package: task-bootstrap
+Status: install ok installed
+Version: 0.6
+
+Package: ppp
+Status: install ok installed
+Conffiles: /etc/ppp/options e85cc881e702d2f022e56fa48a877295
+Version: 2.4.0f-1
+
+Package: pump
+Status: install ok installed
+Version: 0.8.3-3
+
+Package: ssh
+Status: install ok installed
+Version: 1:2.5.2p2-2
+
+Package: wireless-tools
+Status: install ok installed
+Version: 20-1.1
+
+Package: libssl0.9.6
+Status: install ok installed
+Version: 0.9.6a-1
+
+Package: libwrap0
+Status: install ok installed
+Version: 7.6-7
+
+Package: zlib1g
+Status: install ok installed
+Version: 1:1.1.3-14
+
+Package: ntpdate
+Status: install ok installed
+Version: 1:4.0.99g-3
+
+Package: wget
+Status: install ok installed
+Version: 1.6-2
+
+Package: task-familiar-complete
+Status: install ok installed
+Version: 0.5
+
+Package: apmd
+Status: install ok installed
+Version: 3.0final-1
+
+Package: checkers
+Status: install ok installed
+Version: 0.0
+
+Package: dosfstools
+Status: install ok installed
+Version: 2.8-1
+
+Package: fscrib
+Status: install ok installed
+Version: 0.0
+
+Package: h3600-utils
+Status: install ok installed
+Version: 0.4
+
+Package: libglade0
+Status: install ok installed
+Version: 0.16-2
+
+Package: libpopt0
+Status: install ok installed
+Version: 1.5-0.1
+
+Package: libxaw6
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: libxml1
+Status: install ok installed
+Version: 1:1.8.11-1
+
+Package: libxmltok1
+Status: install ok installed
+Version: 1.1-5
+
+Package: loadmeter
+Status: install ok installed
+Version: 0.0
+
+Package: netcat
+Status: install ok installed
+Version: 1.10-17
+
+Package: procps
+Status: install ok installed
+Version: 1:2.0.7-4
+
+Package: pyditor
+Status: install ok installed
+Version: 0.0
+
+Package: qiv
+Status: install ok installed
+Version: 1.6-1
+
+Package: rsync
+Status: install ok installed
+Version: 2.4.6-1
+
+Package: sysset
+Status: install ok installed
+Version: 0.0
+
+Package: task-games
+Status: install ok installed
+Version: 0.0
+
+Package: task-mp3-player
+Status: install ok installed
+Version: 0.0
+
+Package: task-wireless
+Status: install ok installed
+Version: 0.1
+
+Package: task-x
+Status: install ok installed
+Version: 0.0
+
+Package: xvkbd
+Status: install ok installed
+Version: 0.0
+
+Package: gdk-imlib1
+Status: install ok installed
+Version: 1.9.8.1-2
+
+Package: libfltk1
+Status: install ok installed
+Version: 1.0.9-1.1
+
+Package: libfreetype6
+Status: install ok installed
+Version: 2.0.1.20010317-1
+
+Package: libglib1.2
+Status: install ok installed
+Version: 1.2.10-1
+
+Package: libgtk1.2
+Status: install ok installed
+Version: 1.2.10-1
+
+Package: libxaw7
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: madplay
+Status: install ok installed
+Version: 0.0
+
+Package: mixer
+Status: install ok installed
+Version: 0.0
+
+Package: python
+Status: install ok installed
+Version: 0.0
+
+Package: rxvt-aa
+Status: install ok installed
+Version: 1:2.6.3-8
+
+Package: xbase-clients
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: xcalibrate
+Status: install ok installed
+Version: 0.0
+
+Package: xfonts-75dpi
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: xfonts-base
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: xfonts-ttf
+Status: install ok installed
+Version: 0.0
+
+Package: xlibs
+Status: install ok installed
+Version: 4.0.2-13
+
+Package: libdb2
+Status: install ok installed
+Version: 2:2.7.7-3
+
+Package: libjpeg62
+Status: install ok installed
+Version: 6b-1.3
+
+Package: libpng2
+Status: install ok installed
+Version: 1.0.8-1
+
+Package: libungif3g
+Status: install ok installed
+Version: 3.0-3
+
+Package: libxft
+Status: install ok installed
+Version: 0.0
+
+Package: libxrender
+Status: install ok installed
+Version: 0.0
+
+Package: stowaway-h3600
+Status: install ok installed
+Version: 1.0
+
+Package: bash
+Status: install ok installed
+Conffiles: /etc/bash.bashrc 21e4f76f5390e221909e0afaaa41d8ab
+Version: 2.03-6
+
+Package: less
+Status: install ok installed
+Version: 346-7
+
+Package: login
+Status: install ok installed
+Conffiles: /etc/login.defs ef80f19ce81f9fab26602d8398c1b46f
+Essential: yes
+Version: 20000902-3.1
+
+Package: familiar-base
+Status: install ok installed
+Essential: yes
+Version: 0.10
+
+Package: kernel-modules-2.4.3-rmk2-np1
+Status: install ok installed
+Essential: yes
+Version: fam3
+
+Package: util-linux
+Status: install ok installed
+Essential: yes
+Version: 2.11b-2-fam2
+
+Package: pcmcia-modules-2.4.3-rmk2-np1
+Status: install ok installed
+Version: fam3
+
+Package: pcmcia-cs
+Status: install ok installed
+Conffiles: /etc/init.d/pcmcia 2aec30c50530a70e9b530bbe83106062 /etc/pcmcia/cis/3CCFEM556.dat 064309527ab5c6f73f17f99f6b07e471 /etc/pcmcia/cis/3CXEM556.dat 51e99ef0d234ea1b455b0555336f7379 /etc/pcmcia/cis/COMpad2.dat 66748ecad364a24ea2150fccb1adbca0 /etc/pcmcia/cis/COMpad4.dat a1b4e46b220b7ecaec0287875f47e549 /etc/pcmcia/cis/DP83903.dat fb612f42364fd06c46aa936386a79abb /etc/pcmcia/cis/E-CARD.dat 3bd542b30f74fb6066b045436e0c70c6 /etc/pcmcia/cis/LA-PCM.dat bee381e5d148bd073184a5cadfb6c314 /etc/pcmcia/cis/MT5634ZLX.dat 15bc79fe185e6cc00c888ab6e54a0640 /etc/pcmcia/cis/NE2K.dat f6092c8b414a94b96e310654cc5cad04 /etc/pcmcia/cis/PCMLM28.dat bc1d913acfd5b8b70a6694bbd48b5795 /etc/pcmcia/cis/PE-200.dat b779b33a4a692557517a3e6edf343fb2 /etc/pcmcia/cis/PE520.dat fb7b7e2d7664771f0c4a1a39cc2efabf /etc/pcmcia/cis/RS-COM-2P.dat c9dd2f55d05d86f88cdf52f3e1363da2 /etc/pcmcia/config.opts 03b1242472171887224f92ca95ecd40d /etc/pcmcia/config 9f747a17417cfecd7d08f5ddab34935d /etc/pcmcia/ftl.opts c6e0cd4d69e56836a6ff071bba8df4c3 /etc/pcmcia/ftl af805fd6a57f77ace864fe24643a39ed /etc/pcmcia/ide.opts 98f615befe89350382037398ef6cd226 /etc/pcmcia/ide fad802a1eb4cc57656a5dcae090edbb1 /etc/pcmcia/memory.opts bd8486017c46fef68ac2ecf597c8e31b /etc/pcmcia/memory a7a7acf0fa3ea00613ed2649e6b59e8b /etc/pcmcia/network.opts a40e80fb3366f61c8839973f5418e35f /etc/pcmcia/network e4b3d221d57efe4a714fdd5eb5c49224 /etc/pcmcia/parport.opts d7a128b7352b136d60935fca3638a4f6 /etc/pcmcia/parport 89041f80c218454b68c1c0581e29b872 /etc/pcmcia/scsi.opts 6c45330bd15b2db612d1d12d5682face /etc/pcmcia/scsi 983fa0c4829c79222e3f01d690c52897 /etc/pcmcia/serial.opts e26bbd1e4e70571277def2bcac82767e /etc/pcmcia/serial f7f7b6b24f55e7317d684d7f36c6e1f5 /etc/pcmcia/wireless.opts 002a763100acd3ddbd0e1c8283418907 /etc/pcmcia/wireless 64e6cbc2d2fda6b191390536ede71b67 /etc/pcmcia/shared 8b9f0c58f3b9daa43572e5087e97032b
+Version: 0.0-fam3
+
+Package: ipkg
+Status: install ok installed
+Conffiles: /etc/ipkg.conf 5f2dff89026c95afe68ca28b5385525b
+Essential: yes
+Version: 0.4-fam1
+
+Package: blackbox
+Status: install ok installed
+Version: 0.1
+
+Package: xserver-tiny-h3600
+Status: install ok installed
+Version: 0.2
+
+Package: iv
+Status: install ok installed
+Essential: yes
+Version: 0.0
+
diff --git a/noncore/unsupported/oipkg/main.cpp b/noncore/unsupported/oipkg/main.cpp
new file mode 100644
index 0000000..96a5e8d
--- a/dev/null
+++ b/noncore/unsupported/oipkg/main.cpp
@@ -0,0 +1,33 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "packagemanager.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ PackageManager mw;
+ a.showMainDocumentWidget( &mw );
+
+ return a.exec();
+}
diff --git a/noncore/unsupported/oipkg/packagemanager.cpp b/noncore/unsupported/oipkg/packagemanager.cpp
new file mode 100644
index 0000000..f3da15d
--- a/dev/null
+++ b/noncore/unsupported/oipkg/packagemanager.cpp
@@ -0,0 +1,897 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "packagemanager.h"
+#include "pkdesc.h"
+#include "pkfind.h"
+#include "pksettings.h"
+
+#include <qpe/process.h>
+#include <qpe/resource.h>
+#include <qpe/stringutil.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/applnk.h>
+
+#include <qprogressbar.h>
+#include <qcombobox.h>
+#include <qdict.h>
+#include <qfile.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qmessagebox.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qtextview.h>
+#include <qtoolbutton.h>
+
+#include <stdlib.h>
+
+static QPixmap *pm_uninstalled=0;
+static QPixmap *pm_installed=0;
+static QPixmap *pm_uninstall=0;
+static QPixmap *pm_install=0;
+
+
+class PackageItem : public QCheckListItem {
+ bool installed;
+public:
+ PackageItem(QListView* lv, const QString& name, const QString& desc, const QString& size, bool inst ) :
+ QCheckListItem(lv,name,CheckBox), installed(inst)
+ {
+ setText(1,desc);
+ setText(2,size);
+ }
+
+ void paintCell( QPainter *p, const QColorGroup & cg,
+ int column, int width, int alignment )
+ {
+ if ( !p )
+ return;
+
+ p->fillRect( 0, 0, width, height(),
+ isSelected()? cg.highlight() : cg.base() );
+
+ if ( column != 0 ) {
+ // The rest is text
+ QListViewItem::paintCell( p, cg, column, width, alignment );
+ return;
+ }
+
+ QListView *lv = listView();
+ if ( !lv )
+ return;
+ int marg = lv->itemMargin();
+ int r = marg;
+
+ QPixmap pm = statePixmap();
+ p->drawPixmap(marg,(height()-pm.height())/2,pm);
+ r += pm.width()+1;
+
+ p->translate( r, 0 );
+ QListViewItem::paintCell( p, cg, column, width - r, alignment );
+ }
+
+ void paintFocus( QPainter *p, const QColorGroup & cg,
+ const QRect & r )
+ {
+ // Skip QCheckListItem
+ // (makes you wonder what we're getting from QCheckListItem)
+ QListViewItem::paintFocus(p,cg,r);
+ }
+
+ QPixmap statePixmap() const
+ {
+ if ( !isOn() ) {
+ if ( !installed )
+ return *pm_uninstalled;
+ else
+ return *pm_installed;
+ } else {
+ if ( !installed )
+ return *pm_install;
+ else
+ return *pm_uninstall;
+ }
+ }
+
+ QString name() const { return text(0); }
+ QString description() const { return text(1); }
+ bool isInstalled() const { return installed; }
+
+ QString key( int column, bool ascending ) const
+ {
+ if ( column == 2 ) {
+ QString t = text(2);
+ double bytes=t.toDouble();
+ if ( t.contains('M') ) bytes*=1024*1024;
+ else if ( t.contains('K') || t.contains('k') ) bytes*=1024;
+ if ( !ascending ) bytes=999999999-bytes;
+ return QString().sprintf("%09d",(int)bytes);
+ } else {
+ return QListViewItem::key(column,ascending);
+ }
+ }
+};
+
+/*
+ * Constructs a PackageManager which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+PackageManager::PackageManager( QWidget* parent, const char* name, WFlags fl )
+ : PackageManagerBase( parent, name, fl )
+{
+ settings = new PackageManagerSettings(this,0,TRUE);
+ connect( settings->newserver, SIGNAL(clicked()), this, SLOT(newServer()) );
+ connect( settings->removeserver, SIGNAL(clicked()), this, SLOT(removeServer()) );
+ connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) );
+ connect( doit, SIGNAL(clicked()), this, SLOT(doIt()) );
+ settings->servername->setEnabled(FALSE);
+ settings->serverurl->setEnabled(FALSE);
+ serverurl.setAutoDelete(TRUE);
+
+ if (!pm_uninstalled) {
+ pm_uninstalled = new QPixmap(Resource::loadPixmap("uninstalled"));
+ pm_installed = new QPixmap(Resource::loadPixmap("installed"));
+ pm_install = new QPixmap(Resource::loadPixmap("install"));
+ pm_uninstall = new QPixmap(Resource::loadPixmap("uninstall"));
+ }
+
+ QFontMetrics fm = fontMetrics();
+ int w0 = fm.width(PackageManagerBase::tr("Package"))+30;
+ int w2 = fm.width("00000")+4;
+ list->setColumnWidth(0,w0);
+ list->setColumnWidth(1,228-w2-w0); // ### screen-biased
+ list->setColumnWidth(2,w2);
+ list->setColumnWidthMode(0,QListView::Manual);
+ list->setColumnWidthMode(1,QListView::Manual);
+ list->setColumnWidthMode(2,QListView::Manual);
+ list->setSelectionMode( QListView::Multi );
+ details = 0;
+ ipkg_old = 0;
+ readSettings();
+ updatePackageList();
+ progress->hide();
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+PackageManager::~PackageManager()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void PackageManager::newServer()
+{
+ int i = settings->servers->count();
+ if ( settings->servername->isEnabled() || settings->serverurl->text().isEmpty() ) {
+ serverurl.insert(i,new QString("http://"));
+ settings->servers->insertItem(tr("New"));
+ } else {
+ // allows one-level undo
+ serverurl.insert(i,new QString(settings->serverurl->text()));
+ settings->servers->insertItem(settings->servername->text());
+ }
+ settings->servers->setSelected(i,TRUE);
+ editServer(i);
+}
+
+void PackageManager::editServer(int i)
+{
+ if ( settings->servername->isEnabled() ) {
+ disconnect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) );
+ disconnect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) );
+ } else {
+ settings->servername->setEnabled(TRUE);
+ settings->serverurl->setEnabled(TRUE);
+ }
+
+ settings->servername->setText( settings->servers->text(i) );
+ settings->serverurl->setText( *serverurl[i] );
+
+ editedserver = i;
+
+ connect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) );
+ connect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) );
+}
+
+void PackageManager::removeServer()
+{
+ disconnect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) );
+ disconnect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) );
+ settings->servername->setText(settings->servers->text(editedserver));
+ settings->serverurl->setText(*serverurl[editedserver]);
+ disconnect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) );
+ settings->servers->removeItem(editedserver);
+ connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) );
+ settings->servername->setEnabled(FALSE);
+ settings->serverurl->setEnabled(FALSE);
+}
+
+void PackageManager::nameChanged(const QString& t)
+{
+ disconnect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) );
+ settings->servers->changeItem( t, editedserver );
+ connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) );
+}
+
+void PackageManager::urlChanged(const QString& t)
+{
+ serverurl.replace(editedserver, new QString(t));
+}
+
+static void selectComboItem(QComboBox *cb, const QString s)
+{
+ for (int i=0; i<cb->count(); i++) {
+ if ( cb->text(i) == s ) {
+ cb->setCurrentItem(i);
+ return;
+ }
+ }
+}
+
+void PackageManager::updatePackageList()
+{
+ disconnect(section,SIGNAL(activated(int)),this,SLOT(updatePackageList()));
+ disconnect(subsection,SIGNAL(activated(int)),this,SLOT(updatePackageList()));
+
+ list->clear();
+ QString cursection = section->currentText();
+ QString cursubsection = subsection->currentText();
+ QString all=tr("All");
+ if ( cursection == all ) cursection=QString::null;
+ if ( cursubsection == all ) cursubsection=QString::null;
+ section->clear();
+ subsection->clear();
+
+ QDict<void> sections;
+ QDict<void> subsections;
+ QDict<void> installed;
+
+ QRegExp separatorRegExp( ":[\t ]+" );
+
+ QString status = ipkgStatusOutput();
+ if ( !status.isEmpty() ) {
+ QStringList lines = QStringList::split('\n',status,TRUE);
+ QString name;
+ QString status;
+ for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) {
+ QString line = *it;
+ if ( line.length()<=1 ) {
+ // EOR
+ if ( !name.isEmpty() ) {
+ if ( status.contains(" installed") )
+ installed.replace(name,(void*)1);
+ name="";
+ }
+ status="";
+ } else if ( line[0] == ' ' || line[0] == '\t' ) {
+ // continuation
+ } else {
+ int sep = line.find(separatorRegExp);
+ if ( sep >= 0 ) {
+ QString tag = line.left(sep);
+ if ( tag == "Package" ) {
+ name = line.mid(sep+2).simplifyWhiteSpace();
+ } else if ( tag == "Status" ) {
+ status = line.mid(sep+1);
+ }
+ }
+ }
+ }
+ }
+
+ QString info = ipkgInfoOutput();
+ if ( !info.isEmpty() ) {
+ QStringList lines = QStringList::split('\n',info,TRUE);
+ QString description_short;
+ QString name;
+ QString size;
+ QString sec;
+ for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) {
+ QString line = *it;
+ if ( line.length()<=1 ) {
+ // EOR
+ if ( !name.isEmpty() ) {
+ int sl = sec.find('/');
+ QString s = sl < 0 ? sec : sec.left(sl);
+ QString ss = sl < 0 ? QString::null : sec.mid(sl+1);
+ sections.replace(s,(void*)1);
+ if ( cursection.isNull()
+ || cursection == s
+ && (cursubsection.isNull() || cursubsection == ss) )
+ {
+ if ( !cursection.isNull() && !ss.isNull() )
+ subsections.replace(ss,(void*)1);
+ description_short[0] = description_short[0].upper();
+ if ( description_short.left(4) == "The " )
+ description_short = description_short.mid(4);
+ if ( description_short.left(2) == "A " )
+ description_short = description_short.mid(2);
+ description_short[0] = description_short[0].upper();
+ new PackageItem(list,name,description_short,size,
+ installed.find(name));
+ }
+ installed.remove( name );
+ }
+ name="";
+ size="";
+ sec="main";
+ } else if ( line[0] == ' ' || line[0] == '\t' ) {
+ // continuation
+ } else {
+ int sep = line.find(separatorRegExp);
+ if ( sep >= 0 ) {
+ QString tag = line.left(sep);
+ if ( tag == "Package" ) {
+ name = line.mid(sep+2).simplifyWhiteSpace();
+ } else if ( tag == "Description" ) {
+ description_short = line.mid(sep+2).simplifyWhiteSpace();
+ } else if ( tag == "Installed-Size" ) {
+ size = line.mid(sep+2).simplifyWhiteSpace();
+ } else if ( tag == "Section" ) {
+ sec = line.mid(sep+2).simplifyWhiteSpace();
+ }
+ }
+ }
+ }
+ if ( installed.count() && cursection.isNull() ) {
+ // we have some packages without description
+ QDictIterator<void> it( installed );
+ for( ; it.current(); ++it )
+ new PackageItem( list, it.currentKey(), "", "?" , TRUE );
+ }
+
+ QStringList s;
+ QDictIterator<void> it( sections );
+ for( ; it.current(); ++it )
+ s.append(it.currentKey());
+ s.sort();
+ section->insertItem(all);
+ section->insertStringList(s);
+ selectComboItem(section,cursection.isNull()?all:cursection);
+ if ( cursection.isNull() ) {
+ subsection->setEnabled(FALSE);
+ } else {
+ subsection->setEnabled(TRUE);
+ QStringList s;
+ QDictIterator<void> it( subsections );
+ for( ; it.current(); ++it )
+ s.append(it.currentKey());
+ s.sort();
+ subsection->insertItem(all);
+ subsection->insertStringList(s);
+ selectComboItem(subsection,cursubsection.isNull()?all:cursubsection);
+ }
+ } else {
+ new QListViewItem(list,"ERROR");
+ }
+
+ connect(section,SIGNAL(activated(int)),SLOT(updatePackageList()));
+ connect(subsection,SIGNAL(activated(int)),this,SLOT(updatePackageList()));
+}
+
+PackageItem* PackageManager::current() const
+{
+ return (PackageItem*)list->currentItem();
+}
+
+/*
+ * public slot
+ */
+void PackageManager::doCurrentDetails(bool multi)
+{
+ PackageItem* pit = current();
+ if ( pit ) {
+ if ( !details ) {
+ details = new PackageDetails;
+ connect( details->install, SIGNAL(clicked()),
+ this, SLOT(installCurrent()));
+ connect( details->remove, SIGNAL(clicked()),
+ this, SLOT(removeCurrent()));
+ details->description->setTextFormat(RichText);
+ }
+ if ( multi ) {
+ disconnect( details->ignore, SIGNAL(clicked()),
+ details, SLOT(close()));
+ connect( details->ignore, SIGNAL(clicked()),
+ this, SLOT(doNextDetails()));
+ } else {
+ disconnect( details->ignore, SIGNAL(clicked()),
+ this, SLOT(doNextDetails()));
+ connect( details->ignore, SIGNAL(clicked()),
+ details, SLOT(close()));
+ }
+ pit->setSelected(FALSE);
+ details->setCaption("Package: " + pit->name());
+ details->description->setText(fullDetails(pit->name()));
+ details->install->setEnabled(!pit->isInstalled());
+ details->remove->setEnabled(pit->isInstalled());
+ details->showMaximized();
+ }
+}
+
+void PackageManager::doDetails()
+{
+ doCurrentDetails(FALSE);
+}
+
+void PackageManager::doNextDetails()
+{
+ QListViewItem* i = list->firstChild();
+ for ( ; i; i = i->nextSibling() ) {
+ if ( i->isSelected() )
+ break;
+ }
+ list->setCurrentItem(i);
+ if ( i ) {
+ doCurrentDetails(TRUE);
+ } else if ( details )
+ details->close();
+}
+
+QString PackageManager::fullDetails(const QString& pk)
+{
+ QString status;
+ Process ipkg_status(QStringList() << "ipkg" << "info" << pk);
+ if ( ipkg_status.exec("",status) ) {
+ QStringList lines = QStringList::split('\n',status,TRUE);
+ QString description;
+ for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) {
+ QString line = *it;
+ if ( line == " ." ) {
+ description.append("<p>");
+ } else if ( line[0] == ' ' || line[0] == '\t' ) {
+ // continuation
+ description.append(" ");
+ description.append(Qtopia::escapeString(line));
+ } else {
+ int sep = line.find(QRegExp(":[\t ]+"));
+ if ( sep >= 0 ) {
+ QString tag = line.left(sep);
+ description.append("<br>");
+ description.append("<b>");
+ description.append(Qtopia::escapeString(tag));
+ description.append(":</b> ");
+ description.append(Qtopia::escapeString(line.mid(sep+2)));
+ } else {
+ description.append(" ");
+ description.append(Qtopia::escapeString(line));
+ }
+ }
+ }
+ return description;
+ }
+
+ return QString::null;
+}
+
+void PackageManager::installCurrent()
+{
+ current()->setOn(TRUE);
+ details->close();
+}
+
+void PackageManager::removeCurrent()
+{
+ current()->setOn(TRUE);
+ details->close();
+}
+
+bool PackageManager::readIpkgConfig(const QString& conffile)
+{
+ QFile conf(conffile);
+ if ( conf.open(IO_ReadOnly) ) {
+ QTextStream s(&conf);
+ settings->servers->clear();
+ serverurl.clear();
+ ipkg_old=0;
+ int currentserver=0;
+ while ( !s.atEnd() ) {
+ QString l = s.readLine();
+ QStringList token = QStringList::split(' ', l);
+ if ( token[0] == "src" || token[0] == "#src" ) {
+ currentserver=settings->servers->count();
+ serverurl.insert(settings->servers->count(),new QString(token[2]));
+ int a = token[0] == "src" ? 1 : 0;
+ int i = settings->servers->count();
+ settings->servers->insertItem(token[1]);
+ settings->servers->setSelected(i,a);
+ } else if ( token[0] == "dest" ) {
+ // needs UI
+ } else if ( token[0] == "option" ) {
+ // ### somehow need to use the settings from netsetup
+// if ( token[1] == "http_proxy" )
+// settings->http->setText(token[2]);
+// else if ( token[1] == "ftp_proxy" )
+// settings->ftp->setText(token[2]);
+// else if ( token[1] == "proxy_username" )
+// settings->username->setText(token[2]);
+// else if ( token[1] == "proxy_password" )
+// settings->password->setText(token[2]);
+ } else {
+ // Old style?
+ int eq = l.find('=');
+ if ( eq >= 0 ) {
+ QString v = l.mid(eq+1).stripWhiteSpace();
+ if ( v[0] == '"' || v[0] == '\'' ) {
+ int cl=v.find(v[0],1);
+ if ( cl >= 0 )
+ v = v.mid(1,cl-1);
+ }
+ if ( l.left(12) == "IPKG_SOURCE=" ) {
+ ipkg_old=1;
+ currentserver=settings->servers->count();
+ serverurl.insert(settings->servers->count(),new QString(v));
+ settings->servers->insertItem(v);
+ } else if ( l.left(13) == "#IPKG_SOURCE=" ) {
+ serverurl.insert(settings->servers->count(),new QString(v));
+ settings->servers->insertItem(v);
+ } else if ( l.left(10) == "IPKG_ROOT=" ) {
+ // ### no UI
+// } else if ( l.left(20) == "IPKG_PROXY_USERNAME=" ) {
+// settings->username->setText(v);
+// } else if ( l.left(20) == "IPKG_PROXY_PASSWORD=" ) {
+// settings->password->setText(v);
+// } else if ( l.left(16) == "IPKG_PROXY_HTTP=" ) {
+// settings->http->setText(v);
+// } else if ( l.left(16) == "IPKG_PROXY_FTP=" ) {
+// settings->ftp->setText(v);
+ }
+ }
+ }
+ }
+ if ( ipkg_old ) {
+ settings->servers->setSelectionMode(QListBox::Single);
+ settings->servers->setSelected(currentserver,TRUE);
+ }
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * public slot
+ */
+void PackageManager::doSettings()
+{
+ settings->showMaximized();
+ if ( settings->exec() ) {
+ writeSettings();
+ startRun();
+ runIpkg("update");
+ endRun();
+ updatePackageList();
+ } else {
+ readSettings();
+ }
+}
+
+void PackageManager::readSettings()
+{
+ // read from config file(s)
+ readIpkgConfig("/etc/ipkg.conf");
+}
+
+void PackageManager::writeSettings()
+{
+ QFile conf("/etc/ipkg.conf");
+ if ( conf.open(IO_WriteOnly) ) {
+ QTextStream s(&conf);
+ s << "# Written by Qtopia Package Manager\n";
+ if ( !ipkg_old ) {
+ for (int i=0; i<(int)settings->servers->count(); i++) {
+ QString url = serverurl[i] ? *serverurl[i] : QString("???");
+ if ( !settings->servers->isSelected(i) )
+ s << "#";
+ s << "src " << settings->servers->text(i) << " " << url << "\n";
+ }
+ s << "dest root /\n"; // ### need UI
+// if ( !settings->username->text().isEmpty() )
+// s << "option proxy_username " << settings->username->text() << "\n";
+// if ( !settings->password->text().isEmpty() )
+// s << "option proxy_password " << settings->password->text() << "\n";
+// if ( !settings->http->text().isEmpty() )
+// s << "option http_proxy " << settings->http->text() << "\n";
+// if ( !settings->ftp->text().isEmpty() )
+// s << "option ftp_proxy " << settings->ftp->text() << "\n";
+ } else {
+ // Old style
+ bool src_selected=FALSE;
+ for (int i=0; i<(int)settings->servers->count(); i++) {
+ if ( settings->servers->isSelected(i) ) {
+ src_selected=TRUE;
+ } else {
+ s << "#";
+ }
+ s << "IPKG_SOURCE=\"" << settings->servers->text(i) << "\"\n";
+ }
+ if ( !src_selected )
+ s << "IPKG_SOURCE=\"" << settings->servers->currentText() << "\"\n";
+ s << "IPKG_ROOT=/\n"
+// << "IPKG_PROXY_USERNAME=\"" << settings->username->text() << "\"\n"
+// << "IPKG_PROXY_PASSWORD=\"" << settings->password->text() << "\"\n"
+// << "IPKG_PROXY_HTTP=\"" << settings->http->text() << "\"\n"
+// << "IPKG_PROXY_FTP=\"" << settings->ftp->text() << "\"\n"
+ ;
+ }
+ conf.close();
+ }
+}
+
+/*
+ * public slot
+ */
+void PackageManager::doFind()
+{
+ Search s(this, 0, TRUE);
+ if ( s.exec() ) {
+ QString p = s.pattern->text();
+ if ( p.isEmpty() ) {
+ list->selectAll(FALSE);
+ } else {
+ selectPackages(findPackages(p));
+ doNextDetails();
+ }
+ }
+}
+
+void PackageManager::selectPackages( const QStringList& l )
+{
+ QDict<void> d;
+ for (QStringList::ConstIterator it = l.begin(); it != l.end(); ++it)
+ d.replace(*it,(void*)1);
+ QListViewItem* i;
+ for ( i = list->firstChild(); i; i = i->nextSibling() ) {
+ PackageItem* pit = (PackageItem*)i;
+ i->setSelected( d[pit->name()] );
+ }
+}
+
+QStringList PackageManager::findPackages( const QRegExp& r )
+{
+ QStringList matches;
+
+ QString info = ipkgInfoOutput();
+ if ( !info.isEmpty() ) {
+ QStringList lines = QStringList::split('\n',info,TRUE);
+ QRegExp re = r;
+ QString description="";
+ QString name;
+ for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) {
+ QString line = *it;
+ if ( line.length()<=1 ) {
+ // EOR
+ if ( re.match(description) >= 0 )
+ matches.append(name);
+ description="";
+ name="";
+ } else if ( line[0] == ' ' || line[0] == '\t' ) {
+ // continuation
+ description.append(" ");
+ description.append(Qtopia::escapeString(line));
+ } else {
+ int sep = line.find(QRegExp(":[\t ]+"));
+ if ( sep >= 0 ) {
+ QString tag = line.left(sep);
+ if ( tag == "Package" )
+ name = line.mid(sep+2).simplifyWhiteSpace();
+ if ( !description.isEmpty() )
+ description.append("<br>");
+ description.append("<b>");
+ description.append(Qtopia::escapeString(tag));
+ description.append(":</b> ");
+ description.append(Qtopia::escapeString(line.mid(sep+2)));
+ }
+ }
+ }
+ }
+
+ return matches;
+}
+
+/*
+ * public slot
+ */
+void PackageManager::doUpgrade()
+{
+ startMultiRun(2);
+ runIpkg("update");
+ runIpkg("upgrade");
+ updatePackageList();
+ endRun();
+}
+
+
+void PackageManager::doIt()
+{
+ bool ok = commitWithIpkg();
+ updatePackageList(); // things may have changed
+ if (!ok) qApp->beep();
+}
+
+bool PackageManager::commitWithIpkg()
+{
+ // A full implementation would do the following, but we'll just do
+ // it simply and non-interactively for now.
+ //
+ // setenv IPKG_CONF_DIR for a null $IPKG_CONF_DIR/ipkg.conf
+ // setenv IPKG_SOURCE, IPKG_ROOT, etc.
+ // run ipkg, processing interactivity as dialogs
+ // - "... (Y/I/N/O/D) [default=N] ?" -> ...
+ // - "[Press ENTER to continue]" (if D chosen above)
+ // - "The following packages are marked `Essential'... Install them now [Y/n] ?"
+ // - "The following packages...ready to be installed:... Install them now [Y/n] ?"
+ // return FALSE cancelled
+
+ QStringList to_remove, to_install;
+
+ for ( QListViewItem* i = list->firstChild(); i; i = i->nextSibling() ) {
+ PackageItem* pit = (PackageItem*)i;
+ if ( pit->isOn() ) {
+ if ( pit->isInstalled() )
+ to_remove.append(pit->name());
+ else
+ to_install.append(pit->name());
+ }
+ }
+
+ bool ok=TRUE;
+
+ int jobs = to_remove.count()+to_install.count();
+ if ( jobs ) {
+ startMultiRun(jobs);
+
+ if ( to_remove.count() ) {
+ for (QStringList::ConstIterator it=to_remove.begin(); it!=to_remove.end(); ++it) {
+ if ( runIpkg("remove " + *it) != 0 ) {
+ ok = FALSE;
+ }
+ }
+ }
+ if ( to_install.count() ) {
+ for (QStringList::ConstIterator it=to_install.begin(); it!=to_install.end(); ++it) {
+ if ( runIpkg("install " + *it) != 0 ) {
+ ok = FALSE;
+ }
+ }
+ }
+
+ // ##### If we looked in the list of files, we could send out accurate
+ // ##### messages. But we don't bother yet, and just do an "all".
+ QCopEnvelope e("QPE/System", "linkChanged(QString)");
+ QString lf = QString::null;
+ e << lf;
+
+#if QT_VERSION > 230 // a bug breaks this otherwise
+ if ( !ok )
+ QMessageBox::warning(this, "Error", "<p><tt>ipkg</tt> says something went wrong. Sorry.");
+#endif
+
+ endRun();
+ }
+
+ return ok;
+}
+
+QString PackageManager::ipkgStatusOutput()
+{
+ if ( cachedIpkgStatusOutput.isEmpty() ) {
+ Process ipkg_status( QStringList() << "ipkg" << "status" );
+ ipkg_status.exec( 0, cachedIpkgStatusOutput );
+ }
+ return QString::fromLocal8Bit( cachedIpkgStatusOutput );
+}
+
+QString PackageManager::ipkgInfoOutput()
+{
+ if ( cachedIpkgInfoOutput.isEmpty() ) {
+ Process ipkg_info( QStringList() << "ipkg" << "info" );
+ ipkg_info.exec( 0, cachedIpkgInfoOutput );
+ }
+ return QString::fromLocal8Bit( cachedIpkgInfoOutput );
+}
+
+void PackageManager::setCachedIpkgOutputDirty()
+{
+ cachedIpkgInfoOutput = cachedIpkgStatusOutput = QString::null;
+}
+
+void PackageManager::startMultiRun(int jobs)
+{
+ startRun();
+ progress->setTotalSteps(jobs);
+ progress->setProgress(0);
+}
+
+void PackageManager::startRun()
+{
+ progress->show();
+ doit->hide();
+}
+
+void PackageManager::endRun()
+{
+ doit->show();
+ progress->hide();
+}
+
+int PackageManager::runIpkg(const QString& args)
+{
+ if ( progress->progress() == -1 )
+ startMultiRun(1);
+ else
+ startRun();
+ QString cmd = "ipkg ";
+ if ( ipkg_old )
+ cmd += "</dev/null ";
+ else
+ cmd += "-force-defaults ";
+ int r = system((cmd+args).latin1());
+ progress->setProgress(progress->progress()+1);
+ setCachedIpkgOutputDirty();
+ endRun();
+ return r;
+}
+
+// simple hack to get support for ipkg mimetype
+void PackageManager::maybeInstall( const QString &ipk )
+{
+ int pos = ipk.findRev( "/" );
+ QString package = ipk.mid( pos + 1 );
+ pos = package.find ( "_" );
+ if ( pos != -1 )
+ package = package.left( pos );
+ switch ( QMessageBox::information( 0, tr( "Install Package" ),
+ tr("Are you sure you want to\ninstall package\n\n%1")
+ .arg(package), QMessageBox::Yes,
+ QMessageBox::No|QMessageBox::Default|QMessageBox::Escape, 0 ) ) {
+ case QMessageBox::Yes: {
+ startRun();
+ runIpkg("install " + ipk );
+ QCopEnvelope e("QPE/System", "linkChanged(QString)");
+ QString lf = QString::null;
+ e << lf;
+ endRun();
+ }
+ break;
+ case QMessageBox::No:
+ default:
+ // do nothing
+ break;
+ }
+}
+
+void PackageManager::setDocument(const QString& fileref)
+{
+ if ( fileref.isNull() )
+ return;
+ DocLnk doc( fileref );
+ if ( doc.file().isEmpty() )
+ return;
+ maybeInstall( doc.file() );
+ updatePackageList();
+}
diff --git a/noncore/unsupported/oipkg/packagemanager.h b/noncore/unsupported/oipkg/packagemanager.h
new file mode 100644
index 0000000..a3f89d0
--- a/dev/null
+++ b/noncore/unsupported/oipkg/packagemanager.h
@@ -0,0 +1,94 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef PACKAGEMANAGER_H
+#define PACKAGEMANAGER_H
+#include "packagemanagerbase.h"
+#include <qintdict.h>
+
+class PackageItem;
+class PackageDetails;
+class PackageManagerSettings;
+
+class PackageManager : public PackageManagerBase
+{
+ Q_OBJECT
+
+public:
+ PackageManager( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~PackageManager();
+
+
+public slots:
+ void doDetails();
+ void doSettings();
+ void doFind();
+ void doUpgrade();
+ void setDocument(const QString& fileref);
+
+protected slots:
+ void doIt();
+
+private slots:
+ void installCurrent();
+ void removeCurrent();
+ void doNextDetails();
+
+ void newServer();
+ void editServer(int);
+ void removeServer();
+ void nameChanged(const QString&);
+ void urlChanged(const QString&);
+ void updatePackageList();
+
+private:
+ void maybeInstall( const QString &ipk );
+ void startRun();
+ void endRun();
+ void startMultiRun(int jobs);
+ int runIpkg(const QString& args);
+ QString fullDetails(const QString& pk);
+
+ bool readIpkgConfig(const QString& conffile);
+
+ void doCurrentDetails(bool);
+ PackageItem* current() const;
+
+ QStringList findPackages( const QRegExp& re );
+ void selectPackages( const QStringList& l );
+
+ bool commitWithIpkg();
+
+ QString ipkgStatusOutput();
+ QString ipkgInfoOutput();
+ void setCachedIpkgOutputDirty();
+
+ PackageManagerSettings* settings;
+ QIntDict<QString> serverurl;
+ int editedserver;
+ int ipkg_old;
+ void writeSettings();
+ void readSettings();
+
+ PackageDetails* details;
+ QCString cachedIpkgStatusOutput;
+ QCString cachedIpkgInfoOutput;
+};
+
+#endif // PACKAGEMANAGER_H
diff --git a/noncore/unsupported/oipkg/packagemanagerbase.ui b/noncore/unsupported/oipkg/packagemanagerbase.ui
new file mode 100644
index 0000000..9d5a178
--- a/dev/null
+++ b/noncore/unsupported/oipkg/packagemanagerbase.ui
@@ -0,0 +1,268 @@
+<!DOCTYPE UI><UI>
+<class>PackageManagerBase</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form1</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>257</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Package Manager</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>3</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Section:</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" rowspan="1" colspan="3" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>upgrade</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Upgrade all</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>doit</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Do it!</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QProgressBar</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>progress</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>settings_btn</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>find_btn</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>info_btn</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image2</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subsection</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>section</cstring>
+ </property>
+ </widget>
+ <widget row="1" column="0" rowspan="1" colspan="3" >
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Package</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Description</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Size</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>list</cstring>
+ </property>
+ <property stdset="1">
+ <name>allColumnsShowFocus</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="1897">789c5dd3c972db381006e0bb9f82e5beb9527fb88baca939387b9c7851363b49e50082a4e445966dc98b3c35ef3e602f4c3cd6e9d3df683420f8f94e7472b41fed3cdf5aadddfad4477eee6ea29df676b1d8fcfcf5f73f5bdb491a2559546751bafd6c6b7bba8e7c74b0bcec0660124031ff0d26cfaec2474c6aaf6e4757bcbe1e9cc4630e7162fd66a3a5be50e7ea925d9969aeae34ff31388dd3d081f373752ec66f4bfd2b766da61b732af547ea4aebdfa8bde4b41a9c2559acf907b3aebf505bbf4fec7a7433ba663b7396b0cfd495fa44adfbe3ed68599f9b33f1f7c17932d6bf16e7b1d64fd5364f6b96fde896edf24aeb63b3e6976add9feecdb9e4fd68c7ebbbc1456a392a711117fcd8b05417da9fefaf70a31bb3d66fd4b59ed79bb5ff5cdd6afddde0322d139defc12c392dd585e61bb3e60bb62b751e9c9a0b39dfcc5cca7ed7ea5a723a339762cb6d3e9e679295added70bb3e62bf144e7c737b3e62fcd938c9daaedbe0e464bff477633a9f57c4e5c59bf2f83ab2c58ea0fcd15f7a735bba96a9df7caacf564ae1a36bfa7dad7addc0f3d9a6bcf39ffffb9dc252e67f37d3bef3ab92ff07e4ddb383ddf9eba9379c0efd1173ed5fc585dfa82f7e3dfdfb7c12de7fc5edba22d6bd98fdf6bdbb5e1c2b99e7fdfaeec529defa3ba54bf63779dd379b3c17dd9757dc9fe2aee53cd3f8fe6f5b4cbeec3373dbb53f792233137b27e7fb4ccffdeace7bb1a2db9f5efe53cd3b57d407068e0d1a2432f196698e3146738c70516b8c41257b896df052bac718b3bdce3019b903c62172fe4cde1155ee30ddee21dde630f1ff011fb38d09e8738c2149fc2b77bf88c2ff81ab26f360b8ec31427f88e1f884396842cfd3d2732e428506212b2fd3fd7715aa12610910b49f2e7bae99a1af2d492474cddffd7514f331434a3399d3edd2f6467744e17b4a04b5ad2155d3fd9ef986e688515ade9364c7bf8f43ee92eacbda707dad023ed6efffbd7d67f2c679e40</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="1182">789c55d34b739b301007f0bb3f05636e9e0e0181304ca78724b6f3b4e3043b76d2e94148c28f183b7ec7e9f4bb97d52ea4151cf4fbaf249619386b58e37ed76a9cd5b63bb19b494b4ec5c66aa87d9e9f7efefaf1bb56f702abb8796c79f56fb5ba6349abb75a6a9827c5dc76cd008e8801726c18c105ec1225f205e8b965b583840b288901d2368c0a9ac58218211551225320733dc9ccde47a01f33c962200372e613ef91dce50cd82772e4aba1085cdfbc7b0fc91517c00130644184d52b64e88566ef3b918766b126c6589d5734d536304a632f0e804fc038682aacee0ca5283a017e0285145a48e0033265a9a9ce88213200a641445dad916535238a54018740c963afe9037da410d89547d4d8c60752869203af89027947d4d29cec1aaa983753e033326578540b592ebe45aa5099a34e40c59550e6abbb216ae4a5a12eab2ba466c88b923a041e892172020420df2a9abd53a2409e1335726ba8339699bd076288dc130572032c6ac4bc62065c1a662517c40ce938b64885908e1926513a9b4c67735125f6fc6db1c897ab775926729d2ff27c53fcd465924e8a607f387e548938eef3c3f6789a7d259fdbf3e9c565ab6d9749e7eafae6b675b7beef564f17bdf6faa1dd7f7c4acac4e988a2c1ee60f89c94493146e3d1cbabeb255f493192840dfde4dfa48806c1ff09644efdcff7da5f08a60ed0</data>
+ </image>
+ <image>
+ <name>image2</name>
+ <data format="XPM.GZ" length="702">789c7dd1c96ac3301006e0bb9f4224b75092d891b550fa082d3d164a0f238d27abb33a1ba5ef5ecfd89098868e7cd0f75b23c97834501fefaf6a304a0e1554f3a8e20cf66a80c7b2bc7e7ebd7c27bd54abfac9ac4a7b4f496fa8a27adbac0b9e633def8fa5986b66ea783067cccc672ef3cc0d53a77aac659f8310b4d3c03c330d98dc08fb2db1e19c692736b513e652186c6e0373d7d2378c4c37b1e864f1b1617d29e145189c77b2f8da121bae985efbd46be6b665de300863cdc88496be61c5840800c282197430417a17420c10907962c63c9a98334b214688f276cac4820773cf244319192609a5e48f74ea9fa40f21e27d52f016d3d92d99132d80086ec97255ae3744dbbb2ec4dd9e4abc4f0e441576926379c2ce5978be5cbbc9704b84dd1bc29f64d8f43cfcae9fe7e417c79f9e92</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>settings_btn</sender>
+ <signal>clicked()</signal>
+ <receiver>Form1</receiver>
+ <slot>doSettings()</slot>
+ </connection>
+ <connection>
+ <sender>find_btn</sender>
+ <signal>clicked()</signal>
+ <receiver>Form1</receiver>
+ <slot>doFind()</slot>
+ </connection>
+ <connection>
+ <sender>info_btn</sender>
+ <signal>clicked()</signal>
+ <receiver>Form1</receiver>
+ <slot>doDetails()</slot>
+ </connection>
+ <connection>
+ <sender>list</sender>
+ <signal>doubleClicked(QListViewItem*)</signal>
+ <receiver>Form1</receiver>
+ <slot>doDetails()</slot>
+ </connection>
+ <connection>
+ <sender>upgrade</sender>
+ <signal>clicked()</signal>
+ <receiver>Form1</receiver>
+ <slot>doUpgrade()</slot>
+ </connection>
+ <slot access="public">doFind()</slot>
+ <slot access="public">doDetails()</slot>
+ <slot access="public">doSettings()</slot>
+ <slot access="public">doUpgrade()</slot>
+</connections>
+</UI>
diff --git a/noncore/unsupported/oipkg/pkdesc.ui b/noncore/unsupported/oipkg/pkdesc.ui
new file mode 100644
index 0000000..494d3d6
--- a/dev/null
+++ b/noncore/unsupported/oipkg/pkdesc.ui
@@ -0,0 +1,96 @@
+<!DOCTYPE UI><UI>
+<class>PackageDetails</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form7</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>221</width>
+ <height>291</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>(pkgname)</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>6</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget>
+ <class>QTextView</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>description</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>install</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Install</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>remove</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Remove</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ignore</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Ignore</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/noncore/unsupported/oipkg/pkfind.ui b/noncore/unsupported/oipkg/pkfind.ui
new file mode 100644
index 0000000..7a24c00
--- a/dev/null
+++ b/noncore/unsupported/oipkg/pkfind.ui
@@ -0,0 +1,51 @@
+<!DOCTYPE UI><UI>
+<class>Search</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form5</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>196</width>
+ <height>55</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Search Packages</string>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Find:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>pattern</cstring>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+</UI>
diff --git a/noncore/unsupported/oipkg/pksettings.ui b/noncore/unsupported/oipkg/pksettings.ui
new file mode 100644
index 0000000..f182752
--- a/dev/null
+++ b/noncore/unsupported/oipkg/pksettings.ui
@@ -0,0 +1,176 @@
+<!DOCTYPE UI><UI>
+<class>PackageManagerSettings</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form4</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>549</width>
+ <height>683</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Package Servers</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="3" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>servername</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Name:</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>serverurl</cstring>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>URL:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>newserver</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>New</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>removeserver</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Remove</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>servers</cstring>
+ </property>
+ <property stdset="1">
+ <name>selectionMode</name>
+ <enum>Multi</enum>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Servers</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Servers</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+</UI>
diff --git a/noncore/unsupported/oipkg/qipkg.pro b/noncore/unsupported/oipkg/qipkg.pro
new file mode 100644
index 0000000..90d8703
--- a/dev/null
+++ b/noncore/unsupported/oipkg/qipkg.pro
@@ -0,0 +1,13 @@
+DESTDIR = $(QPEDIR)/bin
+TEMPLATE = app
+CONFIG = qt warn_on release
+HEADERS = packagemanager.h
+SOURCES = packagemanager.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES = packagemanagerbase.ui pkdesc.ui pkfind.ui pksettings.ui
+TARGET = qipkg
+
+TRANSLATIONS = ../i18n/de/qipkg.ts
diff --git a/noncore/unsupported/oipkg/qpe-qipkg.control b/noncore/unsupported/oipkg/qpe-qipkg.control
new file mode 100644
index 0000000..3c3e7c8
--- a/dev/null
+++ b/noncore/unsupported/oipkg/qpe-qipkg.control
@@ -0,0 +1,9 @@
+Files: bin/qipkg apps/Settings/qipkg.desktop
+Priority: optional
+Section: qpe/settings
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Package Manager
+ A GUI front-end to ipkg for the Qtopia environment.