summaryrefslogtreecommitdiffstats
path: root/lskat
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitc90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch)
tree6d8391395bce9eaea4ad78958617edb20c6a7573 /lskat
downloadtdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz
tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lskat')
-rw-r--r--lskat/AUTHORS1
-rw-r--r--lskat/COPYING341
-rw-r--r--lskat/Makefile.am11
-rw-r--r--lskat/README33
-rw-r--r--lskat/TODO3
-rw-r--r--lskat/grafix/Makefile.am8
-rw-r--r--lskat/grafix/background.pngbin0 -> 147 bytes
-rw-r--r--lskat/grafix/deck1.pngbin0 -> 4985 bytes
-rw-r--r--lskat/grafix/deck2.pngbin0 -> 5456 bytes
-rw-r--r--lskat/grafix/deck3.pngbin0 -> 6202 bytes
-rw-r--r--lskat/grafix/deck4.pngbin0 -> 5465 bytes
-rw-r--r--lskat/grafix/t1.pngbin0 -> 293 bytes
-rw-r--r--lskat/grafix/t2.pngbin0 -> 295 bytes
-rw-r--r--lskat/grafix/t3.pngbin0 -> 286 bytes
-rw-r--r--lskat/grafix/t4.pngbin0 -> 286 bytes
-rw-r--r--lskat/grafix/t5.pngbin0 -> 377 bytes
-rw-r--r--lskat/grafix/tback.pngbin0 -> 240 bytes
-rw-r--r--lskat/grafix/type1.pngbin0 -> 655 bytes
-rw-r--r--lskat/grafix/type2.pngbin0 -> 1078 bytes
-rw-r--r--lskat/grafix/type3.pngbin0 -> 361 bytes
-rw-r--r--lskat/hi128-app-lskat.pngbin0 -> 13259 bytes
-rw-r--r--lskat/hi16-app-lskat.pngbin0 -> 750 bytes
-rw-r--r--lskat/hi22-app-lskat.pngbin0 -> 1562 bytes
-rw-r--r--lskat/hi32-app-lskat.pngbin0 -> 2045 bytes
-rw-r--r--lskat/hi48-app-lskat.pngbin0 -> 3821 bytes
-rw-r--r--lskat/hi64-app-lskat.pngbin0 -> 5084 bytes
-rw-r--r--lskat/lskat.desktop108
-rw-r--r--lskat/lskat.kdevprj286
-rw-r--r--lskat/lskat.lsm14
-rw-r--r--lskat/lskat/KChildConnect.cpp124
-rw-r--r--lskat/lskat/KChildConnect.h53
-rw-r--r--lskat/lskat/KConnectEntry.cpp165
-rw-r--r--lskat/lskat/KConnectEntry.h56
-rw-r--r--lskat/lskat/KConnectTypes.h38
-rw-r--r--lskat/lskat/KEInput.cpp296
-rw-r--r--lskat/lskat/KEInput.h82
-rw-r--r--lskat/lskat/KEMessage.cpp326
-rw-r--r--lskat/lskat/KEMessage.h66
-rw-r--r--lskat/lskat/KInputChildProcess.cpp106
-rw-r--r--lskat/lskat/KInputChildProcess.h57
-rw-r--r--lskat/lskat/KInteractiveConnect.cpp80
-rw-r--r--lskat/lskat/KInteractiveConnect.h41
-rw-r--r--lskat/lskat/KMessageEntry.cpp81
-rw-r--r--lskat/lskat/KMessageEntry.h42
-rw-r--r--lskat/lskat/KProcessConnect.cpp192
-rw-r--r--lskat/lskat/KProcessConnect.h57
-rw-r--r--lskat/lskat/KRSocket.cpp374
-rw-r--r--lskat/lskat/KRSocket.h169
-rw-r--r--lskat/lskat/KRemoteConnect.cpp334
-rw-r--r--lskat/lskat/KRemoteConnect.h74
-rw-r--r--lskat/lskat/Makefile.am21
-rw-r--r--lskat/lskat/lskat.cpp1081
-rw-r--r--lskat/lskat/lskat.h216
-rw-r--r--lskat/lskat/lskatdoc.cpp817
-rw-r--r--lskat/lskat/lskatdoc.h235
-rw-r--r--lskat/lskat/lskatui.rc25
-rw-r--r--lskat/lskat/lskatview.cpp934
-rw-r--r--lskat/lskat/lskatview.h91
-rw-r--r--lskat/lskat/main.cpp67
-rw-r--r--lskat/lskat/msgdlg.cpp74
-rw-r--r--lskat/lskat/msgdlg.h39
-rw-r--r--lskat/lskat/namedlg.cpp129
-rw-r--r--lskat/lskat/namedlg.h49
-rw-r--r--lskat/lskat/networkdlg.cpp105
-rw-r--r--lskat/lskat/networkdlg.h48
-rw-r--r--lskat/lskat/networkdlgbase.ui306
-rw-r--r--lskat/lskat/templates/cpp_template16
-rw-r--r--lskat/lskat/templates/header_template16
-rw-r--r--lskat/lskatproc/KChildConnect.cpp124
-rw-r--r--lskat/lskatproc/KChildConnect.h45
-rw-r--r--lskat/lskatproc/KConnectTypes.h38
-rw-r--r--lskat/lskatproc/KEMessage.cpp326
-rw-r--r--lskat/lskatproc/KEMessage.h66
-rw-r--r--lskat/lskatproc/KInputChildProcess.cpp106
-rw-r--r--lskat/lskatproc/KInputChildProcess.h57
-rw-r--r--lskat/lskatproc/KMessageEntry.cpp98
-rw-r--r--lskat/lskatproc/KMessageEntry.h44
-rw-r--r--lskat/lskatproc/Makefile.am13
-rw-r--r--lskat/lskatproc/docs/Makefile.am4
-rw-r--r--lskat/lskatproc/docs/en/Makefile.am4
-rw-r--r--lskat/lskatproc/lskatproc.cpp596
-rw-r--r--lskat/lskatproc/lskatproc.h104
-rw-r--r--lskat/lskatproc/main.cpp28
-rw-r--r--lskat/lskatproc/templates/cpp_template16
-rw-r--r--lskat/lskatproc/templates/header_template16
85 files changed, 9572 insertions, 0 deletions
diff --git a/lskat/AUTHORS b/lskat/AUTHORS
new file mode 100644
index 00000000..944b9a7d
--- /dev/null
+++ b/lskat/AUTHORS
@@ -0,0 +1 @@
+Martin Heni <martin@heni-online.de>
diff --git a/lskat/COPYING b/lskat/COPYING
new file mode 100644
index 00000000..54754ab4
--- /dev/null
+++ b/lskat/COPYING
@@ -0,0 +1,341 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/lskat/Makefile.am b/lskat/Makefile.am
new file mode 100644
index 00000000..efb7b82c
--- /dev/null
+++ b/lskat/Makefile.am
@@ -0,0 +1,11 @@
+
+SUBDIRS = lskat grafix lskatproc
+
+####### kdevelop will overwrite this part!!! (end)############
+# not a GNU package. You can remove this line, if
+# have all needed files, that a GNU package needs
+AUTOMAKE_OPTIONS = foreign
+
+KDE_ICON = lskat
+
+xdg_apps_DATA = lskat.desktop
diff --git a/lskat/README b/lskat/README
new file mode 100644
index 00000000..08a01e00
--- /dev/null
+++ b/lskat/README
@@ -0,0 +1,33 @@
+GENERAL NOTE:
+
+ This is a small KDE 2.0 game, I wrote to practise
+ programming in KDE.
+ It should work quite stable. But if you find any bugs
+ please contact me.
+ It would be also nice to give me some general feedback
+ about the program, so that it can be approved or it
+ can be considered in other programs.
+ (Email: martin@heni-online.de)
+
+INSTALLATION:
+
+# unpack the archive
+tar xzf lskat-0.9.tar.gz
+
+# build the package
+cd lskat-0.9
+./configure
+# or if KDE is in /opt/kde2
+./configure --prefix=/opt/kde2
+make
+
+# become superuser for installing
+su -c 'make install'
+
+DECKS:
+
+ You can use up to 6 own carddecks. Simply put into
+ the grafichs directory resp the lskatpic.taz archive
+ BMP graphics of the size 72x96, named deck1.bmp ..
+ deck6.bmp
+
diff --git a/lskat/TODO b/lskat/TODO
new file mode 100644
index 00000000..7c90f740
--- /dev/null
+++ b/lskat/TODO
@@ -0,0 +1,3 @@
+- Convert BMP graphics to PNG (done)
+- Checke QT QString-char * casting
+ (Its a bit of a QCString/QString mess right now)
diff --git a/lskat/grafix/Makefile.am b/lskat/grafix/Makefile.am
new file mode 100644
index 00000000..c99fec81
--- /dev/null
+++ b/lskat/grafix/Makefile.am
@@ -0,0 +1,8 @@
+grafix_DATA = background.png deck1.png deck2.png deck3.png deck4.png \
+t1.png t2.png t3.png \
+t4.png t5.png tback.png type1.png type2.png type3.png
+
+grafixdir = $(kde_datadir)/lskat/grafix
+
+EXTRA_DIST = $(grafix_DATA)
+
diff --git a/lskat/grafix/background.png b/lskat/grafix/background.png
new file mode 100644
index 00000000..7c7546a2
--- /dev/null
+++ b/lskat/grafix/background.png
Binary files differ
diff --git a/lskat/grafix/deck1.png b/lskat/grafix/deck1.png
new file mode 100644
index 00000000..70eb9049
--- /dev/null
+++ b/lskat/grafix/deck1.png
Binary files differ
diff --git a/lskat/grafix/deck2.png b/lskat/grafix/deck2.png
new file mode 100644
index 00000000..a17f390b
--- /dev/null
+++ b/lskat/grafix/deck2.png
Binary files differ
diff --git a/lskat/grafix/deck3.png b/lskat/grafix/deck3.png
new file mode 100644
index 00000000..c04eccd4
--- /dev/null
+++ b/lskat/grafix/deck3.png
Binary files differ
diff --git a/lskat/grafix/deck4.png b/lskat/grafix/deck4.png
new file mode 100644
index 00000000..44e9ef91
--- /dev/null
+++ b/lskat/grafix/deck4.png
Binary files differ
diff --git a/lskat/grafix/t1.png b/lskat/grafix/t1.png
new file mode 100644
index 00000000..1722b1a7
--- /dev/null
+++ b/lskat/grafix/t1.png
Binary files differ
diff --git a/lskat/grafix/t2.png b/lskat/grafix/t2.png
new file mode 100644
index 00000000..a5b11f7a
--- /dev/null
+++ b/lskat/grafix/t2.png
Binary files differ
diff --git a/lskat/grafix/t3.png b/lskat/grafix/t3.png
new file mode 100644
index 00000000..6a1b10fc
--- /dev/null
+++ b/lskat/grafix/t3.png
Binary files differ
diff --git a/lskat/grafix/t4.png b/lskat/grafix/t4.png
new file mode 100644
index 00000000..21079f7e
--- /dev/null
+++ b/lskat/grafix/t4.png
Binary files differ
diff --git a/lskat/grafix/t5.png b/lskat/grafix/t5.png
new file mode 100644
index 00000000..2cc08d8c
--- /dev/null
+++ b/lskat/grafix/t5.png
Binary files differ
diff --git a/lskat/grafix/tback.png b/lskat/grafix/tback.png
new file mode 100644
index 00000000..84132ad6
--- /dev/null
+++ b/lskat/grafix/tback.png
Binary files differ
diff --git a/lskat/grafix/type1.png b/lskat/grafix/type1.png
new file mode 100644
index 00000000..d6714c7d
--- /dev/null
+++ b/lskat/grafix/type1.png
Binary files differ
diff --git a/lskat/grafix/type2.png b/lskat/grafix/type2.png
new file mode 100644
index 00000000..1f646df1
--- /dev/null
+++ b/lskat/grafix/type2.png
Binary files differ
diff --git a/lskat/grafix/type3.png b/lskat/grafix/type3.png
new file mode 100644
index 00000000..66b109d4
--- /dev/null
+++ b/lskat/grafix/type3.png
Binary files differ
diff --git a/lskat/hi128-app-lskat.png b/lskat/hi128-app-lskat.png
new file mode 100644
index 00000000..48c94d8b
--- /dev/null
+++ b/lskat/hi128-app-lskat.png
Binary files differ
diff --git a/lskat/hi16-app-lskat.png b/lskat/hi16-app-lskat.png
new file mode 100644
index 00000000..de69f4cf
--- /dev/null
+++ b/lskat/hi16-app-lskat.png
Binary files differ
diff --git a/lskat/hi22-app-lskat.png b/lskat/hi22-app-lskat.png
new file mode 100644
index 00000000..f811b52f
--- /dev/null
+++ b/lskat/hi22-app-lskat.png
Binary files differ
diff --git a/lskat/hi32-app-lskat.png b/lskat/hi32-app-lskat.png
new file mode 100644
index 00000000..7a605d44
--- /dev/null
+++ b/lskat/hi32-app-lskat.png
Binary files differ
diff --git a/lskat/hi48-app-lskat.png b/lskat/hi48-app-lskat.png
new file mode 100644
index 00000000..259608d1
--- /dev/null
+++ b/lskat/hi48-app-lskat.png
Binary files differ
diff --git a/lskat/hi64-app-lskat.png b/lskat/hi64-app-lskat.png
new file mode 100644
index 00000000..00abe3bf
--- /dev/null
+++ b/lskat/hi64-app-lskat.png
Binary files differ
diff --git a/lskat/lskat.desktop b/lskat/lskat.desktop
new file mode 100644
index 00000000..40044788
--- /dev/null
+++ b/lskat/lskat.desktop
@@ -0,0 +1,108 @@
+[Desktop Entry]
+GenericName=Card Game
+GenericName[af]=Kaart Speletjie
+GenericName[ar]=لعبة الورق
+GenericName[be]=Картачная гульня
+GenericName[bg]=Игра на карти
+GenericName[bn]=তাস খেলা
+GenericName[br]=C'hoari kartennoù
+GenericName[bs]=Igra s kartama
+GenericName[ca]=Joc de cartes
+GenericName[cs]=Karty
+GenericName[cy]=Gêm Cerdiau
+GenericName[da]=Kortspil
+GenericName[de]=Kartenspiel
+GenericName[el]=Παιχνίδι καρτών
+GenericName[eo]=Kartludo
+GenericName[es]=Juego de cartas
+GenericName[et]=Kaardimäng
+GenericName[eu]=Karta-jokoa
+GenericName[fa]=بازی ورق
+GenericName[fi]=Korttipeli
+GenericName[fo]=Kortspøl
+GenericName[fr]=Jeu de cartes
+GenericName[ga]=Cluiche Cártaí
+GenericName[gl]=Xogo de cartas
+GenericName[he]=משחק קלפים
+GenericName[hi]=ताश के खेल
+GenericName[hr]=Kartaška igra
+GenericName[hu]=Kártyajáték
+GenericName[is]=Spil
+GenericName[it]=Gioco di carte
+GenericName[ja]=カードゲーム
+GenericName[km]=ល្បែង​បៀ
+GenericName[ko]=카드 놀이
+GenericName[lt]=Kortų žaidimas
+GenericName[lv]=Kāršu Spēle
+GenericName[mk]=Игра со карти
+GenericName[mt]=Logħba tal-karti
+GenericName[nb]=Kortspill
+GenericName[nds]=Koortenspeel
+GenericName[ne]=कार्ड खेल
+GenericName[nl]=Kaartspel
+GenericName[nn]=Kortspel
+GenericName[nso]=Papadi ya Dikarata
+GenericName[pa]=ਤਾਸ਼ ਖੇਡ
+GenericName[pl]=Gra karciana
+GenericName[pt]=Jogo de Cartas
+GenericName[pt_BR]=Jogo de Cartas
+GenericName[ro]=Un joc de cărţi
+GenericName[ru]=Лейтенант Скат
+GenericName[rw]=Umukino Ikarika
+GenericName[se]=Goartaspeallu
+GenericName[sk]=Kartová hra
+GenericName[sl]=Igra s kartami
+GenericName[sr]=Игра са картама
+GenericName[sr@Latn]=Igra sa kartama
+GenericName[sv]=Kortspel
+GenericName[ta]=அட்டை விளையாட்டு
+GenericName[tg]=Бозии Кортҳо
+GenericName[th]=เกมไพ่
+GenericName[tr]=İskambil Oyunu
+GenericName[uk]=Карти
+GenericName[uz]=Qarta oʻyini
+GenericName[uz@cyrillic]=Қарта ўйини
+GenericName[ven]=Garatha ya Mutambo
+GenericName[vi]=Game thẻ
+GenericName[wa]=Cwårdjeu
+GenericName[xh]=Ikhadi lomdlalo
+GenericName[zh_CN]=牌类游戏
+GenericName[zh_TW]=紙牌遊戲
+GenericName[zu]=Umdlalo wamakhadi
+Exec=lskat
+Icon=lskat
+Name=Lieutenant Skat
+Name[bg]=Лейтенант Скат
+Name[ca]=Tinent Skat
+Name[cs]=Poručík Skat
+Name[da]=Lieutnant Skat
+Name[de]=Offiziersskat
+Name[el]=Υπολοχαγός Skat
+Name[eo]=Leŭtenanta skato
+Name[es]=Teniente Skat
+Name[et]=Leitnant Skat
+Name[eu]=Skat tenientea
+Name[fi]=Luutnantti Skat
+Name[hr]=Vojnički Skat
+Name[hu]=Skat hadnagy
+Name[is]=Hermaðurinn Skat
+Name[it]=Tenente Skat
+Name[km]=Lieutnant Skat
+Name[lt]=Leitenantas Skatas
+Name[nds]=Buernskat
+Name[ne]=लिउटिनान्ट स्काट
+Name[nl]=Luitenant Skat
+Name[nn]=Løytnant Skat
+Name[pl]=Skat porucznika
+Name[pt]=Tenente Skat
+Name[pt_BR]=Tenente Skat
+Name[sl]=Poročnik Skat
+Name[sv]=Officersskat
+Name[uk]=Лейтенант Скет
+Name[wa]=Lieutnant Skat
+Terminal=false
+Type=Application
+DocPath=lskat/index.html
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;CardGame;
diff --git a/lskat/lskat.kdevprj b/lskat/lskat.kdevprj
new file mode 100644
index 00000000..bbba872e
--- /dev/null
+++ b/lskat/lskat.kdevprj
@@ -0,0 +1,286 @@
+[AUTHORS]
+dist=true
+install=false
+install_location=
+type=DATA
+[COPYING]
+dist=true
+install=false
+install_location=
+type=DATA
+[ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+[Config for BinMakefileAm]
+bin_program=lskat
+cxxflags=-O0 -g3 -Wall
+ldadd=-lkfile -lkdeui -lkdecore -lqt -lXext -lX11
+ldflags=
+[General]
+author=Martin Heni
+email=martin@heni-online.de
+kdevprj_version=1.0beta2
+lfv_open_groups=
+makefiles=Makefile.am,lskat/Makefile.am,lskat/docs/Makefile.am,lskat/docs/en/Makefile.am,po/Makefile.am,lskatproc/Makefile
+project_name=LSkat
+project_type=normal_kde
+sub_dir=lskat/
+version=0.9
+version_control=CVS
+[INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+[LFV Groups]
+Dialogs=*.kdevdlg
+GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS
+Headers=*.h,*.hxx,*.hpp,*.H
+Others=*
+Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l
+Translations=*.po
+groups=Headers,Sources,Dialogs,Translations,GNU,Others
+[Makefile.am]
+files=lskat.kdevprj,AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,lskat.lsm
+sub_dirs=lskat,po
+type=normal
+[README]
+dist=true
+install=false
+install_location=
+type=DATA
+[TODO]
+dist=true
+install=false
+install_location=
+type=DATA
+[lskat.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+[lskat.lsm]
+dist=true
+install=false
+install_location=
+type=DATA
+[lskat/KChildConnect.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KChildConnect.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KConnectEntry.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KConnectEntry.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KConnectTypes.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KEInput.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KEInput.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KEMessage.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KEMessage.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KInputChildProcess.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KInputChildProcess.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KInteractiveConnect.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KInteractiveConnect.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KMessageEntry.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KMessageEntry.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KProcessConnect.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KProcessConnect.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KRSocket.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KRSocket.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/KRemoteConnect.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/KRemoteConnect.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/Makefile.am]
+files=lskat/main.cpp,lskat/lskat.cpp,lskat/lskat.h,lskat/lskatdoc.cpp,lskat/lskatdoc.h,lskat/lskatview.cpp,lskat/lskatview.h,lskat/resource.h,lskat/lskat.desktop,lskat/lskat.xpm,lskat/mini-lskat.xpm,lskat/KChildConnect.cpp,lskat/KChildConnect.h,lskat/KConnectEntry.cpp,lskat/KConnectEntry.h,lskat/KConnectTypes.h,lskat/KEInput.cpp,lskat/KEInput.h,lskat/KEMessage.cpp,lskat/KEMessage.h,lskat/KInputChildProcess.cpp,lskat/KInputChildProcess.h,lskat/KInteractiveConnect.cpp,lskat/KInteractiveConnect.h,lskat/KMessageEntry.cpp,lskat/KMessageEntry.h,lskat/KProcessConnect.cpp,lskat/KProcessConnect.h,lskat/KRSocket.cpp,lskat/KRSocket.h,lskat/KRemoteConnect.cpp,lskat/KRemoteConnect.h,lskat/namedlg.cpp,lskat/namedlg.h,lskat/networkdlg.cpp,lskat/networkdlg.h,lskat/aboutdlg.cpp,lskat/aboutdlg.h,lskat/aboutdlgdata.cpp,lskat/msgdlg.cpp,lskat/msgdlg.h
+sub_dirs=
+type=prog_main
+[lskat/aboutdlg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/aboutdlg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/aboutdlgdata.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/docs/Makefile.am]
+sub_dirs=
+type=normal
+[lskat/docs/en/Makefile.am]
+sub_dirs=
+type=normal
+[lskat/lskat.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/lskat.desktop]
+dist=true
+install=true
+install_location=$$(kde_appsdir)/Applications/lskat.desktop
+type=DATA
+[lskat/lskat.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/lskat.xpm]
+dist=true
+install=true
+install_location=$$(kde_icondir)/lskat.xpm
+type=DATA
+[lskat/lskatdoc.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/lskatdoc.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/lskatview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/lskatview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/mini-lskat.xpm]
+dist=true
+install=true
+install_location=$$(kde_minidir)/lskat.xpm
+type=DATA
+[lskat/msgdlg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/msgdlg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/namedlg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/namedlg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/networkdlg.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+[lskat/networkdlg.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[lskat/resource.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+[po/Makefile.am]
+sub_dirs=
+type=po
diff --git a/lskat/lskat.lsm b/lskat/lskat.lsm
new file mode 100644
index 00000000..388ff010
--- /dev/null
+++ b/lskat/lskat.lsm
@@ -0,0 +1,14 @@
+Begin3
+Title: LSkat
+Version: 0.9
+Entered-date:
+Description: A small cardgame for the KDE 2 desktop
+Keywords: skat, card, cardgame,game,kde
+Author: Martin Heni <martin@heni-online.de>
+Maintained-by: Martin Heni <martin@heni-online.de>
+Primary-site:
+Home-page: http://www.heni-online.de/linux
+Original-site:
+Platforms: Linux and other Unices
+Copying-policy: GNU Public License
+End
diff --git a/lskat/lskat/KChildConnect.cpp b/lskat/lskat/KChildConnect.cpp
new file mode 100644
index 00000000..61931693
--- /dev/null
+++ b/lskat/lskat/KChildConnect.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ KChildConnect.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include "KChildConnect.h"
+
+#include "KChildConnect.moc"
+
+KChildConnect::KChildConnect()
+ : QObject(0,0)
+{
+ input_pending=false;
+ inputbuffer="";
+}
+
+KChildConnect::~KChildConnect()
+{
+}
+
+KR_STATUS KChildConnect::QueryStatus()
+{
+ return KR_OK;
+}
+
+// Communication with process
+bool KChildConnect::SendMsg(KEMessage *msg)
+{
+ QString sendstring=msg->ToString();
+ // Debug only
+ if (msg->HasKey(QCString("KLogSendMsg")))
+ {
+ char *p;
+ int size;
+ FILE *fp;
+ msg->GetData(QCString("KLogSendMsg"),p,size);
+ if (p && (fp=fopen(p,"a")) )
+ {
+ fprintf(fp,"------------------------------------\n");
+ fprintf(fp, "%s", sendstring.utf8().data());
+ fclose(fp);
+ }
+ }
+ // end debug only
+ return Send(sendstring);
+}
+
+// Send string to parent
+bool KChildConnect::Send(QString str)
+{
+ if (!str || str.length()<1) return true; // no need to send crap
+ printf("%s",str.latin1());
+ fflush(stdout);
+ return true;
+}
+
+void KChildConnect::Receive(QString input)
+{
+ // Cut out CR
+ int len,pos;
+ QString tmp;
+
+
+ // Call us recursive until there are no CR left
+ len=KEMESSAGE_CR.length();
+ pos=input.find(KEMESSAGE_CR);
+ if (pos>0)
+ {
+ tmp=input.left(pos);
+ if (tmp.length()>0) Receive(tmp); // CR free
+ input=input.right(input.length()-pos-len);
+ if (input.length()>0) Receive(input);
+ return ;
+ }
+
+// printf(" ---> KChildConnect::Receive: '%s'\n",(const char *)input);
+ if (input==(KEMESSAGE_HEAD) && !input_pending)
+ {
+ input_pending=true;
+ inputcache.clear();
+ return ;
+ }
+ if (!input_pending) return ; // ignore
+ if (input!=(KEMESSAGE_TAIL))
+ {
+ inputcache.append(input.latin1());
+ return;
+ }
+ input_pending=0;
+
+ KEMessage *msg=new KEMessage;
+ char *it;
+ for (it=inputcache.first();it!=0;it=inputcache.next())
+ {
+ msg->AddString(QCString(it));
+ }
+
+// printf("+- CHILDprocess:: GOT MESSAGE::Emmiting slotReceiveMsg\n");
+ emit signalReceiveMsg(msg,ID);
+
+ delete msg;
+}
+
+void KChildConnect::SetID(int id)
+{
+ ID=id;
+}
+int KChildConnect::QueryID()
+{
+ return ID;
+}
+
diff --git a/lskat/lskat/KChildConnect.h b/lskat/lskat/KChildConnect.h
new file mode 100644
index 00000000..d90c62ca
--- /dev/null
+++ b/lskat/lskat/KChildConnect.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ KChildConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KCHILDCONNECT_H_
+#define _KCHILDCONNECT_H_
+
+#include <qobject.h>
+#include <qstrlist.h>
+#include "KEMessage.h"
+
+
+class KChildConnect: public QObject
+{
+ Q_OBJECT
+
+ protected:
+ QStrList inputcache;
+ bool input_pending;
+ QString inputbuffer;
+ int ID;
+
+ public:
+ KChildConnect();
+ ~KChildConnect();
+ void Receive(QString input);
+ int QueryID();
+ void SetID(int id);
+
+ virtual bool SendMsg(KEMessage *msg);
+ virtual bool Send(QString str);
+ virtual KR_STATUS QueryStatus();
+
+ public slots:
+
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+#endif
diff --git a/lskat/lskat/KConnectEntry.cpp b/lskat/lskat/KConnectEntry.cpp
new file mode 100644
index 00000000..870b8cd2
--- /dev/null
+++ b/lskat/lskat/KConnectEntry.cpp
@@ -0,0 +1,165 @@
+/***************************************************************************
+ KConnectEntry.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "KConnectEntry.h"
+
+KG_INPUTTYPE KConnectEntry::QueryType()
+{
+ return type;
+}
+
+KRemoteConnect *KConnectEntry::QueryRemoteConnect()
+{
+ return connect.r;
+}
+
+KProcessConnect *KConnectEntry::QueryProcessConnect()
+{
+ return connect.p;
+}
+
+KInteractiveConnect *KConnectEntry::QueryInteractiveConnect()
+{
+ return connect.i;
+}
+
+KR_STATUS KConnectEntry::QueryStatus()
+{
+ switch(type)
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ return connect.i->QueryStatus();
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ return connect.r->QueryStatus();
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ return connect.p->QueryStatus();
+ break;
+ default:
+ return KR_INVALID;
+ break;
+ }
+}
+bool KConnectEntry::SendMsg(KEMessage *msg)
+{
+ switch(type)
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ return connect.i->SendMsg(msg);
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ return connect.r->SendMsg(msg);
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ return connect.p->SendMsg(msg);
+ break;
+ default:
+ return false;
+ break;
+ }
+}
+
+bool KConnectEntry::Exit()
+{
+ bool result;
+ result=FALSE;
+ switch(type)
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ result=connect.i->Exit();
+ delete connect.i;
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ result=connect.r->Exit();
+ delete connect.r;
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ result=connect.p->Exit();
+ delete connect.p;
+ break;
+ default: result=FALSE;
+ break;
+ }
+ return result;
+}
+
+bool KConnectEntry::Init(KG_INPUTTYPE stype,int id,KEMessage *msg)
+{
+ bool result;
+ type=stype;
+ ID=id;
+ switch(stype)
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ connect.i=new KInteractiveConnect;
+ result=connect.i->Init(id,msg);
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ connect.r=new KRemoteConnect;
+ result=connect.r->Init(id,msg);
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ connect.p=new KProcessConnect;
+ result=connect.p->Init(id,msg);
+ break;
+ default: result=FALSE;
+ break;
+ }
+ return result;
+}
+KConnectEntry::KConnectEntry()
+{
+ type=(KG_INPUTTYPE)0;
+ connect.r=0;
+}
+
+KConnectEntry::~KConnectEntry()
+{
+// printf("DESTRUCTING KCONNECTENTRY\n");
+ Exit();
+}
+
+KConnectEntry::KConnectEntry(KConnectEntry &msg)
+{
+ *this=msg;
+}
+KConnectEntry &KConnectEntry::operator=(KConnectEntry &entry)
+{
+ // printf("&KConnectEntry::operator=:: I am not sure whether this is really a good idea...\n");
+ Init(entry.QueryType(),entry.ID);
+
+ return *this;
+}
diff --git a/lskat/lskat/KConnectEntry.h b/lskat/lskat/KConnectEntry.h
new file mode 100644
index 00000000..73619eac
--- /dev/null
+++ b/lskat/lskat/KConnectEntry.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ KConnectEntry.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KCONNECTENTRY_H_
+#define _KCONNECTENTRY_H_
+
+#include <string.h>
+#include "KRemoteConnect.h"
+#include "KProcessConnect.h"
+#include "KInteractiveConnect.h"
+#include "KConnectTypes.h"
+#include "KEMessage.h"
+
+union UConnect
+{
+ KRemoteConnect *r;
+ KProcessConnect *p;
+ KInteractiveConnect *i;
+};
+
+class KConnectEntry
+{
+ private:
+ KG_INPUTTYPE type; // remote,computer,interactive
+ UConnect connect;
+ protected:
+ int ID;
+
+ public:
+ KG_INPUTTYPE QueryType();
+ KRemoteConnect *QueryRemoteConnect();
+ KProcessConnect *QueryProcessConnect();
+ KInteractiveConnect *QueryInteractiveConnect();
+ KConnectEntry();
+ ~KConnectEntry();
+ KConnectEntry(KConnectEntry &entry);
+ KConnectEntry &operator=(KConnectEntry &entry);
+ bool Exit();
+ bool Init(KG_INPUTTYPE stype,int id=0,KEMessage *msg=0);
+ KR_STATUS QueryStatus();
+ bool SendMsg(KEMessage *msg);
+};
+#endif
diff --git a/lskat/lskat/KConnectTypes.h b/lskat/lskat/KConnectTypes.h
new file mode 100644
index 00000000..6a9822b3
--- /dev/null
+++ b/lskat/lskat/KConnectTypes.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ KConnectTypes.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KCONNECTTYPES_H_
+#define _KCONNECTTYPES_H_
+
+enum KGM_TYPE {KGM_TYPE_INVALID=0,KGM_TYPE_SHORT=1,KGM_TYPE_LONG=2,
+ KGM_TYPE_FLOAT=3,KGM_TYPE_DATA=4};
+
+enum KG_INPUTTYPE {
+ KG_INPUTTYPE_INVALID=0,
+ KG_INPUTTYPE_INTERACTIVE=1,
+ KG_INPUTTYPE_PROCESS=2,
+ KG_INPUTTYPE_REMOTE=3};
+
+enum KR_STATUS {
+ KR_NO_SOCKET=-2,
+ KR_WAIT_FOR_CLIENT=-1,
+ KR_INVALID=0,
+ // >0 OK
+ KR_OK=1,
+ KR_CLIENT=2,
+ KR_SERVER=3
+ };
+#endif
diff --git a/lskat/lskat/KEInput.cpp b/lskat/lskat/KEInput.cpp
new file mode 100644
index 00000000..b5765d00
--- /dev/null
+++ b/lskat/lskat/KEInput.cpp
@@ -0,0 +1,296 @@
+/***************************************************************************
+ KEInput.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include "KEInput.h"
+#include "KConnectEntry.h"
+
+#define K_INPUT_DELAY 25 // delay following non interactive moves
+
+#include "KEInput.moc"
+
+KEInput::KEInput(QObject * parent)
+ : QObject(parent,0)
+{
+ number_of_inputs=0;
+ locked=FALSE;
+ previous_input=-1;
+ next_input=-1;
+ cTimer=0;
+// mMsg=(KEMessage *)0;
+}
+
+KEInput::~KEInput()
+{
+ int i;
+ for (i=number_of_inputs-1;i>=0;i--)
+ {
+ RemoveInput(i);
+ }
+ delete cTimer;
+}
+
+int KEInput::QueryNumberOfInputs()
+{
+ return number_of_inputs;
+}
+
+int KEInput::QueryNext()
+{
+ return next_input;
+}
+
+int KEInput::QueryPrevious()
+{
+ return previous_input;
+}
+
+bool KEInput::IsInput(int no)
+{
+ if (no>=number_of_inputs || no<0) return FALSE;
+ if (QueryType(no)==0) return FALSE;
+ return TRUE;
+}
+
+// Default is the type of the current player
+bool KEInput::IsInteractive(int no)
+{
+ return QueryType(no)==KG_INPUTTYPE_INTERACTIVE;
+}
+bool KEInput::IsProcess(int no)
+{
+ return QueryType(no)==KG_INPUTTYPE_PROCESS;
+}
+bool KEInput::IsRemote(int no)
+{
+ return QueryType(no)==KG_INPUTTYPE_REMOTE;
+}
+KG_INPUTTYPE KEInput::QueryType(int no)
+{
+ if (no==-1) no=QueryNext();
+ if (no>=number_of_inputs || no<0) return KG_INPUTTYPE_INVALID;
+ return playerArray[no].QueryType();
+}
+
+KR_STATUS KEInput::QueryStatus(int no)
+{
+ if (no==-1) no=QueryNext();
+ if (no>=number_of_inputs || no<0)
+ {
+ return KR_INVALID;
+ }
+ return playerArray[no].QueryStatus();
+}
+bool KEInput::SendMsg(KEMessage *msg,int no)
+{
+ if (no==-1) no=QueryNext();
+ if (no>=number_of_inputs || no<0)
+ {
+ return false;
+ }
+ return playerArray[no].SendMsg(msg);
+}
+
+
+bool KEInput::SetInputDevice(int no, KG_INPUTTYPE type,KEMessage *msg)
+{
+ bool result;
+ // Grow if necessary
+ if (no<0) return false;
+ else if (no<number_of_inputs)
+ {
+ RemoveInput(no);
+ }
+ if (no>=number_of_inputs)
+ {
+ playerArray.resize(no+1);
+ number_of_inputs=no+1;
+ }
+ result=playerArray[no].Init(type,no,msg);
+ // if (result)
+ // Connect even if remote connection is not yet build
+ if (result || playerArray[no].QueryStatus()==KR_WAIT_FOR_CLIENT)
+ {
+ switch(QueryType(no))
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ connect(playerArray[no].QueryInteractiveConnect(),SIGNAL(signalReceiveMsg(KEMessage *,int )),
+ this,SLOT(slotSetInput(KEMessage *,int )));
+ connect(playerArray[no].QueryInteractiveConnect(),SIGNAL(signalPrepareMove(KEMessage *,KG_INPUTTYPE)),
+ this,SLOT(slotPrepareMove(KEMessage *,KG_INPUTTYPE)));
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ connect(playerArray[no].QueryRemoteConnect(),SIGNAL(signalReceiveMsg(KEMessage *,int )),
+ this,SLOT(slotSetInput(KEMessage *,int )));
+ connect(playerArray[no].QueryRemoteConnect(),SIGNAL(signalPrepareMove(KEMessage *,KG_INPUTTYPE)),
+ this,SLOT(slotPrepareMove(KEMessage *,KG_INPUTTYPE)));
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ connect(playerArray[no].QueryProcessConnect(),SIGNAL(signalReceiveMsg(KEMessage *,int )),
+ this,SLOT(slotSetInput(KEMessage *,int )));
+ connect(playerArray[no].QueryProcessConnect(),SIGNAL(signalPrepareMove(KEMessage *,KG_INPUTTYPE)),
+ this,SLOT(slotPrepareMove(KEMessage *,KG_INPUTTYPE)));
+ break;
+ default:
+ break;
+ }
+ }
+ return result;
+}
+
+bool KEInput::RemoveInput(int no)
+{
+ bool result;
+ if (no>=number_of_inputs || no<0) return FALSE;
+ result=playerArray[no].Exit();
+ // shrink if last entry is removed
+ if (no==number_of_inputs-1)
+ {
+ playerArray.resize(no);
+ number_of_inputs=no;
+ }
+ return result;
+}
+
+
+// Sets a new player and sends it a message
+bool KEInput::Next(int number, bool force)
+{
+ if (locked && !force) return FALSE;
+ if (!IsInput(number)) return FALSE;
+ locked=TRUE;
+
+ // printf("KEInput::Next %d OK ... lock set!!\n",number);
+
+ previous_input=next_input;
+ next_input=number;
+
+ switch(QueryType(number))
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ playerArray[number].QueryInteractiveConnect()->Next();
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ if (QueryType(previous_input)!=0 &&
+ QueryType(previous_input)!=KG_INPUTTYPE_INTERACTIVE)
+ {
+ // delay non interactive move to allow interactive inout
+ if (cTimer) delete cTimer; // Ouch...
+ cTimer=new QTimer(this);
+ connect(cTimer,SIGNAL(timeout()),this,SLOT(slotTimerNextRemote()));
+ cTimer->start(K_INPUT_DELAY,TRUE);
+ }
+ else
+ {
+ playerArray[number].QueryRemoteConnect()->Next();
+ }
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ if (QueryType(previous_input)!=0 &&
+ QueryType(previous_input)!=KG_INPUTTYPE_INTERACTIVE)
+ {
+ // delay non interactive move to allow interactive inout
+ cTimer=new QTimer(this);
+ connect(cTimer,SIGNAL(timeout()),this,SLOT(slotTimerNextProcess()));
+ cTimer->start(K_INPUT_DELAY,TRUE);
+ }
+ else
+ playerArray[number].QueryProcessConnect()->Next();
+ break;
+ default: return FALSE;
+ }
+ return TRUE;
+}
+
+void KEInput::slotTimerNextRemote()
+{
+ delete cTimer;
+ cTimer=0;
+ if (next_input>=0 && next_input<number_of_inputs)
+ playerArray[next_input].QueryRemoteConnect()->Next();
+}
+
+void KEInput::slotTimerNextProcess()
+{
+ delete cTimer;
+ cTimer=0;
+ if (next_input>=0 && next_input<number_of_inputs)
+ playerArray[next_input].QueryProcessConnect()->Next();
+}
+
+// called to prepare a move which is send to a remote/computer
+// should fill in message data
+void KEInput::slotPrepareMove(KEMessage *msg,KG_INPUTTYPE type)
+{
+ // just forward it
+ switch(type)
+ {
+ case KG_INPUTTYPE_INTERACTIVE:
+ emit signalPrepareInteractiveMove(msg);
+ break;
+ case KG_INPUTTYPE_PROCESS:
+ emit signalPrepareProcessMove(msg);
+ break;
+ case KG_INPUTTYPE_REMOTE:
+ emit signalPrepareRemoteMove(msg);
+ break;
+ default: // Do nothing
+ break;
+ }
+}
+// called by ReceiveMsg
+void KEInput::slotSetInput(KEMessage *msg,int id)
+{
+ if (!msg) return ;
+ SetInput(msg,id);
+}
+
+bool KEInput::SetInput(KEMessage *msg,int number)
+{
+ /*
+ if (!locked)
+ {
+ printf("KEINput:SetInput not locked(should be) returning FALSE\n");
+ return FALSE;
+ }
+ */
+ if (number<0 || number>=number_of_inputs) number=next_input; // automatically select player
+// KEMessage *mMsg= new KEMessage;
+ // evt if (mMsg) delete mMsg;
+// *mMsg=*msg;
+ // locked=FALSE;
+ // printf("**** KEInput: emitting signalReceiveInput 474\n");
+ emit signalReceiveInput(msg,number);
+// emit signalReceiveInput(mMsg);
+// delete mMsg;
+ return TRUE;
+}
+
+void KEInput::Lock()
+{
+ locked=true;
+}
+
+void KEInput::Unlock()
+{
+ locked=false;
+}
+
+bool KEInput::IsLocked()
+{
+ return locked;
+}
+
diff --git a/lskat/lskat/KEInput.h b/lskat/lskat/KEInput.h
new file mode 100644
index 00000000..e2f3ef8b
--- /dev/null
+++ b/lskat/lskat/KEInput.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ KEInput.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KEINPUT_H_
+#define _KEINPUT_H_
+
+#include <qptrlist.h>
+#include <qobject.h>
+#include <qtimer.h>
+#include <qmemarray.h>
+#include "KConnectEntry.h"
+#include "KRemoteConnect.h"
+#include "KProcessConnect.h"
+#include "KInteractiveConnect.h"
+#include "KEMessage.h"
+#include "KConnectTypes.h"
+
+
+class KEInput : public QObject
+{
+ Q_OBJECT
+
+ private:
+ int number_of_inputs;
+ int previous_input,next_input;
+ bool locked;
+// KEMessage *mMsg;
+ QTimer *cTimer;
+
+ QPtrList<KRemoteConnect> remoteList;
+ QPtrList<KProcessConnect> computerList;
+ QPtrList<KInteractiveConnect> interactiveList;
+ QMemArray<KConnectEntry> playerArray;
+
+ public:
+ KEInput(QObject * parent=0);
+ ~KEInput();
+ int QueryNumberOfInputs();
+ int QueryNext();
+ bool IsInteractive(int no=-1);
+ bool IsProcess(int no=-1);
+ bool IsRemote(int no=-1);
+ int QueryPrevious();
+ KG_INPUTTYPE QueryType(int no=-1);
+ KR_STATUS QueryStatus(int no=-1);
+ bool IsInput(int no);
+ bool SetInputDevice(int no, KG_INPUTTYPE type, KEMessage *msg=0);
+ bool RemoveInput(int no);
+ bool Next(int number, bool force=false);
+ bool SetInput(KEMessage *msg,int number=-1);
+ bool IsLocked();
+ bool SendMsg(KEMessage *msg,int no=-1);
+ void Unlock();
+ void Lock();
+
+ public slots:
+ void slotTimerNextRemote();
+ void slotTimerNextProcess();
+ void slotSetInput(KEMessage *msg,int id);
+ void slotPrepareMove(KEMessage *msg,KG_INPUTTYPE type);
+
+ signals:
+ void signalReceiveInput(KEMessage *msg,int id);
+ void signalPrepareRemoteMove(KEMessage *msg);
+ void signalPrepareProcessMove(KEMessage *msg);
+ void signalPrepareInteractiveMove(KEMessage *msg);
+
+};
+#endif
diff --git a/lskat/lskat/KEMessage.cpp b/lskat/lskat/KEMessage.cpp
new file mode 100644
index 00000000..9d3d3d3f
--- /dev/null
+++ b/lskat/lskat/KEMessage.cpp
@@ -0,0 +1,326 @@
+/***************************************************************************
+ KEMessage.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "KEMessage.h"
+
+void KEMessage::AddEntry(QString key,KMessageEntry *entry)
+{
+ // printf(" AddingEntry: %s with data field %p\n",(char *)key,entry->QueryData());
+ if (!entry) return ;
+ dict.insert(key,entry);
+ keys.append(key.latin1());
+}
+
+void KEMessage::AddDataType(QString key,int size,const char *data,KGM_TYPE type)
+{
+// printf("AddDataType for %s size=%d\n",(const char *)key,size);
+ if (size<=0) return ;
+ KMessageEntry *entry=new KMessageEntry;
+ entry->SetType(type);
+ entry->CopyData(size,data);
+ AddEntry(key,entry);
+}
+
+void KEMessage::AddData(QString key,short data)
+{
+ AddDataType(key,sizeof(short),(char *)&data,KGM_TYPE_SHORT);
+}
+
+void KEMessage::AddData(QString key,long data)
+{
+ AddDataType(key,sizeof(long),(char *)&data,KGM_TYPE_LONG);
+}
+
+void KEMessage::AddData(QString key,float data)
+{
+ AddDataType(key,sizeof(float),(char *)&data,KGM_TYPE_FLOAT);
+}
+
+void KEMessage::AddData(QString key, const char *data,int size)
+{
+ if (size<0) size=strlen(data)+1; // +1 for 0 Byte
+ AddDataType(key,size,data,KGM_TYPE_DATA);
+}
+
+KGM_TYPE KEMessage::QueryType(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return (KGM_TYPE)0;
+ return entry->QueryType();
+}
+
+bool KEMessage::HasKey(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,short &s)
+{
+ short *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_SHORT) return false;
+ // printf("GetShortData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(short *)entry->QueryData();
+ s=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,long &l)
+{
+ long *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_LONG) return false;
+ result=(long *)entry->QueryData();
+ l=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,float &f)
+{
+ float *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_FLOAT) return false;
+ // printf("GetFloatData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(float *)entry->QueryData();
+ f=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,char * &c,int &size)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_DATA) return false;
+ c=entry->QueryData();
+ size=entry->QuerySize();
+ return true;
+}
+
+QString KEMessage::EntryToString(char *key,KMessageEntry *entry)
+{
+ QString s,tmp;
+ int size,i;
+ KGM_TYPE type;
+ char *data;
+ s=QCString("");
+ if (!entry) return s;
+ size=entry->QuerySize();
+ type=entry->QueryType();
+ data=entry->QueryData();
+
+ // Key
+ /*
+ tmp.sprintf("%s%s%d%s%d%s",
+ key,KEMESSAGE_SEP,
+ size,KEMESSAGE_SEP,
+ (int)type,KEMESSAGE_SEP);
+ */
+ tmp=QCString(key);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",size);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",(int)type);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+
+
+ // We ignore the type of data and process them all as
+ // byte sequence
+ for (i=0;i<size;i++)
+ {
+ // Convert to 4 bit value ... someone can improves
+ tmp.sprintf("%c%c",
+ 'a'+(data[i]&15),
+ 'a'+((data[i]>>4)&15));
+ s+=tmp;
+ }
+ s+=KEMESSAGE_CR;
+
+ return s;
+}
+
+QString KEMessage::StringToEntry(QString str,KMessageEntry *entry)
+{
+ int pos,oldpos,cnt,len;
+ QString key,size,type,data;
+ const char *p;
+ char *q;
+ char c;
+
+ len=KEMESSAGE_SEP.length();
+
+ if (!entry) return QString();
+ pos=str.find(KEMESSAGE_SEP,0);
+ if (pos<0) return QString(); // wrong format
+ key=str.left(pos);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ size=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ type=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ data=str.right(str.length()-pos-len);
+
+
+ cnt=size.toInt();
+ entry->SetType((KGM_TYPE)type.toInt());
+
+ // I hope this works with unicode strings as well
+ p=data.latin1();
+ q=(char *)calloc(data.length()/2,sizeof(char));
+ if (!q) return QString();
+ for(pos=0;pos<cnt;pos++)
+ {
+ if (pos*2+1>(int)data.length()) return QString(); // SEVERE ERROR
+ c=*(p+2*pos)-'a' | ((*(p+2*pos+1)-'a')<<4);
+ q[pos]=c;
+ }
+ entry->CopyData(cnt,q);
+
+ free(q);
+ return key;
+}
+
+QString KEMessage::ToString()
+{
+ QString s;
+ KMessageEntry *entry;
+ char *it;
+ s=KEMESSAGE_HEAD+KEMESSAGE_CR;
+ for (it=keys.first();it!=0;it=keys.next())
+ {
+ entry=dict.find(QCString(it));
+ s+=EntryToString(it,entry);
+ }
+ s+=KEMESSAGE_TAIL+KEMESSAGE_CR;
+ return s;
+}
+
+bool KEMessage::AddString(QString s)
+{
+ // break s into key,size and data
+ QString key;
+ KMessageEntry *entry=new KMessageEntry;
+ key=StringToEntry(s,entry);
+ if (!key) return false;
+ AddEntry(key,entry);
+ return true;
+}
+bool KEMessage::AddStringMsg(QString str)
+{
+ bool result;
+ QString data;
+ int pos,oldpos,len;
+
+ len=KEMESSAGE_CR.length();
+
+ pos=str.find(KEMESSAGE_CR);
+ if (pos<0) return false; // wrong format
+ if (str.left(pos)!=(KEMESSAGE_HEAD)) return false; // wrong message
+
+ do
+ {
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_CR,oldpos+len);
+ if (pos<0) return false; // wrong format
+ data=str.mid(oldpos+len,pos-oldpos-len);
+ if (data!=(KEMESSAGE_TAIL))
+ {
+ result=AddString(data);
+ if (!result) return false; // wrong format
+ }
+ }while(data!=(KEMESSAGE_TAIL));
+
+ return result;
+}
+
+void KEMessage::RemoveAll()
+{
+ keys.clear();
+ dict.clear();
+}
+
+void KEMessage::Remove(QString key)
+{
+ keys.remove(key.latin1());
+ dict.remove(key);
+}
+
+uint KEMessage::QueryNumberOfKeys()
+{
+ return keys.count();
+}
+QStrList *KEMessage::QueryKeys()
+{
+ return &keys;
+}
+
+KEMessage::~KEMessage()
+{
+ // printf("Deleteing KEMessage %p\n",this);
+}
+KEMessage::KEMessage()
+{
+ // printf("KEMessage construct %p\n",this);
+ dict.setAutoDelete(true);
+}
+KEMessage::KEMessage(KEMessage &msg)
+{
+ // printf("KEMessage copy constructor from %p to %p\n",&msg,this);
+ *this=msg;
+}
+KEMessage &KEMessage::operator=(KEMessage &msg)
+{
+ // KEMessage *newmsg=new KEMessage;
+ KMessageEntry *entry;
+ KMessageEntry *newentry;
+ char *it;
+ // printf("Assigning = KEMessage from %p to %p\n",&msg,this);
+ for (it=msg.keys.first();it!=0;it=msg.keys.next())
+ {
+ entry=msg.dict.find(QCString(it));
+ newentry=new KMessageEntry;
+ *newentry=*entry;
+ AddEntry(QCString(it),newentry);
+
+ }
+ // return *newmsg;
+ return *this;
+}
diff --git a/lskat/lskat/KEMessage.h b/lskat/lskat/KEMessage.h
new file mode 100644
index 00000000..0a1913cc
--- /dev/null
+++ b/lskat/lskat/KEMessage.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ KEMessage.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KEMESSAGE_H_
+#define _KEMESSAGE_H_
+
+#include <string.h>
+#include <qstring.h>
+#include <qstrlist.h>
+#include <qdict.h>
+#include "KMessageEntry.h"
+
+#define KEMESSAGE_HEAD QString(QCString("BEGIN_V1000"))
+#define KEMESSAGE_TAIL QString(QCString("END_V1000"))
+#define KEMESSAGE_CR QString(QCString("\n"))
+#define KEMESSAGE_SEP QString(QCString(":::"))
+
+class KEMessage
+{
+ private:
+ QStrList keys;
+ QDict<KMessageEntry> dict;
+
+ protected:
+ void AddEntry(QString key,KMessageEntry *entry);
+ public:
+ QStrList *QueryKeys();
+ uint QueryNumberOfKeys();
+ void AddDataType(QString key,int size,const char *data,KGM_TYPE type);
+ void AddData(QString key,short data);
+ void AddData(QString key,long data);
+ void AddData(QString key,float data);
+ void AddData(QString key,const char *data,int size=-1);
+ bool GetData(QString key,short &s);
+ bool GetData(QString key,long &l);
+ bool GetData(QString key,float &f);
+ bool GetData(QString key,char * &c,int &size);
+ bool HasKey(QString key);
+ void Remove(QString key);
+ KGM_TYPE QueryType(QString key);
+ QString ToString();
+ QString EntryToString(char *key,KMessageEntry *entry);
+ QString StringToEntry(QString str,KMessageEntry *entry);
+ bool AddString(QString s);
+ bool AddStringMsg(QString str);
+ void RemoveAll();
+ ~KEMessage();
+ KEMessage();
+ KEMessage(KEMessage &msg);
+ KEMessage &operator=(KEMessage &msg);
+};
+
+#endif
diff --git a/lskat/lskat/KInputChildProcess.cpp b/lskat/lskat/KInputChildProcess.cpp
new file mode 100644
index 00000000..fb6e743a
--- /dev/null
+++ b/lskat/lskat/KInputChildProcess.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ KInputChildProcess.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <qstring.h>
+
+#include "KInputChildProcess.h"
+#include "KInputChildProcess.moc"
+
+
+KInputChildProcess::~KInputChildProcess()
+{
+ delete buffer;
+ delete childConnect;
+}
+KInputChildProcess::KInputChildProcess(int size_buffer)
+ : QObject(0,0)
+{
+ buffersize=size_buffer;
+ if (buffersize<1) buffersize=1024;
+ buffer=new char[buffersize];
+ inputbuffer="";
+ terminateChild=false;
+}
+bool KInputChildProcess::exec()
+{
+ int pos;
+ QString s;
+
+ childConnect=new KChildConnect;
+ if (!childConnect) return false;
+ connect(childConnect,SIGNAL(signalReceiveMsg(KEMessage *,int)),
+ this,SLOT(slotReceiveMsg(KEMessage *,int)));
+ do
+ {
+ // Wait for input
+ if (feof(stdin))
+ {
+ sleep(1);
+ continue;
+ }
+
+ if (!fgets(buffer,buffersize,stdin) )
+ {
+ continue;
+ }
+ s=buffer;
+ s=inputbuffer+s;
+ // printf("ChildABC '%s'\n",(const char *)s);
+ // fflush(stdout);
+ pos=s.findRev(KEMESSAGE_CR);
+ if (pos<0)
+ {
+ inputbuffer=s;
+ }
+ else if (pos+KEMESSAGE_CR.length()==s.length())
+ {
+ // CR at the end...calling receive
+ childConnect->Receive(s);
+ }
+ else
+ {
+ inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length());
+ s=s.left(pos+KEMESSAGE_CR.length());
+ // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer);
+ childConnect->Receive(s);
+ }
+ }while(!terminateChild);
+ return true;
+}
+
+void KInputChildProcess::Terminate()
+{
+ terminateChild=true;
+}
+bool KInputChildProcess::IsTerminated()
+{
+ return terminateChild;
+}
+
+bool KInputChildProcess::ReceiveMsg(KEMessage *,int )
+{
+ return false;
+}
+void KInputChildProcess::slotReceiveMsg(KEMessage *msg,int id)
+{
+ if (!ReceiveMsg(msg,id)) // made for virtual override
+ {
+ // otherwise emit signal
+ emit signalReceiveMsg(msg,id);
+ }
+}
+bool KInputChildProcess::SendMsg(KEMessage *msg)
+{
+ if (childConnect) return childConnect->SendMsg(msg);
+ return false;
+}
+
+
diff --git a/lskat/lskat/KInputChildProcess.h b/lskat/lskat/KInputChildProcess.h
new file mode 100644
index 00000000..b4694df5
--- /dev/null
+++ b/lskat/lskat/KInputChildProcess.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ KInputChildProcess.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KINPUTCHILDPROCESS_H_
+#define _KINPUTCHILDPROCESS_H_
+
+#include <qobject.h>
+#include "KEMessage.h"
+#include "KChildConnect.h"
+
+
+class KInputChildProcess : public QObject
+{
+ Q_OBJECT
+
+ private:
+ char *buffer;
+ QString inputbuffer;
+ int buffersize;
+ bool terminateChild;
+ protected:
+ KChildConnect *childConnect;
+
+ public:
+ KInputChildProcess(int size_buffer=4096);
+ ~KInputChildProcess();
+ bool exec();
+ virtual bool ReceiveMsg(KEMessage *msg,int id);
+ // Forward calls to childconnect
+ bool SendMsg(KEMessage *msg);
+ // Immediately kills child's exec !
+ void Terminate();
+ bool IsTerminated();
+
+
+ public slots:
+ void slotReceiveMsg(KEMessage *msg,int id);
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+
+#endif
diff --git a/lskat/lskat/KInteractiveConnect.cpp b/lskat/lskat/KInteractiveConnect.cpp
new file mode 100644
index 00000000..e95dcbe1
--- /dev/null
+++ b/lskat/lskat/KInteractiveConnect.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ KInteractiveConnect.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include "KInteractiveConnect.h"
+
+#include "KInteractiveConnect.moc"
+
+bool KInteractiveConnect::Next()
+{
+ // Dummy only for interactive
+ KEMessage *msg=new KEMessage;
+ emit signalPrepareMove(msg,KG_INPUTTYPE_INTERACTIVE);
+ delete msg;
+ return true;
+}
+bool KInteractiveConnect::Init(int id,KEMessage *)
+{
+ // emit signalReceiveMsg(msg);
+ SetID(id);
+ return true;
+}
+bool KInteractiveConnect::Exit()
+{
+ return true;
+}
+
+KInteractiveConnect::~KInteractiveConnect()
+{
+// printf("DESTRUCTING INTERACTIVE\n");
+}
+
+KInteractiveConnect::KInteractiveConnect()
+ : KChildConnect()
+{
+}
+
+bool KInteractiveConnect::SendMsg(KEMessage *msg)
+{
+ printf("+- Interactive::SendMessage MESSAGE::Emmiting slotReceiveMsg\n");
+ emit signalReceiveMsg(msg,QueryID());
+ return true;
+}
+// Try not to use this..prodices just unnecessary string-msg
+// conversion
+bool KInteractiveConnect::Send(QString str)
+{
+ Receive(str);
+ return true;
+}
diff --git a/lskat/lskat/KInteractiveConnect.h b/lskat/lskat/KInteractiveConnect.h
new file mode 100644
index 00000000..5a393c26
--- /dev/null
+++ b/lskat/lskat/KInteractiveConnect.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ KInteractiveConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KINTERACTIVECONNECT_H_
+#define _KINTERACTIVECONNECT_H_
+
+#include "KEMessage.h"
+#include "KChildConnect.h"
+
+class KInteractiveConnect:public KChildConnect
+{
+ Q_OBJECT
+
+ public:
+ KInteractiveConnect();
+ ~KInteractiveConnect();
+ bool Next();
+ bool Init(int id=0,KEMessage *msg=0);
+ bool Exit();
+ bool SendMsg(KEMessage *msg);
+ bool Send(QString str);
+
+ signals:
+ void signalPrepareMove(KEMessage *msg,KG_INPUTTYPE type);
+// void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+#endif
diff --git a/lskat/lskat/KMessageEntry.cpp b/lskat/lskat/KMessageEntry.cpp
new file mode 100644
index 00000000..cb9b2dc0
--- /dev/null
+++ b/lskat/lskat/KMessageEntry.cpp
@@ -0,0 +1,81 @@
+/***************************************************************************
+ KMessageEntry.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "KMessageEntry.h"
+
+void KMessageEntry::SetType(KGM_TYPE t)
+{
+ type=t;
+}
+
+KGM_TYPE KMessageEntry::QueryType()
+{
+ return type;
+}
+
+int KMessageEntry::QuerySize()
+{
+ return size;
+}
+
+char * KMessageEntry::QueryData()
+{
+ return data;
+}
+
+bool KMessageEntry::CopyData(int s,const char *c)
+{
+ if (s<1) return false;
+ data=(char *)calloc(s,1);
+ if (!data) return false;
+ // printf(" MessageEntry Copy Data to calloc %p\n",data);
+ memcpy(data,c,s);
+ size=s;
+ return true;
+}
+
+KMessageEntry::KMessageEntry()
+{
+ // printf("KMessageEntry construct %p\n",this);
+ size=0;
+ type=(KGM_TYPE)0;
+ data=(char *)0;
+}
+
+KMessageEntry::KMessageEntry(KMessageEntry &entry)
+{
+ // printf("KMessageEntry copy constructor from %p to %p\n",&entry,this);
+ *this=entry;
+}
+KMessageEntry &KMessageEntry::operator=(KMessageEntry &entry)
+{
+ // printf("KMessageEntry operator= from %p to %p\n",&entry,this);
+ SetType(entry.type);
+ CopyData(entry.size,entry.data);
+ return *this;
+}
+
+KMessageEntry::~KMessageEntry()
+{
+ // printf("MessageEntry destructor %p\n",this);
+ // printf(" MessageEntry free %p\n",data);
+ if (data) free(data);
+ data=(char *)0;
+}
+
diff --git a/lskat/lskat/KMessageEntry.h b/lskat/lskat/KMessageEntry.h
new file mode 100644
index 00000000..3feb4fad
--- /dev/null
+++ b/lskat/lskat/KMessageEntry.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ KMessageEntry.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _KMESSAGEENTRY_H_
+#define _KMESSAGEENTRY_H_
+
+#include "KConnectTypes.h"
+
+class KMessageEntry
+{
+ private:
+ int size;
+ KGM_TYPE type;
+ char *data;
+
+ public:
+ void SetType(KGM_TYPE t);
+ KGM_TYPE QueryType();
+ int QuerySize();
+ char *QueryData();
+ bool CopyData(int s,const char *c);
+ KMessageEntry();
+ KMessageEntry(KMessageEntry &entry);
+ KMessageEntry &operator=(KMessageEntry &entry);
+ ~KMessageEntry();
+};
+
+#endif
diff --git a/lskat/lskat/KProcessConnect.cpp b/lskat/lskat/KProcessConnect.cpp
new file mode 100644
index 00000000..740486b3
--- /dev/null
+++ b/lskat/lskat/KProcessConnect.cpp
@@ -0,0 +1,192 @@
+/***************************************************************************
+ KProcessConnect.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include "KProcessConnect.h"
+
+#include "KProcessConnect.moc"
+
+KProcessConnect::KProcessConnect()
+ : KChildConnect()
+{
+ running=false;
+ process=0;
+}
+
+KProcessConnect::~KProcessConnect()
+{
+ Exit();
+ delete process;
+// printf("DESTRUCTRING KPROCESSCONNECT\n");
+}
+
+bool KProcessConnect::Init(int id,KEMessage *msg)
+{
+ int size;
+ char *p;
+
+ SetID(id);
+ if (msg)
+ {
+ if (!msg->GetData(QCString("ProcessName"),p,size)) return false; // no process name
+ processname=p;
+ /*
+ printf("Found processname '%s' size %d size=%u\n",
+ p,size,msg->QueryNumberOfKeys());
+ */
+ msg->Remove(QCString("ProcessName"));
+ }
+ if (processname.length()<1) return false;
+
+ inputbuffer="";
+
+ // Delete first on multiple init
+ if (running) Exit();
+
+ // create process
+ process=new KProcess;
+ *process << processname;
+ connect(process, SIGNAL(receivedStdout(KProcess *, char *, int )),
+ this, SLOT(slotReceivedStdout(KProcess *, char * , int )));
+ connect(process, SIGNAL(processExited(KProcess *)),
+ this, SLOT(slotProcessExited(KProcess *)));
+ /*
+ connect(process, SIGNAL(wroteStdin(KProcess *)),
+ this, SLOT(slotWroteStdin(KProcess *)));
+ */
+
+ // TRUE if ok
+ running=process->start(KProcess::NotifyOnExit,KProcess::All);
+
+ if (running && msg && msg->QueryNumberOfKeys()>0)
+ {
+ SendMsg(msg);
+ }
+
+ return running;
+}
+
+void KProcessConnect::slotReceivedStdout(KProcess *, char *buffer, int buflen)
+{
+ QString s;
+ char c;
+ int pos;
+
+ if (buflen<1) return ;
+ if (buffer[buflen-1]!=0) // shit..we got a not null terminated string
+ {
+ c=buffer[buflen-1];
+ buffer[buflen-1]=0;
+ s=buffer;
+ s+=c;
+ }
+ else
+ {
+ s=buffer;
+ }
+ // Append old unresolved input
+ s=inputbuffer+s;
+ pos=s.findRev(KEMESSAGE_CR);
+ // printf("String '%s' pos=%d len=%d\n",(const char *)s,pos,s.length());
+ if (pos<0)
+ {
+ inputbuffer=s;
+ }
+ else if (pos+KEMESSAGE_CR.length()==s.length())
+ {
+ // CR at the end...calling receive
+ Receive(s);
+ }
+ else
+ {
+ inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length());
+ s=s.left(pos+KEMESSAGE_CR.length());
+ // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer);
+ Receive(s);
+ }
+}
+void KProcessConnect::slotProcessExited(KProcess *)
+{
+ running=false;
+ delete process;
+ process=0;
+ Init(QueryID());
+}
+void KProcessConnect::slotWroteStdin(KProcess *)
+{
+ printf("slotWroteStdin:: IS NEVER CALLED\n");
+}
+
+bool KProcessConnect::Exit()
+{
+ // kill process if running
+ if (running)
+ {
+ running=false;
+ if (process) process->kill();
+ delete process;
+ process=0;
+ }
+ return true;
+}
+
+bool KProcessConnect::Next()
+{
+ bool result;
+ if (!running) return false;
+ // create and send message
+ // printf("+- KProcessConnect::ProcessNext\n");
+ KEMessage *msg=new KEMessage;
+ // User fills message
+ emit signalPrepareMove(msg,KG_INPUTTYPE_PROCESS);
+ result=SendMsg(msg);
+ delete msg;
+ return result;
+}
+
+// Send string to child
+bool KProcessConnect::Send(QString str)
+{
+ bool result;
+ // printf("****** PROCESS:SEND\n");
+ if (!running || !process) return false;
+ if (!str || str.length()<1) return true; // no need to send crap
+ // TODO ..why?
+ QString s;
+ s=KEMESSAGE_CR+KEMESSAGE_CR;
+ str=s+str;
+ // printf("+++ Sending to child '%s'!!!\n",(const char *)str);
+ result=process->writeStdin(str.latin1(),str.length()+1);
+ if (!result) printf("ERROR in PROCESS SEND\n");
+ return result;
+}
+
diff --git a/lskat/lskat/KProcessConnect.h b/lskat/lskat/KProcessConnect.h
new file mode 100644
index 00000000..9229ddd4
--- /dev/null
+++ b/lskat/lskat/KProcessConnect.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ KProcessConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KPROCESSCONNECT_H_
+#define _KPROCESSCONNECT_H_
+
+#include <kprocess.h>
+//#include <ksock.h>
+// #include "KEInput.h"
+#include "KEMessage.h"
+#include "KChildConnect.h"
+
+
+class KProcessConnect: public KChildConnect
+{
+ Q_OBJECT
+
+ private:
+ KProcess *process;
+ QString processname;
+ bool running;
+
+ public:
+ KProcessConnect();
+ ~KProcessConnect();
+ bool Init(int id=0,KEMessage *msg=0);
+ bool Exit();
+ bool Next();
+ // bool SendMsg(KEMessage *msg);
+ virtual bool Send(QString str);
+ // void Receive(QString input);
+
+ public slots:
+ void slotReceivedStdout(KProcess *proc, char *buffer, int buflen);
+ void slotProcessExited(KProcess *p);
+ void slotWroteStdin(KProcess *p);
+
+
+ signals:
+ void signalPrepareMove(KEMessage *msg,KG_INPUTTYPE type);
+// void signalReceiveMsg(KEMessage *msg);
+};
+
+#endif
diff --git a/lskat/lskat/KRSocket.cpp b/lskat/lskat/KRSocket.cpp
new file mode 100644
index 00000000..0a699600
--- /dev/null
+++ b/lskat/lskat/KRSocket.cpp
@@ -0,0 +1,374 @@
+/***************************************************************************
+ KRSocket.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1997 Torben Weis (weis@kde.org)
+ *
+ * $Id$
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+// on Linux/libc5, this includes linux/socket.h where SOMAXCONN is defined
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/un.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include "KRSocket.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+// defines MAXDNAME under Solaris
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYSENT_H
+#include <sysent.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+
+// Play it safe, use a reasonable default, if SOMAXCONN was nowhere defined.
+#ifndef SOMAXCONN
+#warning Your header files do not seem to support SOMAXCONN
+#define SOMAXCONN 5
+#endif
+
+#include <qsocketnotifier.h>
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108 // this is the value, I found under Linux
+#endif
+
+#include <kdebug.h>
+
+KRServerSocket::KRServerSocket( const char *_path, int optname, int value, int level) :
+ notifier( 0L ), sock( -1 )
+{
+ domain = PF_UNIX;
+
+ if ( !init ( _path,optname,value,level ) )
+ {
+ qFatal("Error constructing PF_UNIX domain server socket\n");
+ return;
+ }
+
+ notifier = new QSocketNotifier( sock, QSocketNotifier::Read );
+ connect( notifier, SIGNAL( activated(int) ), this, SLOT( slotAccept(int) ) );
+}
+
+KRServerSocket::KRServerSocket( const char *_path ) :
+ notifier( 0L ), sock( -1 )
+{
+ domain = PF_UNIX;
+
+ if ( !init ( _path ) )
+ {
+ qFatal("Error constructing PF_UNIX domain server socket\n");
+ return;
+ }
+
+ notifier = new QSocketNotifier( sock, QSocketNotifier::Read );
+ connect( notifier, SIGNAL( activated(int) ), this, SLOT( slotAccept(int) ) );
+}
+
+KRServerSocket::KRServerSocket( unsigned short int _port ) :
+ notifier( 0L ), sock( -1 )
+{
+ domain = PF_INET;
+
+ if ( !init ( _port ) )
+ {
+ // fatal("Error constructing\n");
+ return;
+ }
+
+ notifier = new QSocketNotifier( sock, QSocketNotifier::Read );
+ connect( notifier, SIGNAL( activated(int) ), this, SLOT( slotAccept(int) ) );
+}
+
+KRServerSocket::KRServerSocket( unsigned short int _port,int optname,int value,int level ) :
+ notifier( 0L ), sock( -1 )
+{
+ domain = PF_INET;
+
+ if ( !init ( _port,optname,value,level ) )
+ {
+ // fatal("Error constructing\n");
+ return;
+ }
+
+ notifier = new QSocketNotifier( sock, QSocketNotifier::Read );
+ connect( notifier, SIGNAL( activated(int) ), this, SLOT( slotAccept(int) ) );
+}
+
+bool KRServerSocket::init( const char *_path )
+{
+ return init(_path,0);
+}
+
+bool KRServerSocket::init( const char *_path,int optname,int value,int level )
+{
+ if ( domain != PF_UNIX )
+ return false;
+
+ int l = strlen( _path );
+ if ( l > UNIX_PATH_MAX - 1 )
+ {
+ kdWarning() << "Too long PF_UNIX domain name: " << _path << endl;
+ return false;
+ }
+
+ sock = ::socket( PF_UNIX, SOCK_STREAM, 0 );
+ if (sock < 0)
+ {
+ kdWarning() << "Could not create socket" << endl;
+ return false;
+ }
+ // Heni - 05042000
+ if (optname>0)
+ {
+ kde_socklen_t len=sizeof(value);
+ if (-1==setsockopt(sock,level,optname,(char*)&value,len ))
+ {
+ kdWarning() << "Could not set socket options." << endl;
+ }
+ }
+ // end Heni
+
+ unlink(_path );
+
+ struct sockaddr_un name;
+ name.sun_family = AF_UNIX;
+ strcpy( name.sun_path, _path );
+
+ if ( bind( sock, (struct sockaddr*) &name,sizeof( name ) ) < 0 )
+ {
+ kdWarning() << "Could not bind to socket." << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+
+ if ( chmod( _path, 0600) < 0 )
+ {
+ kdWarning() << "Could not setupt premissions for server socket." << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+
+ if ( listen( sock, SOMAXCONN ) < 0 )
+ {
+ kdWarning() << "Error listening on socket." << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+
+ return true;
+}
+
+bool KRServerSocket::init( unsigned short int _port )
+{
+ return init(_port,0);
+}
+bool KRServerSocket::init( unsigned short int _port,int optname,int value,int level )
+{
+ if (
+#ifdef INET6
+ ( domain != PF_INET6 ) &&
+#endif
+ ( domain != PF_INET ) )
+ return false;
+
+ sock = ::socket( domain, SOCK_STREAM, 0 );
+ if (sock < 0)
+ {
+ kdWarning() << "Could not create socket" << endl;
+ return false;
+ }
+ // Heni - 05042000
+ if (optname>0)
+ {
+ kde_socklen_t len=sizeof(value);
+ if (-1==setsockopt(sock,level,optname,(char*)&value,len ))
+ {
+ kdWarning() << "Could not set socket options." << endl;
+ }
+ }
+ // end Heni
+
+ if (domain == AF_INET) {
+
+ sockaddr_in name;
+
+ name.sin_family = domain;
+ name.sin_port = htons( _port );
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if ( bind( sock, (struct sockaddr*) &name,sizeof( name ) ) < 0 ) {
+ kdWarning() << "Could not bind to socket." << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+ }
+#ifdef INET6
+ else if (domain == AF_INET6) {
+ sockaddr_in6 name;
+
+ name.sin6_family = domain;
+ name.sin6_flowinfo = 0;
+ name.sin6_port = htons(_port);
+ memcpy(&name.sin6_addr, &in6addr_any, sizeof(in6addr_any));
+
+ if ( bind( sock, (struct sockaddr*) &name,sizeof( name ) ) < 0 ) {
+ kdWarning() << "Could not bind to socket!" << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+ }
+#endif
+
+ if ( listen( sock, SOMAXCONN ) < 0 )
+ {
+ kdWarning() << "Error listening on socket" << endl;
+ ::close( sock );
+ sock = -1;
+ return false;
+ }
+
+ return true;
+}
+
+unsigned short int KRServerSocket::port()
+{
+ if ( domain != PF_INET )
+ return false;
+
+ ksockaddr_in name; kde_socklen_t len = sizeof(name);
+ getsockname(sock, (struct sockaddr *) &name, &len);
+ return ntohs(get_sin_port(name));
+}
+
+unsigned long KRServerSocket::ipv4_addr()
+{
+ if ( domain != PF_INET )
+ return 0;
+
+ sockaddr_in name; kde_socklen_t len = sizeof(name);
+ getsockname(sock, (struct sockaddr *) &name, &len);
+ if (name.sin_family == AF_INET) // It's IPv4
+ return ntohl(name.sin_addr.s_addr);
+#ifdef INET6
+ else if (name.sin_family == AF_INET6) // It's IPv6 Ah.
+ return 0;
+#endif
+ else // We dunno what it is
+ return 0;
+}
+
+void KRServerSocket::slotAccept( int )
+{
+ if ( domain == PF_INET )
+ {
+ ksockaddr_in clientname;
+ int new_sock;
+
+ kde_socklen_t size = sizeof(clientname);
+
+ if ((new_sock = accept (sock, (struct sockaddr *) &clientname, &size)) < 0)
+ {
+ kdWarning() << "Error accepting" << endl;
+ return;
+ }
+
+ emit accepted( new KSocket( new_sock ) );
+ }
+ else if ( domain == PF_UNIX )
+ {
+ struct sockaddr_un clientname;
+ int new_sock;
+
+ kde_socklen_t size = sizeof(clientname);
+
+ if ((new_sock = accept (sock, (struct sockaddr *) &clientname, &size)) < 0)
+ {
+ kdWarning() << "Error accepting" << endl;
+ return;
+ }
+
+ emit accepted( new KSocket( new_sock ) );
+ }
+}
+
+KRServerSocket::~KRServerSocket()
+{
+ delete notifier;
+
+ close( sock );
+}
+
+#include "KRSocket.moc"
diff --git a/lskat/lskat/KRSocket.h b/lskat/lskat/KRSocket.h
new file mode 100644
index 00000000..6c0b9974
--- /dev/null
+++ b/lskat/lskat/KRSocket.h
@@ -0,0 +1,169 @@
+/***************************************************************************
+ KRSocket.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ * Remark: This is a copy of the ksock library. It will be merged with
+ * the ksock file as soon as it supports the SOCK_REUSE_ADDR flag
+*/
+
+
+#ifndef KRSOCK_H
+#define KRSOCK_H
+
+#include <qobject.h>
+#include <sys/types.h>
+// we define STRICT_ANSI to get rid of some warnings in glibc
+#ifndef __STRICT_ANSI__
+#define __STRICT_ANSI__
+#define _WE_DEFINED_IT_
+#endif
+#include <sys/socket.h>
+#ifdef _WE_DEFINED_IT_
+#undef __STRICT_ANSI__
+#undef _WE_DEFINED_IT_
+#endif
+
+#include <sys/un.h>
+
+#include <netinet/in.h>
+class QSocketNotifier;
+
+#ifdef INET6
+typedef sockaddr_in6 ksockaddr_in;
+#define KSOCK_DEFAULT_DOMAIN PF_INET6
+#else
+typedef sockaddr_in ksockaddr_in;
+#define KSOCK_DEFAULT_DOMAIN PF_INET
+#endif
+
+#include <ksock.h>
+
+class KRServerSocketPrivate;
+
+
+/**
+ * Monitor a port for incoming TCP/IP connections.
+ *
+ * You can use a KRServerSocket to listen on a port for incoming
+ * connections. When a connection arrived in the port, a KSocket
+ * is created and the signal accepted is raised. Make sure you
+ * always connect to this signal. If you dont the ServerSocket will
+ * create new KSocket's and no one will delete them!
+ *
+ * If socket() is -1 or less the socket was not created properly.
+ *
+ * @author Torben Weis <weis@stud.uni-frankfurt.de>
+ * @version $Id$
+ * @short Monitor a port for incoming TCP/IP connections.
+*/
+class KRServerSocket : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructor.
+ * @param _port the port number to monitor for incoming connections.
+ */
+ KRServerSocket( unsigned short int _port );
+ KRServerSocket( unsigned short int _port, int optname, int value=1, int level=SOL_SOCKET);
+
+ /**
+ * Creates a UNIX domain server socket.
+ */
+ KRServerSocket( const char *_path );
+ KRServerSocket( const char *_path, int optname, int value=1, int level=SOL_SOCKET);
+
+ /**
+ * Destructor. Closes the socket if it was not already closed.
+ */
+ ~KRServerSocket();
+
+ /**
+ * Get the file descriptor assoziated with the socket.
+ */
+ int socket() const { return sock; }
+
+ /**
+ * Returns the port number which is being monitored.
+ */
+ unsigned short int port();
+
+ /**
+ * The address.
+ */
+ unsigned long ipv4_addr();
+
+public slots:
+ /**
+ * Called when someone connected to our port.
+ */
+ virtual void slotAccept( int );
+
+signals:
+ /**
+ * A connection has been accepted.
+ * It is your task to delete the KSocket if it is no longer needed.
+ */
+ void accepted( KSocket* );
+
+protected:
+ bool init( short unsigned int );
+ bool init( const char *_path );
+ bool init( const char *_path, int optname, int value=1, int level=SOL_SOCKET);
+ bool init( short unsigned int, int optname, int value=1, int level=SOL_SOCKET);
+
+ /**
+ * Notifies us when there is something to read on the port.
+ */
+ QSocketNotifier *notifier;
+
+ /**
+ * The file descriptor for this socket. sock may be -1.
+ * This indicates that it is not connected.
+ */
+ int sock;
+
+ int domain;
+
+private:
+ KRServerSocket(const KRServerSocket&);
+ KRServerSocket& operator=(const KRServerSocket&);
+
+ KRServerSocketPrivate *d;
+};
+
+
+// Here are a whole bunch of hackish macros that allow one to
+// get at the correct member of ksockaddr_in
+
+#ifdef INET6
+#define get_sin_addr(x) x.sin6_addr
+#define get_sin_port(x) x.sin6_port
+#define get_sin_family(x) x.sin6_family
+#define get_sin_paddr(x) x->sin6_addr
+#define get_sin_pport(x) x->sin6_port
+#define get_sin_pfamily(x) x->sin6_family
+#else
+#define get_sin_addr(x) x.sin_addr
+#define get_sin_port(x) x.sin_port
+#define get_sin_family(x) x.sin_family
+#define get_sin_paddr(x) x->sin_addr
+#define get_sin_pport(x) x->sin_port
+#define get_sin_pfamily(x) x->sin_family
+#endif
+
+#endif
diff --git a/lskat/lskat/KRemoteConnect.cpp b/lskat/lskat/KRemoteConnect.cpp
new file mode 100644
index 00000000..f1bcb4f3
--- /dev/null
+++ b/lskat/lskat/KRemoteConnect.cpp
@@ -0,0 +1,334 @@
+/***************************************************************************
+ KRemoteConnect.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "KRemoteConnect.h"
+
+#include "KRemoteConnect.moc"
+
+const char* LSKAT_SERVICE = "_lskat._tcp";
+
+KRemoteConnect::KRemoteConnect()
+ : KChildConnect()
+{
+ port=7687;
+ IP="localhost";
+ socketStatus=KR_INVALID;
+ kSocket=0;
+ service=0;
+ kServerSocket=0;
+ bufferMsg=0;
+ buffer=new char[4097];
+ inputbuffer="";
+ input_pending=false;
+}
+KRemoteConnect::~KRemoteConnect()
+{
+ Exit();
+ delete buffer;
+ delete service;
+ printf("DESTGRUCTING KRemoteConenct\n");
+}
+
+KR_STATUS KRemoteConnect::QueryStatus()
+{
+ return socketStatus;
+}
+
+bool KRemoteConnect::Init(int id,KEMessage *msg)
+{
+short prt;
+char *p;
+int size;
+bool tryserver;
+
+ SetID(id);
+ if (msg)
+ {
+ if (msg->GetData(QCString("Port"),prt))
+ {
+ port=(unsigned int)prt;
+ msg->Remove(QCString("Port"));
+ }
+ if (msg->GetData(QCString("IP"),p,size))
+ {
+ IP=QCString(p);
+ msg->Remove(QCString("IP"));
+ }
+ if (msg->GetData(QCString("Name"),p,size))
+ {
+ Name=QString::fromUtf8(p);
+ msg->Remove(QCString("Name"));
+ }
+ }
+ /*
+ printf("Connecting to %s %u (remain=%d)\n",
+ (const char *)IP,port,msg->QueryNumberOfKeys());
+ */
+
+ // First try to connect to given host:socket
+ // if no IP given only offer server
+ tryserver=false;
+ if (!IP.isEmpty())
+ {
+ kSocket=new KSocket(IP.latin1(),port);
+ if (!kSocket) return false;
+ if (kSocket->socket()!=-1) // success
+ {
+ kSocket->enableRead(TRUE);
+ //kSocket->enableWrite(TRUE);
+ connect(kSocket,SIGNAL(closeEvent(KSocket *)),
+ this,SLOT(socketClosed(KSocket *)));
+ connect(kSocket,SIGNAL(readEvent(KSocket *)),
+ this,SLOT(socketRead(KSocket *)));
+ /*
+ connect(kSocket,SIGNAL(writeEvent(KSocket *)),
+ this,SLOT(socketWrite(KSocket *)));
+ */
+ /*
+ printf("Socket(%d) %p connection built to a server\n",
+ kSocket->socket(),kSocket);
+ */
+ socketStatus=KR_CLIENT;
+
+ // Send msg if any
+ if (msg->QueryNumberOfKeys()>0)
+ {
+ msg->AddData(QCString("Server"),(short)QueryID());
+ SendMsg(msg);
+ }
+
+ }
+ else
+ {
+ tryserver=true;
+ }
+ }
+ else
+ {
+ printf("NO IP given..only server possible\n");
+ tryserver=true;
+ }
+
+ if (tryserver) // become a server
+ {
+ delete kSocket;
+ kSocket=0;
+ delete service;
+ service = 0;
+ // Store message
+ if (msg->QueryNumberOfKeys()>0)
+ {
+ bufferMsg=new KEMessage;
+ *bufferMsg=*msg;
+ }
+ else
+ {
+ bufferMsg=0;
+ }
+ socketStatus=KR_WAIT_FOR_CLIENT;
+ OfferServerSocket();
+ return false;
+ }
+
+ return true;
+}
+
+bool KRemoteConnect::OfferServerSocket()
+{
+ if (kServerSocket)
+ {
+ return false;
+ }
+ kServerSocket=new KRServerSocket(port,SO_REUSEADDR);
+ if (!kServerSocket)
+ {
+ socketStatus=KR_INVALID;
+ return false;
+ }
+ if (kServerSocket->socket()==-1)
+ {
+ socketStatus=KR_NO_SOCKET;
+ return false;
+ }
+ printf("Offering socket and publishing stuff\n");
+ service = new DNSSD::PublicService(Name,LSKAT_SERVICE,port);
+ service->publishAsync();
+ connect(kServerSocket,SIGNAL(accepted(KSocket *)),
+ this,SLOT(socketRequest(KSocket *)));
+
+ return true;
+}
+void KRemoteConnect::socketRequest(KSocket *sock)
+{
+ if (kSocket) // already connected
+ {
+ delete sock;
+ delete kServerSocket;
+ kServerSocket=0;
+ return ;
+ }
+ kSocket=sock;
+ if (kSocket->socket()!=-1) // success
+ {
+ kSocket->enableRead(TRUE);
+ //kSocket->enableWrite(TRUE);
+ connect(kSocket,SIGNAL(closeEvent(KSocket *)),
+ this,SLOT(socketClosed(KSocket *)));
+ connect(kSocket,SIGNAL(readEvent(KSocket *)),
+ this,SLOT(socketRead(KSocket *)));
+ /*
+ connect(kSocket,SIGNAL(writeEvent(KSocket *)),
+ this,SLOT(socketWrite(KSocket *)));
+ */
+ socketStatus=KR_SERVER;
+ delete kServerSocket; // no more connections
+ kServerSocket=0;
+ if (bufferMsg)
+ {
+ // Delayed sending of init msg
+ bufferMsg->AddData(QCString("Client"),(short)QueryID());
+ SendMsg(bufferMsg);
+ delete bufferMsg;
+ bufferMsg=0;
+ }
+ }
+}
+
+void KRemoteConnect::socketClosed(KSocket *sock)
+{
+ delete sock;
+ kSocket=0;
+ socketStatus=KR_INVALID;
+ KEMessage *msg=new KEMessage;
+ msg->AddData(QCString("ConnectionLost"),(short)QueryID());
+ emit signalReceiveMsg(msg,QueryID());
+ delete msg;
+}
+void KRemoteConnect::socketRead(KSocket *sock)
+{
+ ssize_t buflen;
+ QString s;
+ char c;
+ int pos;
+
+ // printf("++++++ Incoming socket read +++++++\n");
+ if (-1==sock->socket()) return ;
+ // printf("Read input on socket %p\n",sock);
+ buflen=read(sock->socket(),buffer,4096);
+ buffer[buflen]=0;
+ // printf("Read %d byte <%s>\n",buflen,buffer);
+
+ if (buflen<1) return ;
+ if (buffer[buflen-1]!=0) // shit..we got a not null terminated string
+ {
+ c=buffer[buflen-1];
+ buffer[buflen-1]=0;
+ s=buffer;
+ s+=c;
+ }
+ else
+ {
+ s=buffer;
+ }
+
+ // Append old unresolved input
+ s=inputbuffer+s;
+ pos=s.findRev(KEMESSAGE_CR);
+ // printf("String '%s' pos=%d len=%d\n",(const char *)s,pos,s.length());
+ if (pos<0)
+ {
+ inputbuffer=s;
+ }
+ else if (pos+KEMESSAGE_CR.length()==s.length())
+ {
+ // CR at the end...calling receive
+ Receive(s);
+ }
+ else
+ {
+ inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length());
+ s=s.left(pos+KEMESSAGE_CR.length());
+ // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer);
+ Receive(s);
+ }
+}
+
+
+void KRemoteConnect::socketWrite(KSocket *)
+{
+ // printf("wrtie input on socket %p\n",sock);
+}
+
+bool KRemoteConnect::Exit()
+{
+ delete kSocket;
+ delete kServerSocket;
+ delete bufferMsg;
+ kSocket=0;
+ kServerSocket=0;
+ bufferMsg=0;
+ socketStatus=KR_INVALID;
+ return true;
+}
+bool KRemoteConnect::Next()
+{
+ bool result;
+ // printf("+- KRemoteConnect::Next() status=%d\n",socketStatus);
+ if (socketStatus<=0) return false;
+ // create and send message
+ KEMessage *msg=new KEMessage;
+ // User fills message
+ emit signalPrepareMove(msg,KG_INPUTTYPE_REMOTE);
+ result=SendMsg(msg);
+ delete msg;
+ return result;
+}
+
+// Send string to child
+bool KRemoteConnect::Send(QString str)
+{
+ // connected?
+ if (!kSocket || kSocket->socket()==-1) return false;
+ if (socketStatus<=0) return false;
+
+ if (-1==write(kSocket->socket(),str.latin1(),str.length()+1))
+ {
+ printf("Warning: Problems writing to socket.\n");
+ return false;
+ }
+ return true;;
+}
diff --git a/lskat/lskat/KRemoteConnect.h b/lskat/lskat/KRemoteConnect.h
new file mode 100644
index 00000000..baa005d6
--- /dev/null
+++ b/lskat/lskat/KRemoteConnect.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ KRemoteConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KREMOTECONNECT_H_
+#define _KREMOTECONNECT_H_
+
+//#include <ksock.h>
+#include "KEMessage.h"
+#include "KRSocket.h"
+//#include "ksock.h"
+#include "KChildConnect.h"
+#include <dnssd/publicservice.h>
+
+
+
+class KRemoteConnect: public KChildConnect
+{
+ Q_OBJECT
+
+ protected:
+ KRServerSocket *kServerSocket;
+ KSocket *kSocket;
+ QString IP;
+ QString Name;
+ ushort port;
+ KR_STATUS socketStatus;
+ char *buffer;
+ KEMessage *bufferMsg;
+ DNSSD::PublicService *service;
+// QString inputbuffer;
+// bool input_pending;
+// QStrList inputcache;
+
+ public:
+ KRemoteConnect();
+ ~KRemoteConnect();
+ bool Init(int id=0,KEMessage *msg=0);
+ bool Exit();
+ bool Next();
+// bool SendMsg(KEMessage *msg);
+ virtual bool Send(QString str);
+// void Receive(QString input);
+ virtual KR_STATUS QueryStatus();
+
+ protected:
+ bool OfferServerSocket();
+
+ protected slots:
+ void socketClosed(KSocket *sock);
+ void socketRead(KSocket *sock);
+ void socketWrite(KSocket *sock);
+ void socketRequest(KSocket *sock);
+
+
+
+ signals:
+ void signalPrepareMove(KEMessage *msg,KG_INPUTTYPE type);
+// void signalReceiveMsg(KEMessage *msg);
+};
+
+#endif
diff --git a/lskat/lskat/Makefile.am b/lskat/lskat/Makefile.am
new file mode 100644
index 00000000..ade32c96
--- /dev/null
+++ b/lskat/lskat/Makefile.am
@@ -0,0 +1,21 @@
+
+####### kdevelop will overwrite this part!!! (begin)##########
+bin_PROGRAMS = lskat
+lskat_SOURCES = msgdlg.cpp networkdlg.cpp namedlg.cpp KRemoteConnect.cpp KRSocket.cpp KProcessConnect.cpp KMessageEntry.cpp KInteractiveConnect.cpp KInputChildProcess.cpp KEMessage.cpp KEInput.cpp KConnectEntry.cpp KChildConnect.cpp lskatview.cpp lskatdoc.cpp lskat.cpp main.cpp networkdlgbase.ui
+
+lskat_LDADD = $(LIB_KFILE) $(LIB_KDEGAMES) $(LIB_KDNSSD)
+lskat_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+INCLUDES = -I$(top_srcdir)/libkdegames $(all_includes)
+
+METASOURCES = AUTO
+
+lskat_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+rcdir = $(kde_datadir)/lskat
+rc_DATA = lskatui.rc
+
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/lskat.pot
+
diff --git a/lskat/lskat/lskat.cpp b/lskat/lskat/lskat.cpp
new file mode 100644
index 00000000..9d1ce7a6
--- /dev/null
+++ b/lskat/lskat/lskat.cpp
@@ -0,0 +1,1081 @@
+/*
+ lskat.cpp - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for QT
+#include <qprogressdialog.h>
+
+// include files for KDE
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <khelpmenu.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "lskat.h"
+#include "lskatview.h"
+#include "lskatdoc.h"
+#include "namedlg.h"
+#include "networkdlg.h"
+#include "msgdlg.h"
+#include <kcarddialog.h>
+
+#include <stdlib.h>
+#include <kstatusbar.h>
+
+#define ACTION(x) (actionCollection()->action(x))
+#define ID_STATUS_MSG 1003
+#define ID_STATUS_MOVER 1002
+
+LSkatApp::LSkatApp() : KMainWindow(0)
+{
+ config=kapp->config();
+
+ // localise data file
+ QString file=QString::fromLatin1("lskat/grafix/t1.png");
+ mGrafix=kapp->dirs()->findResourceDir("data", file);
+ if (mGrafix.isNull()) mGrafix = QCString("grafix/");
+ else mGrafix+=QCString("lskat/grafix/");
+ if (global_debug>3) printf("Localised datafile=%s\n",mGrafix.latin1());
+
+
+ ///////////////////////////////////////////////////////////////////
+ // call inits to invoke all other construction parts
+ initGUI();
+ initStatusBar();
+
+ setupGUI(KMainWindow::StatusBar | Save);
+ createGUI(QString::null, false);
+
+ initDocument();
+ initView();
+
+ doc->ReadConfig(config);
+
+ // Needs to be after readOptions as we read in default paths
+ doc->LoadGrafix(mGrafix);
+
+ mInput=new KEInput(this);
+ doc->SetInputHandler(mInput);
+ connect(mInput,SIGNAL(signalPrepareProcessMove(KEMessage *)),
+ this,SLOT(slotPrepareProcessMove(KEMessage *)));
+ connect(mInput,SIGNAL(signalPrepareRemoteMove(KEMessage *)),
+ this,SLOT(slotPrepareRemoteMove(KEMessage *)));
+ connect(mInput,SIGNAL(signalPrepareInteractiveMove(KEMessage *)),
+ this,SLOT(slotPrepareInteractiveMove(KEMessage *)));
+ connect(mInput,SIGNAL(signalReceiveInput(KEMessage *, int)),
+ this,SLOT(slotReceiveInput(KEMessage *,int )));
+
+ setMinimumSize(640,480);
+ setMaximumSize(800,600);
+ resize( 640, 480 );
+
+ // better be last in init
+ checkMenus();
+}
+
+LSkatApp::~LSkatApp()
+{
+ delete mInput;
+}
+
+void LSkatApp::checkMenus(int menu)
+{
+ if (!menu || (menu&CheckFileMenu))
+ {
+ if (doc->IsRunning()) disableAction("new_game");
+ else enableAction("new_game");
+
+ if (!doc->IsRunning()) disableAction("end_game");
+ else enableAction("end_game");
+
+ if (doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE ||
+ doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE )
+ {
+ enableAction("send_message");
+ }
+ else
+ {
+ disableAction("send_message");
+ }
+ }
+
+ if (!menu || (menu&CheckOptionsMenu))
+ {
+ ((KSelectAction *)ACTION("startplayer"))->setCurrentItem(doc->GetStartPlayer());
+
+ if (doc->IsRunning()) disableAction("startplayer");
+ else enableAction("startplayer");
+
+ if (doc->GetPlayedBy(0)==KG_INPUTTYPE_INTERACTIVE)
+ ((KSelectAction *)ACTION("player1"))->setCurrentItem(0);
+ else if (doc->GetPlayedBy(0)==KG_INPUTTYPE_PROCESS)
+ ((KSelectAction *)ACTION("player1"))->setCurrentItem(1);
+ else
+ ((KSelectAction *)ACTION("player1"))->setCurrentItem(2);
+
+ /*
+ if (doc->IsRunning()) disableAction("player1");
+ else enableAction("player1");
+ */
+
+ if (doc->GetPlayedBy(1)==KG_INPUTTYPE_INTERACTIVE)
+ ((KSelectAction *)ACTION("player2"))->setCurrentItem(0);
+ else if (doc->GetPlayedBy(1)==KG_INPUTTYPE_PROCESS)
+ ((KSelectAction *)ACTION("player2"))->setCurrentItem(1);
+ else
+ ((KSelectAction *)ACTION("player2"))->setCurrentItem(2);
+
+ /*
+ if (doc->IsRunning()) disableAction("player2");
+ else enableAction("player2");
+ */
+
+ ((KSelectAction *)ACTION("choose_level"))->setCurrentItem(doc->GetComputerLevel()-1);
+ }
+
+}
+
+void LSkatApp::initGUI()
+{
+ QStringList list;
+
+ (void)KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection(), "new_game");
+ ACTION("new_game")->setStatusText(i18n("Starting a new game..."));
+ ACTION("new_game")->setWhatsThis(i18n("Starting a new game..."));
+ (void)new KAction(i18n("&End Game"),"stop", 0, this, SLOT(slotFileEnd()),
+ actionCollection(), "end_game");
+ ACTION("end_game")->setStatusText(i18n("Ending the current game..."));
+ ACTION("end_game")->setWhatsThis(i18n("Aborts a currently played game. No winner will be declared."));
+ (void)new KAction(i18n("&Clear Statistics"),"flag", 0, this, SLOT(slotFileStatistics()),
+ actionCollection(), "clear_statistics");
+ ACTION("clear_statistics")->setStatusText(i18n("Delete all time statistics..."));
+ ACTION("clear_statistics")->setWhatsThis(i18n("Clears the all time statistics which is kept in all sessions."));
+ (void)new KAction(i18n("Send &Message..."), CTRL+Key_M, this, SLOT(slotFileMessage()),
+ actionCollection(), "send_message");
+ ACTION("send_message")->setStatusText(i18n("Sending message to remote player..."));
+ ACTION("send_message")->setWhatsThis(i18n("Allows you to talk with a remote player."));
+ (void)KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection(), "game_exit");
+ ACTION("game_exit")->setStatusText(i18n("Exiting..."));
+ ACTION("game_exit")->setWhatsThis(i18n("Quits the program."));
+
+ (void)new KSelectAction(i18n("Starting Player"),0,this,SLOT(slotStartplayer()),
+ actionCollection(), "startplayer");
+ ACTION("startplayer")->setStatusText(i18n("Changing starting player..."));
+ ACTION("startplayer")->setWhatsThis(i18n("Chooses which player begins the next game."));
+ list.clear();
+ list.append(i18n("Player &1"));
+ list.append(i18n("Player &2"));
+ ((KSelectAction *)ACTION("startplayer"))->setItems(list);
+
+ (void)new KSelectAction(i18n("Player &1 Played By"),0,this,SLOT(slotPlayer1By()),
+ actionCollection(), "player1");
+ ACTION("player1")->setStatusText(i18n("Changing who plays player 1..."));
+ ACTION("player1")->setWhatsThis(i18n("Changing who plays player 1..."));
+ list.clear();
+ list.append(i18n("&Player"));
+ list.append(i18n("&Computer"));
+ list.append(i18n("&Remote"));
+ ((KSelectAction *)ACTION("player1"))->setItems(list);
+ (void)new KSelectAction(i18n("Player &2 Played By"),0,this,SLOT(slotPlayer2By()),
+ actionCollection(), "player2");
+ ACTION("player1")->setStatusText(i18n("Changing who plays player 2..."));
+ ACTION("player1")->setWhatsThis(i18n("Changing who plays player 2..."));
+ ((KSelectAction *)ACTION("player2"))->setItems(list);
+
+ (void)new KSelectAction(i18n("&Level"),0,this,SLOT(slotLevel()),
+ actionCollection(), "choose_level");
+ ACTION("choose_level")->setStatusText(i18n("Change level..."));
+ ACTION("choose_level")->setWhatsThis(i18n("Change the strength of the computer player."));
+ list.clear();
+ list.append(i18n("&Normal"));
+ list.append(i18n("&Advanced"));
+ list.append(i18n("&Hard"));
+ ((KSelectAction *)ACTION("choose_level"))->setItems(list);
+
+ (void)new KAction(i18n("Select &Card Deck..."), 0, this, SLOT(slotOptionsCardDeck()),
+ actionCollection(), "select_carddeck");
+ ACTION("select_carddeck")->setStatusText(i18n("Configure card decks..."));
+ ACTION("select_carddeck")->setWhatsThis(i18n("Choose how the cards should look."));
+
+ (void)new KAction(i18n("Change &Names..."), 0, this, SLOT(slotOptionsNames()),
+ actionCollection(), "change_names");
+ ACTION("change_names")->setStatusText(i18n("Configure player names..."));
+ ACTION("change_names")->setWhatsThis(i18n("Configure player names..."));
+
+ actionCollection()->setHighlightingEnabled(true);
+ connect(actionCollection(), SIGNAL(actionStatusText(const QString &)), SLOT(slotStatusMsg(const QString &)));
+ connect(actionCollection(), SIGNAL(clearStatusText()), SLOT(slotClearStatusMsg()));
+
+ KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
+actionCollection());
+}
+
+
+void LSkatApp::initStatusBar()
+{
+ ///////////////////////////////////////////////////////////////////
+ // STATUSBAR
+ // statusBar()->setInsertOrder(KStatusBar::RightToLeft);
+ statusBar()->insertItem(i18n("This leaves space for the mover"),ID_STATUS_MOVER,0,true);
+ statusBar()->insertItem(i18n("Ready"), ID_STATUS_MSG);
+
+ slotStatusMover(i18n("(c) Martin Heni "));
+ slotStatusMsg(i18n("Welcome to Lieutenant Skat"));
+
+ // computer move timer
+ procTimer=new QTimer(this);
+ connect(procTimer,SIGNAL(timeout()),this,SLOT(slotProcTimer()));
+}
+
+void LSkatApp::initDocument()
+{
+ doc = new LSkatDoc(this);
+ // TODO check for return false !!!
+ doc->newDocument(config,mGrafix);
+}
+
+void LSkatApp::initView()
+{
+ ////////////////////////////////////////////////////////////////////
+ // create the main widget here that is managed by KMainWindow's view-region and
+ // connect the widget to your document to display document contents.
+ view = new LSkatView(this);
+ doc->addView(view);
+ setCentralWidget(view);
+ setCaption(i18n("Lieutenant Skat"));
+}
+
+void LSkatApp::enableAction(const char *s)
+{
+ if (s)
+ {
+ KAction *act=actionCollection()->action(s);
+ if (act) act->setEnabled(true);
+ }
+
+}
+void LSkatApp::disableAction(const char *s)
+{
+ if (s)
+ {
+ KAction *act=actionCollection()->action(s);
+ if (act) act->setEnabled(false);
+ }
+}
+
+LSkatDoc *LSkatApp::getDocument() const
+{
+ return doc;
+}
+
+void LSkatApp::saveProperties(KConfig *_cfg)
+{
+ if(doc->getTitle()!=i18n("Untitled") && !doc->isModified())
+ {
+ // saving to tempfile not necessary
+ }
+ else
+ {
+ QString filename=doc->getAbsFilePath();
+ _cfg->writePathEntry("filename", filename);
+ _cfg->writeEntry("modified", doc->isModified());
+
+ QString tempname = kapp->tempSaveName(filename);
+ doc->saveDocument(tempname);
+ }
+}
+
+
+void LSkatApp::readProperties(KConfig* _cfg)
+{
+ QString filename = _cfg->readPathEntry("filename");
+ bool modified = _cfg->readBoolEntry("modified", false);
+ if(modified)
+ {
+ bool canRecover;
+ QString tempname = kapp->checkRecoverFile(filename, canRecover);
+
+ if(canRecover)
+ {
+ doc->openDocument(tempname);
+ doc->setModified();
+ QFileInfo info(filename);
+ doc->setAbsFilePath(info.absFilePath());
+ doc->setTitle(info.fileName());
+ QFile::remove(tempname);
+ }
+ }
+ else
+ {
+ if(!filename.isEmpty())
+ {
+ doc->openDocument(filename);
+ }
+ }
+
+ //QString caption=kapp->caption();
+ setCaption(i18n("Lieutenant Skat"));
+}
+
+bool LSkatApp::queryClose()
+{
+ return true;
+ return doc->saveModified();
+}
+
+bool LSkatApp::queryExit()
+{
+ doc->WriteConfig(config);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATION
+/////////////////////////////////////////////////////////////////////
+
+void LSkatApp::slotFileStatistics()
+{
+ QString message;
+ message=i18n("Do you really want to clear the all time "
+ "statistical data?");
+
+ if (KMessageBox::Yes==KMessageBox::questionYesNo(this,message,QString::null,KStdGuiItem::clear()))
+ {
+ doc->ClearStats();
+ doc->slotUpdateAllViews(0);
+ }
+}
+
+/** send message */
+void LSkatApp::slotFileMessage()
+{
+ int res;
+
+ MsgDlg *dlg=new MsgDlg(this,QCString("Send message..."));
+ res=dlg->exec();
+ if (res==QDialog::Accepted)
+ {
+ QString s;
+ s=dlg->GetMsg();
+ if (!s || s.length()<1) s=QCString("...");
+ KEMessage *msg=new KEMessage;
+
+ // printf("Msg: %s\n",(char *)msg);
+
+ msg->AddData(QCString("Message"),(char *)(s.latin1()));
+ if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,0);
+ if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,1);
+ delete msg;
+ }
+}
+
+void LSkatApp::slotFileNew()
+{
+ NewGame();
+ checkMenus(CheckFileMenu|CheckOptionsMenu);
+}
+
+void LSkatApp::slotFileEnd()
+{
+ doc->EndGame(true);
+ doc->slotUpdateAllViews(0);
+ slotStatusMsg(i18n("Game ended...start a new one..."));
+
+ KEMessage *msg=new KEMessage;
+ msg->AddData(QCString("EndGame"),(short)1);
+ if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,0);
+ if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,1);
+
+ msg->RemoveAll();
+ msg->AddData(QCString("Terminate"),(short)1);
+ if (mInput->QueryType(0)==KG_INPUTTYPE_PROCESS)
+ mInput->SendMsg(msg,0);
+ if (mInput->QueryType(1)==KG_INPUTTYPE_PROCESS)
+ mInput->SendMsg(msg,1);
+ delete msg;
+ checkMenus(CheckFileMenu|CheckOptionsMenu);
+ slotStatusNames();
+}
+
+void LSkatApp::slotFileQuit()
+{
+ doc->WriteConfig(config);
+ if (view) view->close();
+ close();
+ kdDebug() << "slotFileQuit done"<<endl;
+}
+
+void LSkatApp::slotStartplayer()
+{
+ int i=((KSelectAction *)ACTION("startplayer"))->currentItem();
+ doc->SetStartPlayer(i);
+ doc->UpdateViews(UPDATE_STATUS);
+}
+
+void LSkatApp::slotPlayer1By()
+{
+ switch(((KSelectAction *)ACTION("player1"))->currentItem())
+ {
+ case 0:
+ slotPlayer1(KG_INPUTTYPE_INTERACTIVE);
+ break;
+ case 1:
+ slotPlayer1(KG_INPUTTYPE_PROCESS);
+ break;
+ case 2:
+ slotPlayer1(KG_INPUTTYPE_REMOTE);
+ break;
+ }
+}
+
+void LSkatApp::slotPlayer2By()
+{
+ switch(((KSelectAction *)ACTION("player2"))->currentItem())
+ {
+ case 0:
+ slotPlayer2(KG_INPUTTYPE_INTERACTIVE);
+ break;
+ case 1:
+ slotPlayer2(KG_INPUTTYPE_PROCESS);
+ break;
+ case 2:
+ slotPlayer2(KG_INPUTTYPE_REMOTE);
+ break;
+ }
+}
+
+void LSkatApp::slotPlayer1(KG_INPUTTYPE i)
+{
+ doc->SetPlayedBy(0,i);
+ if (doc->IsRunning())
+ {
+ MakeInputDevice(0);
+ // New: Start computer when switched during game
+ if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE &&
+ doc->GetCurrentPlayer()==0 )
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetCurrentPlayer());
+ }
+ }
+ doc->UpdateViews(UPDATE_STATUS);
+}
+
+void LSkatApp::slotPlayer2(KG_INPUTTYPE i)
+{
+ doc->SetPlayedBy(1,i);
+ if (doc->IsRunning())
+ {
+ MakeInputDevice(1);
+ // New: Start computer when switched during game
+ if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE &&
+ doc->GetCurrentPlayer()==1 )
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetCurrentPlayer());
+ }
+ }
+ doc->UpdateViews(UPDATE_STATUS);
+}
+
+void LSkatApp::slotOptionsNames()
+{
+ NameDlg *dlg=new NameDlg(this,QCString("Enter your name..."));
+ dlg->SetNames(doc->GetName(0),doc->GetName(1));
+ if (dlg->exec()==QDialog::Accepted)
+ {
+ QString n1,n2;
+ dlg->GetNames(n1,n2);
+ doc->SetName(0,n1);
+ doc->SetName(1,n2);
+ doc->UpdateViews(UPDATE_STATUS);
+ slotStatusNames();
+ }
+}
+
+void LSkatApp::slotOptionsCardDeck()
+{
+ QString s1,s2;
+ int result;
+ s1=doc->GetDeckpath();
+ s2=doc->GetCardpath();
+
+ result=KCardDialog::getCardDeck(s1,s2);
+ if (result==QDialog::Accepted)
+ {
+ doc->SetCardDeckPath(s1,s2);
+ doc->slotUpdateAllViews(0);
+ }
+}
+
+void LSkatApp::slotLevel()
+{
+ int i=((KSelectAction *)ACTION("choose_level"))->currentItem();
+ i++; // we start at 1
+ doc->SetComputerLevel(i);
+ doc->UpdateViews(UPDATE_STATUS);
+ printf("Level set to %d\n",i);
+}
+
+void LSkatApp::slotClearStatusMsg()
+{
+ slotStatusMsg(i18n("Ready"));
+}
+
+void LSkatApp::slotStatusMsg(const QString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status message permanently
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+void LSkatApp::slotStatusMover(const QString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status mover permanently
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MOVER);
+}
+
+
+void LSkatApp::slotStatusHelpMsg(const QString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status message of whole statusbar temporary (text, msec)
+ statusBar()->message(text, 2000);
+}
+
+/** Triggers the processmove timer */
+void LSkatApp::slotProcTimer(void)
+{
+ mInput->Unlock();
+ mInput->Next(doc->GetCurrentPlayer());
+ /*
+ printf("Delayed setting Next=%d ->%d\n",
+ doc->GetCurrentPlayer(),mInput->QueryNext());
+ */
+}
+
+/** Set the names in the mover field */
+void LSkatApp::slotStatusNames(){
+
+ QString msg;
+ if (!doc->IsRunning()) msg=i18n("No game running");
+ else
+ {
+ msg=i18n("%1 to move...").arg(doc->GetName(doc->GetCurrentPlayer()));
+ }
+ slotStatusMover(msg);
+}
+
+void LSkatApp::NewGame()
+{
+ bool res;
+ // doc->SetIntro(0);
+ doc->NewGame();
+ doc->slotUpdateAllViews(0);
+ res=MakeInputDevice(0);
+ if (!res)
+ {
+ KMessageBox::error(this,
+ i18n("Cannot start player 1. Maybe the network connection "
+ "failed or the computer player process file is not "
+ "found."));
+ return ;
+ }
+ res=MakeInputDevice(1);
+ if (!res)
+ {
+ KMessageBox::error(this,
+ i18n("Cannot start player 2. Maybe the network connection "
+ "failed or the computer player process file is not "
+ "found."));
+ return ;
+ }
+ // Remote game is started when receiving the start mesage .. not here!
+ if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE &&
+ mInput->QueryType(1)!=KG_INPUTTYPE_REMOTE )
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetStartPlayer());
+ }
+ // Connected 0 and we are server
+ else if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE &&
+ mInput->QueryStatus()>0 && doc->IsServer())
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetStartPlayer());
+ }
+ // Connected 1 and we are server
+ else if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE &&
+ mInput->QueryStatus()>1 && doc->IsServer())
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetStartPlayer());
+ }
+ slotStatusNames();
+}
+
+bool LSkatApp::MakeInputDevice(int no)
+{
+ bool res=true;
+ KEMessage *msg;
+ disableAction("send_message");
+ KG_INPUTTYPE type=doc->GetPlayedBy(no);
+ if (type==KG_INPUTTYPE_INTERACTIVE)
+ {
+ if (mInput->QueryType(no)!=type)
+ res=mInput->SetInputDevice(no,type);
+ }
+ else if (type==KG_INPUTTYPE_REMOTE)
+ {
+ QString host;
+ short port;
+ QString Name;
+ msg=new KEMessage;
+ PrepareGame(msg);
+ // Build new connection
+ if ( mInput->QueryType(no)!=type || mInput->QueryStatus(no)<=0)
+ {
+ OptionsNetwork();
+ port=doc->QueryPort();
+ host=doc->QueryHost();
+ Name=doc->QueryName();
+ msg->AddData(QCString("Port"),(short)port);
+ msg->AddData(QCString("IP"),(char *)(host.latin1()));
+ msg->AddData(QCString("Name"),(const char *)(Name.utf8()));
+ res=mInput->SetInputDevice(no,type,msg);
+ if (!res)
+ {
+ QProgressDialog *progress;
+ QString s;
+ int tim,j;
+ tim=10000;
+ if (!host.isEmpty())
+ {
+ s=i18n("Remote connection to %1:%2...").arg(host).arg(port);
+ }
+ else
+ {
+ s=i18n("Offering remote connection on port %1...").arg(port);
+ }
+ progress=new QProgressDialog(s, i18n("Abort"), tim, this,0,true );
+ progress->setCaption(i18n("Lieutenant Skat"));
+ for (j=0; j<tim; j++)
+ {
+ progress->setProgress( j );
+ if ( progress->wasCancelled() ) break;
+ if (mInput->QueryStatus(no)>0) break;
+ usleep(100);
+ }
+ // progress.setProgress(tim);
+ delete progress;
+ }
+ }
+ else // we are already connected
+ {
+ // force the other one to be client
+ usleep(1000);
+ if (doc->IsServer())
+ {
+ if (global_debug>10)
+ printf("We want theother one to be client\n");
+ msg->AddData(QCString("Client"),(short)-1); // force client
+ mInput->SendMsg(msg,no);
+ }
+ // resp server
+ else
+ {
+ if (global_debug>10)
+ printf("We want theother one to be server\n");
+ msg->AddData(QCString("Server"),(short)-1); // force server
+ mInput->SendMsg(msg,no);
+ }
+ }
+ delete msg;
+ if (mInput->QueryStatus(no)>0)
+ {
+ res=true;
+ }
+ else res=false;
+ enableAction("send_message");
+ }
+ else if (type==KG_INPUTTYPE_PROCESS)
+ {
+ if (mInput->QueryType(no)!=type)
+ {
+ // QString path=kapp->dirs()->findExe(doc->QueryProcessName());
+ QString path=doc->GetProcess();
+ if (global_debug>5)
+ {
+ printf("Make Process %d\n",no);
+ printf("Exe file found: %s\n",path.latin1());
+ }
+ if (path.isNull()) return false;
+ msg=new KEMessage;
+ msg->AddData(QCString("ProcessName"),(char *)(path.latin1()));
+ // msg->AddData("ProcessName",doc->QueryProcessName());
+ res=mInput->SetInputDevice(no,KG_INPUTTYPE_PROCESS,msg);
+ delete msg;
+ }
+
+ }
+ return res;
+}
+
+void LSkatApp::OptionsNetwork()
+{
+ int res;
+
+ NetworkDlg *dlg=new NetworkDlg(this,QCString("Configure a network game..."));
+ dlg->SetPort(doc->QueryPort());
+ dlg->SetHost(doc->QueryHost());
+ dlg->SetName(doc->QueryName());
+ res=dlg->exec();
+ doc->SetPort(dlg->QueryPort());
+ doc->SetHost(dlg->QueryHost());
+ doc->SetName(dlg->QueryName());
+ delete dlg;
+}
+
+void LSkatApp::slotPrepareProcessMove(KEMessage *msg)
+{
+ if (global_debug>3)
+ printf("+++ main should prepare process move\n");
+ slotStatusMsg(i18n("Waiting for the computer to move..."));
+
+ msg->AddData(QCString("Hint"),(short)0);
+ msg->AddData(QCString("Move"),(short)1);
+
+ if (global_debug>3)
+ printf("PREPARE GAME in processmove\n");
+ if (global_debug>1)
+ msg->AddData(QCString("KLogSendMsg"),"process.log");
+ PrepareGame(msg);
+}
+
+void LSkatApp::slotPrepareRemoteMove(KEMessage *)
+{
+ if (global_debug>3)
+ printf("+++ main should prepare remote move\n");
+ slotStatusMsg(i18n("Waiting for remote player..."));
+}
+
+void LSkatApp::slotPrepareInteractiveMove(KEMessage *)
+{
+ if (global_debug>3)
+ printf("+++ main should prepare interactive move\n");
+ slotStatusMsg(i18n("Please make your move..."));
+}
+
+void LSkatApp::slotReceiveInput(KEMessage *msg,int )
+{
+ /*
+ if (global_debug>=0)
+ {
+ QStrList *keys=msg->QueryKeys();
+ char *it;
+ printf(" MESSAGESIZE=%u\n",msg->QueryNumberOfKeys());
+ for (it=keys->first();it!=0;it=keys->next())
+ {
+ printf(" Key '%s' type=%d\n",it,msg->QueryType(it));
+ }
+ }
+ */
+ short move;
+ QString message;
+ short x,y,player;
+ bool remotesend;
+ int size;
+
+ if (msg->HasKey(QCString("Debug")))
+ {
+ char *debug;
+ msg->GetData(QCString("Debug"),debug,size);
+ printf("Received Debug: %d <%s>\n",size,debug);
+ }
+ if (msg->HasKey(QCString("ConnectionLost")))
+ {
+ if (msg->GetData(QCString("ConnectionLost"),move))
+ {
+ if (move==0)
+ {
+ message=i18n("Remote connection lost for player 1...");
+ KMessageBox::information(this,message);
+ slotStatusMsg(message);
+ slotPlayer1(KG_INPUTTYPE_INTERACTIVE);
+ }
+ else
+ {
+ message=i18n("Remote connection lost for player 2...");
+ KMessageBox::information(this,message);
+ slotStatusMsg(message);
+ slotPlayer2(KG_INPUTTYPE_INTERACTIVE);
+ }
+ }
+ }
+ if (msg->HasKey(QCString("Message")))
+ {
+ char *p;
+ if (msg->GetData(QCString("Message"),p,size))
+ {
+ message=i18n("Message from remote player:\n")+p;
+ KMessageBox::information(this,message);
+ if (global_debug>3)
+ printf("MESSAGE **** %s ****\n",message.latin1());
+ }
+ }
+ if (msg->HasKey(QCString("EndGame")))
+ {
+ KEMessage *msg2=new KEMessage;
+
+ msg2->AddData(QCString("Terminate"),(short)1);
+ if (mInput->QueryType(0)==KG_INPUTTYPE_PROCESS)
+ mInput->SendMsg(msg2,0);
+ if (mInput->QueryType(1)==KG_INPUTTYPE_PROCESS)
+ mInput->SendMsg(msg2,1);
+ delete msg2;
+
+ msg->GetData(QCString("EndGame"),move);
+ message=i18n("Remote player ended game...");
+ KMessageBox::information(this,message);
+ slotStatusMsg(message);
+
+ doc->EndGame(true);
+ doc->slotUpdateAllViews(0);
+ slotStatusNames();
+ }
+
+ if (msg->HasKey(QCString("Move")))
+ {
+ slotStatusMsg(i18n("Ready"));
+ msg->GetData(QCString("Move"),player);
+ msg->GetData(QCString("MoveX"),x);
+ msg->GetData(QCString("MoveY"),y);
+ remotesend=msg->HasKey(QCString("RemoteMove"));
+ if (remotesend && doc->IsRemoteSwitch())
+ player=1-player;
+ Move((int)x,(int)y,(int)player,remotesend);
+ }
+ // Client key is automatically added by message system !!!
+ if (msg->HasKey(QCString("Client")))
+ {
+ if (global_debug>5)
+ printf("We are client and extracting game data now.\n");
+ slotStatusMsg(i18n("You are network client...loading remote game..."));
+ doc->NewGame();
+ ExtractGame(msg);
+ doc->SetServer(false);
+ doc->slotUpdateAllViews(0);
+ mInput->Unlock();
+ mInput->Next(doc->GetStartPlayer());
+ }
+ // Server key is automatically added by message system !!!
+ if (msg->HasKey(QCString("Server")))
+ {
+ if (global_debug>5)
+ printf("We are server now.\n");
+ slotStatusMsg(i18n("You are network server..."));
+ doc->SetServer(true);
+ mInput->Unlock();
+ mInput->Next(doc->GetStartPlayer());
+ }
+}
+
+// Called after the move animation done
+void LSkatApp::MoveFinished()
+{
+ int res=doc->MakeMove();
+ QString ld,s;
+ if (res==2) // end game
+ {
+ doc->EvaluateGame();
+ doc->slotUpdateAllViews(0);
+ // m->SetStatusBar(i18n("Game over"),3);
+ //doc->SwitchStartPlayer();
+ doc->slotUpdateAllViews(0);
+ checkMenus(CheckFileMenu|CheckOptionsMenu);
+ }
+ else if (doc->IsRunning()) // continue game
+ {
+ // Delay fast playing of the computer !
+ /*
+ printf("*** next=%d current=%d playedby=%d\n",
+ mInput->QueryNext(),doc->GetCurrentPlayer() ,
+ doc->GetPlayedBy(doc->GetCurrentPlayer()));
+ */
+ // Maybe we do not need to distinquish these two cases?
+ // Computer was last and is next
+ if (doc->GetPlayedBy(mInput->QueryNext())==KG_INPUTTYPE_PROCESS &&
+ doc->GetPlayedBy(doc->GetCurrentPlayer())==KG_INPUTTYPE_PROCESS)
+ {
+ procTimer->start(1000,true);
+ }
+ // Computer is next
+ else if (doc->GetPlayedBy(doc->GetCurrentPlayer())==KG_INPUTTYPE_PROCESS)
+ {
+ procTimer->start(1000,true);
+ }
+ else
+ {
+ mInput->Unlock();
+ mInput->Next(doc->GetCurrentPlayer());
+ }
+ }
+ slotStatusNames();
+}
+
+void LSkatApp::Move(int x,int y,int player,bool remote)
+{
+ KEMessage *msg;
+ if (global_debug>1)
+ printf("Move of %d to x=%d y=%d\n",player,x,y);
+ if (x<0 || y<0 || x>7 || y>1 || player <0 || player>1)
+ {
+ KMessageBox::error(this,
+ i18n("Severe internal error. Move to illegal position.\n"
+ "Restart game and report bug to the developer.\n"));
+ return ;
+ }
+ int res=doc->PrepareMove(player,y*4+x);
+ if (res>0)
+ {
+ doc->InitMove(0,player,x,y);
+ if (mInput->QueryType()!=KG_INPUTTYPE_REMOTE && !remote )
+ {
+ msg=new KEMessage;
+ if (doc->IsRemoteSwitch()) player=1-player;
+ msg->AddData(QCString("Move"),(short)player);
+ msg->AddData(QCString("MoveX"),(short)x);
+ msg->AddData(QCString("MoveY"),(short)y);
+ msg->AddData(QCString("RemoteMove"),(short)1);
+ if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,0);
+ if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE)
+ mInput->SendMsg(msg,1);
+ delete msg;
+ }
+ }
+ else if (res==-3)
+ {
+ KMessageBox::information(this,
+ i18n("This move would not follow the rulebook.\n"
+ "Better think again!\n"));
+ return ;
+ }
+ else if (res==-2)
+ {
+ KMessageBox::information(this,i18n("It is not your turn.\n"));
+ return ;
+ }
+ else
+ {
+ KMessageBox::information(this, i18n("This move is not possible.\n"));
+ return ;
+ }
+}
+
+void LSkatApp::PrepareGame(KEMessage *msg)
+{
+ if (!msg)
+ return;
+
+ msg->AddData(QCString("Cards"),(char *)doc->GetCardP(),NO_OF_CARDS*sizeof(int));
+ msg->AddData(QCString("Startplayer"),(short)doc->GetStartPlayer());
+ msg->AddData(QCString("CurrentPlayer"),(short)doc->GetCurrentPlayer());
+ if (doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE)
+ msg->AddData(QCString("RemoteIs"),(short)0);
+ else if (doc->GetPlayedBy(1)==KG_INPUTTYPE_REMOTE)
+ msg->AddData(QCString("RemoteIs"),(short)1);
+ msg->AddData(QCString("Trump"),(short)doc->GetTrump());
+ // For computer player
+ // -1 or the current played card
+ msg->AddData(QCString("CurrentMove"),(short)doc->GetMove(doc->GetStartPlayer()));
+ msg->AddData(QCString("Height"),(char *)doc->GetCardHeightP(),NO_OF_CARDS/2*sizeof(int));
+ msg->AddData(QCString("No"),(short)doc->GetMoveNo());
+ msg->AddData(QCString("Sc1"),(short)doc->GetScore(0));
+ msg->AddData(QCString("Sc2"),(short)doc->GetScore(1));
+ msg->AddData(QCString("Level"),(short)doc->GetComputerLevel());
+}
+
+void LSkatApp::ExtractGame(KEMessage *msg)
+{
+ if (!msg)
+ return;
+ // Do we have to switch players?
+ bool switchit;
+ short remote;
+ msg->GetData(QCString("RemoteIs"),remote);
+ if (doc->GetPlayedBy(remote)==KG_INPUTTYPE_REMOTE) switchit=true;
+ else switchit=false;
+
+ short start;
+ int i,size;
+ int *cards;
+ char *p;
+ short trump;
+ msg->GetData(QCString("Startplayer"),start);
+ msg->GetData(QCString("Cards"),p,size);
+ cards=(int *)p;
+ msg->GetData(QCString("Trump"),trump);
+ if (size!=NO_OF_CARDS*sizeof(int))
+ {
+ printf("Error: Transmission of cards failed..wrong sizes\n");
+ }
+
+ doc->SetRemoteSwitch(switchit);
+ if (switchit)
+ {
+ start=1-start;
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ if (i>=NO_OF_CARDS/2)
+ doc->SetCard(i-NO_OF_CARDS/2,cards[i]);
+ else
+ doc->SetCard(i+NO_OF_CARDS/2,cards[i]);
+ }
+ }
+ else
+ {
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ doc->SetCard(i,cards[i]);
+ }
+ }
+
+ doc->SetStartPlayer(start);
+ doc->SetCurrentPlayer(start);
+ doc->SetTrump((CCOLOUR)trump);
+}
+
+
+void LSkatApp::SetGrafix(QString s)
+{
+ mGrafix=s;
+}
+
+#include "lskat.moc"
diff --git a/lskat/lskat/lskat.h b/lskat/lskat/lskat.h
new file mode 100644
index 00000000..b5686dde
--- /dev/null
+++ b/lskat/lskat/lskat.h
@@ -0,0 +1,216 @@
+/***************************************************************************
+ lskat.h - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LSKAT_H
+#define LSKAT_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for Qt
+#include <qstrlist.h>
+
+// include files for KDE
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <kaccel.h>
+
+#include "KEInput.h"
+#include "KEMessage.h"
+#include "KConnectTypes.h"
+
+typedef enum {Club=0,Spade=1,Heart=2,Diamond=3,Grand=4} CCOLOUR;
+typedef enum {Ace=0,King=1,Queen=2,Jack=3,Ten=4,Nine=5,Eight=6,Seven=7} CCARD;
+#define NO_OF_CARDS 32
+#define NO_OF_TILES 16
+#define NO_OF_TRUMPS 5
+//#define NO_OF_DECKS 6
+#define NO_OF_ANIM 24
+
+// Window update codes
+#define UPDATE_STATUS 1
+
+extern int global_debug;
+// forward declaration of the LSkat classes
+class LSkatDoc;
+class LSkatView;
+
+/**
+ * The base class for LSkat application windows. It sets up the main
+ * window and reads the config file as well as providing a menubar, toolbar
+ * and statusbar. An instance of LSkatView creates your center view, which is connected
+ * to the window's Doc object.
+ * LSkatApp reimplements the methods that KMainWindow provides for main window handling and supports
+ * full session management as well as keyboard accelerator configuration by using KAccel.
+ * @see KMainWindow
+ * @see KApplication
+ * @see KConfig
+ * @see KAccel
+ *
+ * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
+ * @version KDevelop version 0.4 code generation
+ */
+class LSkatApp : public KMainWindow
+{
+ Q_OBJECT
+
+ friend class LSkatView;
+
+ public:
+ /** construtor of LSkatApp, calls all init functions to create the application.
+ */
+ LSkatApp();
+ ~LSkatApp();
+ /** enables menuentries/toolbar items
+ */
+ void enableAction(const char *);
+ /** disables menuentries/toolbar items
+ */
+ void disableAction(const char *);
+ /** add a opened file to the recent file list and update recent_file_menu
+ */
+ /** returns a pointer to the current document connected to the KMainWindow instance and is used by
+ * the View class to access the document object's methods
+ */
+ LSkatDoc *getDocument() const;
+ void MoveFinished();
+ void Move(int x,int y,int player,bool remote);
+ void SetGrafix(QString s);
+
+ protected:
+ void NewGame();
+ bool MakeInputDevice(int no);
+ void OptionsNetwork();
+ // Puts all game data into a message
+ void PrepareGame(KEMessage *msg);
+ void ExtractGame(KEMessage *msg);
+
+ /** initGUI creates the menubar and inserts the menupopups as well as creating the helpMenu.
+ * @see KApplication#getHelpMenu
+ */
+ void initGUI();
+ /** Checks all menus..usually done on init programm */
+ void checkMenus(int menu=0);
+
+ /** this creates the toolbars.
+ */
+ /** sets up the statusbar for the main window by initialzing a statuslabel.
+ */
+ void initStatusBar();
+ /** initializes the document object of the main window that is connected to the view in initView().
+ * @see initView();
+ */
+ void initDocument();
+ /** creates the centerwidget of the KMainWindow instance and sets it as the view
+ */
+ void initView();
+ /** queryClose is called by KMainWindow on each closeEvent of a window. Against the
+ * default implementation (only returns true), this calles saveModified() on the document object to ask if the document shall
+ * be saved if Modified; on cancel the closeEvent is rejected.
+ * @see KMainWindow#queryClose
+ * @see KMainWindow#closeEvent
+ */
+ virtual bool queryClose();
+ /** queryExit is called by KMainWindow when the last window of the application is going to be closed during the closeEvent().
+ * Against the default implementation that just returns true, this calls saveOptions() to save the settings of the last window's
+ * properties.
+ * @see KMainWindow#queryExit
+ * @see KMainWindow#closeEvent
+ */
+ virtual bool queryExit();
+ /** saves the window properties for each open window during session end to the session config file, including saving the currently
+ * opened file by a temporary filename provided by KApplication.
+ * @see KMainWindow#saveProperties
+ */
+ virtual void saveProperties(KConfig *_cfg);
+ /** reads the session config file and restores the application's state including the last opened files and documents by reading the
+ * temporary files saved by saveProperties()
+ * @see KMainWindow#readProperties
+ */
+ virtual void readProperties(KConfig *_cfg);
+
+ public slots:
+ void slotPrepareProcessMove(KEMessage *msg);
+ void slotPrepareRemoteMove(KEMessage *msg);
+ void slotPrepareInteractiveMove(KEMessage *msg);
+ void slotReceiveInput(KEMessage *msg,int id);
+
+ /** clears the document in the actual view to reuse it as the new document */
+ void slotFileNew();
+ /** asks for saving if the file is modified, then closes the actual file and window*/
+ void slotFileEnd();
+ /** closes all open windows by calling close() on each memberList item until the list is empty, then quits the application.
+ * If queryClose() returns false because the user canceled the saveModified() dialog, the closing breaks.
+ */
+ void slotFileQuit();
+ // clear all time stats
+ void slotFileStatistics();
+ /** Msg to remote player */
+ void slotFileMessage();
+ /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const QString &text);
+ void slotClearStatusMsg();
+ /** changes the status message of the whole statusbar for two seconds, then restores the last status. This is used to display
+ * statusbar messages that give information about actions for toolbar icons and menuentries.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusHelpMsg(const QString &text);
+ /** Set the names in the mover field */
+ void slotStatusNames();
+ void slotStatusMover(const QString &text);
+
+ void slotLevel();
+ void slotStartplayer();
+ void slotPlayer1(KG_INPUTTYPE i);
+ void slotPlayer2(KG_INPUTTYPE i);
+ void slotPlayer1By();
+ void slotPlayer2By();
+ void slotOptionsNames();
+ void slotOptionsCardDeck();
+ /** Triggers the process timer */
+ void slotProcTimer(void);
+
+protected: // Protected attributes
+
+ enum CheckFlags {All=0,CheckFileMenu=1,CheckOptionsMenu=2,CheckViewMenu=4};
+
+ /** */
+ /** Counts the time in the status bar */
+ QTimer * procTimer;
+ KEInput *mInput;
+ QString mGrafix;
+
+ private:
+ /** contains the recently used filenames */
+ QStrList recentFiles;
+
+ /** the configuration object of the application */
+ KConfig *config;
+
+ LSkatView *view;
+ /** doc represents your actual document and is created only once. It keeps
+ * information such as filename and does the serialization of your files.
+ */
+ LSkatDoc *doc;
+};
+
+#endif // LSKAT_H
+
diff --git a/lskat/lskat/lskatdoc.cpp b/lskat/lskat/lskatdoc.cpp
new file mode 100644
index 00000000..8da62ea4
--- /dev/null
+++ b/lskat/lskat/lskatdoc.cpp
@@ -0,0 +1,817 @@
+/***************************************************************************
+ lskatdoc.cpp - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for Qt
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+
+// include files for KDE
+#include <klocale.h>
+
+// application specific includes
+#include "lskatdoc.h"
+#include "lskat.h"
+#include "lskatview.h"
+#include <kcarddialog.h>
+
+QPtrList<LSkatView> *LSkatDoc::pViewList = 0L;
+
+LSkatDoc::LSkatDoc(QWidget *parent, const char *name) : QObject(parent, name)
+{
+ int i;
+ if(!pViewList)
+ {
+ pViewList = new QPtrList<LSkatView>();
+ }
+
+ pViewList->setAutoDelete(true);
+
+ isrunning=0;
+ wasgame=false;
+ initrandom();
+ // Allow translation of playernames
+ /*
+ names[0]=i18n("Alice");
+ names[1]=i18n("Bob");
+ */
+
+ for (i=0;i<14;i++) cardvalues[i]=0;
+ cardvalues[(int)Ace]=11;
+ cardvalues[(int)Ten]=10;
+ cardvalues[(int)King]=4;
+ cardvalues[(int)Queen]=3;
+ cardvalues[(int)Jack]=2;
+
+ /*
+ computerlevel=2;
+ playedby[1]=KG_INPUTTYPE_INTERACTIVE;
+ playedby[0]=KG_INPUTTYPE_PROCESS;
+ // playedby[1]=KG_INPUTTYPE_INTERACTIVE;
+ */
+
+
+ isintro=1;
+ server=false;
+ port=7432;
+ host="";
+ Name="";
+ remoteswitch=false;
+
+
+ ClearStats();
+}
+
+LSkatDoc::~LSkatDoc()
+{
+}
+
+void LSkatDoc::addView(LSkatView *view)
+{
+ pViewList->append(view);
+}
+
+void LSkatDoc::removeView(LSkatView *view)
+{
+ pViewList->remove(view);
+}
+
+void LSkatDoc::setAbsFilePath(const QString &filename)
+{
+ absFilePath=filename;
+}
+
+const QString &LSkatDoc::getAbsFilePath() const
+{
+ return absFilePath;
+}
+
+void LSkatDoc::setTitle(const QString &_t)
+{
+ title=_t;
+}
+
+const QString &LSkatDoc::getTitle() const
+{
+ return title;
+}
+
+void LSkatDoc::InitMove(LSkatView *sender,int player,int x,int y)
+{
+ LSkatView *w;
+ if(pViewList)
+ {
+ for(w=pViewList->first(); w!=0; w=pViewList->next())
+ {
+ if(w!=sender) w->InitMove(player,x,y);
+ }
+ }
+
+}
+void LSkatDoc::slotUpdateAllViews(LSkatView *sender)
+{
+ LSkatView *w;
+ if(pViewList)
+ {
+ for(w=pViewList->first(); w!=0; w=pViewList->next())
+ {
+ if(w!=sender)
+ w->repaint();
+ }
+ }
+}
+void LSkatDoc::UpdateViews(int mode)
+{
+ LSkatView *w;
+ if (IsIntro()) return ;
+ if(pViewList)
+ {
+ for(w=pViewList->first(); w!=0; w=pViewList->next())
+ {
+ if (mode & UPDATE_STATUS) w->updateStatus();
+ }
+ }
+}
+
+bool LSkatDoc::saveModified()
+{
+ return true;
+}
+
+void LSkatDoc::closeDocument()
+{
+ deleteContents();
+}
+
+bool LSkatDoc::newDocument(KConfig * /*config*/,QString path)
+{
+ int res;
+ modified=false;
+ absFilePath=QDir::homeDirPath();
+ title=i18n("Untitled");
+ if (global_debug>1) printf("path=%s\n",path.latin1());
+ res=LoadBitmap(path);
+ if (res==0) return false;
+ return true;
+}
+
+bool LSkatDoc::LoadGrafix(QString path)
+{
+ int res;
+ res=LoadCards(cardPath);
+ if (res==0) return false;
+ res=LoadDeck(deckPath);
+ if (res==0) return false;
+ return true;
+}
+
+bool LSkatDoc::SetCardDeckPath(QString deck,QString card)
+{
+ bool update=false;
+ if (!deck.isNull() && deck!=deckPath)
+ {
+ update=true;
+ deckPath=deck;
+ LoadDeck(deckPath);
+ }
+ if (!card.isNull() && card!=cardPath)
+ {
+ update=true;
+ cardPath=card;
+ LoadCards(cardPath);
+ }
+ return update;
+}
+
+bool LSkatDoc::openDocument(const QString &filename, const char * /*format*/ /*=0*/)
+{
+ QFileInfo fileInfo(filename);
+ title=fileInfo.fileName();
+ absFilePath=fileInfo.absFilePath();
+ /////////////////////////////////////////////////
+ // TODO: Add your document opening code here
+ /////////////////////////////////////////////////
+
+ modified=false;
+ return true;
+}
+
+bool LSkatDoc::saveDocument(const QString & /*filename*/, const char * /*format*/ /*=0*/)
+{
+ /////////////////////////////////////////////////
+ // TODO: Add your document saving code here
+ /////////////////////////////////////////////////
+
+ modified=false;
+ return true;
+}
+
+void LSkatDoc::deleteContents()
+{
+ /////////////////////////////////////////////////
+ // TODO: Add implementation to delete the document contents
+ /////////////////////////////////////////////////
+
+}
+
+// Called after game ends..give points to players
+void LSkatDoc::EvaluateGame()
+{
+ if (score[0]+score[1]!=120)
+ {
+ printf("Warning: Score does not end up to 120\n");
+ }
+ stat_games[0]++;
+ stat_games[1]++;
+ if (score[0]==score[1]) // drawn
+ {
+ stat_points[0]++;
+ stat_points[1]++;
+ }
+ else if (score[0]>score[1])
+ {
+ stat_won[0]++;
+ stat_points[0]+=2;
+ if (score[0]>=90) stat_points[0]++; // Schneider
+ if (score[0]>=120) stat_points[0]++; // SChwarz
+ }
+ else
+ {
+ stat_won[1]++;
+ stat_points[1]+=2;
+ if (score[1]>=90) stat_points[1]++; // Schneider
+ if (score[1]>=120) stat_points[1]++; // SChwarz
+ }
+}
+
+void LSkatDoc::EndGame(bool aborted)
+{
+ if (aborted)
+ {
+ stat_brk[0]++;
+ stat_brk[1]++;
+ }
+ else
+ {
+ startplayer=1-began_game;
+ }
+ isrunning=0;
+ wasgame=true;
+}
+
+void LSkatDoc::NewGame()
+{
+ int i,r;
+ int num[NO_OF_CARDS];
+
+ isintro=0;
+
+ began_game=startplayer;
+ for (i=0;i<NO_OF_TILES;i++)
+ {
+ cardheight[i]=2;
+ }
+ trump=(CCOLOUR)(random(4));
+ if (global_debug>5) printf("Trump=%d\n",trump);
+ if (random(8)==0) trump=Grand; // grand
+
+ // Fast drawing of random cards
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ num[i]=i;
+ }
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ r=random(NO_OF_CARDS-i); // cards available 32-i (+1)
+ card[i]=num[r];
+ num[r]=num[NO_OF_CARDS-i-1]; // shift numbers
+ }
+ isrunning=1;
+ movestatus=-1;
+ currentplayer=startplayer;
+ laststartplayer=-1;
+ moveno=0;
+ computerscore=0;
+ lock=false;
+ for (i=0;i<2;i++)
+ {
+ score[i]=0;
+ curmove[i]=-1;
+ }
+}
+
+int LSkatDoc::GetMove(int no) {return curmove[no];}
+
+CCOLOUR LSkatDoc::GetTrump()
+{
+ return trump;
+}
+void LSkatDoc::SetTrump(CCOLOUR i)
+{
+ trump=i;
+}
+
+// pos=0..7, height=2..1..(0 no card left), player=0..1
+int LSkatDoc::GetCard(int player, int pos,int height)
+{
+ int i;
+ if (height==0) return -1;
+ height=2-height;
+
+ i=NO_OF_TILES*player+8*height+pos;
+ return card[i];
+}
+
+// pos=0..7, player=0..1
+int LSkatDoc::GetHeight(int player, int pos)
+{
+ int i;
+ i=8*player+pos;
+ return cardheight[i];
+}
+// pos=0..7, player=0..1
+void LSkatDoc::SetHeight(int player, int pos,int h)
+{
+ int i;
+ i=8*player+pos;
+ cardheight[i]=h;
+}
+
+
+int LSkatDoc::random(int max)
+{
+double value;
+int r;
+ r=rand();
+ value=(double)((double)r*(double)max)/(double)RAND_MAX;
+ return (int)value;
+}
+
+void LSkatDoc::initrandom()
+{
+ srand( (unsigned)time( NULL ) ); // randomize
+}
+
+bool LSkatDoc::IsRunning() {return isrunning;}
+
+bool LSkatDoc::LegalMove(int p1, int p2)
+{
+ CCOLOUR col1,col2,col3;
+ CCARD card1,card2,card3;
+ card1=(CCARD)((p1)/4);
+ col1=(CCOLOUR)((p1)%4);
+ card2=(CCARD)((p2)/4);
+ col2=(CCOLOUR)((p2)%4);
+
+ // force trump colour
+ if (card1==Jack) col1=trump;
+ if (card2==Jack) col2=trump;
+
+ // same colour always ok
+ if (col1==col2) return true;
+
+ // Search for same colour
+ bool flag=true;
+ for (int i=0;i<8;i++)
+ {
+ int h,c;
+ h=GetHeight(1-startplayer,i);
+ if (h==0) continue;
+ c=GetCard(1-startplayer,i,h);
+ card3=(CCARD)((c)/4);
+ col3=(CCOLOUR)((c)%4);
+ if (card3==Jack) col3=trump;
+
+ if (col3==col1)
+ {
+ flag=false;
+ break;
+ }
+ }
+ if (flag) return true;
+
+ return false;
+}
+
+int LSkatDoc::PrepareMove(int player,int pos)
+{
+ int h,card;
+ h=GetHeight(player,pos);
+ if (h==0) return -1; // not possible
+ if (player!=currentplayer) return -2; // wrong player
+
+ card=GetCard(player,pos,h);
+
+ // New round
+ if (currentplayer==startplayer)
+ {
+ curmove[0]=-1;
+ curmove[1]=-1;
+ }
+ else
+ {
+ if (!LegalMove(curmove[startplayer],card))
+ {
+ printf("Illegal move\n");
+ return -3;
+ }
+ }
+ lock=true;
+
+ movestatus=card;
+ SetHeight(player,pos,h-1);
+ return 1;
+}
+int LSkatDoc::MakeMove()
+{
+ lock=false;
+ curmove[currentplayer]=movestatus;
+ if (currentplayer==startplayer)
+ {
+ moveno++;
+ currentplayer=1-startplayer;
+ }
+ else
+ {
+ laststartplayer=startplayer;
+
+ if (WonMove(curmove[startplayer],curmove[1-startplayer]))
+ {
+ // switch startplayer
+ startplayer=1-startplayer;
+ }
+ else
+ {
+ }
+ currentplayer=startplayer;
+ score[startplayer]+=CardValue(curmove[0]);
+ score[startplayer]+=CardValue(curmove[1]);
+ if (moveno==NO_OF_TILES)
+ {
+ EndGame(false);
+ return 2;
+ }
+ }
+ movestatus=-1;
+ return 1;
+}
+int LSkatDoc::CardValue(int card)
+{
+ int card1;
+
+ card1=card/4;
+ return cardvalues[card1];
+}
+
+int LSkatDoc::WonMove(int c1,int c2)
+{
+ CCOLOUR col1,col2;
+ CCARD card1,card2;
+
+ card1=(CCARD)((c1)/4);
+ col1=(CCOLOUR)((c1)%4);
+ card2=(CCARD)((c2)/4);
+ col2=(CCOLOUR)((c2)%4);
+
+ // Two jacks
+ if (card1==Jack && card2==Jack)
+ {
+ if (col1<col2) return 0;
+ else return 1;
+ }
+ // One Jack wins always
+ if (card1==Jack) return 0;
+ if (card2==Jack) return 1;
+
+ // higher one wins if same colour
+ if (col1==col2)
+ {
+ if (card1==Ten)
+ {
+ if (card2==Ace) return 1;
+ else return 0;
+ }
+ if (card2==Ten)
+ {
+ if (card1==Ace) return 0;
+ return 1;
+ }
+
+ if ((int)card1<(int)card2) return 0;
+ return 1;
+ }
+ // trump wins
+ if (col1==trump) return 0;
+ if (col2==trump) return 1;
+
+ // first one wins
+ return 0;
+
+}
+
+int LSkatDoc::GetMoveStatus() {return movestatus;}
+void LSkatDoc::SetMoveStatus(int i) { movestatus=i; }
+int LSkatDoc::GetCurrentPlayer() {return currentplayer;}
+void LSkatDoc::SetCurrentPlayer(int i) {currentplayer=i;}
+int LSkatDoc::GetStartPlayer() {return startplayer;}
+void LSkatDoc::SetStartPlayer(int i) {startplayer=i;}
+
+void LSkatDoc::SetName(int no, QString n) { names[no]=n; }
+QString LSkatDoc::GetName(int no) {return names[no];}
+int LSkatDoc::GetScore(int no) {return score[no];}
+
+int LSkatDoc::GetMoveNo() {return moveno;}
+/*
+void LSkatDoc::SetDeckNo(int no) {deckno=no;}
+int LSkatDoc::GetDeckNo() {return deckno;}
+*/
+
+
+int LSkatDoc::GetLastStartPlayer() {return laststartplayer;}
+
+KG_INPUTTYPE LSkatDoc::GetPlayedBy(int no) {return playedby[no];}
+void LSkatDoc::SetPlayedBy(int no,KG_INPUTTYPE type) {playedby[no]=type;}
+int LSkatDoc::GetComputerLevel() {return computerlevel;}
+void LSkatDoc::SetComputerLevel(int lev) {computerlevel=lev;}
+
+void LSkatDoc::SetComputerScore(int sc) {computerscore=sc;}
+int LSkatDoc::GetComputerScore() {return computerscore;}
+void LSkatDoc::SetLock() {lock=true;}
+void LSkatDoc::ReleaseLock() {lock=false;}
+bool LSkatDoc::IsLocked() {return lock;}
+bool LSkatDoc::IsIntro() {return isintro;}
+bool LSkatDoc::WasRunning() {return wasgame;}
+void LSkatDoc::SetIntro(bool b) {isintro=b;}
+
+int LSkatDoc::LoadBitmap(QString path)
+{
+ int i;
+ QString buf;
+ if (global_debug>5) printf("Loading bitmaps\n");
+ for (i=0;i<NO_OF_TRUMPS;i++)
+ {
+ buf.sprintf("%st%d.png",path.latin1(),i+1);
+ if(!mPixTrump[i].load(buf))
+ {
+ printf("Fatal error: bitmap %s not found \n",buf.latin1());
+ }
+ }
+
+
+ for (i=0;i<3;i++)
+ {
+ buf.sprintf("%stype%d.png",path.latin1(),i+1);
+ if (!mPixType[i].load(buf))
+ {
+ printf("Fatal error: bitmap %s not found \n",buf.latin1());
+ }
+ }
+
+ buf.sprintf("%sbackground.png",path.latin1());
+
+ mPixBackground.load(buf);
+ if (!mPixBackground.load(buf))
+ {
+ printf("Fatal error: bitmap %s not found \n",buf.latin1());
+ }
+
+ for (i=0;i<NO_OF_ANIM;i++)
+ {
+ buf.sprintf("%s4000%02d.png",path.latin1(),i);
+ if(!mPixAnim[i].load(buf))
+ {
+ printf("Fatal error: bitmap %s not found \n",buf.latin1());
+ }
+ }
+ return 1;
+}
+
+
+int LSkatDoc::LoadCards(QString path)
+{
+ QString buf;
+ for (int i=0;i<NO_OF_CARDS;i++)
+ {
+ buf.sprintf("%s%d.png",path.latin1(),i+1);
+ if(!mPixCard[i].load(buf))
+ {
+ printf("Fatal error: bitmap %s not found \n",buf.latin1());
+ return 0;
+ }
+ }
+ cardsize=mPixCard[0].size();
+ return 1;
+}
+
+int LSkatDoc::LoadDeck(QString path)
+{
+ if (!mPixDeck.load(path))return 0;
+ return 1;
+}
+
+void LSkatDoc::SetInputHandler(KEInput *i)
+{
+ inputHandler=i;
+}
+KEInput *LSkatDoc::QueryInputHandler()
+{
+ return inputHandler;
+}
+
+int LSkatDoc::SwitchStartPlayer()
+{
+ startplayer=1-startplayer;
+ return startplayer;
+}
+
+bool LSkatDoc::IsServer()
+{
+ return server;
+}
+void LSkatDoc::SetServer(bool b)
+{
+ server=b;
+}
+void LSkatDoc::SetHost(QString h)
+{
+ host=h;
+}
+void LSkatDoc::SetName(const QString& n)
+{
+ Name=n;
+}
+void LSkatDoc::SetPort(short p)
+{
+ port=p;
+}
+QString LSkatDoc::QueryHost()
+{
+ return host;
+}
+short LSkatDoc::QueryPort()
+{
+ return port;
+}
+QString LSkatDoc::QueryName() const
+{
+ return Name;
+}
+int *LSkatDoc::GetCardP()
+{
+ return card;
+}
+int *LSkatDoc::GetCardHeightP()
+{
+ return cardheight;
+}
+
+void LSkatDoc::SetCard(int no,int c)
+{
+ card[no]=c;
+}
+void LSkatDoc::SetRemoteSwitch(bool b)
+{
+ remoteswitch=b;
+}
+bool LSkatDoc::IsRemoteSwitch()
+{
+ return remoteswitch;
+}
+
+int LSkatDoc::GetStatWon(int no)
+{
+ return stat_won[no];
+}
+int LSkatDoc::GetStatGames(int no)
+{
+ return stat_games[no];
+}
+int LSkatDoc::GetStatAborted(int no)
+{
+ return stat_brk[no];
+}
+int LSkatDoc::GetStatPoints(int no)
+{
+ return stat_points[no];
+}
+
+QString LSkatDoc::GetProcess()
+{
+ return procfile;
+}
+
+void LSkatDoc::ClearStats()
+{
+ for (int j=0;j<2;j++)
+ {
+ stat_won[j]=0;
+ stat_points[j]=0;
+ stat_games[j]=0;
+ stat_brk[j]=0;
+ }
+}
+void LSkatDoc::ReadConfig(KConfig *config)
+{
+ KConfig emailCfg( "emaildefaults", true );
+ emailCfg.setGroup( "UserInfo" );
+ QString name = emailCfg.readEntry( "FullName" );
+ if ( name.isEmpty() )
+ {
+ struct passwd *pw = getpwuid( getuid() );
+ if ( pw )
+ name = QString::fromLocal8Bit( pw->pw_gecos );
+ }
+
+ config->setGroup("Parameter");
+ host=config->readEntry("host");
+ port=(unsigned short)config->readNumEntry("port",7432);
+ procfile=config->readEntry("process",QCString("lskatproc"));
+ Name=config->readEntry("gamename");
+ names[0]=config->readEntry("Name1",i18n("Alice"));
+ // names[1]=config->readEntry("Name2",i18n("Bob"));
+ names[1]=config->readEntry("Name2", name.isEmpty() ? i18n("Bob") : name);
+
+
+ // This is for debug and testing as you can run it from the CVS without
+ // installing the carddecks !
+ // For the release version you can remove the aruments to the following two
+ // functions !!!!
+ cardPath=config->readPathEntry("cardpath", KCardDialog::getDefaultCardDir());
+ deckPath=config->readPathEntry("deckpath", KCardDialog::getDefaultDeck());
+
+ // Debug only
+ if (global_debug>3)
+ printf("cardPath=%s\ndeckPath=%s\n",cardPath.latin1(),deckPath.latin1());
+
+ startplayer=config->readNumEntry("Startplayer",0);
+ if (startplayer>1 || startplayer<0) startplayer=0;
+ began_game=startplayer;
+ computerlevel=config->readNumEntry("Level",2);
+ playedby[0]=(KG_INPUTTYPE)config->readNumEntry("Player1",
+ (int)KG_INPUTTYPE_PROCESS);
+ playedby[1]=(KG_INPUTTYPE)config->readNumEntry("Player2",
+ (int)KG_INPUTTYPE_INTERACTIVE);
+
+ stat_won[0]=config->readNumEntry("Stat1W",0);
+ stat_won[1]=config->readNumEntry("Stat2W",0);
+ stat_brk[0]=config->readNumEntry("Stat1B",0);
+ stat_brk[1]=config->readNumEntry("Stat2B",0);
+ stat_points[0]=config->readNumEntry("Stat1P",0);
+ stat_points[1]=config->readNumEntry("Stat2P",0);
+ stat_games[0]=config->readNumEntry("Stat1G",0);
+ stat_games[1]=config->readNumEntry("Stat2G",0);
+}
+
+/** write config file */
+void LSkatDoc::WriteConfig(KConfig *config)
+{
+ config->setGroup("Parameter");
+ config->writeEntry("host",host);
+ config->writeEntry("port",port);
+ config->writeEntry("process",procfile);
+ config->writePathEntry("tmppath",picpath);
+ config->writeEntry("delpath",delpath);
+ config->writeEntry("Name1",names[0]);
+ config->writeEntry("Name2",names[1]);
+ config->writeEntry("gamename",Name);
+
+ config->writeEntry("Startplayer",startplayer);
+ config->writeEntry("Level",computerlevel);
+ config->writeEntry("Player1",int(playedby[0]));
+ config->writeEntry("Player2",int(playedby[1]));
+
+ config->writeEntry("Stat1W",stat_won[0]);
+ config->writeEntry("Stat2W",stat_won[1]);
+ config->writeEntry("Stat1B",stat_brk[0]);
+ config->writeEntry("Stat2B",stat_brk[1]);
+ config->writeEntry("Stat1P",stat_points[0]);
+ config->writeEntry("Stat2P",stat_points[1]);
+ config->writeEntry("Stat1G",stat_games[0]);
+ config->writeEntry("Stat2G",stat_games[1]);
+
+ config->writePathEntry("cardpath",cardPath);
+ config->writePathEntry("deckpath",deckPath);
+
+ config->sync();
+}
+
+#include "lskatdoc.moc"
diff --git a/lskat/lskat/lskatdoc.h b/lskat/lskat/lskatdoc.h
new file mode 100644
index 00000000..1b880360
--- /dev/null
+++ b/lskat/lskat/lskatdoc.h
@@ -0,0 +1,235 @@
+/***************************************************************************
+ lskatdoc.h - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LSKATDOC_H
+#define LSKATDOC_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for QT
+#include <qobject.h>
+#include <qstring.h>
+#include <qptrlist.h>
+
+#include <kconfig.h>
+#include "lskat.h"
+#include "KEInput.h"
+
+// forward declaration of the LSkat classes
+class LSkatView;
+
+/** LSkatDoc provides a document object for a document-view model.
+ *
+ * The LSkatDoc class provides a document object that can be used in conjunction with the classes LSkatApp and LSkatView
+ * to create a document-view model for standard KDE applications based on KApplication and KTMainWindow. Thereby, the document object
+ * is created by the LSkatApp instance and contains the document structure with the according methods for manipulation of the document
+ * data by LSkatView objects. Also, LSkatDoc contains the methods for serialization of the document data from and to files.
+ *
+ * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
+ * @version KDevelop version 0.4 code generation
+ */
+class LSkatDoc : public QObject
+{
+ Q_OBJECT
+ public:
+ /** Constructor for the fileclass of the application */
+ LSkatDoc(QWidget *parent, const char *name=0);
+ /** Destructor for the fileclass of the application */
+ ~LSkatDoc();
+
+ /** adds a view to the document which represents the document contents. Usually this is your main view. */
+ void addView(LSkatView *view);
+ /** removes a view from the list of currently connected views */
+ void removeView(LSkatView *view);
+ /** sets the modified flag for the document after a modifying action on the view connected to the document.*/
+ void setModified(bool _m=true){ modified=_m; }
+ /** returns if the document is modified or not. Use this to determine if your document needs saving by the user on closing.*/
+ bool isModified(){ return modified; }
+ /** "save modified" - asks the user for saving if the document is modified */
+ bool saveModified();
+ /** deletes the document's contents */
+ void deleteContents();
+ /** initializes the document generally */
+ bool newDocument(KConfig *config,QString path);
+ /** closes the acutal document */
+ void closeDocument();
+ /** loads the document by filename and format and emits the updateViews() signal */
+ bool openDocument(const QString &filename, const char *format=0);
+ /** saves the document under filename and format.*/
+ bool saveDocument(const QString &filename, const char *format=0);
+ /** sets the path to the file connected with the document */
+ void setAbsFilePath(const QString &filename);
+ /** returns the pathname of the current document file*/
+ const QString &getAbsFilePath() const;
+ /** sets the filename of the document */
+ void setTitle(const QString &_t);
+ /** returns the title of the document */
+ const QString &getTitle() const;
+
+ int random(int max);
+ void NewGame();
+ void EndGame(bool aborted=false);
+ void ClearStats();
+ void EvaluateGame();
+ int GetCard(int player,int pos,int height=0);
+ int GetHeight(int player, int pos);
+ void SetHeight(int player, int pos,int h);
+ int GetMove(int i);
+ int PrepareMove(int player,int pos);
+ int MakeMove();
+ bool IsRunning();
+ CCOLOUR GetTrump();
+ void SetTrump(CCOLOUR i);
+ int GetMoveStatus();
+ void SetMoveStatus(int i);
+ int GetCurrentPlayer();
+ void SetCurrentPlayer(int i);
+ int GetStartPlayer();
+ void SetStartPlayer(int i);
+ void SetName(int no,QString n);
+ QString GetName(int no);
+ int GetScore(int no);
+ int GetMoveNo();
+ bool LegalMove(int card1, int card2);
+ int WonMove(int card1,int card2);
+ int CardValue(int card);
+ /*
+ int GetDeckNo();
+ void SetDeckNo(int no);
+ */
+ int GetLastStartPlayer();
+ KG_INPUTTYPE GetPlayedBy(int no);
+ void SetPlayedBy(int no,KG_INPUTTYPE type);
+ int GetComputerLevel();
+ void SetComputerLevel(int lev);
+ void SetComputerScore(int sc);
+ int GetComputerScore();
+ void SetLock();
+ void ReleaseLock();
+ bool IsLocked();
+ bool IsIntro();
+ bool WasRunning();
+ void SetIntro(bool b);
+
+ // Stats
+ int GetStatWon(int no);
+ int GetStatGames(int no);
+ int GetStatAborted(int no);
+ int GetStatPoints(int no);
+
+ void WriteConfig(KConfig *config);
+ void ReadConfig(KConfig *config);
+
+ void SetInputHandler(KEInput *i);
+ KEInput *QueryInputHandler();
+ void InitMove(LSkatView *sender,int player,int x,int y);
+ int SwitchStartPlayer();
+ void UpdateViews(int mode);
+ bool IsServer();
+ void SetServer(bool b);
+ void SetHost(QString h);
+ void SetName(const QString& n);
+ void SetPort(short p);
+ QString QueryHost();
+ short QueryPort();
+ QString QueryName() const;
+ // Only for fast remote access
+ int *GetCardP();
+ int *GetCardHeightP();
+ void SetCard(int i,int c);
+ bool IsRemoteSwitch();
+ void SetRemoteSwitch(bool b);
+ QString GetProcess();
+ int LoadCards(QString path);
+ int LoadDeck(QString path);
+ bool SetCardDeckPath(QString deck,QString card);
+ QString GetDeckpath() {return deckPath;}
+ QString GetCardpath() {return cardPath;}
+ bool LoadGrafix(QString path);
+
+ protected:
+ void initrandom();
+ int LoadBitmap(QString path);
+
+public:
+ QPixmap mPixCard[NO_OF_CARDS];
+ QPixmap mPixTrump[NO_OF_TRUMPS];
+ QPixmap mPixDeck;
+ QPixmap mPixBackground;
+ QSize cardsize;
+ QPixmap mPixType[3];
+ QPixmap mPixAnim[NO_OF_ANIM];
+
+ private:
+ QString procfile;
+ QString picpath;
+ int delpath;
+ bool remoteswitch;
+ KEInput *inputHandler;
+ short port;
+ QString host;
+ QString Name;
+ bool server;
+ bool lock;
+ int startplayer;
+ int cardheight[16];
+ int card[NO_OF_CARDS];
+ int curmove[2];
+ int moveno;
+ int isrunning;
+ bool isintro;
+ bool wasgame;
+ int movestatus;
+ int currentplayer;
+ CCOLOUR trump;
+ QString names[2];
+ int score[2];
+ int laststartplayer;
+ int began_game;
+
+ KG_INPUTTYPE playedby[2];
+ int computerlevel;
+ int computerscore;
+
+ int stat_won[2]; // how many wins
+ int stat_points[2]; // how many points
+ int stat_games[2]; // how many games
+ int stat_brk[2]; // how many games aborted
+
+ int cardvalues[14];
+
+ public slots:
+ /** calls repaint() on all views connected to the document object and is called by the view by which the document has been changed.
+ * As this view normally repaints itself, it is excluded from the paintEvent.
+ */
+ void slotUpdateAllViews(LSkatView *sender);
+
+ public:
+ /** the list of the views currently connected to the document */
+ static QPtrList<LSkatView> *pViewList;
+
+ private:
+ /** the modified flag of the current document */
+ bool modified;
+ QString title;
+ QString absFilePath;
+ QString deckPath,cardPath;
+};
+
+#endif // LSKATDOC_H
diff --git a/lskat/lskat/lskatui.rc b/lskat/lskat/lskatui.rc
new file mode 100644
index 00000000..867f21c0
--- /dev/null
+++ b/lskat/lskat/lskatui.rc
@@ -0,0 +1,25 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="standard_containers" version="4">
+<MenuBar>
+ <Menu name="game" noMerge="1"><text>&amp;Game</text>
+ <Action name="new_game"/>
+ <Separator />
+ <Action name="end_game"/>
+ <Separator />
+ <Action name="clear_statistics"/>
+ <Action name="send_message"/>
+ <Separator />
+ <Action name="game_exit"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="show_statusbar" append="show_merge"/>
+ <Action name="startplayer" append="save_merge"/>
+ <Action name="player1" append="save_merge"/>
+ <Action name="player2" append="save_merge"/>
+ <Action name="choose_level" append="save_merge"/>
+ <Action name="select_carddeck" append="save_merge"/>
+ <Action name="change_names" append="save_merge"/>
+ </Menu>
+</MenuBar>
+<StatusBar/>
+</kpartgui>
diff --git a/lskat/lskat/lskatview.cpp b/lskat/lskat/lskatview.cpp
new file mode 100644
index 00000000..c14d5cee
--- /dev/null
+++ b/lskat/lskat/lskatview.cpp
@@ -0,0 +1,934 @@
+/***************************************************************************
+ lskatview.cpp - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for Qt
+#include <qpixmap.h>
+#include <qcolor.h>
+#include <qrect.h>
+#include <qfontmetrics.h>
+#include <qpoint.h>
+#include <qstring.h>
+#include <qpainter.h>
+#include <qdatetime.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <math.h>
+#include <stdio.h>
+#include <kglobalsettings.h>
+
+
+// application specific includes
+#include "lskatview.h"
+#include "lskatdoc.h"
+#include "lskat.h"
+#include "KEInput.h"
+#include "KEMessage.h"
+
+#define CARD_X_OFFSET 32 // offset fromleft side
+#define CARD_Y_OFFSET 5 // offset from top
+#define CARD_X_SPACE 10 // space between cards
+#define CARD_Y_SPACE 5 // space between cards
+#define CARD_Y_BOARD_OFFSET 20 // space between players
+
+#define CARD_X_DECK 5 // shift deck and card
+#define CARD_Y_DECK 3 // shift deck and card
+
+#define CARD_X_MOVE1 430 // positon of first moved card
+#define CARD_Y_MOVE1 140
+#define CARD_X_MOVE2 450 // psoiton of second moved card
+#define CARD_Y_MOVE2 190
+
+// Probably most unnecessary and unused now
+#define STATUS_X0 15 // pos in status win
+#define STATUS_X1 60
+#define STATUS_X2 100
+#define STATUS_Y0 26
+#define STATUS_Y1 44
+#define STATUS_Y2 62
+#define STATUS_Y3 80
+#define STATUS_XT 128
+#define STATUS_YT 47
+#define STATUS_XTYPE 135
+#define STATUS_YTYPE 12
+
+#define FINAL_XT1 15
+#define FINAL_XT2 -55
+#define FINAL_YT 15
+
+#define FINAL_X0 140
+#define FINAL_Y0 35
+
+#define FINAL_X1 110
+#define FINAL_Y1 90
+
+#define FINAL_X2 130
+#define FINAL_Y2 65
+
+#define FINAL_X3 30
+#define FINAL_X4 90
+#define FINAL_X5 170
+#define FINAL_X6 230
+
+#define FINAL_Y3 95
+#define FINAL_Y4 125
+
+#define FINAL_X7 30
+#define FINAL_Y7 155
+
+//#define COL_STATUSLIGHT white
+#define COL_STATUSBORDER black
+//#define COL_STATUSFIELD QColor(192,192,192)
+//#define COL_STATUSDARK QColor(65,65,65)
+#define COL_STATUSFIELD QColor(130,130,255)
+#define COL_STATUSDARK QColor(0,0,65)
+#define COL_STATUSLIGHT QColor(210,210,255)
+#define COL_PLAYER QColor(255,255,0)
+
+#define DLGBOXTITLE TITLE
+
+#define MOVECOUNTER 20 // so many moves when playing card
+#define MOVE_TIMER_DELAY 7 // timer in milllisec default 7
+
+LSkatView::LSkatView(QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ setBackgroundMode(PaletteBase);
+ // setBackgroundMode(NoBackground);
+
+ status_rect1=QRect(412,CARD_Y_OFFSET+5,180,95+25);
+ status_rect2=QRect(412,310,180,95+25);
+ status_rect3=QRect(CARD_X_OFFSET+60,CARD_Y_OFFSET+5+100+15+20,
+ 400,320-100-CARD_Y_OFFSET-30);
+
+ setBackgroundColor(QColor(0,0,128));
+ setBackgroundPixmap( getDocument()->mPixBackground );
+
+ moveTimer=new QTimer(this);
+ moveTimer->stop();
+ connect(moveTimer,SIGNAL(timeout()),this,SLOT(moveTimerReady()));
+
+ introcnt=0;
+ introTimer=new QTimer(this);
+ introTimer->stop();
+ connect(introTimer,SIGNAL(timeout()),this,SLOT(introTimerReady()));
+ introTimer->start(75,FALSE);
+
+ for (int i=0;i<NO_OF_CARDS;i++)
+ {
+ introCards[i]=getDocument()->random(NO_OF_CARDS);
+ }
+}
+
+// Access the document with the game data
+LSkatDoc *LSkatView::getDocument() const
+{
+ LSkatApp *theApp=(LSkatApp *) parentWidget();
+ return theApp->getDocument();
+}
+
+// draw a border around a rect
+// p: Painter
+// rect: The rect to draw a border
+// offset: An offset to the rect to make it smaller
+// width: The width of the border
+// mode: 0: Light border, 1: dark border
+void LSkatView::drawBorder(QPainter *p,QRect rect,int offset,int width,int mode)
+{
+QPen graypen;
+int i;
+QPoint p1,p2;
+
+ if (mode!=0 && mode!=1) return;
+
+ p1=rect.topLeft();
+ p2=rect.bottomRight();
+
+ if (mode==0) p->setPen(COL_STATUSLIGHT);
+ else if (mode==1) p->setPen(COL_STATUSDARK);
+
+ for (i=0;i<width;i++)
+ {
+ p->moveTo(p1.x()+offset+i,p2.y()-offset-i);
+ p->lineTo(p1.x()+offset+i,p1.y()+offset+i);
+ p->lineTo(p2.x()-offset-i,p1.y()+offset+i);
+ }
+ if (mode==1) p->setPen(COL_STATUSLIGHT);
+ else if (mode==0) p->setPen(COL_STATUSDARK);
+ for (i=0;i<width;i++)
+ {
+ p->moveTo(p1.x()+offset+i,p2.y()-offset-i);
+ p->lineTo(p2.x()-offset-i,p2.y()-offset-i);
+ p->lineTo(p2.x()-offset-i,p1.y()+offset+i);
+ }
+}
+
+// draw a move by animating the movment and turning of the
+// card. This is called until the card reaches its final
+// position
+void LSkatView::drawMove(QPainter *p)
+{
+ int m1,m2;
+ int below;
+ QPoint point1,point2;
+
+ m1=getDocument()->GetMove(0);
+ m2=getDocument()->GetMove(1);
+ point1=QPoint(CARD_X_MOVE1,CARD_Y_MOVE1);
+ point2=QPoint(CARD_X_MOVE2,CARD_Y_MOVE2);
+
+ below=getDocument()->GetLastStartPlayer();
+ if (below<0) below=getDocument()->GetStartPlayer();
+
+ if (below==0)
+ {
+ if (m1>=0) p->drawPixmap(point1,getDocument()->mPixCard[m1]);
+ if (m2>=0) p->drawPixmap(point2,getDocument()->mPixCard[m2]);
+ }
+ else
+ {
+ if (m2>=0) p->drawPixmap(point2,getDocument()->mPixCard[m2]);
+ if (m1>=0) p->drawPixmap(point1,getDocument()->mPixCard[m1]);
+ }
+
+ int card;
+ QPoint point;
+ card=getDocument()->GetMoveStatus();
+ if (card>=0)
+ {
+
+ if (cardmoveunder>=0)
+ {
+ // turn new card
+ if ((double)cardmovecnt/(double)MOVECOUNTER>0.5)
+ {
+ QPixmap pix1(getDocument()->mPixCard[cardmoveunder]);
+ int wid=pix1.width();
+ QWMatrix m;
+ m.scale(2.0*((double)cardmovecnt/(double)MOVECOUNTER-0.5),1.0);
+ pix1=pix1.xForm(m);
+ point=QPoint((wid-pix1.width())/2,0);
+ p->drawPixmap(cardorigin+point,pix1);
+ }
+ // turn deck
+ else
+ {
+ QPixmap pix1(getDocument()->mPixDeck);
+ int wid=pix1.width();
+ QWMatrix m;
+ m.scale(1.0-2.0*((double)cardmovecnt/(double)MOVECOUNTER),1.0);
+ pix1=pix1.xForm(m);
+ point=QPoint((wid-pix1.width())/2,0);
+ p->drawPixmap(cardorigin+point,pix1);
+ }
+ } /* end turn card */
+
+ point=cardorigin+(cardend-cardorigin)*cardmovecnt/MOVECOUNTER;
+ p->drawPixmap(point,getDocument()->mPixCard[card]);
+
+ }
+}
+
+// Show the intro (Cards+Text)
+// This is called repeatetly
+void LSkatView::drawIntro(QPainter *p)
+{
+ int i,c1,c2,x,cnt,y,col,col2,col3,col4;
+ // The window width;
+ // int win_width = p->window().width();
+ QPoint point,point1,p2;
+ QString s;
+ // Get a nice font
+ QFont font = KGlobalSettings::generalFont();
+ font.setPointSize(48);
+ // Get the font info to determine text sizes
+ QFontMetrics fontMetrics(font);
+
+ p->setFont(font);
+
+ cnt=introcnt;
+ if (cnt>NO_OF_CARDS) cnt=NO_OF_CARDS;
+
+
+ i=0;
+ point=QPoint(20,20);
+ point1=QPoint(550,20);
+
+ for (i=0;i<cnt;i++)
+ {
+ x=(int)((i+10)*5*sin(1.5*i*M_PI/(float)NO_OF_CARDS));
+ c1=introCards[i];
+ c2=introCards[(i+17)%NO_OF_CARDS];
+ p2=QPoint(i*10+x, i*10);
+ p->drawPixmap(point+p2,getDocument()->mPixCard[c1]);
+ p2=QPoint(-i*10-x, i*10);
+ p->drawPixmap(point1+p2,getDocument()->mPixCard[c2]);
+ }
+
+ // All text are positioned that they end up at x=310-textwidth/2
+ // All texts are drawn twice with different colors to produce a shadow
+ col=255-8*i;
+ if (col<0) col=0;
+ col2=2*col/3;
+ col3=255-2*i;
+ col4=2*col3/3;
+ s=i18n("Lieutenant Skat");
+ x=310-fontMetrics.width(s)/2;
+ y=-20+(int)(200.0*sin(0.5*M_PI/(float)NO_OF_CARDS*cnt));
+ p->setPen(QColor(col4,col2,0));
+ p->drawText(x-2,y+2,s);
+
+ p->setPen(QColor(col3,col,0));
+ p->drawText(x,y,s);
+
+ s=i18n("for");
+ y=270+(NO_OF_CARDS-cnt)*3;
+ x=-fontMetrics.width(s)/2+(int)(310.0*sin(0.5*M_PI/(float)NO_OF_CARDS*cnt));
+ p->setPen(QColor(col4,col2,0));
+ p->drawText(x-2,y+2,s);
+
+ p->setPen(QColor(col3,col,0));
+ p->drawText(x,y,s);
+
+ s=i18n("K D E");
+ y=350+(NO_OF_CARDS-cnt)*3;
+ // x=640-(int)(380.0*sin(0.5*M_PI/(float)NO_OF_CARDS*cnt));
+ x=570-fontMetrics.width(s)/2-(int)(260.0*sin(0.5*M_PI/(float)NO_OF_CARDS*cnt));
+ p->setPen(QColor(col4,col2,0));
+ p->drawText(x-2,y+2,s);
+
+ p->setPen(QColor(col3,col,0));
+ p->drawText(x,y,s);
+}
+
+// Draw all cards to create the game board
+void LSkatView::drawDeck(QPainter *p)
+{
+ int x,y,card;
+ int player,pos,height;
+ QPoint point;
+
+ for (y=0;y<4;y++)
+ {
+ if (y<2) player=0;
+ else player=1;
+
+ for (x=0;x<4;x++)
+ {
+ pos=x+4*(y%2);
+
+ point=calcCardPos(x,y);
+ if (getDocument()->IsRunning())
+ {
+ height=getDocument()->GetHeight(player,pos);
+ card=getDocument()->GetCard(player,pos,height);
+
+
+ if (height==2)
+ p->drawPixmap(point-QPoint(CARD_X_DECK,CARD_Y_DECK),getDocument()->mPixDeck);
+
+ if (cardmovecnt<1 || x!=cardmovex || y!=cardmovey)
+ {
+ if (height>0 ) p->drawPixmap(point,getDocument()->mPixCard[card]);
+ }
+ else
+ {
+ // moved to drawMove
+ // if (height>0 ) p->drawPixmap(point,getDocument()->mPixDeck);
+ }
+ }
+ else
+ {
+ p->drawPixmap(point,getDocument()->mPixDeck);
+ }
+ }
+ }
+}
+// Draw the winner field
+void LSkatView::drawFinal(QPainter *p)
+{
+ int sc1,sc0,pt0,pt1;
+ //QPoint p1,p2;
+ int trump;
+ //QRect r;
+ QString ld;
+ int ts[10];
+
+ QFont font24 = KGlobalSettings::generalFont();
+ font24.setPointSize(24);
+ QFont font14 = KGlobalSettings::generalFont();
+ font14.setPointSize(13);
+
+ //p1=status_rect3.topLeft();
+ //p2=status_rect3.bottomRight();
+
+ sc0=getDocument()->GetScore(0);
+ sc1=getDocument()->GetScore(1);
+
+ if (sc0>=120) pt0=4;
+ else if (sc0>=90) pt0=3;
+ else if (sc0>60) pt0=2;
+ else if (sc0==60) pt0=1;
+ else pt0=0;
+ if (sc1>=120) pt1=4;
+ else if (sc1>=90) pt1=3;
+ else if (sc1>60) pt1=2;
+ else if (sc1==60) pt1=1;
+ else pt1=0;
+
+
+ trump=getDocument()->GetTrump();
+
+
+
+ QString line1,line2,line3,line4,line5;
+ QString col1_3,col2_3,col3_3,col4_3;
+ QString col1_4,col2_4,col3_4,col4_4;
+ QRect sumrect;
+ QRect rect;
+ QRect brect1,brect2,brect3,brect4,brect5;
+ QRect brect1_3,brect2_3,brect3_3,brect4_3;
+ QRect brect1_4,brect2_4,brect3_4,brect4_4;
+
+ // Calculate geometry
+ line1=i18n("Game over");
+ rect=p->window();
+ //rect1.moveBy(0,FINAL_Y0-24);
+ p->setFont(font24);
+ brect1=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line1);
+ //QRect wrect=p->window();
+ sumrect=brect1;
+
+ if (sc0+sc1!=120) // aborted
+ {
+ line2=i18n("Game was aborted - no winner");
+ int hp=getDocument()->mPixTrump[trump].height()+5;
+ rect=QRect(0,hp>sumrect.height()?hp:sumrect.height(),p->window().width(),p->window().height());
+ p->setFont(font14);
+ brect2=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line2);
+ sumrect|=brect2;
+ }
+ else
+ {
+ if (sc0==sc1)
+ {
+ line2=i18n(" Game is drawn");
+ }
+ else if (sc0>sc1)
+ {
+ line2=i18n("Player 1 - %1 won ").arg(getDocument()->GetName(0));
+ }
+ else
+ {
+ line2=i18n("Player 2 - %1 won ").arg(getDocument()->GetName(1));
+ }
+ int hp=getDocument()->mPixTrump[trump].height()+5;
+ rect=QRect(0,hp>sumrect.height()?hp:sumrect.height(),p->window().width(),p->window().height());
+ p->setFont(font14);
+ brect2=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line2);
+ sumrect|=brect2;
+
+ p->setFont(font14);
+ col1_3=i18n("Score:");
+ col1_4=QString(" ");
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect1_3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col1_3);
+ ts[0]=brect1_3.width()+10;
+
+ col2_3=getDocument()->GetName(0);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect2_3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col2_3);
+
+ col2_4=getDocument()->GetName(1);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect2_4=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col2_4);
+ rect=brect2_3|brect2_4;
+ ts[1]=ts[0]+rect.width()+10;
+
+
+ col3_3.sprintf("%d",sc0);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect3_3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col3_3);
+
+ col3_4.sprintf("%d",sc1);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect3_4=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col3_4);
+ rect=brect3_3|brect3_4;
+ ts[2]=ts[1]+rect.width()+30;
+
+ col4_3=i18n("%1 points").arg(pt0);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect4_3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col4_3);
+
+ col4_4=i18n("%1 points").arg(pt1);
+ rect=QRect(0,0,p->window().width(),p->window().height());
+ brect4_4=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,col4_4);
+
+ rect=brect4_3|brect4_4;
+ ts[3]=ts[2]+rect.width()+10;
+ ts[4]=0;
+
+ line3=col1_3+QString("\t")+col2_3+QString("\t")+col3_3+QString("\t")+col4_3;
+ line4=col1_4+QString("\t")+col2_4+QString("\t")+col3_4+QString("\t")+col4_4;
+ brect3=QRect(sumrect.left(),sumrect.bottom()+10,ts[3],brect4_3.height());
+ brect4=QRect(sumrect.left(),sumrect.bottom()+10+brect4_3.height()+6,ts[3],brect4_4.height());
+ sumrect|=brect3;
+ sumrect|=brect4;
+
+
+ p->setFont(font14);
+ if (sc0>=120)
+ {
+ line5=i18n("%1 won to nil. Congratulations!").arg(getDocument()->GetName(0));
+ rect=QRect(0,sumrect.height()+10,p->window().width(),p->window().height());
+ brect5=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line5);
+ sumrect|=brect5;
+ }
+ else if (sc0>=90)
+ {
+ if (sc0==90)
+ line5=i18n("%1 won with 90 points. Super!").arg(getDocument()->GetName(0));
+ else
+ line5=i18n("%1 won over 90 points. Super!").arg(getDocument()->GetName(0));
+ rect=QRect(0,sumrect.height()+10,p->window().width(),p->window().height());
+ brect5=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line5);
+ sumrect|=brect5;
+ }
+ if (sc1>=120)
+ {
+ line5=i18n("%1 won to nil. Congratulations!").arg(getDocument()->GetName(1));
+ rect=QRect(0,sumrect.height()+10,p->window().width(),p->window().height());
+ brect5=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line5);
+ sumrect|=brect5;
+ }
+ else if (sc1>=90)
+ {
+ if (sc1==90)
+ line5=i18n("%1 won with 90 points. Super!").arg(getDocument()->GetName(1));
+ else
+ line5=i18n("%1 won over 90 points. Super!").arg(getDocument()->GetName(1));
+ rect=QRect(0,sumrect.height()+10,p->window().width(),p->window().height());
+ brect5=p->boundingRect(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line5);
+ sumrect|=brect5;
+ }
+ }
+
+
+ QPoint offset=QPoint(status_rect3.left()-sumrect.left(),status_rect3.top());
+ sumrect.moveBy(offset.x(),offset.y());
+
+ // draw actual strings and symbols
+ QRect borderrect=QRect(sumrect.left()-20,sumrect.top()-20,sumrect.width()+40,sumrect.height()+40);
+ p->drawRect(borderrect);
+ drawBorder(p,borderrect,0,4,0);
+ drawBorder(p,borderrect,10,1,1);
+
+
+ p->setPen(black);
+ p->setFont(font24);
+ rect=sumrect;
+ rect.setTop(brect1.top()+offset.y());
+ //brect1.moveBy(offset.x(),offset.y());
+ p->drawText(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line1);
+
+ p->setFont(font14);
+ p->setPen(COL_PLAYER);
+ rect=sumrect;
+ rect.setTop(brect2.top()+offset.y());
+ //brect2.moveBy(offset.x(),offset.y());
+ p->drawText(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line2);
+
+ p->drawPixmap(sumrect.topLeft()+QPoint(-5,-5), getDocument()->mPixTrump[trump]);
+ p->drawPixmap(sumrect.topLeft()+QPoint(5,-5)+QPoint(sumrect.width()-getDocument()->mPixTrump[trump].width(),0),
+ getDocument()->mPixTrump[trump]);
+
+
+ if (!col1_3.isNull())
+ {
+ p->setTabArray(ts);
+ p->setFont(font14);
+ p->setPen(Qt::black);
+ rect=sumrect;
+ rect.setTop(brect3.top()+offset.y());
+
+ // Workaround for the next line where the ExpandTab crashes!!!
+ drawTabText(p,rect,line3,ts);
+ // p->drawText(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop|Qt::ExpandTabs,line3);
+ rect=sumrect;
+ rect.setTop(brect4.top()+offset.y());
+ // Workaround for the next line where the ExpandTab crashes!!!
+ drawTabText(p,rect,line4,ts);
+ // p->drawText(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop|Qt::ExpandTabs,line4);
+ }
+ if (!line5.isNull())
+ {
+ p->setFont(font14);
+ p->setPen(Qt::black);
+ rect=sumrect;
+ rect.setTop(brect5.top()+offset.y());
+ p->drawText(rect,Qt::AlignHCenter|Qt::SingleLine|Qt::AlignTop,line5);
+ }
+}
+
+// This function is just a workaround for the QT function drawText
+// with Qt::EXpandTAbs eanbled. For some strange reasons this crashes...
+void LSkatView::drawTabText(QPainter *p,QRect rect,QString s,int *ts)
+{
+ int lcnt=0;
+
+ // p->setPen(Qt::black);
+ // p->drawRect(rect);
+ while(s.length()>0 && (lcnt==0 || ts[lcnt-1]) )
+ {
+ int lpos=s.find("\t");
+ int rpos=s.length()-lpos-1;
+ if (lpos<0)
+ {
+ lpos=s.length();
+ rpos=0;
+ }
+ QString tmp=s.left(lpos);
+ s=s.right(rpos);
+ QRect rect2=rect;
+ if (lcnt>0)
+ rect2.setLeft(rect.left()+ts[lcnt-1]);
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,tmp);
+ lcnt++;
+ }
+}
+
+// Draw the status field at the right side
+void LSkatView::drawStatus(QPainter *p)
+{
+ QPoint p1,p2;
+ int trump;
+ QRect drawrect;
+ // For loop
+ QRect srect[2];
+ srect[0]=status_rect1;
+ srect[1]=status_rect2;
+
+ QFont font10 = KGlobalSettings::generalFont();
+ font10.setPointSize(13);
+ p->setFont(font10);
+
+ trump=getDocument()->GetTrump();
+
+
+ // draw text
+ QString ld;
+ QString line1,line2,line3,line4,line2a,line2b,line2c;
+ QRect sumrect,rect,rect2,brect1,brect2,brect3,brect4;
+ QPoint pa;
+
+ for (int pl=0;pl<2;pl++)
+ {
+ drawrect=QRect(srect[pl].left()+14,srect[pl].top()+14,srect[pl].width()-28,srect[pl].height()-28);
+ p1=drawrect.topLeft();
+ p2=drawrect.bottomRight();
+
+ // Draw border and field
+ p->setPen(COL_STATUSBORDER);
+ p->setBrush(COL_STATUSFIELD);
+ p->drawRect(srect[pl]);
+ drawBorder(p,srect[pl],0,4,0);
+ drawBorder(p,srect[pl],10,1,1);
+
+
+ // Player pl -------------------
+ // line1=QString(i18n("Player 1"))+QString(QCString(" - "))+getDocument()->GetName(0);
+ line1=getDocument()->GetName(pl);
+ brect1=p->boundingRect(drawrect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line1);
+ sumrect=brect1;
+
+ if (getDocument()->IsRunning())
+ {
+ // Geometry and strings
+ line2=i18n("Score:");
+ rect=QRect(drawrect.left(),sumrect.bottom()+16,drawrect.width(),drawrect.height()-sumrect.height());
+ brect2=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2);
+ sumrect|=brect2;
+ line3=i18n("Move:");
+ rect=QRect(drawrect.left(),sumrect.bottom()+10,drawrect.width(),drawrect.height()-sumrect.height());
+ brect3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line3);
+ sumrect|=brect3;
+
+ rect=brect2|brect3;
+ rect.setWidth(rect.width()+10);
+ line2a.sprintf("%3d",getDocument()->GetScore(pl));
+ line2b.sprintf("%3d",getDocument()->GetMoveNo());
+
+ // paint
+ if (getDocument()->GetStartPlayer()==pl) p->setPen(COL_PLAYER);
+ else p->setPen(black);
+ p->drawText(brect1,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line1);
+ p->setPen(black);
+ p->drawText(brect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2);
+ p->drawText(brect3,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line3);
+ rect2=QRect(brect2.left()+rect.width(),brect2.top(),drawrect.width()-brect2.width()-rect.width(),brect2.height());
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2a);
+ rect2=QRect(brect3.left()+rect.width(),brect3.top(),drawrect.width()-brect3.width()-rect.width(),brect3.height());
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2b);
+
+ pa=QPoint(drawrect.width()-getDocument()->mPixTrump[trump].width(),drawrect.height()-getDocument()->mPixTrump[trump].height());
+ if (getDocument()->GetStartPlayer()==pl)
+ p->drawPixmap(p1+pa+QPoint(3,3),getDocument()->mPixTrump[trump]);
+
+ pa=QPoint(drawrect.width()-getDocument()->mPixType[getDocument()->GetPlayedBy(pl)-1].width(),0);
+ p->drawPixmap(p1+pa+QPoint(3,-3), getDocument()->mPixType[getDocument()->GetPlayedBy(pl)-1]);
+ }
+ else // draw all time score
+ {
+ // Geometry and strings
+ line2=i18n("Points:");
+ rect=QRect(drawrect.left(),sumrect.bottom()+6,drawrect.width(),drawrect.height()-sumrect.height());
+ brect2=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2);
+ sumrect|=brect2;
+
+ line3=i18n("Won:");
+ rect=QRect(drawrect.left(),sumrect.bottom()+6,drawrect.width(),drawrect.height()-sumrect.height());
+ brect3=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line3);
+ sumrect|=brect3;
+
+ line4=i18n("Games:");
+ rect=QRect(drawrect.left(),sumrect.bottom()+6,drawrect.width(),drawrect.height()-sumrect.height());
+ brect4=p->boundingRect(rect,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line4);
+ sumrect|=brect4;
+
+ rect=brect2|brect3|brect4;
+ rect.setWidth(rect.width()+10);
+ line2a.sprintf("%d",getDocument()->GetStatPoints(pl));
+ line2b.sprintf("%d",getDocument()->GetStatWon(pl));
+ line2c.sprintf("%d",getDocument()->GetStatGames(pl));
+
+ // paint
+ p->setPen(COL_PLAYER);
+ p->drawText(brect1,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line1);
+ p->setPen(black);
+ p->drawText(brect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2);
+ p->drawText(brect3,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line3);
+ p->drawText(brect4,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line4);
+ rect2=QRect(brect2.left()+rect.width(),brect2.top(),drawrect.width()-brect2.width()-rect.width()+5,brect2.height());
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2a);
+ rect2=QRect(brect3.left()+rect.width(),brect3.top(),drawrect.width()-brect3.width()-rect.width()+5,brect3.height());
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2b);
+ rect2=QRect(brect4.left()+rect.width(),brect4.top(),drawrect.width()-brect4.width()-rect.width()+5,brect4.height());
+ p->drawText(rect2,Qt::AlignLeft|Qt::SingleLine|Qt::AlignTop,line2c);
+
+ pa=QPoint(drawrect.width()-getDocument()->mPixType[getDocument()->GetPlayedBy(pl)-1].width(),0);
+ p->drawPixmap(p1+pa+QPoint(3,-3), getDocument()->mPixType[getDocument()->GetPlayedBy(pl)-1]);
+
+ }
+
+ }// end pl
+}
+
+// paint function
+void LSkatView::Paint(QPainter *p)
+{
+ // If game is running
+ drawStatus(p);
+ drawDeck(p);
+ if (getDocument()->IsRunning())
+ {
+ drawMove(p);
+ }
+ else if (getDocument()->WasRunning() && !getDocument()->IsIntro())
+ {
+ drawFinal(p);
+ }
+}
+
+// paint event
+void LSkatView::paintEvent( QPaintEvent * e)
+{
+ if (getDocument()->IsIntro())
+ {
+ QPixmap pm(this->rect().size());
+ QPainter p;
+ QBrush brush;
+ p.begin(&pm,this);
+ brush.setPixmap( getDocument()->mPixBackground );
+ p.fillRect(0,0,this->rect().width(),this->rect().height(),brush);
+ drawIntro(&p);
+ p.end();
+ bitBlt(this,0,0,&pm);
+ }
+ else
+ {
+ QPainter paint( this );
+ paint.setClipRect(e->rect());
+ Paint( &paint );
+ }
+}
+
+
+// x=0..4, y=0..4
+QPoint LSkatView::calcCardPos(int x,int y)
+{
+ QPoint point;
+ point=QPoint(CARD_X_OFFSET+x*(CARD_X_SPACE+getDocument()->cardsize.width()),
+ CARD_Y_OFFSET+y*(CARD_Y_SPACE+getDocument()->cardsize.height()));
+ if (y>=2) point+=QPoint(0,CARD_Y_BOARD_OFFSET);
+ point+=QPoint(CARD_X_DECK,CARD_Y_DECK);
+ return point;
+}
+
+// mouse click event
+void LSkatView::mousePressEvent( QMouseEvent *mouse )
+{
+ if (mouse->button()!=LeftButton) return ;
+ if (!getDocument()->IsRunning()) return ;
+
+ if (getDocument()->GetMoveStatus()!=-1) return ;
+
+ QPoint point;
+ int mx,my,player;
+
+ point=mouse->pos();
+ point-=QPoint(CARD_X_OFFSET,CARD_Y_OFFSET);
+ if (point.y()>2*(getDocument()->cardsize.height()+CARD_Y_SPACE))
+ {
+ point-=QPoint(0,CARD_Y_BOARD_OFFSET+2*(getDocument()->cardsize.height()+CARD_Y_SPACE));
+ player=1;
+ }
+ else
+ {
+ player=0;
+ }
+ if (point.x()<0 || point.y()<0) return ;
+ mx=point.x()/(getDocument()->cardsize.width()+CARD_X_SPACE);
+ my=point.y()/(getDocument()->cardsize.height()+CARD_Y_SPACE);
+ if (mx>3 || my>1) return ;
+
+ if (global_debug>10)
+ printf("Type=%d Next=%d player=%d\n",
+ getDocument()->QueryInputHandler()->QueryType(player),
+ getDocument()->QueryInputHandler()->QueryNext(),player);
+ if (getDocument()->QueryInputHandler()->IsInteractive(player) &&
+ getDocument()->QueryInputHandler()->QueryNext()==player &&
+ !getDocument()->IsLocked())
+ {
+ KEMessage *msg=new KEMessage;
+ msg->AddData(QCString("Move"),(short)player);
+ msg->AddData(QCString("MoveX"),(short)mx);
+ msg->AddData(QCString("MoveY"),(short)my);
+ getDocument()->QueryInputHandler()->SetInput(msg);
+ delete msg;
+ }
+ else
+ {
+ QString m;
+ switch(getDocument()->random(4))
+ {
+ case 0:
+ m=i18n("Hold on... the other player hasn't been yet...");
+ break;
+ case 1:
+ m=i18n("Hold your horses...");
+ break;
+ case 2:
+ m=i18n("Ah ah ah... only one go at a time...");
+ break;
+ default:
+ m=i18n("Please wait... it is not your turn.");
+ }
+ KMessageBox::information(this,m);
+ }
+}
+
+
+void LSkatView::InitMove(int player,int mx,int my)
+{
+ cardmovex=mx;
+ cardmovey=my+2*player;
+ cardmoveunder=getDocument()->GetCard(player,mx+4*my,getDocument()->GetHeight(player,mx+4*my));
+ introTimer->stop();
+ moveTimer->start(MOVE_TIMER_DELAY,FALSE);
+ cardmovecnt=0;
+ cardorigin=calcCardPos(mx,my+2*player);
+ if (getDocument()->GetCurrentPlayer()==0)
+ cardend=QPoint(CARD_X_MOVE1,CARD_Y_MOVE1);
+ else cardend=QPoint(CARD_X_MOVE2,CARD_Y_MOVE2);
+ update(QRect(
+ cardorigin-QPoint(CARD_X_DECK,CARD_Y_DECK),
+ getDocument()->cardsize+QSize(CARD_X_DECK,CARD_Y_DECK)));
+
+ QPoint point1=QPoint(CARD_X_MOVE1,CARD_Y_MOVE1);
+ QPoint point2=QPoint(CARD_X_MOVE2,CARD_Y_MOVE2);
+ update(QRect(point1,getDocument()->cardsize));
+ update(QRect(point2,getDocument()->cardsize));
+}
+void LSkatView::introTimerReady()
+{
+ if (!getDocument()->IsIntro())
+ {
+ introTimer->stop();
+ return ;
+ }
+ introcnt++;
+ if (introcnt>NO_OF_CARDS*4)
+ {
+ introcnt=0;
+ for (int i=0;i<NO_OF_CARDS;i++)
+ {
+ introCards[i]=getDocument()->random(NO_OF_CARDS);
+ }
+ }
+ else if (introcnt<NO_OF_CARDS)
+ {
+ repaint(false);
+ }
+}
+
+void LSkatView::moveTimerReady()
+{
+ QPoint pos;
+ QString ld,s;
+ if (cardmovecnt>=MOVECOUNTER)
+ {
+ LSkatApp *m=(LSkatApp *) parentWidget();
+ moveTimer->stop();
+ cardmovecnt=0;
+ update(QRect(cardend,getDocument()->cardsize));
+ update(QRect(cardorigin,getDocument()->cardsize));
+ update(status_rect1);
+ update(status_rect2);
+ m->MoveFinished();
+
+ }
+ else
+ {
+ pos=cardorigin+(cardend-cardorigin)*cardmovecnt/MOVECOUNTER;
+ update(QRect(pos,getDocument()->cardsize));
+ cardmovecnt++;
+ pos=cardorigin+(cardend-cardorigin)*cardmovecnt/MOVECOUNTER;
+ update(QRect(pos,getDocument()->cardsize));
+ // Turning of the card
+ if ( cardmoveunder>=0)
+ {
+ update(QRect(cardorigin,getDocument()->cardsize));
+ }
+ }
+}
+
+void LSkatView::updateStatus()
+{
+ update(status_rect1);
+ update(status_rect2);
+}
+
+#include "lskatview.moc"
diff --git a/lskat/lskat/lskatview.h b/lskat/lskat/lskatview.h
new file mode 100644
index 00000000..05b31356
--- /dev/null
+++ b/lskat/lskat/lskatview.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+ lskatview.h - description
+ -------------------
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LSKATVIEW_H
+#define LSKATVIEW_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qwidget.h>
+#include <qrect.h>
+#include "lskat.h"
+
+class LSkatDoc;
+
+/** The LSkatView class provides the view widget for the LSkatApp instance.
+ * The View instance inherits QWidget as a base class and represents the view object of a KTMainWindow. As LSkatView is part of the
+ * docuement-view model, it needs a reference to the document object connected with it by the LSkatApp class to manipulate and display
+ * the document structure provided by the LSkatDoc class.
+ *
+ * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
+ * @version KDevelop version 0.4 code generation
+ */
+class LSkatView : public QWidget
+{
+ Q_OBJECT
+ public:
+ /** Constructor for the main view */
+ LSkatView(QWidget *parent = 0, const char *name=0);
+
+ /** returns a pointer to the document connected to the view instance. Mind that this method requires a LSkatApp instance as a parent
+ * widget to get to the window document pointer by calling the LSkatApp::getDocument() method.
+ *
+ * @see LSkatApp#getDocument
+ */
+ LSkatDoc *getDocument() const;
+
+ void paintEvent( QPaintEvent * p);
+ void Paint(QPainter *p);
+ void InitMove(int player,int x,int y);
+ void updateStatus();
+
+ protected:
+ void drawDeck(QPainter *p);
+ void drawIntro(QPainter *p);
+ void drawMove(QPainter *p);
+ void drawStatus(QPainter *p);
+ void drawFinal(QPainter *p);
+ void drawBorder(QPainter *p,QRect rect,int offset,int width,int mode);
+ QPoint calcCardPos(int x,int y);
+
+ void mousePressEvent ( QMouseEvent *m );
+
+ protected slots:
+ void moveTimerReady();
+ void introTimerReady();
+ void drawTabText(QPainter *p,QRect rect,QString s,int *ts);
+
+
+ private:
+ QRect status_rect1;
+ QRect status_rect2;
+ QRect status_rect3;
+ QTimer *moveTimer;
+ QTimer *introTimer;
+ int introcnt;
+ int cardmovecnt;
+ int cardmovex,cardmovey;
+ int cardmoveunder;
+ QPoint cardorigin;
+ QPoint cardend;
+ int introCards[NO_OF_CARDS];
+
+};
+
+#endif // LSKATVIEW_H
diff --git a/lskat/lskat/main.cpp b/lskat/lskat/main.cpp
new file mode 100644
index 00000000..50910540
--- /dev/null
+++ b/lskat/lskat/main.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ begin : Tue May 2 15:47:11 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include "lskat.h"
+
+static KCmdLineOptions options[] =
+{
+ { "d", 0, 0},
+ { "debug <level>", I18N_NOOP("Enter debug level"), 0 },
+ KCmdLineLastOption
+};
+
+int global_debug;
+
+int main(int argc, char *argv[])
+{
+
+ global_debug=0;
+ KAboutData aboutData( "lskat", I18N_NOOP("Lieutenant Skat"),
+ "1.0",
+ I18N_NOOP("Card Game"),
+ KAboutData::License_GPL,
+ "(c) 2000, Martin Heni");
+ aboutData.addAuthor("Martin Heni",0, "martin@heni-online.de");
+ aboutData.addCredit("Laura", I18N_NOOP("Beta testing"), 0);
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+
+ /* command line handling */
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if (args->isSet("debug"))
+ {
+ QString s = args->getOption("debug");
+ global_debug = s.toInt();
+ qDebug("Debug level set to %d\n", global_debug);
+ }
+ args->clear();
+
+ KApplication app;
+
+ if (app.isRestored())
+ {
+ RESTORE(LSkatApp);
+ }
+ else
+ {
+ LSkatApp *lskat = new LSkatApp();
+ lskat->show();
+ }
+
+ return app.exec();
+}
diff --git a/lskat/lskat/msgdlg.cpp b/lskat/lskat/msgdlg.cpp
new file mode 100644
index 00000000..daea1dac
--- /dev/null
+++ b/lskat/lskat/msgdlg.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ Msgdlg - Send message to remote
+ -------------------
+ begin : Thu Mar 30 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ Msgdlg.cpp
+
+ $Id$
+
+ Msg dialog for player names
+
+ (c) Martin Heni, martin@heni-online.de
+ June 1999
+
+ License: GPL
+
+*/
+
+#include <qgroupbox.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include "msgdlg.h"
+
+
+
+// Create the dialog for changing the player names
+MsgDlg::MsgDlg( QWidget *parent, const char *name,const char * /*sufi */ )
+ : QDialog( parent, name,TRUE )
+{
+ setCaption(i18n("Send Message to Remote Player"));
+ setMinimumSize(400,160);
+ setMaximumSize(600,360);
+ resize( 400, 160 );
+
+ QGroupBox* grp;
+ grp = new QGroupBox(i18n("Enter Message"), this);
+ grp->resize(380,100);
+ grp->move(10,10);
+
+ MultiLine = new QMultiLineEdit( grp, "MLineEdit" );
+ MultiLine->setGeometry( 10, 20, 360, 70 );
+ MultiLine->setText(QCString("") );
+
+ QPushButton *PushButton;
+ PushButton = new QPushButton( i18n("Send" ), this, "PushButton_1" );
+ PushButton->setGeometry( 20, 120, 65, 30 );
+ connect( PushButton, SIGNAL(clicked()), SLOT(accept()) );
+ PushButton->setAutoRepeat( FALSE );
+
+ PushButton = new KPushButton( KStdGuiItem::cancel(), this, "PushButton_2" );
+ PushButton->setGeometry( 305, 120, 65, 30 );
+ connect( PushButton, SIGNAL(clicked()), SLOT(reject()) );
+ PushButton->setAutoRepeat( FALSE );
+}
+
+QString MsgDlg::GetMsg()
+{
+ return MultiLine->text();
+}
+
+#include "msgdlg.moc"
diff --git a/lskat/lskat/msgdlg.h b/lskat/lskat/msgdlg.h
new file mode 100644
index 00000000..614fa332
--- /dev/null
+++ b/lskat/lskat/msgdlg.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ LSKat for KDE
+ -------------------
+ begin : March 2000
+ copyright : (C) 1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef __MSGDLG_H_
+#define __MSGDLG_H_
+#include <qmultilineedit.h>
+#include <qstring.h>
+#include <qdialog.h>
+
+class MsgDlg : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ MsgDlg (QWidget* parent = NULL,const char* name = NULL,const char *sufi=NULL);
+ QString GetMsg();
+
+protected slots:
+
+protected:
+ QMultiLineEdit *MultiLine;
+
+
+
+};
+#endif
diff --git a/lskat/lskat/namedlg.cpp b/lskat/lskat/namedlg.cpp
new file mode 100644
index 00000000..478f5ea5
--- /dev/null
+++ b/lskat/lskat/namedlg.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+** Form implementation generated from reading ui file 'namedlg.ui'
+**
+** Created: Thu Nov 23 11:10:17 2000
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#include "namedlg.h"
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+#include <klocale.h>
+
+#define NAME_MAX_LEN 12
+
+/*
+ * Constructs a NameDlg which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+NameDlg::NameDlg( QWidget *parent, const char *name,bool /* modal */, WFlags /* fl */ )
+ : KDialogBase( Plain, i18n("Configure Names"), Ok|Cancel, Ok,
+ parent, name, true,true )
+
+{
+ QWidget *page = plainPage();
+ if ( !name ) setName( "NameDlg" );
+ resize( 252, 186 );
+// setCaption( i18n( "Configure Names" ) );
+ vbox = new QVBoxLayout( page,spacingHint() );
+ vbox->setSpacing( 6 );
+ vbox->setMargin( 11 );
+
+ hbox = new QHBoxLayout;
+ hbox->setSpacing( 6 );
+ hbox->setMargin( 0 );
+
+ player_names = new QGroupBox( page, "player_names" );
+ player_names->setTitle(i18n("Player Names") );
+ player_names->setColumnLayout(0, Qt::Vertical );
+ player_names->layout()->setSpacing( 0 );
+ player_names->layout()->setMargin( 0 );
+ vbox_2 = new QVBoxLayout( player_names->layout() );
+ vbox_2->setAlignment( Qt::AlignTop );
+ vbox_2->setSpacing( 6 );
+ vbox_2->setMargin( 11 );
+
+ vbox_3 = new QVBoxLayout;
+ vbox_3->setSpacing( 6 );
+ vbox_3->setMargin( 0 );
+
+ hbox_2 = new QHBoxLayout;
+ hbox_2->setSpacing( 6 );
+ hbox_2->setMargin( 0 );
+
+ text_player1 = new QLabel( player_names, "text_player1" );
+ text_player1->setText( i18n("Player 1:" ) );
+ hbox_2->addWidget( text_player1 );
+
+ edit_player1 = new QLineEdit( player_names, "edit_player1" );
+ edit_player1->setMaxLength( NAME_MAX_LEN );
+ QWhatsThis::add( edit_player1, i18n( "Enter a player's name" ) );
+
+ hbox_2->addWidget( edit_player1 );
+ vbox_3->addLayout( hbox_2 );
+
+ hbox_3 = new QHBoxLayout;
+ hbox_3->setSpacing( 6 );
+ hbox_3->setMargin( 0 );
+
+ text_player2 = new QLabel( player_names, "text_player2" );
+ text_player2->setText( i18n("Player 2:" ) );
+ hbox_3->addWidget( text_player2 );
+
+ edit_player2 = new QLineEdit( player_names, "edit_player2" );
+ edit_player2->setMaxLength( NAME_MAX_LEN );
+ QWhatsThis::add( edit_player2, i18n( "Enter a player's name" ) );
+ hbox_3->addWidget( edit_player2 );
+ vbox_3->addLayout( hbox_3 );
+ vbox_2->addLayout( vbox_3 );
+
+ // left
+ QSpacerItem* spacer_3 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ hbox->addItem( spacer_3 );
+
+ hbox->addWidget( player_names );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ hbox->addItem( spacer );
+
+ // top
+ QSpacerItem* spacer_4 = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ vbox->addItem( spacer_4 );
+
+ vbox->addLayout( hbox );
+ QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ vbox->addItem( spacer_2 );
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+NameDlg::~NameDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+// In and output the name strings
+void NameDlg::SetNames(QString n1, QString n2)
+{
+ edit_player1->setText( n1 );
+ edit_player2->setText( n2 );
+}
+void NameDlg::GetNames(QString &n1, QString &n2)
+{
+ n1=edit_player1->text( );
+ n1.truncate(NAME_MAX_LEN);
+ n2=edit_player2->text( );
+ n2.truncate(NAME_MAX_LEN);
+}
+
+#include "namedlg.moc"
diff --git a/lskat/lskat/namedlg.h b/lskat/lskat/namedlg.h
new file mode 100644
index 00000000..c5d3391a
--- /dev/null
+++ b/lskat/lskat/namedlg.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'namedlg.ui'
+**
+** Created: Thu Nov 23 11:10:15 2000
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#ifndef NAMEDLG_H
+#define NAMEDLG_H
+
+#include <kdialogbase.h>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+class NameDlg : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ NameDlg( QWidget* parent = 0, const char* name = 0, bool modal = TRUE, WFlags fl = 0 );
+ ~NameDlg();
+ void SetNames(QString n1,QString n2);
+ void GetNames(QString &n1,QString &n2);
+
+ QGroupBox* player_names;
+ QLabel* text_player1;
+ QLineEdit* edit_player1;
+ QLabel* text_player2;
+ QLineEdit* edit_player2;
+ QPushButton* PushButton1;
+ QPushButton* PushButton2;
+
+protected:
+ QHBoxLayout* hbox;
+ QHBoxLayout* hbox_2;
+ QHBoxLayout* hbox_3;
+ QHBoxLayout* hbox_4;
+ QVBoxLayout* vbox;
+ QVBoxLayout* vbox_2;
+ QVBoxLayout* vbox_3;
+};
+
+#endif // NAMEDLG_H
diff --git a/lskat/lskat/networkdlg.cpp b/lskat/lskat/networkdlg.cpp
new file mode 100644
index 00000000..f43a1fd9
--- /dev/null
+++ b/lskat/lskat/networkdlg.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ networkdlg.cpp - description
+ -------------------
+ copyright : (C) 2004 by Jakub Stachowski
+ email : qbast@go2.pl
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "networkdlg.h"
+#include <qspinbox.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qbuttongroup.h>
+#include <qwidgetstack.h>
+
+extern const char* LSKAT_SERVICE;
+
+// Create the dialog
+NetworkDlg::NetworkDlg( QWidget *parent, const char *name )
+ : NetworkDlgBase( parent, name, TRUE )
+{
+ browser = new DNSSD::ServiceBrowser(QString::fromLatin1(LSKAT_SERVICE));
+ connect(browser,SIGNAL(finished()),SLOT(gamesFound()));
+ browser->startBrowse();
+}
+
+NetworkDlg::~NetworkDlg()
+{
+ delete browser;
+}
+
+void NetworkDlg::SetHost(const QString& host)
+{
+ hostname->setText(host);
+}
+
+void NetworkDlg::SetName(const QString& name)
+{
+ serverName->setText(name);
+}
+QString NetworkDlg::QueryName() const
+{
+ return serverName->text();
+}
+
+void NetworkDlg::SetPort(unsigned short port)
+{
+ this->port->setValue(port);
+}
+
+void NetworkDlg::gamesFound()
+{
+ bool autoselect=false;
+ if (!clientName->count() && group->selectedId()==1) autoselect=true;
+ clientName->clear();
+ QStringList names;
+ QValueList<DNSSD::RemoteService::Ptr>::ConstIterator itEnd = browser->services().end();
+ for (QValueList<DNSSD::RemoteService::Ptr>::ConstIterator it = browser->services().begin();
+ it!=itEnd; ++it) names << (*it)->serviceName();
+ clientName->insertStringList(names);
+ if (autoselect && clientName->count()) gameSelected(0);
+}
+
+void NetworkDlg::gameSelected(int nr)
+{
+ if (nr>=browser->services().count() || nr<0) return;
+ DNSSD::RemoteService::Ptr srv = browser->services()[nr];
+ if (!srv->isResolved() && !srv->resolve()) return;
+ hostname->setText(srv->hostName());
+ port->setValue(srv->port());
+}
+
+unsigned short NetworkDlg::QueryPort() const
+{
+ return port->value();
+}
+
+QString NetworkDlg::QueryHost() const
+{
+ return hostname->text();
+}
+
+void NetworkDlg::toggleServerClient()
+{
+ stack->raiseWidget(group->selectedId());
+ if (group->selectedId()==1) {
+ gameSelected(clientName->currentItem());
+ hostname->setEnabled(true);
+ }
+ else {
+ hostname->setText(QString::null);
+ hostname->setEnabled(false);
+ }
+}
+
+#include "networkdlg.moc"
diff --git a/lskat/lskat/networkdlg.h b/lskat/lskat/networkdlg.h
new file mode 100644
index 00000000..fb180eeb
--- /dev/null
+++ b/lskat/lskat/networkdlg.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ networkdlg.h - description
+ -------------------
+ copyright : (C) 2004 by Jakub Stachowski
+ email : qbast@go2.pl
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef NETWORKDLG_H
+#define NETWORKDLG_H
+
+#include <qstring.h>
+#include <dnssd/servicebrowser.h>
+#include "networkdlgbase.h"
+
+
+class NetworkDlg : public NetworkDlgBase
+{
+ Q_OBJECT
+
+ public:
+ NetworkDlg(QWidget* parent=NULL, const char* name=NULL);
+ ~NetworkDlg();
+ void SetName(const QString& name);
+ void SetHost(const QString& host);
+ void SetPort(unsigned short port);
+ QString QueryName() const;
+ unsigned short QueryPort() const;
+ QString QueryHost() const;
+ protected:
+ virtual void toggleServerClient();
+ virtual void gameSelected(int nr);
+ private slots:
+ void gamesFound();
+ private:
+ DNSSD::ServiceBrowser* browser;
+};
+
+#endif // NETWORKDLG_H
+
diff --git a/lskat/lskat/networkdlgbase.ui b/lskat/lskat/networkdlgbase.ui
new file mode 100644
index 00000000..861c77f3
--- /dev/null
+++ b/lskat/lskat/networkdlgbase.ui
@@ -0,0 +1,306 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>NetworkDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>NetworkDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>218</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Network Options</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>group</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Play As</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>serverBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Server</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>clientBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Client</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidgetStack">
+ <property name="name">
+ <cstring>stack</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>serverPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>serverLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Game name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>serverName</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>serverName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>clientPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>clientLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Network games:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>clientName</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>clientName</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>hostLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Host:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>hostname</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>portLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>port</cstring>
+ </property>
+ <property name="maxValue">
+ <number>65000</number>
+ </property>
+ <property name="value">
+ <number>7432</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Choose a port to connect to</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>61</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>NetworkDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>clientName</sender>
+ <signal>activated(int)</signal>
+ <receiver>NetworkDlgBase</receiver>
+ <slot>gameSelected(int)</slot>
+ </connection>
+ <connection>
+ <sender>serverBtn</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>NetworkDlgBase</receiver>
+ <slot>toggleServerClient()</slot>
+ </connection>
+ <connection>
+ <sender>clientBtn</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>NetworkDlgBase</receiver>
+ <slot>toggleServerClient()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">toggleServerClient()</slot>
+ <slot access="protected">gameSelected(int nr)</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lskat/lskat/templates/cpp_template b/lskat/lskat/templates/cpp_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskat/templates/cpp_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
diff --git a/lskat/lskat/templates/header_template b/lskat/lskat/templates/header_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskat/templates/header_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
diff --git a/lskat/lskatproc/KChildConnect.cpp b/lskat/lskatproc/KChildConnect.cpp
new file mode 100644
index 00000000..0308a3f0
--- /dev/null
+++ b/lskat/lskatproc/KChildConnect.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ KChildConnect.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <stdio.h>
+#include "KChildConnect.h"
+
+#include "KChildConnect.moc"
+
+KChildConnect::KChildConnect()
+ : QObject(0,0)
+{
+ input_pending=false;
+ inputbuffer="";
+}
+
+KChildConnect::~KChildConnect()
+{
+}
+
+KR_STATUS KChildConnect::QueryStatus()
+{
+ return KR_OK;
+}
+
+// Communication with process
+bool KChildConnect::SendMsg(KEMessage *msg)
+{
+ QString sendstring=msg->ToString();
+ // Debug only
+ if (msg->HasKey(QCString("KLogSendMsg")))
+ {
+ char *p;
+ int size;
+ FILE *fp;
+ msg->GetData(QCString("KLogSendMsg"),p,size);
+ if (p && (fp=fopen(p,"a")) )
+ {
+ fprintf(fp,"------------------------------------\n");
+ fprintf(fp,"%s", sendstring.utf8().data());
+ fclose(fp);
+ }
+ }
+ // end debug only
+ return Send(sendstring);
+}
+
+// Send string to parent
+bool KChildConnect::Send(QString str)
+{
+ if (!str || str.length()<1) return true; // no need to send crap
+ printf("%s",str.latin1());
+ fflush(stdout);
+ return true;
+}
+
+void KChildConnect::Receive(QString input)
+{
+ // Cut out CR
+ int len,pos;
+ QString tmp;
+
+
+ // Call us recursive until there are no CR left
+ len=KEMESSAGE_CR.length();
+ pos=input.find(KEMESSAGE_CR);
+ if (pos>0)
+ {
+ tmp=input.left(pos);
+ if (tmp.length()>0) Receive(tmp); // CR free
+ input=input.right(input.length()-pos-len);
+ if (input.length()>0) Receive(input);
+ return ;
+ }
+
+// printf(" ---> KChildConnect::Receive: '%s'\n",(const char *)input);
+ if (input==QString(KEMESSAGE_HEAD) && !input_pending)
+ {
+ input_pending=true;
+ inputcache.clear();
+ return ;
+ }
+ if (!input_pending) return ; // ignore
+ if (input!=QString(KEMESSAGE_TAIL))
+ {
+ inputcache.append(input.latin1());
+ return;
+ }
+ input_pending=0;
+
+ KEMessage *msg=new KEMessage;
+ char *it;
+ for (it=inputcache.first();it!=0;it=inputcache.next())
+ {
+ msg->AddString(QCString(it));
+ }
+
+// printf("+- CHILDprocess:: GOT MESSAGE::Emmiting slotReceiveMsg\n");
+ emit signalReceiveMsg(msg,ID);
+
+ delete msg;
+}
+
+void KChildConnect::SetID(int id)
+{
+ ID=id;
+}
+int KChildConnect::QueryID()
+{
+ return ID;
+}
+
diff --git a/lskat/lskatproc/KChildConnect.h b/lskat/lskatproc/KChildConnect.h
new file mode 100644
index 00000000..9cad1a5d
--- /dev/null
+++ b/lskat/lskatproc/KChildConnect.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ KChildConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+#ifndef _KCHILDCONNECT_H_
+#define _KCHILDCONNECT_H_
+
+#include <qobject.h>
+#include <qstrlist.h>
+#include "KEMessage.h"
+
+
+class KChildConnect: public QObject
+{
+ Q_OBJECT
+
+ protected:
+ QStrList inputcache;
+ bool input_pending;
+ QString inputbuffer;
+ int ID;
+
+ public:
+ KChildConnect();
+ ~KChildConnect();
+ void Receive(QString input);
+ int QueryID();
+ void SetID(int id);
+
+ virtual bool SendMsg(KEMessage *msg);
+ virtual bool Send(QString str);
+ virtual KR_STATUS QueryStatus();
+
+ public slots:
+
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+#endif
diff --git a/lskat/lskatproc/KConnectTypes.h b/lskat/lskatproc/KConnectTypes.h
new file mode 100644
index 00000000..12e9561a
--- /dev/null
+++ b/lskat/lskatproc/KConnectTypes.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ KConnectTypes.h - description
+ -------------------
+ begin : Sun Apr 9 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KCONNECTTYPES_H_
+#define _KCONNECTTYPES_H_
+
+enum KGM_TYPE {KGM_TYPE_INVALID=0,KGM_TYPE_SHORT=1,KGM_TYPE_LONG=2,
+ KGM_TYPE_FLOAT=3,KGM_TYPE_DATA=4};
+
+enum KG_INPUTTYPE {
+ KG_INPUTTYPE_INVALID=0,
+ KG_INPUTTYPE_INTERACTIVE=1,
+ KG_INPUTTYPE_PROCESS=2,
+ KG_INPUTTYPE_REMOTE=3};
+
+enum KR_STATUS {
+ KR_NO_SOCKET=-2,
+ KR_WAIT_FOR_CLIENT=-1,
+ KR_INVALID=0,
+ // >0 OK
+ KR_OK=1,
+ KR_CLIENT=2,
+ KR_SERVER=3
+ };
+#endif
diff --git a/lskat/lskatproc/KEMessage.cpp b/lskat/lskatproc/KEMessage.cpp
new file mode 100644
index 00000000..db598573
--- /dev/null
+++ b/lskat/lskatproc/KEMessage.cpp
@@ -0,0 +1,326 @@
+/***************************************************************************
+ KEMessage.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "KEMessage.h"
+
+void KEMessage::AddEntry(QString key,KMessageEntry *entry)
+{
+ // printf(" AddingEntry: %s with data field %p\n",(char *)key,entry->QueryData());
+ if (!entry) return ;
+ dict.insert(key,entry);
+ keys.append(key.latin1());
+}
+
+void KEMessage::AddDataType(QString key,int size,const char *data,KGM_TYPE type)
+{
+// printf("AddDataType for %s size=%d\n",(const char *)key,size);
+ if (size<=0) return ;
+ KMessageEntry *entry=new KMessageEntry;
+ entry->SetType(type);
+ entry->CopyData(size,data);
+ AddEntry(key,entry);
+}
+
+void KEMessage::AddData(QString key,short data)
+{
+ AddDataType(key,sizeof(short),(char *)&data,KGM_TYPE_SHORT);
+}
+
+void KEMessage::AddData(QString key,long data)
+{
+ AddDataType(key,sizeof(long),(char *)&data,KGM_TYPE_LONG);
+}
+
+void KEMessage::AddData(QString key,float data)
+{
+ AddDataType(key,sizeof(float),(char *)&data,KGM_TYPE_FLOAT);
+}
+
+void KEMessage::AddData(QString key,const char *data,int size)
+{
+ if (size<0) size=strlen(data)+1; // +1 for 0 Byte
+ AddDataType(key,size,data,KGM_TYPE_DATA);
+}
+
+KGM_TYPE KEMessage::QueryType(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return (KGM_TYPE)0;
+ return entry->QueryType();
+}
+
+bool KEMessage::HasKey(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,short &s)
+{
+ short *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_SHORT) return false;
+ // printf("GetShortData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(short *)entry->QueryData();
+ s=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,long &l)
+{
+ long *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_LONG) return false;
+ result=(long *)entry->QueryData();
+ l=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,float &f)
+{
+ float *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_FLOAT) return false;
+ // printf("GetFloatData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(float *)entry->QueryData();
+ f=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,char * &c,int &size)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_DATA) return false;
+ c=entry->QueryData();
+ size=entry->QuerySize();
+ return true;
+}
+
+QString KEMessage::EntryToString(char *key,KMessageEntry *entry)
+{
+ QString s,tmp;
+ int size,i;
+ KGM_TYPE type;
+ char *data;
+ s=QCString("");
+ if (!entry) return s;
+ size=entry->QuerySize();
+ type=entry->QueryType();
+ data=entry->QueryData();
+
+ // Key
+ /*
+ tmp.sprintf("%s%s%d%s%d%s",
+ key,KEMESSAGE_SEP,
+ size,KEMESSAGE_SEP,
+ (int)type,KEMESSAGE_SEP);
+ */
+ tmp=QCString(key);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",size);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",(int)type);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+
+
+ // We ignore the type of data and process them all as
+ // byte sequence
+ for (i=0;i<size;i++)
+ {
+ // Convert to 4 bit value ... someone can improves
+ tmp.sprintf("%c%c",
+ 'a'+(data[i]&15),
+ 'a'+((data[i]>>4)&15));
+ s+=tmp;
+ }
+ s+=KEMESSAGE_CR;
+
+ return s;
+}
+
+QString KEMessage::StringToEntry(QString str,KMessageEntry *entry)
+{
+ int pos,oldpos,cnt,len;
+ QString key,size,type,data;
+ const char *p;
+ char *q;
+ char c;
+
+ len=KEMESSAGE_SEP.length();
+
+ if (!entry) return QString();
+ pos=str.find(KEMESSAGE_SEP,0);
+ if (pos<0) return QString(); // wrong format
+ key=str.left(pos);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ size=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ type=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ data=str.right(str.length()-pos-len);
+
+
+ cnt=size.toInt();
+ entry->SetType((KGM_TYPE)type.toInt());
+
+ // I hope this works with unicode strings as well
+ p=data.latin1();
+ q=(char *)calloc(data.length()/2,sizeof(char));
+ if (!q) return QString();
+ for(pos=0;pos<cnt;pos++)
+ {
+ if (pos*2+1>(int)data.length()) return QString(); // SEVERE ERROR
+ c=*(p+2*pos)-'a' | ((*(p+2*pos+1)-'a')<<4);
+ q[pos]=c;
+ }
+ entry->CopyData(cnt,q);
+
+ free(q);
+ return key;
+}
+
+QString KEMessage::ToString()
+{
+ QString s;
+ KMessageEntry *entry;
+ char *it;
+ s=KEMESSAGE_HEAD+KEMESSAGE_CR;
+ for (it=keys.first();it!=0;it=keys.next())
+ {
+ entry=dict.find(QCString(it));
+ s+=EntryToString(it,entry);
+ }
+ s+=KEMESSAGE_TAIL+KEMESSAGE_CR;
+ return s;
+}
+
+bool KEMessage::AddString(QString s)
+{
+ // break s into key,size and data
+ QString key;
+ KMessageEntry *entry=new KMessageEntry;
+ key=StringToEntry(s,entry);
+ if (!key) return false;
+ AddEntry(key,entry);
+ return true;
+}
+bool KEMessage::AddStringMsg(QString str)
+{
+ bool result;
+ QString data;
+ int pos,oldpos,len;
+
+ len=KEMESSAGE_CR.length();
+
+ pos=str.find(KEMESSAGE_CR);
+ if (pos<0) return false; // wrong format
+ if (str.left(pos)!=(KEMESSAGE_HEAD)) return false; // wrong message
+
+ do
+ {
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_CR,oldpos+len);
+ if (pos<0) return false; // wrong format
+ data=str.mid(oldpos+len,pos-oldpos-len);
+ if (data!=(KEMESSAGE_TAIL))
+ {
+ result=AddString(data);
+ if (!result) return false; // wrong format
+ }
+ }while(data!=(KEMESSAGE_TAIL));
+
+ return result;
+}
+
+void KEMessage::RemoveAll()
+{
+ keys.clear();
+ dict.clear();
+}
+
+void KEMessage::Remove(QString key)
+{
+ keys.remove(key.latin1());
+ dict.remove(key);
+}
+
+uint KEMessage::QueryNumberOfKeys()
+{
+ return keys.count();
+}
+QStrList *KEMessage::QueryKeys()
+{
+ return &keys;
+}
+
+KEMessage::~KEMessage()
+{
+ // printf("Deleteing KEMessage %p\n",this);
+}
+KEMessage::KEMessage()
+{
+ // printf("KEMessage construct %p\n",this);
+ dict.setAutoDelete(true);
+}
+KEMessage::KEMessage(KEMessage &msg)
+{
+ // printf("KEMessage copy constructor from %p to %p\n",&msg,this);
+ *this=msg;
+}
+KEMessage &KEMessage::operator=(KEMessage &msg)
+{
+ // KEMessage *newmsg=new KEMessage;
+ KMessageEntry *entry;
+ KMessageEntry *newentry;
+ char *it;
+ // printf("Assigning = KEMessage from %p to %p\n",&msg,this);
+ for (it=msg.keys.first();it!=0;it=msg.keys.next())
+ {
+ entry=msg.dict.find(QCString(it));
+ newentry=new KMessageEntry;
+ *newentry=*entry;
+ AddEntry(QCString(it),newentry);
+
+ }
+ // return *newmsg;
+ return *this;
+}
diff --git a/lskat/lskatproc/KEMessage.h b/lskat/lskatproc/KEMessage.h
new file mode 100644
index 00000000..0a1913cc
--- /dev/null
+++ b/lskat/lskatproc/KEMessage.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ KEMessage.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KEMESSAGE_H_
+#define _KEMESSAGE_H_
+
+#include <string.h>
+#include <qstring.h>
+#include <qstrlist.h>
+#include <qdict.h>
+#include "KMessageEntry.h"
+
+#define KEMESSAGE_HEAD QString(QCString("BEGIN_V1000"))
+#define KEMESSAGE_TAIL QString(QCString("END_V1000"))
+#define KEMESSAGE_CR QString(QCString("\n"))
+#define KEMESSAGE_SEP QString(QCString(":::"))
+
+class KEMessage
+{
+ private:
+ QStrList keys;
+ QDict<KMessageEntry> dict;
+
+ protected:
+ void AddEntry(QString key,KMessageEntry *entry);
+ public:
+ QStrList *QueryKeys();
+ uint QueryNumberOfKeys();
+ void AddDataType(QString key,int size,const char *data,KGM_TYPE type);
+ void AddData(QString key,short data);
+ void AddData(QString key,long data);
+ void AddData(QString key,float data);
+ void AddData(QString key,const char *data,int size=-1);
+ bool GetData(QString key,short &s);
+ bool GetData(QString key,long &l);
+ bool GetData(QString key,float &f);
+ bool GetData(QString key,char * &c,int &size);
+ bool HasKey(QString key);
+ void Remove(QString key);
+ KGM_TYPE QueryType(QString key);
+ QString ToString();
+ QString EntryToString(char *key,KMessageEntry *entry);
+ QString StringToEntry(QString str,KMessageEntry *entry);
+ bool AddString(QString s);
+ bool AddStringMsg(QString str);
+ void RemoveAll();
+ ~KEMessage();
+ KEMessage();
+ KEMessage(KEMessage &msg);
+ KEMessage &operator=(KEMessage &msg);
+};
+
+#endif
diff --git a/lskat/lskatproc/KInputChildProcess.cpp b/lskat/lskatproc/KInputChildProcess.cpp
new file mode 100644
index 00000000..a821aa7a
--- /dev/null
+++ b/lskat/lskatproc/KInputChildProcess.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ KInputChildProcess.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <qstring.h>
+
+#include "KInputChildProcess.h"
+#include "KInputChildProcess.moc"
+
+
+KInputChildProcess::~KInputChildProcess()
+{
+ delete buffer;
+ delete childConnect;
+}
+KInputChildProcess::KInputChildProcess(int size_buffer)
+ : QObject(0,0)
+{
+ buffersize=size_buffer;
+ if (buffersize<1) buffersize=1024;
+ buffer=new char[buffersize];
+ inputbuffer="";
+ terminateChild=false;
+}
+bool KInputChildProcess::exec()
+{
+ int pos;
+ QString s;
+
+ childConnect=new KChildConnect;
+ if (!childConnect) return false;
+ connect(childConnect,SIGNAL(signalReceiveMsg(KEMessage *,int)),
+ this,SLOT(slotReceiveMsg(KEMessage *,int)));
+ do
+ {
+ // Wait for input
+ if (feof(stdin))
+ {
+ sleep(1);
+ continue;
+ }
+
+ if (!fgets(buffer,buffersize,stdin) )
+ {
+ continue;
+ }
+ s=buffer;
+ s=inputbuffer+s;
+ // printf("ChildABC '%s'\n",(const char *)s);
+ // fflush(stdout);
+ pos=s.findRev(KEMESSAGE_CR);
+ if (pos<0)
+ {
+ inputbuffer=s;
+ }
+ else if (pos+KEMESSAGE_CR.length()==s.length())
+ {
+ // CR at the end...calling receive
+ childConnect->Receive(s);
+ }
+ else
+ {
+ inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length());
+ s=s.left(pos+KEMESSAGE_CR.length());
+ // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer);
+ childConnect->Receive(s);
+ }
+ }while(!terminateChild);
+ return true;
+}
+
+void KInputChildProcess::Terminate()
+{
+ terminateChild=true;
+}
+bool KInputChildProcess::IsTerminated()
+{
+ return terminateChild;
+}
+
+bool KInputChildProcess::ReceiveMsg(KEMessage *msg,int id)
+{
+ return false;
+}
+void KInputChildProcess::slotReceiveMsg(KEMessage *msg,int id)
+{
+ if (!ReceiveMsg(msg,id)) // made for virtual override
+ {
+ // otherwise emit signal
+ emit signalReceiveMsg(msg,id);
+ }
+}
+bool KInputChildProcess::SendMsg(KEMessage *msg)
+{
+ if (childConnect) return childConnect->SendMsg(msg);
+ return false;
+}
+
+
diff --git a/lskat/lskatproc/KInputChildProcess.h b/lskat/lskatproc/KInputChildProcess.h
new file mode 100644
index 00000000..b4694df5
--- /dev/null
+++ b/lskat/lskatproc/KInputChildProcess.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ KInputChildProcess.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KINPUTCHILDPROCESS_H_
+#define _KINPUTCHILDPROCESS_H_
+
+#include <qobject.h>
+#include "KEMessage.h"
+#include "KChildConnect.h"
+
+
+class KInputChildProcess : public QObject
+{
+ Q_OBJECT
+
+ private:
+ char *buffer;
+ QString inputbuffer;
+ int buffersize;
+ bool terminateChild;
+ protected:
+ KChildConnect *childConnect;
+
+ public:
+ KInputChildProcess(int size_buffer=4096);
+ ~KInputChildProcess();
+ bool exec();
+ virtual bool ReceiveMsg(KEMessage *msg,int id);
+ // Forward calls to childconnect
+ bool SendMsg(KEMessage *msg);
+ // Immediately kills child's exec !
+ void Terminate();
+ bool IsTerminated();
+
+
+ public slots:
+ void slotReceiveMsg(KEMessage *msg,int id);
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+
+#endif
diff --git a/lskat/lskatproc/KMessageEntry.cpp b/lskat/lskatproc/KMessageEntry.cpp
new file mode 100644
index 00000000..e91f645a
--- /dev/null
+++ b/lskat/lskatproc/KMessageEntry.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ KMessageEntry.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "KMessageEntry.h"
+
+
+void KMessageEntry::SetType(KGM_TYPE t)
+{
+ type=t;
+}
+
+KGM_TYPE KMessageEntry::QueryType()
+{
+ return type;
+}
+
+int KMessageEntry::QuerySize()
+{
+ return size;
+}
+
+char * KMessageEntry::QueryData()
+{
+ return data;
+}
+
+bool KMessageEntry::CopyData(int s,const char *c)
+{
+ if (s<1) return false;
+ data=(char *)calloc(s,1);
+ if (!data) return false;
+ // printf(" MessageEntry Copy Data to calloc %p\n",data);
+ memcpy(data,c,s);
+ size=s;
+ return true;
+}
+
+KMessageEntry::KMessageEntry()
+{
+ // printf("KMessageEntry construct %p\n",this);
+ size=0;
+ type=(KGM_TYPE)0;
+ data=(char *)0;
+}
+
+KMessageEntry::KMessageEntry(KMessageEntry &entry)
+{
+ // printf("KMessageEntry copy constructor from %p to %p\n",&entry,this);
+ *this=entry;
+}
+KMessageEntry &KMessageEntry::operator=(KMessageEntry &entry)
+{
+ // printf("KMessageEntry operator= from %p to %p\n",&entry,this);
+ SetType(entry.type);
+ CopyData(entry.size,entry.data);
+ return *this;
+}
+
+KMessageEntry::~KMessageEntry()
+{
+ // printf("MessageEntry destructor %p\n",this);
+ // printf(" MessageEntry free %p\n",data);
+ if (data) free(data);
+ data=(char *)0;
+}
+
diff --git a/lskat/lskatproc/KMessageEntry.h b/lskat/lskatproc/KMessageEntry.h
new file mode 100644
index 00000000..947ce1ff
--- /dev/null
+++ b/lskat/lskatproc/KMessageEntry.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ KMessageEntry.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KMESSAGEENTRY_H_
+#define _KMESSAGEENTRY_H_
+
+#include <string.h>
+#include "KConnectTypes.h"
+
+
+
+class KMessageEntry
+{
+ private:
+ int size;
+ KGM_TYPE type;
+ char *data;
+
+ public:
+ void SetType(KGM_TYPE t);
+ KGM_TYPE QueryType();
+ int QuerySize();
+ char *QueryData();
+ bool CopyData(int s,const char *c);
+ KMessageEntry();
+ KMessageEntry(KMessageEntry &entry);
+ KMessageEntry &operator=(KMessageEntry &entry);
+ ~KMessageEntry();
+};
+
+#endif
diff --git a/lskat/lskatproc/Makefile.am b/lskat/lskatproc/Makefile.am
new file mode 100644
index 00000000..4f99375b
--- /dev/null
+++ b/lskat/lskatproc/Makefile.am
@@ -0,0 +1,13 @@
+bin_PROGRAMS = lskatproc
+
+lskatproc_SOURCES = lskatproc.cpp KChildConnect.cpp KInputChildProcess.cpp KEMessage.cpp KMessageEntry.cpp main.cpp
+
+lskatproc_LDADD = $(LIB_KFILE)
+
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+
+METASOURCES = AUTO
+
+# the library search path.
+lskatproc_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/lskat/lskatproc/docs/Makefile.am b/lskat/lskatproc/docs/Makefile.am
new file mode 100644
index 00000000..271bd418
--- /dev/null
+++ b/lskat/lskatproc/docs/Makefile.am
@@ -0,0 +1,4 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/lskat/lskatproc/docs/en/Makefile.am b/lskat/lskatproc/docs/en/Makefile.am
new file mode 100644
index 00000000..271bd418
--- /dev/null
+++ b/lskat/lskatproc/docs/en/Makefile.am
@@ -0,0 +1,4 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/lskat/lskatproc/lskatproc.cpp b/lskat/lskatproc/lskatproc.cpp
new file mode 100644
index 00000000..c1fdcfba
--- /dev/null
+++ b/lskat/lskatproc/lskatproc.cpp
@@ -0,0 +1,596 @@
+/***************************************************************************
+ lskatproc.cpp - description
+ -------------------
+ begin : Sun Apr 9 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "lskatproc.h"
+
+#define MIN_TIME 1000 // usec
+
+// ------------ class game ---------------------------------
+lgame::lgame()
+{
+ int i;
+ for (i=0;i<14;i++) cardvalues[i]=0;
+ cardvalues[(int)Ace]=11;
+ cardvalues[(int)Ten]=10;
+ cardvalues[(int)King]=4;
+ cardvalues[(int)Queen]=3;
+ cardvalues[(int)Jack]=2;
+ curmove[0]=-1;
+ curmove[1]=-1;
+ score[0]=0;
+ score[1]=0;
+ level=0;
+ endgame=false;
+ for (i=0;i<NO_OF_CARDS;i++) played[i]=0;
+}
+
+lgame::lgame(lgame &game)
+{
+ *this=game;
+}
+
+lgame &lgame::operator=(lgame &game)
+{
+ int i;
+ currentplayer=game.currentplayer;
+ startplayer=game.startplayer;
+ trump=game.trump;
+ movenumber=game.movenumber;
+ score[0]=game.score[0];
+ score[1]=game.score[1];
+ curmove[0]=game.curmove[0];
+ curmove[1]=game.curmove[1];
+ for (i=0;i<NO_OF_CARDS;i++) played[i]=game.played[i];
+ for (i=0;i<NO_OF_CARDS;i++) card[i]=game.card[i];
+ for (i=0;i<16;i++) cardheight[i]=game.cardheight[i];
+ endgame=game.endgame;
+ level=game.level;
+ return *this;
+}
+
+int lgame::MakeMove(int c,int pos)
+{
+ int h;
+ curmove[currentplayer]=c;
+ h=GetHeight(currentplayer,pos);
+ if (currentplayer==startplayer)
+ {
+ movenumber++;
+ SetHeight(currentplayer,pos,h-1);
+ currentplayer=1-startplayer;
+ }
+ else
+ {
+ if (!LegalMove(curmove[startplayer],c)) return -1;
+ SetHeight(currentplayer,pos,h-1);
+ if (WonMove(curmove[startplayer],curmove[1-startplayer]))
+ {
+ // switch startplayer
+ startplayer=1-startplayer;
+ }
+ currentplayer=startplayer;
+ score[startplayer]+=CardValue(curmove[0]);
+ score[startplayer]+=CardValue(curmove[1]);
+
+ if (movenumber==NO_OF_TILES)
+ {
+ endgame=true;
+ return 2;
+ }
+ }
+ return 1;
+}
+
+void lgame::Init()
+{
+ int player,i,h,j,card;
+ // check what cards are played
+ for (player=0;player<2;player++)
+ {
+ for (i=0;i<8;i++)
+ {
+ h=GetHeight(player,i);
+ for (j=h;j<2;j++)
+ {
+ card=GetCard(player,i,j+1);
+ if (card>=0) played[card]=1;
+ }
+ }
+ }
+}
+
+// Add value of both cards to the score of startplayer
+void lgame::AddScore(int c1,int c2)
+{
+ score[startplayer]+=CardValue(c1);
+ score[startplayer]+=CardValue(c2);
+}
+// Switch the startplayer
+void lgame::SwitchStartplayer()
+{
+ startplayer=1-startplayer;
+}
+
+// pos=0..7, player=0..1
+void lgame::SetHeight(int player, int pos,int h)
+{
+ int i;
+ i=8*player+pos;
+ cardheight[i]=h;
+}
+bool lgame::LegalMove(int p1, int p2)
+{
+ CCOLOUR col1,col2,col3;
+ CCARD card1,card2,card3;
+ card1=(CCARD)((p1)/4);
+ col1=(CCOLOUR)((p1)%4);
+ card2=(CCARD)((p2)/4);
+ col2=(CCOLOUR)((p2)%4);
+
+ // force trump colour
+ if (card1==Jack) col1=trump;
+ if (card2==Jack) col2=trump;
+
+ // same colour always ok
+ if (col1==col2) return true;
+
+ // Search for same colour
+ bool flag=true;
+ for (int i=0;i<8;i++)
+ {
+ int h,c;
+ h=GetHeight(1-startplayer,i);
+ if (h==0) continue;
+ c=GetCard(1-startplayer,i,h);
+ card3=(CCARD)((c)/4);
+ col3=(CCOLOUR)((c)%4);
+ if (card3==Jack) col3=trump;
+
+ if (col3==col1)
+ {
+ flag=false;
+ break;
+ }
+ }
+ if (flag) return true;
+
+
+ return false;
+}
+int lgame::CardValue(int card)
+{
+ int card1;
+
+ card1=card/4;
+ return cardvalues[card1];
+}
+int lgame::WonMove(int c1,int c2)
+{
+ CCOLOUR col1,col2;
+ CCARD card1,card2;
+
+ card1=(CCARD)((c1)/4);
+ col1=(CCOLOUR)((c1)%4);
+ card2=(CCARD)((c2)/4);
+ col2=(CCOLOUR)((c2)%4);
+
+ // Two jacks
+ if (card1==Jack && card2==Jack)
+ {
+ if (col1<col2) return 0;
+ else return 1;
+ }
+ // One Jack wins always
+ if (card1==Jack) return 0;
+ if (card2==Jack) return 1;
+
+ // higher one wins if same colour
+ if (col1==col2)
+ {
+ if (card1==Ten)
+ {
+ if (card2==Ace) return 1;
+ else return 0;
+ }
+ if (card2==Ten)
+ {
+ if (card1==Ace) return 0;
+ return 1;
+ }
+
+ if ((int)card1<(int)card2) return 0;
+ return 1;
+ }
+ // trump wins
+ if (col1==trump) return 0;
+ if (col2==trump) return 1;
+
+ // first one wins
+ return 0;
+
+}
+// pos=0..7, height=2..1..(0 no card left), player=0..1
+int lgame::GetCard(int player, int pos,int height)
+{
+ int i;
+ if (height==0) return -1;
+ height=2-height;
+
+ i=NO_OF_TILES*player+8*height+pos;
+ return card[i];
+}
+
+
+
+// pos=0..7, player=0..1
+int lgame::GetHeight(int player, int pos)
+{
+ int i;
+ i=8*player+pos;
+ return cardheight[i];
+}
+
+// Returns a value for the given side
+// applies all rules
+int lgame::Subvalue(int side)
+{
+ int sc,card;
+ int i,h,c;
+ CCOLOUR col1;
+ CCARD card1;
+ int trum1;
+ int jack1;
+ int havecol[4];
+ bool haveten[4];
+ bool haveace[4];
+ bool havejack[4];
+
+ sc=0;
+ trum1=0;
+ for (i=0;i<4;i++)
+ {
+ havecol[i]=false;
+ haveten[i]=false;
+ haveace[i]=false;
+ havejack[i]=false;
+ }
+ jack1=0;
+ for (i=0;i<8;i++)
+ {
+ h=GetHeight(side,i);
+ c=GetCard(side,i,h);
+ if (c<0) continue;
+
+ card1=(CCARD)((c)/4);
+ col1=(CCOLOUR)((c)%4);
+
+ if (col1==trump) trum1++;
+ havecol[(int)col1]++;
+ if (card1==Ten)
+ {
+ haveten[(int)col1]=true;
+ }
+ else if (card1==Ace)
+ {
+ haveace[(int)col1]=true;
+ }
+ else if (card1==Jack)
+ {
+ havejack[(int)col1]=true;
+ jack1++;
+ }
+ if (col1!=trump)
+ {
+ if (card1==Seven) sc-=60;
+ if (card1==Eight) sc-=50;
+ if (card1==Nine) sc-=40;
+ if (card1==Queen) sc-=10;
+ }
+ }
+ for (i=0;i<4;i++)
+ {
+ if (havecol[i]==0 && i!=trump) sc+=1000;
+ if (havecol[i]>5) sc+=800;
+
+ if (haveten[i]&&havecol[i]<2)
+ {
+ card=8*i+Ace;
+ if (!played[card] && !haveace[i]) sc-=2500; // free ten
+ }
+ if (haveace[i]) sc+=1500; // ace
+ if (havejack[i])
+ {
+ if (trump==Grand) sc+=4000+300*(4-i);
+ else sc+=2700+100*(4-i);
+ }
+ }
+ // evaluate
+ sc+=trum1*2500;
+ if (trum1==0) sc-=7000;
+ else if (trum1==1) sc-=5000;
+ return sc;
+}
+
+int lgame::Value(int player)
+{
+ int sc;
+ sc=0;
+
+ // Someone won?
+ if (score[0]>90) sc+=90000;
+ else if (score[0]>60) sc+=70000;
+ else if (score[0]==60) sc+=40000;
+
+ if (score[1]>90) sc-=90000;
+ else if (score[1]>60) sc-=70000;
+ else if (score[1]==60) sc-=40000;
+
+ // Reward points
+ sc+=(score[0]-score[1])*650;
+
+ // Calulate cards
+ sc+=Subvalue(0);
+ sc-=Subvalue(1);
+
+ // random
+ sc+=random(500)-250;
+
+ if (player==1) return -sc;
+ return sc;
+}
+
+
+// -------------class lskatproc ----------------------------
+lskatproc::lskatproc()
+ : KInputChildProcess(4096)
+{
+
+ initrandom();
+}
+
+lskatproc::~lskatproc(){
+}
+
+
+
+bool lskatproc::ReceiveMsg(KEMessage* msg,int id)
+{
+// time_t timee,timea;
+short x,y;
+
+ SendDebug("Receiv Msg");
+ // end of process
+ if (msg->HasKey(QCString("Terminate")))
+ {
+ Terminate();
+ }
+ // Init of process
+ if (msg->HasKey(QCString("Init")))
+ {
+ // No init necessary
+ }
+ // Make a move
+ if (msg->HasKey(QCString("Cards")))
+ {
+ SendDebug("Process HasKey(Cards)");
+ // new game object
+ lgame game;
+ // extract data from message
+ game.ExtractGame(msg);
+ game.Init(); // must be AFTER ExtractGame
+
+ // Debug stuff only
+ sprintf(buf,"Trump=%d move=%d sc1=%d sc2=%d",
+ game.trump,game.curmove[1-game.currentplayer],game.score[0],game.score[1]);
+ SendDebug(buf);
+
+ if (game.currentplayer==0 && game.startplayer==0)
+ sprintf(buf,"+++ Computer ACTS as player ONE\n");
+ else if (game.currentplayer==0 && game.startplayer==1)
+ sprintf(buf,"+++ Computer REACTS as player ONE\n");
+ else if (game.currentplayer==1 && game.startplayer==1)
+ sprintf(buf,"+++ Computer ACTS as player TWO\n");
+ else
+ sprintf(buf,"+++ Computer REACTS as player TWO\n");
+ SendDebug(buf);
+
+ // fills data
+ x=0;y=0;
+ GetComputerMove(game,x,y,0);
+ sprintf(buf,"Computer move player=%d x=%d y=%d",game.currentplayer,x,y);
+ SendDebug(buf);
+
+
+ // report move
+ msg->RemoveAll();
+ msg->AddData(QCString("Move"),game.currentplayer);
+ msg->AddData(QCString("MoveX"),x);
+ msg->AddData(QCString("MoveY"),y);
+
+ //timee=time(0);
+ // Sleep a minimum amount to slow down moves
+ //if ( 1000*(timee-timea) < MIN_TIME) usleep((MIN_TIME-1000*(timee-timea)));
+ SendDebug("Sending move back to main");
+
+ if (!IsTerminated()) SendMsg(msg);
+ fflush(stdout); // I do not know why it is needed..send does it too?
+ }
+
+ return true;
+}
+
+
+/* --------------------------------------------------------------------------- */
+/* Computer Routinen */
+/* --------------------------------------------------------------------------- */
+
+// extract game from msg
+int lgame::ExtractGame(KEMessage *msg)
+{
+ int i;
+ short tmp;
+ char *p;
+ int size;
+
+ msg->GetData(QCString("Startplayer"),startplayer);
+ msg->GetData(QCString("CurrentPlayer"),currentplayer);
+ msg->GetData(QCString("Cards"),p,size);
+ msg->GetData(QCString("Level"),level);
+ level--; // start with level 0
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ card[i]=((int *)p)[i];
+ }
+ msg->GetData(QCString("Height"),p,size);
+ for (i=0;i<NO_OF_TILES;i++)
+ {
+ cardheight[i]=((int *)p)[i];
+ }
+ msg->GetData(QCString("Trump"),tmp);
+ trump=(CCOLOUR)tmp;
+ short mm;
+ msg->GetData(QCString("CurrentMove"),mm);
+ curmove[1-currentplayer]=(int)mm;
+ curmove[currentplayer]=-1;
+ msg->GetData(QCString("No"),movenumber);
+ msg->GetData(QCString("Sc1"),score[0]);
+ msg->GetData(QCString("Sc2"),score[1]);
+ return 1;
+}
+
+long lgame::random(long max)
+{
+double value;
+int r;
+ r=rand();
+ value=(double)((double)r*(double)max)/(double)RAND_MAX;
+ return (long)value;
+}
+
+void lskatproc::initrandom()
+{
+ srand( (unsigned)time( NULL ) ); // randomize
+}
+
+
+int lskatproc::GetComputerMove(lgame game,short &x,short &y,int rek)
+{
+ int i,maxvalue,maxmove,h,c;
+ //short oldscore;
+ bool startflag;
+ int startplayer;
+ int value;
+ lgame cgame;
+ char sbuf[100];
+ short mx,my;
+
+
+ for (i=0;i<2*rek;i++) sbuf[i]=' ';
+ sbuf[2*rek]=0;
+
+ x=0;
+ y=0;
+ if (game.currentplayer==game.startplayer) startflag=true;
+ else startflag=false;
+
+ startplayer=game.startplayer;
+
+ maxmove=0;
+ maxvalue=LOWERT;
+
+ sprintf(buf,"%s:Prepareing computer move (cur=%d) startflag=%d",
+ sbuf,game.currentplayer,startflag);
+ //SendDebug(buf);
+ for (i=0;i<8;i++)
+ {
+ sprintf(buf,"%s:Checking for card %d of player %d\n",sbuf,i,game.currentplayer);
+ // SendDebug(buf);
+ cgame=game;
+ h=cgame.GetHeight(cgame.currentplayer,i);
+ if (h<1)
+ {
+ sprintf(buf,"%s:i=%d:: no cards left",sbuf,i);
+ // SendDebug(buf);
+ continue; // no cards left
+ }
+ c=cgame.GetCard(cgame.currentplayer,i,h);
+ if (cgame.MakeMove(c,i)<0)
+ {
+ sprintf(buf,"%s:i=%d:: no legal move c1=%d c2=%d",
+ sbuf,i,cgame.curmove[cgame.startplayer],c);
+ // SendDebug(buf);
+ continue; // wrong card
+ }
+ if (!startflag) // we are second
+ {
+ sprintf(buf,"LEVEL %d %d",cgame.level,rek);
+ SendDebug(buf);
+ // Still recursion necessary and game not yet ended?
+ if (rek<2*cgame.level && !cgame.endgame)
+ {
+ // If we have the same startplayer the movesequence
+ // is not switched and we can take the negative value
+ // otherwise we play again, and have to take the poitiv value
+ if (cgame.startplayer==startplayer)
+ {
+ value=-GetComputerMove(cgame,mx,my,rek+1);
+ // if (value==-LOWERT) value=LOWERT; // no move possible
+ }
+ else
+ value=GetComputerMove(cgame,mx,my,rek+1);
+ }
+ else // evaluate position
+ {
+ value=cgame.Value(1-startplayer);
+ }
+ }
+ else // we are first player
+ {
+ // Alwayss the other player moves now
+ value=-GetComputerMove(cgame,mx,my,rek+1);
+ }
+
+ sprintf(buf,"%s:i=%d:: Value=%d",sbuf,i,value);
+ SendDebug(buf);
+
+ if (value>maxvalue)
+ {
+ maxvalue=value;
+ maxmove=i;
+ }
+ }
+ x=maxmove%4;
+ y=maxmove/4;
+ return maxvalue;
+}
+
+void lskatproc::SendDebug(const char *s)
+{
+ KEMessage *msg=new KEMessage;
+ msg->AddData(QCString("Debug"),s);
+// msg->AddData("KLogSendMsg","debug.log");
+// DEBUG
+// SendMsg(msg);
+// printf("%s\n",s);
+
+ delete msg;
+}
diff --git a/lskat/lskatproc/lskatproc.h b/lskat/lskatproc/lskatproc.h
new file mode 100644
index 00000000..b5840461
--- /dev/null
+++ b/lskat/lskatproc/lskatproc.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ lskatproc.h - description
+ -------------------
+ begin : Sun Apr 9 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef LSKATPROC_H
+#define LSKATPROC_H
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+#include "KInputChildProcess.h"
+
+/**
+ *@author Martin Heni
+ */
+
+
+
+#define LOWERT -999999999L
+#define SIEG_WERT 9999999L
+
+
+#define START_REK 1 // (0) 1:Nur Stellungsbewertung bei Level 1
+ // 0:Level 1 schon eine Rekursion
+
+typedef enum {Club=0,Spade=1,Heart=2,Diamond=3,Grand=4} CCOLOUR;
+typedef enum {Ace=0,King=1,Queen=2,Jack=3,Ten=4,Nine=5,Eight=6,Seven=7} CCARD;
+#define NO_OF_CARDS 32
+#define NO_OF_TILES 16
+#define NO_OF_TRUMPS 5
+
+class lgame
+{
+ public:
+ lgame();
+ lgame(lgame &game);
+ lgame &operator=(lgame &game);
+
+ int WonMove(int c1,int c2);
+ int CardValue(int card);
+ bool LegalMove(int p1, int p2);
+ void SetHeight(int player, int pos,int h);
+ int GetHeight(int player, int pos);
+ int GetCard(int player, int pos,int height);
+ int Value(int player);
+ void AddScore(int c1,int c2);
+ void SwitchStartplayer();
+ int MakeMove(int c,int pos);
+ void Init();
+ long random(long max);
+ int Subvalue(int side);
+ int ExtractGame(KEMessage *msg);
+
+ short currentplayer;
+ short startplayer;
+ int card[NO_OF_CARDS];
+ int cardheight[16];
+ int cardvalues[14];
+ short score[2];
+ CCOLOUR trump;
+ short movenumber;
+ int curmove[2];
+ bool endgame;
+ int played[NO_OF_CARDS]; // cards already played
+ short level;
+};
+
+
+class lskatproc : public KInputChildProcess
+{
+
+private:
+
+public:
+ lskatproc();
+ ~lskatproc();
+
+ virtual bool ReceiveMsg(KEMessage *msg,int id);
+
+
+ void initrandom();
+ int GetComputerMove(lgame game,short &x,short &y,int rek);
+ void SendDebug(const char *s);
+
+ private:
+ char buf[1024];
+};
+
+#endif
diff --git a/lskat/lskatproc/main.cpp b/lskat/lskatproc/main.cpp
new file mode 100644
index 00000000..d25cd8c9
--- /dev/null
+++ b/lskat/lskatproc/main.cpp
@@ -0,0 +1,28 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Sun Apr 9 22:56:15 CEST 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include "lskatproc.h"
+
+
+
+
+int main(int argc, char *argv[])
+{
+ lskatproc mComm;
+ return mComm.exec() ? 0 : 1;
+}
diff --git a/lskat/lskatproc/templates/cpp_template b/lskat/lskatproc/templates/cpp_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskatproc/templates/cpp_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
diff --git a/lskat/lskatproc/templates/header_template b/lskat/lskatproc/templates/header_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskatproc/templates/header_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/