estic-1.61.orig/0040755000176100001440000000000007061535301013013 5ustar debacleusersestic-1.61.orig/compile.doc0100644000176100001440000001202607031424676015141 0ustar debacleusers ESTIC V 1.60, 05.03.1997 Enhanced Supervisor Tool for ISTEC Configuration Copyright (C) 1995-97 Ullrich von Bassewitz Nutzungsbestimmungen und Weitergabe ----------------------------------- Die Software (sowohl die Quellcodes, als auch die Binaries) werden ohne jegliche Zusagen/Garantien bezüglich Funktionalität oder Funktionsfähigkeit abgegeben. Weder die Autoren noch die Distributoren übernehmen eine Verantwortung für Schäden, die durch die Benutzung der Software verursacht werden. Die Software darf frei verwendet und weitergegeben werden, wobei "frei" ausdrücklich auch eine kommerzielle Nutzung/Weitergabe einschließt, *vorausgesetzt* die folgenden Bedingungen werden eingehalten: 1. Die Herkunft der Software muß - wenn überhaupt - dann korrekt angegeben werden. Es ist nicht erlaubt, die Software als Werk eines anderen auszugeben. Wird die Software in Teilen oder als Ganzes in einem Produkt benutzt, dann würde ich mich über einen Hinweis auf die Herkunft in der Dokumentation freuen. Ein solcher Hinweis ist aber nicht zwingend notwendig. 2. Geänderte Quellcodes müssen deutlich als solche gekennzeichnet werden und dürfen nicht ohne einen expliziten Hinweis auf die durchgeführten Änderungen weiterverteilt werden. 3. Die Bedingungen über die Nutzung/Weitergabe dürfen nicht entfernt oder geändert werden. Speziell für ESTIC gilt noch der folgende Hinweis: * Die Bestimmungen des Datenschutzes sind zu beachten! Das Logging-Feature kann speziell bei Anwendung im kommerziellen Bereich gegen Datenschutzbestimmungen verstoßen! Anleitung zum Übersetzen der ESTIC Sourcen: ------------------------------------------- Vorbemerkung: Beim Auspacken (unter DOS & OS/2 unbedingt Info-Zip's unzip mit Parameter -a verwenden!) werden drei Unterverzeichnisse erzeugt: spunk, areacode und estic. In spunk befindet sich die zugrundeliegende Klassenbibliothek, in estic der applikationsspezifische Code. Die folgenden Schritte müssen zuerst im Verzeichnis spunk, dann im Verzeichnis areacode, dann im Verzeichnis estic ausgeführt werden. 0. Notwendiger Compiler ist gcc unter Linux und FreeBSD bzw. Watcom-C unter DOS & OS/2. Spunk selber läßt sich auch mit Borland-C übersetzen (sowohl die DOS als auch die OS/2 Version), BCC hat jedoch diverse Problemchen, um die ich mich bei estic nicht weiter gekümmert habe, für estic existiert deshalb kein Makefile für bcc. Wer unbedingt eine Übersetzung hinbekommen will sollte kurz bei mir fuer nähere Infos anfragen. 1. Passendes Makefile aus dem Verzeichnis "make" nach "Makefile" kopieren. linux.mak für Linux verwenden, freebsd.mak für FreeBSD usw. 2. Nur für Linux & FreeBSD: File Dependencies erzeugen durch Aufruf von "make dep". 3. "make" eingeben. Wer wenig Zeit hat, der kann im Verzeichnis spunk auch "make lib" verwenden, dann wird der Resourcen-Editor nicht erzeugt. 4. Nicht vergessen: Dasselbe nochmal im Verzeichnis estic wiederholen... Sonstige Hinweise: ------------------ Die Übersetzung unter Linux erfolgte mit g++ 2.7.2. * Ich übernehme keinerlei Garantie dafür, daß sich ESTIC auch mit neueren Compilern übersetzen läßt. Ich habe in der Vergangenheit versucht, mit der Entwicklung Schritt zu halten und den Code so zu schreiben, daß er die Fehler und Unzulänglichkeiten aller GNU-C++ Compiler umgeht. Da jede neue g++ Version aber neue Fehler hat, oder bisher völlig legale Konstrukte plötzlich nicht mehr schluckt, ist aber inzwischen zu einem solchen Aufwand geworden, daß ich beschlossen habe, es sein zu lassen. ESTIC *sollte* sich mit g++ 2.6.3 übersetzen lassen, evtl. funktioniert das auch mit neueren Versionen (Kommentar im Makefile beachten), ich übernehme aber wie gesagt keine Garantien. Für Erfolgs-/Mißerfolgsmeldungen bin ich dankbar, definitive Anpassungen gibt's erst, wenn ich selber den entsprechenden Compiler verwende. * ESTIC enthält z.T. unsinnigen Code um einige gcc Warnungen abzustellen. * Einige Warnungen, speziell bei Bibliotheksfiles ließen sich auch durch wildeste Cast-Orgien nicht beseitigen. Es ist sonst nicht meine Art, Code herauszugeben, der sich nicht ohne Warnungen uebersetzen läßt, hier hatte ich leider keine andere Möglichkeit. FreeBSD: * Die Übersetzung erfolgte unter FreeBSD 2.1.0 mit g++ 2.6.3. FreeBSD hat einige Probleme von Linux nicht, weil unter FreeBSD ein eigener Linker verwendet wird, der sich - speziell bei Templates - anders verhält. Die Übersetzung unter DOS bzw. OS/2 wurde mit Watcom C Version 10.6 durchgeführt. Aufgrund von Speicherproblemen wurde die DOS Version diesmal als 32-Bit Version erzeugt. Wenn viel DOS Speicher zur Verfügung steht kann auch versuchsweise eine 16-Bit Version erzeugt werden ("make dos" anstelle von "make dos32" eingeben). Die als Binary gelieferte Version benutzt den DOS4GW Extender. Für die an spunk interessierten: Es existiert für spunk etwas ähnliches wie eine Dokumentation im Verzeichnis spunk/doc Happy hacking! Uz estic-1.61.orig/areacode/0040755000176100001440000000000007061535300014555 5ustar debacleusersestic-1.61.orig/areacode/make/0040755000176100001440000000000007061535300015472 5ustar debacleusersestic-1.61.orig/areacode/make/linux.mak0100644000176100001440000000564107031424721017327 0ustar debacleusers# ***************************************************************************** # * * # * AREACODE Makefile for Linux * # * * # * (C) 1995-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Stuff you may want to edit # The name of the data file after installation. You may want to define # AREACODE_DATAFILE before calling make instead ifdef AREACODE_DATAFILE DATATARGET=$(AREACODE_DATAFILE) else DATATARGET=/usr/lib/areacodes endif # Command line for the installation of the data file INSTALL = install -o bin -g bin -m 644 # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip # Flags for the GNU C compiler CFLAGS = -g -O2 -Wall # Name of the data file DATASOURCE=areacode.dat # ------------------------------------------------------------------------------ # Implicit rules .c.o: gcc $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: actest acvers include .depend else all: depend endif actest: areacode.o actest.o gcc -o actest areacode.o actest.o acvers: acvers.o gcc -o acvers acvers.o areacode.o: areacode.h areacode.c gcc $(CFLAGS) -DDATA_FILENAME="\"$(DATATARGET)\"" \ -DCHARSET_ISO -c -o areacode.o areacode.c install: areacode.o acvers @if [ `id -u` != 0 ]; then \ echo ""; \ echo 'Do "make install" as root'; \ echo ""; \ false; \ fi @if [ -f $(DATATARGET) ]; then \ NewVersion=`./acvers $(DATASOURCE) | awk '{ print $$3 }'`;\ OldVersion=`./acvers $(DATATARGET) | awk '{ print $$3 }'`;\ echo "Current datafile build number: $$OldVersion"; \ echo "Build number of new datafile: $$NewVersion"; \ if [ $$NewVersion -gt $$OldVersion ]; then \ echo "Installing new datafile"; \ $(INSTALL) $(DATASOURCE) $(DATATARGET); \ else \ echo "Installed datafile is same or newer, skipping...";\ fi; \ else \ echo "Installing new datafile"; \ $(INSTALL) $(DATASOURCE) $(DATATARGET); \ fi # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -MM *.c > .depend # ------------------------------------------------------------------------------ # clean up distclean: clean clean: -rm -f *.bak *~ *.o .depend -rm -f acvers actest zap: distclean estic-1.61.orig/areacode/make/svr40.mak0100644000176100001440000000622007031424721017140 0ustar debacleusers# ***************************************************************************** # * * # * AREACODE Makefile for SVR4 * # * * # * (C) 1995-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # * * # * SVR40 Port by Felix Blank (felix@tasha.muc.de) * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Stuff you may want to edit # The name of the data file after installation. You may want to define # AREACODE_DATAFILE before calling make instead ifdef AREACODE_DATAFILE DATATARGET=$(AREACODE_DATAFILE) else DATATARGET=/usr/lib/areacodes endif # Command line for the installation of the data file INSTALL = install -o bin -g bin -m 644 # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = gcc # Flags for the GNU C compiler CFLAGS=-O2 -Wall # Name of the data file DATASOURCE=areacode.dat # ------------------------------------------------------------------------------ # Implicit rules .c.o: gcc $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: actest acvers include .depend else all: depend endif actest: areacode.o actest.o gcc -o actest areacode.o actest.o acvers: acvers.o gcc -o acvers acvers.o areacode.o: areacode.h areacode.c gcc $(CFLAGS) -DDATA_FILENAME="\"$(DATATARGET)\"" \ -DCHARSET_ISO -c -o areacode.o areacode.c install: areacode.o acvers @if [ `id -u` != 0 ]; then \ echo ""; \ echo 'Do "make install" as root'; \ echo ""; \ false; \ fi @if [ -f $(DATATARGET) ]; then \ NewVersion=`./acvers $(DATASOURCE) | awk '{ print $$3 }'`;\ OldVersion=`./acvers $(DATATARGET) | awk '{ print $$3 }'`;\ echo "Current datafile build number: $$OldVersion"; \ echo "Build number of new datafile: $$NewVersion"; \ if [ $$NewVersion -gt $$OldVersion ]; then \ echo "Installing new datafile"; \ $(INSTALL) $(DATASOURCE) $(DATATARGET); \ else \ echo "Installed datafile is same or newer, skipping...";\ fi; \ else \ echo "Installing new datafile"; \ $(INSTALL) $(DATASOURCE) $(DATATARGET); \ fi # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -MM *.c > .depend # ------------------------------------------------------------------------------ # clean up distclean: zap -rm acvers actest clean: -rm *.bak *~ zap: clean -rm *.o -rm .depend estic-1.61.orig/areacode/make/watcom.mak0100644000176100001440000000637107031424721017463 0ustar debacleusers# ***************************************************************************** # * * # * AREACODE Makefile * # * * # * (C) 1996 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Generelle Einstellungen .AUTODEPEND .SUFFIXES .ASM .C .CC .CPP .SWAP # ------------------------------------------------------------------------------ # Allgemeine Definitionen # Names of executables AS = TASM AR = WLIB LD = WLINK !if $d(__OS2__) ZIP = zip MV = c:\os2\4os2\4os2 /C MOVE /Q !else ZIP = pkzip MV = mv !endif !if !$d(TARGET) !if $d(__OS2__) TARGET = OS2 !else TARGET = DOS !endif !endif LIBDIR= ..\spunk INCDIR= ..\spunk # target specific macros. !if $(TARGET)==OS2 # --------------------- OS2 --------------------- SYSTEM = os2v2 CPP = WPP386 CC = WCC386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d2 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !elif $(TARGET)==DOS32 # -------------------- DOS4G -------------------- SYSTEM = dos4g CPP = WPP386 CC = WCC386 CCCFG = -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d2 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==DOS # --------------------- DOS --------------------- SYSTEM = dos CPP = WPP CC = WCC # Optimize for size when running under plain DOS, but use 286 code. Don't # include ANY debugging code to make as many programs runable under plain DOS # as possible. CCCFG = -bt=$(TARGET) -d$(TARGET) -dSPUNK_NODEBUG -i=$(INCDIR) -d1 -oailmns -s -zp2 -zc -2 -fp2 -ml -zq -w2 -ze -zt255 !elif $(TARGET)==NETWARE # --------------------- NETWARE ------------------- SYSTEM = netware CPP = WPP386 CC = WCC386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==NT # --------------------- NT ---------------------- SYSTEM = nt CPP = WPP386 CC = WCC386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !else !error !endif LIB = $(LIBDIR)\$(TARGET)\SPUNK.LIB # ------------------------------------------------------------------------------ # Implicit rules .c.obj: $(CC) $(CCCFG) $< .cc.obj: $(CPP) $(CCCFG) $< # -------------------------------------------------------------------- all: actest acvers actest: actest.exe acvers: acvers.exe os2: $(MAKE) -DTARGET=OS2 nt: $(MAKE) -DTARGET=NT dos32: $(MAKE) -DTARGET=DOS32 dos: $(MAKE) -DTARGET=DOS # -------------------------------------------------------------------- # actest actest.exe: areacode.obj \ actest.obj -@if exist makefile copy makefile make\watcom.mak > nul $(LD) system $(SYSTEM) @&&| DEBUG all NAME actest.exe OPTION DOSSEG OPTION STACK=32K FILE areacode.obj FILE actest.obj | acvers.exe: acvers.obj -@if exist makefile copy makefile make\watcom.mak > nul $(LD) system $(SYSTEM) @&&| DEBUG all NAME acvers.exe OPTION DOSSEG OPTION STACK=32K FILE acvers.obj | # ------------------------------------------------------------------------------ # Aufr„umen clean: -del *.bak zap: clean -del *.obj -del *.mbr -del *.dbr estic-1.61.orig/areacode/.cvsignore0100644000176100001440000000011507031424721016550 0ustar debacleusers*.err *.zip *.exe *.obj makefile Makefile .depend areacode.dat actest acvers estic-1.61.orig/areacode/actest.c0100644000176100001440000000740007031424721016203 0ustar debacleusers/*****************************************************************************/ /* */ /* ACTEST.C */ /* */ /* Test an areacode data file */ /* */ /* */ /* */ /* (C) 1996,97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /* */ /* This software is provided 'as-is', without any express or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ #include #include #include #include "areacode.h" int main (int argc, char* argv []) { acInfo AC; char Buf [256]; unsigned RC; acMaxMem = 0; /* See if there is an argument given. If so, use it as name and path of * the database. */ if (argc >= 2) { acFileName = argv [1]; } /* Test loop */ while (1) { printf ("Enter phone number: "); fflush (stdout); gets (Buf); if (strlen (Buf) == 0) { break; } switch ((RC = GetAreaCodeInfo (&AC, Buf))) { case acOk: printf ("acOK:\n" " PrefixLen = %d\n" " Info = %s\n", AC.AreaCodeLen, AC.Info); break; case acFileError: printf ("acFileError\n"); break; case acInvalidFile: printf ("acInvalidFile\n"); break; case acWrongVersion: printf ("acWrongVersion\n"); break; default: printf ("Unknown return: %u\n", RC); break; } printf ("\n"); } return 0; } estic-1.61.orig/areacode/acvers.c0100644000176100001440000001063007031424721016202 0ustar debacleusers/*****************************************************************************/ /* */ /* ACVERS.C */ /* */ /* Get the version and build of an areacode data file */ /* */ /* */ /* */ /* (C) 1996,97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /* */ /* This software is provided 'as-is', without any express or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* This code assumes 8 bit bytes */ #include #include #include /*****************************************************************************/ /* Data */ /*****************************************************************************/ #define MAGIC0 0x68 #define MAGIC1 0x57 #define MAGIC2 0x46 #define MAGIC3 0x35 /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void Usage (const char* ProgName) /* Print usage information and exit */ { printf ("%s: Print the version of an areacode database\n\n" "Usage: \t%s file ...\n", ProgName, ProgName); exit (1); } int main (int argc, char* argv []) { int I; if (argc < 2) { Usage (argv [0]); } for (I = 1; I < argc; I++) { FILE* F; const char* Filename = argv [I]; unsigned char MagicBuf [4]; unsigned char BuildBuf [2]; unsigned char VersionBuf [2]; unsigned Build; if ((F = fopen (Filename, "rb")) == 0) { perror ("Cannot open input file"); exit (2); } fread (MagicBuf, sizeof (MagicBuf), 1, F); if (MagicBuf [0] != MAGIC0 || MagicBuf [1] != MAGIC1 || MagicBuf [2] != MAGIC2 || MagicBuf [3] != MAGIC3) { fprintf (stderr, "No dial prefix database\n"); exit (3); } fread (BuildBuf, sizeof (BuildBuf), 1, F); fread (VersionBuf, sizeof (VersionBuf), 1, F); fclose (F); Build = ((unsigned) BuildBuf [1]) * 256 + ((unsigned) BuildBuf [0]); printf ("%d %d %u\n", VersionBuf [1], VersionBuf [0], Build); } return 0; } estic-1.61.orig/areacode/areacode.c0100644000176100001440000004402107031424721016463 0ustar debacleusers/*****************************************************************************/ /* */ /* AREACODE.C */ /* */ /* Portable library module to search for an area code in a database. */ /* */ /* */ /* */ /* (C) 1996,97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /* */ /* This software is provided 'as-is', without any express or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* * The code assumes * - 8 bit bytes * - unsigned long is 32 bit. This may be changed by #defining u32 to * a data type that is an 32 bit unsigned when compiling this module. * - ascii character set * * The code does *not* assume * - a specific byte order. Currently the code autoadjusts to big or * little endian data. If you have something more weird than that, * you have to add conversion code. * */ #include #include #include #include #include "areacode.h" /*****************************************************************************/ /* Externally visible data */ /*****************************************************************************/ /* The name of the areacode data file. The default is what is #defined as * DATA_FILENAME. If this is not #defined, the default is "areacode.dat", * which is probably not what you want. In the latter case set this to * the correct filename *before* your first call to GetAreaCodeInfo. */ #ifdef DATA_FILENAME char* acFileName = DATA_FILENAME; #else char* acFileName = "areacode.dat"; #endif /* How much dynamic memory is GetAreaCodeInfo allowed to consume? Having less * memory means more disk access and vice versa. The function does even work * if you set this value to zero. For maximum performance, the function needs * 4 byte per area code stored in the data file. The default is 32KB. */ unsigned long acMaxMem = 0x8000L; /*****************************************************************************/ /* Data and structures */ /*****************************************************************************/ /* Define an unsigned quantity with 32 bits. Try to make some clever * assumptions using the data from limits.h. This may break some older * (non ISO compliant) compilers, but I can't help... */ #if !defined(u32) && defined(ULONG_MAX) # if ULONG_MAX == 4294967295UL # define u32 unsigned long # endif #endif #if !defined(u32) && defined(UINT_MAX) # if UINT_MAX == 4294967295UL # define u32 unsigned # endif #endif #if !defined(u32) && defined(USHRT_MAX) # if USHRT_MAX == 4294967295UL # define u32 unsigned short # endif #endif #if !defined(u32) # define u32 unsigned long #endif /* The version of the data file we support */ #define acVersion 0x100 /* The magic words in little and big endian format */ #define LittleMagic 0x35465768L #define BigMagic 0x68574635L /* Defining the byte ordering */ #define boLittleEndian 0 #define boBigEndian 1 /* The byte order used in the file is little endian (intel) format */ #define FileByteOrder boLittleEndian /* This is the header data of the data file. It is not used anywhere in * the code, just have a look at it since it describes the layout in the * file. */ typedef struct { u32 Magic; u32 Version; /* Version in hi word, build in lo word */ u32 Count; u32 AreaCodeStart; u32 NameIndexStart; u32 NameStart; } PrefixHeader; /* This is what's really used: */ typedef struct { /* The file we read from */ FILE* F; /* Machine byte order */ unsigned ByteOrder; /* Stuff from the file header */ unsigned Version; unsigned Build; u32 Count; u32 AreaCodeStart; u32 NameIndexStart; u32 NameStart; /* Control data */ long First; long Last; u32* Table; } AreaCodeDesc; /* Translation table for translation CP850 --> ISO-8859-1. To save some space, * the table covers only values > 127 */ #ifdef CHARSET_ISO static char ISOMap [128] = { 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFC, 0xF9, 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x50, 0x66, 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, 0xBF, 0x2D, 0xAC, 0xC6, 0xBC, 0xA1, 0xAB, 0xBB, 0xFE, 0xFE, 0xFE, 0x7C, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x7C, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2D, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2D, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x61, 0xDF, 0x63, 0x70, 0x5A, 0x73, 0xB5, 0x74, 0x70, 0x54, 0x4F, 0x64, 0x38, 0x30, 0x65, 0x55, 0x3D, 0xB1, 0x3E, 0x3C, 0x66, 0x4A, 0xF7, 0x7E, 0xB0, 0xB7, 0xB7, 0x2F, 0x6E, 0xB2, 0xFE, 0xFF }; #endif /* Macro to convert from big endian to little endian format and vice versa. * Beware: The macro evaluates its parameter more than once! */ #define _ByteSwap(__V) ((((__V) & 0x000000FF) << 24) | \ (((__V) & 0xFF000000) >> 24) | \ (((__V) & 0x0000FF00) << 8) | \ (((__V) & 0x00FF0000) >> 8)) /*****************************************************************************/ /* Helper functions */ /*****************************************************************************/ static u32 _ByteSwapIfNeeded (u32 D, unsigned ByteOrder) /* Put the bytes into the correct order according to ByteOrder */ { /* Swap bytes if needed and return the result */ switch (ByteOrder) { case boLittleEndian: return D; default: return _ByteSwap (D); } } static u32 ByteSwapIfNeeded (u32 D, const AreaCodeDesc* Desc) /* Put the bytes into the correct order according to ByteOrder in Desc */ { /* Swap bytes if needed and return the result */ return _ByteSwapIfNeeded (D, Desc->ByteOrder); } static u32 _Load_u32 (FILE* F, unsigned ByteOrder) /* Load an u32 from the current file position and swap it if needed */ { u32 D; /* Read the data from the file */ fread (&D, sizeof (D), 1, F); /* Swap bytes if needed and return the result */ return _ByteSwapIfNeeded (D, ByteOrder); } static u32 Load_u32 (const AreaCodeDesc* Desc) /* Load an u32 from the current file position and swap it if needed */ { return _Load_u32 (Desc->F, Desc->ByteOrder); } static unsigned LoadFileHeader (AreaCodeDesc* Desc) /* Load the header of a data file. Return one of the acXXX codes. */ { u32 Version; /* Load the magic word in the format used int the file (do not convert) */ u32 Magic = _Load_u32 (Desc->F, FileByteOrder); /* Check what we got from the file, determine the byte order */ switch (Magic) { case BigMagic: Desc->ByteOrder = boBigEndian; break; case LittleMagic: Desc->ByteOrder = boLittleEndian; break; default: /* OOPS - the file is probably not a valid data file */ return acInvalidFile; } /* Now read the rest of the header data */ Version = Load_u32 (Desc); Desc->Version = (Version >> 16); Desc->Build = (Version & 0xFFFF); Desc->Count = Load_u32 (Desc); Desc->AreaCodeStart = Load_u32 (Desc); Desc->NameIndexStart = Load_u32 (Desc); Desc->NameStart = Load_u32 (Desc); /* Check for some error conditions */ if (ferror (Desc->F)) { /* Some sort of file problem */ return acFileError; } else if (feof (Desc->F) || Desc->Count == 0) { /* This should not happen on a valid file */ return acInvalidFile; } else if (Desc->Version != acVersion) { return acWrongVersion; } else { /* Data is sane */ return acOk; } } static u32 EncodeNumber (const char* Phone) /* Encode the number we got from the caller into the internally used BCD * format. */ { unsigned I; unsigned Len; u32 P = 0; /* Initialize to make gcc happy */ /* Get the amount of characters to convert */ Len = strlen (Phone); if (Len > 8) { Len = 8; } /* Convert the characters */ for (I = 0; I < Len; I++) { P = (P << 4) | ((unsigned) ((unsigned char) Phone [I]) & 0x0F); } /* Fill the rest of the number with 0x0F */ I = 8 - Len; while (I--) { P = (P << 4) | 0x0F; } /* Done - return the result */ return P; } static u32 ReadPhone (const AreaCodeDesc* Desc, long Index) /* Read the phone number that is located at the given index. If we have a * part of the table already loaded into memory, use the memory copy, else * read the phone number from disk. */ { if (Desc->Table && Index >= Desc->First && Index <= Desc->Last) { /* Use the already loaded table, but don't forget to swap bytes */ return ByteSwapIfNeeded (Desc->Table [Index - Desc->First], Desc); } else { /* Load the value from the file */ fseek (Desc->F, Desc->AreaCodeStart + Index * sizeof (u32), SEEK_SET); return Load_u32 (Desc); } } static void LoadTable (AreaCodeDesc* Desc) /* Load a part of the table into memory */ { u32 SpaceNeeded = (Desc->Last - Desc->First + 1) * sizeof (u32); Desc->Table = malloc (SpaceNeeded); if (Desc->Table == 0) { /* Out of memory. There is no problem with this now since we do * not really need the table in core memory (it speeds things up, * that's all). In addition to that, the memory requirement halves * with each iteration, so maybe we have more luck next time. */ return; } /* Seek to the correct position in the file */ fseek (Desc->F, Desc->AreaCodeStart + Desc->First * sizeof (u32), SEEK_SET); /* Read the data */ fread (Desc->Table, SpaceNeeded, 1, Desc->F); } static unsigned CalcCodeLen (u32 Code) /* Calculate the length of a given (encoded) area code in characters */ { u32 Mask; unsigned Len = 0; for (Mask = 0xF0000000L; Mask; Mask >>= 4) { if ((Code & Mask) != Mask) { Len++; } else { break; } } return Len; } /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned GetAreaCodeInfo (acInfo* AC, const char* PhoneNumber) /* Return - if possible - an information for the area code of the given number. * The function returns one of the error codes defined in areacode.h. If the * returned value is acOk, the AC struct is filled with the data of the * area code found. If we did not have an error, but there is no area code * that corresponds to the given number, the function returns acOk, but the * AC struct is filled with an empty Info field and a AreaCodeLen of zero. */ { u32 Phone; /* PhoneNumber encoded in BCD */ long First, Last, Current; /* For binary search */ u32 CurrentVal; /* The value at Table [Current] */ unsigned AreaCodeLen; /* The length of the area code found */ unsigned char InfoLen; /* Length of info string */ unsigned RC = acOk; /* Result code of the function */ u32 Mask; AreaCodeDesc Desc; /* Clear the fields of the AC struct. Write a zero to the last field of * Info - this field is never written to by the rest of the code. So by * setting this to zero, we will assure a terminated string in case some * problem prevents the code below from executing correctly. */ AC->Info [0] = '\0'; AC->Info [sizeof (AC->Info) - 1] = '\0'; AC->AreaCodeLen = 0; /* If the number is empty, return immidiately */ if (strlen (PhoneNumber) == 0) { return acOk; } /* Open the database file, check for errors */ Desc.F = fopen (acFileName, "rb"); if (Desc.F == 0) { /* We had an error opening the file */ return acFileError; } /* Initialize descriptor data where needed */ Desc.Table = 0; /* Read the header from the file */ RC = LoadFileHeader (&Desc); if (RC != acOk) { /* Wrong file or file read error */ goto ExitWithClose; } /* Convert the phone number into the internal representation */ Phone = EncodeNumber (PhoneNumber); /* Add dead code to work around gcc warnings */ Current = 0; CurrentVal = 0; /* Now do a binary search over the data */ First = 0; Last = (long) Desc.Count - 1; while (First <= Last) { /* If we don't have read the table into memory, check if we can do * so now. */ if (Desc.Table == 0) { u32 NeedMemory = (Last - First + 1) * sizeof (u32); if (NeedMemory <= acMaxMem) { /* Ok, the current part of the table is now small enough to * load it into memory. */ Desc.First = First; Desc.Last = Last; LoadTable (&Desc); } } /* Set current to mid of range */ Current = (Last + First) / 2; /* Get the phone number from that place */ CurrentVal = ReadPhone (&Desc, Current); /* Do a compare */ if (Phone > CurrentVal) { First = Current + 1; } else { Last = Current - 1; if (Phone == CurrentVal) { /* Set the condition to terminate the loop */ First = Current; } } } /* First is the index of the area code, we eventually found. Put the index * into Current and the value into CurrentVal. */ if (Current != First) { Current = First; CurrentVal = ReadPhone (&Desc, Current); } /* * We may now delete an eventually allocated table space since it is * not needed any more. */ free (Desc.Table); Desc.Table = 0; /* If Current points behind Last, we did not find anything */ if (Current >= (long) Desc.Count) { /* Not found */ goto ExitWithClose; } /* Calculate the length of the area code */ AreaCodeLen = CalcCodeLen (CurrentVal); /* Check if the Prefix is actually the first part of the phone number */ Mask = 0xFFFFFFFFL << ((8 - AreaCodeLen) * 4); if ((Phone & Mask) != (CurrentVal & Mask)) { /* They are different */ goto ExitWithClose; } /* Ok, we have now definitely found the code. Set up the data structure, * we return to the caller. */ AC->AreaCodeLen = AreaCodeLen; /* Current is the index of the area code. Seek to the corresponding * position in the name index, get the name position from there and seek * to that place. */ fseek (Desc.F, Desc.NameIndexStart + Current * sizeof (u32), SEEK_SET); fseek (Desc.F, Desc.NameStart + Load_u32 (&Desc), SEEK_SET); /* Read the length of the name and add the trailing zero to the info * field in the result struct. */ fread (&InfoLen, 1, 1, Desc.F); AC->Info [InfoLen] = '\0'; /* Read the info into the result struct */ fread (AC->Info, 1, InfoLen, Desc.F); #ifdef CHARSET_ISO /* Translate the info to the ISO-8859-1 charset */ { unsigned I; for (I = 0; I < InfoLen; I++) { unsigned char C = (unsigned char) AC->Info [I]; if (C >= 128) { AC->Info [I] = ISOMap [C - 128]; } } } #endif ExitWithClose: /* Close the data file */ fclose (Desc.F); /* Done, return the result */ return RC; } estic-1.61.orig/areacode/areacode.doc0100644000176100001440000001164007031424721017007 0ustar debacleusers AREACODE Portable library module to search for an area code in a database. Version 1.01 (C) Copyright 1996,97 by Ullrich von Bassewitz 1. Overview ----------- The areacode module together with its database serves as a helper for finding names for area codes. It is freely available, subject to the copyright notice below. 2. Function ----------- The module exports a few data types and one function. The function resolves a phone number (including the country code) to some text describing the area code found in the phone number. Current descriptions are in german, the database contains german, swiss and austrian area codes. Usage is easy, just have a look into the header file areacode.h. 3. Supported systems and limitations ------------------------------------ The module should run on nearly all system that have the following characteristics: * 8 bit bytes * An unsigned data type with 32 bits. The code makes some checks with the values in limits.h to find such a datatype for itself, if all checks fail, unsigned long is used. This may be overriden by #defining the macro u32 to the datatype needed. * An ANSI compatible compiler supporting prototypes. The code should also compile with a C++ compiler, the header file uses the #ifdef __cpluplus checks. * Big or little endian architectures. For something more weird (old Vaxes?) code has to be added. * Systems with CP437, CP850 or ISO-8859-1 character sets. The "native" format is CP850/CP437, for ISO-8859-1, the #define CHARSET_ISO has to be added when compiling the module. The code has been tested under * DOS (Watcom C/C++ 10.6) * Windows-NT (Watcom C/C++ 10.6) * OS/2 2.x (Watcom C/C++ 10.6) * i386-Linux (gcc 2.7.2) For these environments makefiles can be found in the make subdirectory. The package has some limits as stated below: * Current language is german. * The data file contains area codes for germany and switzerland. * The area code including the country code (but not including the international prefix, often 00) may not exceed 8 digits. This may be bumped up to 9 digits if needed with some disadvantages (more complicated code). * An area code description must be shorter than 256 characters. 4. How to get the source & data files ------------------------------------- You may get the source for the package itself, for the datafile builder and for new datafiles from ftp://ftp.musoftware.com/areacode Note: Please do not distribute modified data files. The data files contain a version stamp to make shure, users don't overwrite newer versions with older ones. This scheme will no longer work if data files are distributed by third parties. Note: The datafile builder needs spunk, a C++ class library to compile. You may want to have a look in ftp://ftp.musoftwware.com/spunk for the current spunk version. 5. Installing the package ------------------------- For all systems the location of the data file has to be known. The default name (including the path) may be compiled into the module by #defining DATA_FILENAME, or set at runtime (see areacode.h). The Linux makefile will install the data file in a common place, so more than one software package depending on areacode is able to use the data file. The data file contains a version stamp, to avoid overwriting a newer file by an older one, when installing more than one software package. The program acvers is used to determine the build version, it will output three numbers, the last one is the data file build (the first two are format version numbers that - hopefully - will not change). 6. Copying ---------- This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. 7. Credits ---------- Many thanks to all people that helped developing the module: Andreas Kool (akool@kool.f.eunet.de), author of isdnlog, for many suggestions and code testing. Norbert Staudt (VKRG.Staudt@t-online.de), who sent me lots of sample programs resolving area codes. Andreas Gutzwiller (andy@hippo.proxyon.imp.com), for the swiss area codes. Alois Schneider (Alois.Schneider@magnet.at), for the austrian area codes. estic-1.61.orig/areacode/areacode.h0100644000176100001440000001233107031424721016467 0ustar debacleusers/*****************************************************************************/ /* */ /* AREACODE.H */ /* */ /* Portable library module to search for an area code in a database. */ /* */ /* */ /* */ /* (C) 1996,97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /* */ /* This software is provided 'as-is', without any express or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* * The code assumes * - 8 bit bytes * - unsigned long is 32 bit. This may be changed by #defining u32 to * a data type that is an 32 bit unsigned when compiling this module. * - ascii character set * * The code does *not* assume * - a specific byte order. Currently the code autoadjusts to big or * little endian data. If you have something more weird than that, * you have to add conversion code. * */ #ifndef _AREACODE_H #define _AREACODE_H #ifdef __cplusplus extern "C" { #endif /*****************************************************************************/ /* Data, structs and constants */ /*****************************************************************************/ /* The name of the areacode data file. The default is what is #defined as * DATA_FILENAME. If this is not #defined, the default is "areacode.dat", * which is probably not what you want. In the latter case set this to * the correct filename *before* your first call to GetAreaCodeInfo. */ extern char* acFileName; /* How much dynamic memory is GetAreaCodeInfo allowed to consume? Having less * memory means more disk access and vice versa. The function does even work * if you set this value to zero. For maximum performance, the function needs * 4 byte per area code stored in the data file. The default is 32KB. */ extern unsigned long acMaxMem; /* Result codes of GetAreaCodeInfo */ #define acOk 0 /* Done */ #define acFileError 1 /* Cannot open/read file */ #define acInvalidFile 2 /* The file exists but is no area code data file */ #define acWrongVersion 3 /* Wrong version of data file */ /* The result of an area code search */ typedef struct { unsigned AreaCodeLen; /* The length of the area code found */ char Info [256]; /* An info string */ } acInfo; /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned GetAreaCodeInfo (acInfo* /*AC*/ , const char* /*PhoneNumber*/); /* Return - if possible - an information for the area code of the given number. * The function returns one of the error codes defined in areacode.h. If the * returned value is acOk, the AC struct is filled with the data of the * area code found. If we did not have an error, but there is no area code * that corresponds to the given number, the function returns acOk, but the * AC struct is filled with an empty Info field and a AreaCodeLen of zero. */ #ifdef __cplusplus } #endif /* End of AREACODE.H */ #endif estic-1.61.orig/estic/0040755000176100001440000000000007061535301014122 5ustar debacleusersestic-1.61.orig/estic/data/0040755000176100001440000000000007061535301015033 5ustar debacleusersestic-1.61.orig/estic/data/1008.ic0100644000176100001440000000275207031424727015751 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/1016.ic0100644000176100001440000000223507031424727015744 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/1024.ic0100644000176100001440000000223507031424727015743 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/2016.ic0100644000176100001440000000223507031424727015745 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/2024.ic0100644000176100001440000000223507031424727015744 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/2400.ic0100644000176100001440000000223507031424730015734 0ustar debacleusers3˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙33˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/2416.ic0100644000176100001440000000223507031424730015743 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/data/2424.ic0100644000176100001440000000223507031424730015742 0ustar debacleusers˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ @€˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙estic-1.61.orig/estic/.cvsignore0100644000176100001440000000014307031424721016115 0ustar debacleusersestic estic.rc estic.ini cron.dat alias.dat *.log makefile Makefile *.ic *.sn .depend areacode.dat estic-1.61.orig/estic/bsdterm.txt0100644000176100001440000000776107031424721016333 0ustar debacleusersFrom ibb.schwaben.com!wuschel.ibb.schwaben.com!seicom.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!news.sprintlink.net!in2.uu.net!news1.digital.com!nntp-hub2.barrnet.net!nntp-hub.barrnet.net!inet-nntp-gw-1.us.oracle.com!news.caldera.com!park.uvsc.edu!usenet Tue Oct 3 21:28:59 1995 Path: ibb.schwaben.com!wuschel.ibb.schwaben.com!seicom.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!news.sprintlink.net!in2.uu.net!news1.digital.com!nntp-hub2.barrnet.net!nntp-hub.barrnet.net!inet-nntp-gw-1.us.oracle.com!news.caldera.com!park.uvsc.edu!usenet From: Terry Lambert Newsgroups: comp.unix.bsd.freebsd.misc Subject: Re: Q: Writing to lower right of console Date: 2 Oct 1995 19:41:12 GMT Organization: Utah Valley State College, Orem, Utah Lines: 73 Message-ID: <44pf8o$ap@park.uvsc.edu> References: NNTP-Posting-Host: hecate.artisoft.com uz@wuschel.ibb.schwaben.com (Ullrich von Bassewitz) wrote: ] ] I'm trying to port a program from linux to freebsd. Until now there is only ] one problem: ] ] If I write to the last char of the screen (the char in the lower right ] corner), a scroll happens and my last line goes one line up, the first ] line vanishes. ] ] My program is screen oriented, it has a menu line as the first and a status ] line as the last line of the screen. You can imagine, what happens if the ] screen scrolls one line up when writing the status line... ] ] I know, that this is not really a freebsd problem, many terminals may have ] this too (the Linux console and xterm windows under X don't have it). ] With a special terminal, I can tell people, that my program will ] not support this terminal - but telling people that the console is not ] suppported would be a very unpopular approach :-) To support the terminals that do this: 1) look for the "xn" flag in the termcap entry using the tgetflag() routine. 2a) If the flag is set, use the current code. The "xnwrap" flag means that the cursor wraps BEFORE character 81 instead of AFTER character 80. This is also called "delayed wrap". 2b) If the flag is not set, then you will need to do the following to write the last character position (SCO Xenix and all Televideo sequence terminals -- like the Wyse-50, the most popular one of all time -- terminals do not have the xn flag set); i) Rememeber the second to last character. ii) write the last character in the second to last character position. iiia) use "insert character mode" to insert the second to last character in the correct position. This will force the last character to the right, and put it into the correct position as well. iiib) if the terminal does not support "insert character mode", but supports "inseert character" as an operation, then insert a character before the second to last character. This will force the correct character into the last postion. Then write the second to last character. iiic) if the terminal does not support either "insert character mode" or "insert character", then use "insert line" instead. iiid) if the terminal does not support any of "insert character mode", "insert character", or "insert line", then use a scroll region to implement insert line. iiie) if the terminal does not support any of "insert character mode", "insert character". "insert line", or scroll regions, then omit drawing the last character position entirely. Note that curses will implement these workarounds for you automatically: you should be using curses (I may be mistaken about curses knowing about using a scoll region to do an insert line; I seem to rememebr vi being stupid about this on real VT100's). All of the above are instances of a well known programming technique, the techinical name of which is "brute force". 8-). Terry Lambert terry@cs.weber.edu --- Any opinions in this posting are my own and not those of my present or previous employers. estic-1.61.orig/estic/callwin.cc0100644000176100001440000000553007031424722016063 0ustar debacleusers/*****************************************************************************/ /* */ /* CALLWIN.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Call window #include "eventid.h" #include "event.h" #include "coll.h" #include "textitem.h" #include "settings.h" #include "progutil.h" #include "icmsg.h" #include "icobjid.h" #include "icevents.h" #include "devstate.h" #include "callwin.h" // Register the class LINK (CallWindow, ID_CallWindow); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msCallWindowTitle = MSGBASE_ICCWIN + 0; const u16 msCallWindowHeader1 = MSGBASE_ICCWIN + 1; const u16 msCallWindowHeader2 = MSGBASE_ICCWIN + 2; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Count of CallWindows unsigned CallWindow::WindowCount = 0; /*****************************************************************************/ /* class CallWindow */ /*****************************************************************************/ inline CallWindow::CallWindow (StreamableInit): IstecMsgWindow (Empty) // Build constructor { // One window more WindowCount++; // Tell the program that a new window is active PostEvent (evCallWinChange, WindowCount); } CallWindow::CallWindow (): IstecMsgWindow (msCallWindowTitle, msCallWindowHeader1, msCallWindowHeader2, "CallWindow.Bounds") // Construct an CallWindow { // Ok, we have the window now WindowCount++; // Tell the program that a new window is active PostEvent (evCallWinChange, WindowCount); } CallWindow::~CallWindow () // Destruct an CallWindow { // Decrease the window count and invalidate the global pointer WindowCount--; // Tell the program that a window has been destroyed PostEvent (evCallWinChange, WindowCount); } u16 CallWindow::StreamableID () const { return ID_CallWindow; } Streamable* CallWindow::Build () // Make the window persistent { return new CallWindow (Empty); } void CallWindow::HandleEvent (Event& E) // Handle an incoming event { // Call the derived function IstecMsgWindow::HandleEvent (E); if (E.Handled) { return; } // Switch on the type of the arriving event switch (E.What) { case evCallComplete: Write (((DevStateInfo*) E.Info.O)->LogMsg ()); break; } } estic-1.61.orig/estic/callwin.h0100644000176100001440000000230007031424722015715 0ustar debacleusers/*****************************************************************************/ /* */ /* CALLWIN.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Call window #ifndef _CALLWIN_H #define _CALLWIN_H #include "icmsgwin.h" /*****************************************************************************/ /* class CallWindow */ /*****************************************************************************/ class CallWindow: public IstecMsgWindow { static unsigned WindowCount; // Count of CallWindows public: CallWindow (StreamableInit); // Build constructor CallWindow (); // Construct an CallWindow virtual ~CallWindow (); // Destruct an CallWindow virtual u16 StreamableID () const; static Streamable* Build (); // Make the window persistent virtual void HandleEvent (Event& E); // Handle an incoming event }; // End of CALLWIN.H #endif estic-1.61.orig/estic/chargwin.cc0100644000176100001440000002146007031424722016234 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARGWIN.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Charge display window #include "listbox.h" #include "textitem.h" #include "settings.h" #include "progutil.h" #include "icmsg.h" #include "icobjid.h" #include "icevents.h" #include "iccom.h" #include "chargwin.h" // Register the classes LINK (ChargeWindow, ID_ChargeWindow); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msChargeWindowTitle = MSGBASE_CHARGWIN + 0; const u16 msChargeWindowHeader = MSGBASE_CHARGWIN + 1; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name that the window uses to store it's position/size in the settings file static const String ChargeWindowBounds = "ChargeWindow.Bounds"; // Count of ChargeWindows unsigned ChargeWindow::WindowCount = 0; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class ListBox; #endif /*****************************************************************************/ /* class ChargeColl */ /*****************************************************************************/ class ChargeColl: public Collection { public: ChargeColl (IstecCharges& Charges); // Create a ChargeColl }; ChargeColl::ChargeColl (IstecCharges& Charges): Collection (IstecDevCount, 0, 0) { for (unsigned I = 0; I < IstecDevCount; I++) { Insert (&Charges [I]); } } /*****************************************************************************/ /* class ChargeListbox */ /*****************************************************************************/ class ChargeListbox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: ChargeListbox (i16 aID, const Point& aSize); // Create a charge listbox virtual void Store (Stream&) const; // Store the object into a stream virtual void Load (Stream&); // Load the object from a stream ChargeListbox (StreamableInit); // Build constructor virtual u16 StreamableID () const; // Return the streamable ID static Streamable* Build (); // Build an empty object }; ChargeListbox::ChargeListbox (i16 aID, const Point& aSize): ListBox ("", aID, aSize, atEditNormal, atEditBar, atEditNormal, NULL) // Create a charge listbox { // Create and assign the collection SetColl (new ChargeColl (Charges)); } ChargeListbox::ChargeListbox (StreamableInit): ListBox (Empty) // Build constructor { } void ChargeListbox::Store (Stream& S) const // Store the object into a stream { // Cast away the object constness ChargeListbox* THIS = (ChargeListbox*) this; // Temporarily replace the collection by a NULL pointer Collection* C = THIS->Coll; THIS->Coll = NULL; // Now store the box ListBox::Store (S); // Reset the collection pointer THIS->Coll = C; } void ChargeListbox::Load (Stream& S) // Load the object from a stream { // Call the derived function ListBox::Load (S); // Create a new collection SetColl (new ChargeColl (Charges)); } u16 ChargeListbox::StreamableID () const // Return the streamable ID { return ID_ChargeListbox; } Streamable* ChargeListbox::Build () // Build an empty object { return new ChargeListbox (Empty); } void ChargeListbox::Print (int Index, int X, int Y, u16 Attr) // Display one of the listbox entries { // Get the line String S = FormatStr (" %2d %2u", Index+21, *(Coll->At (Index))); // Pad the line to length S.Pad (String::Right, Size.X); // Write out the string Owner->Write (X, Y, S, Attr); } // Register the ChargeListbox LINK (ChargeListbox, ID_ChargeListbox); /*****************************************************************************/ /* class ChargeWindow */ /*****************************************************************************/ ChargeWindow::ChargeWindow (): ItemWindow (Rect (32, 10, 32+18, 10+11), wfFramed | wfCanMove | wfCanResize | wfSaveVisible), ZoomSize (OBounds), Box (NULL) // Construct an ChargeWindow { // Lock window output Lock (); // If there is a stored window size in the settings file, resize the // window to the stored rectangle. Rect StoredBounds = StgGetRect (ChargeWindowBounds, OBounds); if (StoredBounds != OBounds) { Resize (StoredBounds); } // Set the window title SetHeader (LoadAppMsg (msChargeWindowTitle)); // Create and insert the header line TextItem* HdrItem = new TextItem (LoadAppMsg (msChargeWindowHeader), 100, atTextNormal, NULL); AddItem (HdrItem); HdrItem->SetWidth (IXSize ()); HdrItem->SetPos (0, 0); // Create a listbox inside the window Point Size (IXSize (), IYSize () - 1); Box = new ChargeListbox (1, Size); AddItem (Box); Box->SetPos (0, 1); Box->Draw (); // Redraw the window contents DrawInterior (); // Unlock the window, allowing output Unlock (); // Ok, we have the window now WindowCount++; // Tell the application that the window count has changed PostEvent (evChargeWinChange, WindowCount); } ChargeWindow::ChargeWindow (StreamableInit): ItemWindow (Empty) { // One window more WindowCount++; // Tell the application that the window count has changed PostEvent (evChargeWinChange, WindowCount); } ChargeWindow::~ChargeWindow () // Destruct an ChargeWindow { // Write the current position to the settings file StgPutRect (OBounds, ChargeWindowBounds); // One window less WindowCount--; // Tell the application that the window count has changed PostEvent (evChargeWinChange, WindowCount); } void ChargeWindow::Store (Stream &S) const // Store the window in a stream { // Store the data from ItemWindow ItemWindow::Store (S); // Store additional data S << ZoomSize; } void ChargeWindow::Load (Stream& S) // Load the window from a stream { // Load the parental data ItemWindow::Load (S); // Get a pointer to the listbox Box = (ChargeListbox*) ForcedItemWithID (1); // Load additional data S >> ZoomSize; } u16 ChargeWindow::StreamableID () const // Return the stream ID { return ID_ChargeWindow; } Streamable* ChargeWindow::Build () // Create an empty ChargeWindow { return new ChargeWindow (Empty); } unsigned ChargeWindow::MinXSize () const // Return the minimum X size of the window. Override this to limit resizing. { return 18; } unsigned ChargeWindow::MinYSize () const // Return the minumim Y size of the window. Override this to limit resizing. { return 4; // One line at least } void ChargeWindow::Resize (const Rect& NewBounds) // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). { // If we have already a matrix listbox, resize it to fit into the new // window if (Box) { Box->SetWidth (NewBounds.XSize () - 2); Box->SetHeight (NewBounds.YSize () - 3); } // Now do the actual resize ItemWindow::Resize (NewBounds); } void ChargeWindow::Zoom () // Zoom the window { // Get the desktop bounds Rect Desktop = Background->GetDesktop (); // Check if we must zoom in or out if (OBounds != Desktop) { // Remember the old size, then zoom out ZoomSize = OBounds; Resize (Desktop); } else { // Zoom in Resize (ZoomSize); } } void ChargeWindow::HandleKey (Key& K) // Key dispatcher used in Browse { // First call the derived function. ItemWindow::HandleKey (K); // Maybe the listbox has some work Box->HandleKey (K); } void ChargeWindow::HandleEvent (Event& E) // Handle incoming events. { // Call the derived function ItemWindow::HandleEvent (E); if (E.Handled) { return; } // Check which event switch (E.What) { case evChargeUpdate: // Update the listbox Box->Draw (); break; } } estic-1.61.orig/estic/chargwin.h0100644000176100001440000000505707031424722016102 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARGWIN.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Charge display window #ifndef _CHARGWIN_H #define _CHARGWIN_H #include "itemwin.h" /*****************************************************************************/ /* class ChargeWindow */ /*****************************************************************************/ class ChargeWindow: public ItemWindow { static unsigned WindowCount; // Count of ChargeWindows Rect ZoomSize; // Small window size for zooming class ChargeListbox* Box; // Pointer to the charge listbox protected: virtual void HandleKey (Key& K); // Key dispatcher used in Browse public: ChargeWindow (StreamableInit); // Build constructor ChargeWindow (); // Construct an ChargeWindow virtual ~ChargeWindow (); // Destruct an ChargeWindow virtual void Store (Stream &) const; virtual void Load (Stream &); virtual u16 StreamableID () const; static Streamable* Build (); // Make the window persistent virtual unsigned MinXSize () const; // Return the minimum X size of the window. Override this to limit resizing. virtual unsigned MinYSize () const; // Return the minumim Y size of the window. Override this to limit resizing. virtual void Resize (const Rect& NewBounds); // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). virtual void Zoom (); // Zoom the window void Update (); // Update the window if information has changed void HandleEvent (Event& E); // Handle incoming events. Calls Update() if the application is idle }; // End of CHARGWIN.H #endif estic-1.61.orig/estic/cliwin.cc0100644000176100001440000000732107031424722015717 0ustar debacleusers/*****************************************************************************/ /* */ /* CLIWIN.CC */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Call window #include "eventid.h" #include "event.h" #include "coll.h" #include "textitem.h" #include "settings.h" #include "progutil.h" #include "icmsg.h" #include "icobjid.h" #include "icevents.h" #include "devstate.h" #include "iccom.h" #include "iccli.h" #include "cliwin.h" // Register the class LINK (CLIWindow, ID_CLIWindow); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msCLIWindowTitle = MSGBASE_ICCLIWIN + 0; const u16 msCLIWindowHeader1 = MSGBASE_ICCLIWIN + 1; const u16 msCLIWindowHeader2 = MSGBASE_ICCLIWIN + 2; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Switch off diag mode if the CLI window is active int CLINoDiagMode = 1; // Count of CLIWindows unsigned CLIWindow::WindowCount = 0; /*****************************************************************************/ /* class CLIWindow */ /*****************************************************************************/ inline CLIWindow::CLIWindow (StreamableInit): IstecMsgWindow (Empty) // Build constructor { // One window more WindowCount++; // Tell the program that a new window is active PostEvent (evCLIWinChange, WindowCount); // Disable diag mode DisableDiagMode (); } CLIWindow::CLIWindow (): IstecMsgWindow (msCLIWindowTitle, msCLIWindowHeader1, msCLIWindowHeader2, "CLIWindow.Bounds") // Construct an CLIWindow { // Ok, we have the window now WindowCount++; // Tell the program that a new window is active PostEvent (evCLIWinChange, WindowCount); // Disable diag mode DisableDiagMode (); } CLIWindow::~CLIWindow () // Destruct an CLIWindow { // Enable diag mode EnableDiagMode (); // Decrease the window count and invalidate the global pointer WindowCount--; // Tell the program that a window has been destroyed PostEvent (evCLIWinChange, WindowCount); } u16 CLIWindow::StreamableID () const { return ID_CLIWindow; } Streamable* CLIWindow::Build () // Make the window persistent { return new CLIWindow (Empty); } void CLIWindow::HandleEvent (Event& E) // Handle an incoming event { // Call the derived function IstecMsgWindow::HandleEvent (E); if (E.Handled) { return; } // Switch on the type of the arriving event switch (E.What) { case evIncomingLogMsg: CLI* Info; Info = ((CLI*) E.Info.O); Write (* (String*) E.Info.O); break; } } estic-1.61.orig/estic/cliwin.h0100644000176100001440000000371507031424722015564 0ustar debacleusers/*****************************************************************************/ /* */ /* CLIWIN.H */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Calling line identification window #ifndef _CLIWIN_H #define _CLIWIN_H #include "icmsgwin.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Switch off diag mode if the CLI window is active extern int CLINoDiagMode; /*****************************************************************************/ /* class CLIWindow */ /*****************************************************************************/ class CLIWindow: public IstecMsgWindow { static unsigned WindowCount; // Count of CLIWindows public: CLIWindow (StreamableInit); // Build constructor CLIWindow (); // Construct an CLIWindow virtual ~CLIWindow (); // Destruct an CLIWindow virtual u16 StreamableID () const; static Streamable* Build (); // Make the window persistent virtual void HandleEvent (Event& E); // Handle an incoming event }; // End of CLIWIN.H #endif estic-1.61.orig/estic/compile.doc0100644000176100001440000001202607031424722016240 0ustar debacleusers ESTIC V 1.60, 05.03.1997 Enhanced Supervisor Tool for ISTEC Configuration Copyright (C) 1995-97 Ullrich von Bassewitz Nutzungsbestimmungen und Weitergabe ----------------------------------- Die Software (sowohl die Quellcodes, als auch die Binaries) werden ohne jegliche Zusagen/Garantien bezüglich Funktionalität oder Funktionsfähigkeit abgegeben. Weder die Autoren noch die Distributoren übernehmen eine Verantwortung für Schäden, die durch die Benutzung der Software verursacht werden. Die Software darf frei verwendet und weitergegeben werden, wobei "frei" ausdrücklich auch eine kommerzielle Nutzung/Weitergabe einschließt, *vorausgesetzt* die folgenden Bedingungen werden eingehalten: 1. Die Herkunft der Software muß - wenn überhaupt - dann korrekt angegeben werden. Es ist nicht erlaubt, die Software als Werk eines anderen auszugeben. Wird die Software in Teilen oder als Ganzes in einem Produkt benutzt, dann würde ich mich über einen Hinweis auf die Herkunft in der Dokumentation freuen. Ein solcher Hinweis ist aber nicht zwingend notwendig. 2. Geänderte Quellcodes müssen deutlich als solche gekennzeichnet werden und dürfen nicht ohne einen expliziten Hinweis auf die durchgeführten Änderungen weiterverteilt werden. 3. Die Bedingungen über die Nutzung/Weitergabe dürfen nicht entfernt oder geändert werden. Speziell für ESTIC gilt noch der folgende Hinweis: * Die Bestimmungen des Datenschutzes sind zu beachten! Das Logging-Feature kann speziell bei Anwendung im kommerziellen Bereich gegen Datenschutzbestimmungen verstoßen! Anleitung zum Übersetzen der ESTIC Sourcen: ------------------------------------------- Vorbemerkung: Beim Auspacken (unter DOS & OS/2 unbedingt Info-Zip's unzip mit Parameter -a verwenden!) werden drei Unterverzeichnisse erzeugt: spunk, areacode und estic. In spunk befindet sich die zugrundeliegende Klassenbibliothek, in estic der applikationsspezifische Code. Die folgenden Schritte müssen zuerst im Verzeichnis spunk, dann im Verzeichnis areacode, dann im Verzeichnis estic ausgeführt werden. 0. Notwendiger Compiler ist gcc unter Linux und FreeBSD bzw. Watcom-C unter DOS & OS/2. Spunk selber läßt sich auch mit Borland-C übersetzen (sowohl die DOS als auch die OS/2 Version), BCC hat jedoch diverse Problemchen, um die ich mich bei estic nicht weiter gekümmert habe, für estic existiert deshalb kein Makefile für bcc. Wer unbedingt eine Übersetzung hinbekommen will sollte kurz bei mir fuer nähere Infos anfragen. 1. Passendes Makefile aus dem Verzeichnis "make" nach "Makefile" kopieren. linux.mak für Linux verwenden, freebsd.mak für FreeBSD usw. 2. Nur für Linux & FreeBSD: File Dependencies erzeugen durch Aufruf von "make dep". 3. "make" eingeben. Wer wenig Zeit hat, der kann im Verzeichnis spunk auch "make lib" verwenden, dann wird der Resourcen-Editor nicht erzeugt. 4. Nicht vergessen: Dasselbe nochmal im Verzeichnis estic wiederholen... Sonstige Hinweise: ------------------ Die Übersetzung unter Linux erfolgte mit g++ 2.7.2. * Ich übernehme keinerlei Garantie dafür, daß sich ESTIC auch mit neueren Compilern übersetzen läßt. Ich habe in der Vergangenheit versucht, mit der Entwicklung Schritt zu halten und den Code so zu schreiben, daß er die Fehler und Unzulänglichkeiten aller GNU-C++ Compiler umgeht. Da jede neue g++ Version aber neue Fehler hat, oder bisher völlig legale Konstrukte plötzlich nicht mehr schluckt, ist aber inzwischen zu einem solchen Aufwand geworden, daß ich beschlossen habe, es sein zu lassen. ESTIC *sollte* sich mit g++ 2.6.3 übersetzen lassen, evtl. funktioniert das auch mit neueren Versionen (Kommentar im Makefile beachten), ich übernehme aber wie gesagt keine Garantien. Für Erfolgs-/Mißerfolgsmeldungen bin ich dankbar, definitive Anpassungen gibt's erst, wenn ich selber den entsprechenden Compiler verwende. * ESTIC enthält z.T. unsinnigen Code um einige gcc Warnungen abzustellen. * Einige Warnungen, speziell bei Bibliotheksfiles ließen sich auch durch wildeste Cast-Orgien nicht beseitigen. Es ist sonst nicht meine Art, Code herauszugeben, der sich nicht ohne Warnungen uebersetzen läßt, hier hatte ich leider keine andere Möglichkeit. FreeBSD: * Die Übersetzung erfolgte unter FreeBSD 2.1.0 mit g++ 2.6.3. FreeBSD hat einige Probleme von Linux nicht, weil unter FreeBSD ein eigener Linker verwendet wird, der sich - speziell bei Templates - anders verhält. Die Übersetzung unter DOS bzw. OS/2 wurde mit Watcom C Version 10.6 durchgeführt. Aufgrund von Speicherproblemen wurde die DOS Version diesmal als 32-Bit Version erzeugt. Wenn viel DOS Speicher zur Verfügung steht kann auch versuchsweise eine 16-Bit Version erzeugt werden ("make dos" anstelle von "make dos32" eingeben). Die als Binary gelieferte Version benutzt den DOS4GW Extender. Für die an spunk interessierten: Es existiert für spunk etwas ähnliches wie eine Dokumentation im Verzeichnis spunk/doc Happy hacking! Uz estic-1.61.orig/estic/devstate.cc0100644000176100001440000003677507031424722016270 0ustar debacleusers/*****************************************************************************/ /* */ /* DEVSTATE.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // State of one device // This module contains some unnecessary globale overrides ("::") to work // around one of the gcc bugs. #include "event.h" #include "coll.h" #include "delay.h" #include "strcvt.h" #include "progutil.h" #include "devstate.h" #include "icevents.h" #include "icac.h" #include "icalias.h" #include "iccom.h" #include "iclog.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Wait time after a call before requesting the charges int DebugWaitAfterCall = 700; // How many digits of the phone number should be replaced by an 'X'? int XDigits = 0; // Max length of the phone number static const unsigned CallPhoneMaxLen = 16; // Width of the matrix window. ## BEWARE: DUPLICATED IN ICDIAG.CC!!! static const unsigned MatrixWindowWidth = 64; /*****************************************************************************/ /* Constants for the State field in DevStateInfo */ /*****************************************************************************/ const unsigned stSchleife = 0x0001; const unsigned stAmt1 = 0x0002; const unsigned stAmt2 = 0x0004; const unsigned stAmt = stAmt1 | stAmt2; const unsigned stInt1 = 0x0008; const unsigned stInt2 = 0x0010; const unsigned stInt3 = 0x0020; const unsigned stInt = stInt1 | stInt2 | stInt3; const unsigned stTon = 0x0040; const unsigned stWTon = 0x0080; const unsigned stTFE = 0x0100; const unsigned stRuf = 0x0200; const unsigned stBusy = 0x0FFF; // Idle if none of the bits is set const unsigned stAliasRead = 0x1000; const unsigned stForcedRing = 0x2000; const unsigned stForcedRingOn = 0x4000; // Ring state for forced ring /*****************************************************************************/ /* class CallQueue */ /*****************************************************************************/ class CallQueue: public Collection, public EventHandler { public: CallQueue (); // Create a CallQueue DevStateInfo* At (int Index); // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING virtual void HandleEvent (Event& E); // Handle incoming events }; CallQueue::CallQueue (): Collection (10, 10) { } DevStateInfo* CallQueue::At (int Index) // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING { // Check range if (Index < 0 || Index >= Count) { FAIL ("CallQueue::At: Index out of bounds"); return NULL; } return Collection::At (Index); } void CallQueue::HandleEvent (Event& E) // Handle incoming events { // Switch on the type of event switch (E.What) { case evChargeUpdate: if (GetCount () > 0) { // There's something in the queue. Get the first entry. DevStateInfo* DS = At (0); // Update the charges DS->CallCharges = ::Charges [DS->DevNum] - DS->StartCharges; // Replace the last few digits of the phone number by the // character 'X' DS->ReplaceDigits (XDigits); // Get the log message String Msg = DS->LogMsg (); // Post the message with the log string PostEvent (evCallLogMsg, new String (Msg)); // Now post the "call complete" event with the object as // data. The DevStateInfo object will be deleted when the // call is delivered. PostEvent (evCallComplete, DS); // Delete the entry (since ShouldDelete is zero, this will // only delete the pointer, not the object). AtDelete (0); } break; } } static CallQueue Queue; /*****************************************************************************/ /* class DevStateInfo */ /*****************************************************************************/ DevStateInfo::DevStateInfo (unsigned char Device): DevNum (Device), State (0), HasExt (0), MatrixLine (MatrixWindowWidth) { // Set the width of the matrix line and insert the number MatrixLine.Set (0, MatrixWindowWidth, ' '); MatrixLine.Replace (colNr, U32Str (Device + 21)); // Create the rest of the line MatrixLine.Replace (colAmt1, '-'); MatrixLine.Replace (colAmt2, '-'); MatrixLine.Replace (colInt1, '-'); MatrixLine.Replace (colInt2, '-'); MatrixLine.Replace (colInt3, '-'); MatrixLine.Replace (colTon, '-'); MatrixLine.Replace (colWTon, '-'); MatrixLine.Replace (colTFE, '-'); MatrixLine.Replace (colRuf, '-'); } DevStateInfo::DevStateInfo (const DevStateInfo& X): DevNum (X.DevNum), State (X.State), CallPhone (X.CallPhone), CallStart (X.CallStart), CallDuration (X.CallDuration), StartCharges (X.StartCharges), CallCharges (X.CallCharges), HasExt (X.HasExt), MatrixLine (X.MatrixLine) { } void DevStateInfo::ClearCallPhone () // Clear the call phone number, reset the stuff in the matrix line { // Clear the number CallPhone.Clear (); // Reset the matrix line MatrixLine.Set (colPhone, CallPhoneMaxLen, ' '); } String DevStateInfo::LogMsg () // Create a message for the logfile from the data { // If AutoReadAliases is set, reread the alias file before trying to // resolve call data, but do this only once. if (AutoReadAliases != 0 && GetState (stAliasRead) == 0) { SetState (stAliasRead); ReadAliasFile (); } // Format of the line: // 1 2 3 4 5 6 7 8 // 012345678901234567890123456789012345678901234567890123456789012345678901234567890 // NR ALIAS_______ DATE____ START___ DURATION CALLPHONE_______ UNIT DM____ String StartDate = CallStart.DateTimeStr ("%d.%m.%y"); String StartTime = CallStart.DateTimeStr ("%H:%M:%S"); unsigned DurSec = CallDuration.GetSec (); unsigned DurMin = (DurSec % 3600) / 60; unsigned DurHour = DurSec / 3600; DurSec %= 60; String DevAlias = GetAlias (DevNum+21); DevAlias.Trunc (12); // Use the alias of the phone number if one is defined, otherwise use // the number String Phone = GetAlias (CallPhone); if (Phone.IsEmpty ()) { Phone = CallPhone; } Phone.Trunc (CallPhoneMaxLen); return FormatStr ("%d %-12s %s %s %02d:%02d:%02d %-16s %4d %6.2f", DevNum+21, DevAlias.GetStr (), StartDate.GetStr (), StartTime.GetStr (), DurHour, DurMin, DurSec, Phone.GetStr (), CallCharges, CallCharges * PricePerUnit); } int DevStateInfo::GetState (unsigned StateMask) { return (State & StateMask) != 0; } void DevStateInfo::SetState (unsigned NewState) { State |= NewState; } void DevStateInfo::ClrState (unsigned NewState) { State &= ~NewState; } void DevStateInfo::SetSchleife (int State) { // If we already have the correct settings, ignore the call if (State == GetState (stSchleife)) { // Ignore it return; } // Now check which change if (State) { // Mark the device in the matrix MatrixLine.Replace (colSchleife, '*'); // Set the state bit SetState (stSchleife); // Clear forced ring ClrState (stForcedRing | stForcedRingOn); // Clear the phone number ClearCallPhone (); } else { // Unmark the device MatrixLine.Replace (colSchleife, ' '); // Reset the state bit ClrState (stSchleife); // Clear the phone number if we have no external line. Otherwise // simulate the "Amt off" message to circumvent a bug in the istec // firmware if (GetState (stAmt) == 0) { // Clear the phonre number ClearCallPhone (); } else { // Simulate "Amt off" SetAmt (0, GetState (stAmt1)? 1 : 2); } } } void DevStateInfo::SetAmt (int State, unsigned Amt) { // If we already have the correct settings, ignore the call if (State == GetState (stAmt)) { // Ignore it return; } // Map the line number to a column number in the matrix unsigned Column = 0; // Make gcc happy unsigned Mask = 0; // Make gcc happy switch (Amt) { case 1: Column = colAmt1; Mask = stAmt1; break; case 2: Column = colAmt2; Mask = stAmt2; break; default: FAIL ("SetAmt: Invalid value for Amt"); } // Check which state change if (State) { // Update the matrix line MatrixLine.Replace (Column, 'x'); // Remember the line used SetState (Mask); // This should be an external call, so handle the phone number. // This is somewhat difficult to handle since there are different // firmware versions, some that get a line if you pick up the phone, // others that need a predialed zero. Worse, sometimes the diag message // indicating that we have an external line comes late, after dialing // two or even three digits. Further more, the new firmware with the // "knock" feature disables and then re-enables the external line // status each time, a knock signal is generated. // So assume the following: If the phone number is not empty when we // get the external line signal, AND if the device is active (loop) // AND there is no tone signal on this line, THEN delete the first // digit of the phone number. if (GetState (stSchleife) && GetState (stTon) == 0 && CallPhone.Len () > 0) { // Delete the string in the matrix line MatrixLine.Set (colPhone, CallPhoneMaxLen, ' '); // Delete the first digit CallPhone.Del (0, 1); // Try to beautify the phone number by putting a separator behind // the areacode CallPhone = IstecBeautifyPhone (CallPhone); // Put the new number into the matrix line if (CallPhone.Len () > 0) { MatrixLine.Replace (colPhone, CallPhone); } } } else { // Update the matrix line MatrixLine.Replace (Column, '-'); // Clear the used line ClrState (stAmt); // Unfortunately, beginning with firmware 1.95, the release of the // external line does *not* mean that the call is terminated. The // Istec generates a off/on sequence each time, the knock signal // tone is generated. To verify that the call is really terminated, // use the Tone state in addition to the "line off" state. // If we had an external call, print the info if (GetState (stTon) == 0 && HasExt) { // Get current time Time Current = Now (); // Calculate the durcation of the call CallDuration = Current - CallStart; // Reset flag for external call HasExt = 0; // Create an entry for the queue DevStateInfo* DI = new DevStateInfo (*this); // Wait some time Delay (DebugWaitAfterCall); // Insert the entry into into the call queue Queue.Insert (DI); // Request a charge update from the istec IstecRequestCharges (); } // If the device is inactive now (Schleife == 0), clear the called // phone number. SetSchleife will act in a similiar way, clearing the // call phone if there is no external line, so the number is cleared // if both, Amt and Schleife are inactive. if (GetState (stSchleife) == 0) { // Both, Amt and Schleife are inactive, clear the displayed // phone number ClearCallPhone (); } } } void DevStateInfo::SetInt (int State, unsigned Int) { // Map the line number to a column number in the matrix unsigned Column = 0; // Make gcc happy unsigned Mask = 0; // Make gcc happy switch (Int) { case 1: Column = colInt1; Mask = stInt1; break; case 2: Column = colInt2; Mask = stInt2; break; case 3: Column = colInt3; Mask = stInt3; break; default: FAIL ("SetInt: Invalid column number"); } // Ignore the call if we already have the correct state if (State == GetState (Mask)) { return; } // Check which state change we have if (State) { // Show the change MatrixLine.Replace (Column, 'x'); // Set the state bit SetState (Mask); // Remember which device uses this internal line IntCon [Int-1] = DevNum; } else { // Show the change MatrixLine.Replace (Column, '-'); // Reset the state bit ClrState (Mask); // If the internal connection goes off, but we have an external one, // we have an external call. if (GetState (stAmt)) { // Remember the starting time CallStart = Now (); // Remember the charge info on start StartCharges = ::Charges [DevNum]; // Remember that we are connected externally HasExt = 1; } } } void DevStateInfo::SetTon (int State) { if (State) { MatrixLine.Replace (colTon, 'x'); SetState (stTon); } else { MatrixLine.Replace (colTon, '-'); ClrState (stTon); } } void DevStateInfo::SetWTon (int State) { if (State) { MatrixLine.Replace (colWTon, 'x'); SetState (stWTon); } else { MatrixLine.Replace (colWTon, '-'); ClrState (stWTon); } } void DevStateInfo::SetTFE (int State) { if (State) { MatrixLine.Replace (colTFE, 'x'); SetState (stTFE); } else { MatrixLine.Replace (colTFE, '-'); ClrState (stTFE); } } void DevStateInfo::SetRuf (int State) { if (State) { // Update the display MatrixLine.Replace (colRuf, 'x'); // Set the state bit SetState (stRuf); // Clear forced ring ClrState (stForcedRing | stForcedRingOn); } else { // Update the display MatrixLine.Replace (colRuf, '-'); // Clear the state bit ClrState (stRuf); } } void DevStateInfo::AddDigit (char Digit) // Add a digit to the phone number if the device is in a state where a digit // is accepted (dialed) { if (Digit != 'R' && (GetState (stAmt) == 0 || HasExt == 0)) { MatrixLine.Replace (colPhone + CallPhone.Len (), Digit); CallPhone += Digit; } } void DevStateInfo::ReplaceDigits (int Count, char C) // Replace the given number of trailing digits of the phone number by // the character C. { if (Count > 0) { // The count may not be greater than the length of the string int Len = (int) CallPhone.Len (); if (Count > Len) { Count = Len; } // Replace trailing digits while (Count) { CallPhone.Replace (Len - Count, C); Count--; } } } void DevStateInfo::HandleEvent (Event& E) // Handle incoming events. { switch (E.What) { case evForcedRing: // Accept if this is the correct device and the line is idle if (unsigned (DevNum + 21) == unsigned (E.Info.U % 256)) { if (GetState (stBusy) == 0) { // Get the duration ForcedRingEnd = Time () + TimeDiff (double (E.Info.U / 256)); // Set the new state SetState (stForcedRing | stForcedRingOn); // Send the command to the istec IstecRingOn (DevNum); } // The event is handled now E.Handled = 1; } break; case evSecondChange: // Check if we have an active forced ring if (GetState (stForcedRing) && GetState (stBusy) == 0) { if (*(Time*) E.Info.O >= ForcedRingEnd) { // End the forced ring ClrState (stForcedRing | stForcedRingOn); IstecRingOff (DevNum); } else { // No end. Toggle ring state if (GetState (stForcedRingOn)) { // Ring is on, switch it off ClrState (stForcedRingOn); IstecRingOff (DevNum); } else { // Ring is off, switch it on SetState (stForcedRingOn); IstecRingOn (DevNum); } } } break; case evExit: // Shutdown forced ring if active if (GetState (stForcedRing) && GetState (stForcedRingOn)) { // Forced ring is active, clear it ClrState (stForcedRing | stForcedRingOn); IstecRingOff (DevNum); } break; } } estic-1.61.orig/estic/devstate.h0100644000176100001440000000775407031424722016125 0ustar debacleusers/*****************************************************************************/ /* */ /* DEVSTATE.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // State of one device #ifndef _DEVSTATE_H #define _DEVSTATE_H #include "event.h" #include "datetime.h" #include "icintcon.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Wait time after a call before requesting the charges extern int DebugWaitAfterCall; // How many digits of the phone number should be replaced by an 'X'? extern int XDigits; /*****************************************************************************/ /* class DevStateInfo */ /*****************************************************************************/ class DevStateInfo: public Object, public EventHandler { // Columns for the matrix window // 1 2 3 4 5 6 7 // 01234567890123456789012345678901234567890123456789012345678901234567890 // // Nr. Amt1 Amt2 Int1 Int2 Int3 Ton WTon TFE Ruf Nummer enum { colNr = 1, colSchleife = 3, colAmt1 = 6, colAmt2 = 11, colInt1 = 16, colInt2 = 21, colInt3 = 26, colTon = 31, colWTon = 35, colTFE = 40, colRuf = 44, colPhone = 47 }; void ClearCallPhone (); // Clear the call phone number, reset the stuff in the matrix line public: const unsigned char DevNum; // Device number u32 State; // Device state String CallPhone; // Phone number dialed Time CallStart; // Start of call TimeDiff CallDuration; // Duration of call u16 StartCharges; // Charges at start of call u16 CallCharges; // Charges for call unsigned HasExt; // True if device had an external call String MatrixLine; // The line that's displayed Time ForcedRingEnd; // End of forced ring DevStateInfo (unsigned char Device); // Create a DevStateInfo object DevStateInfo (const DevStateInfo& X); // Copy constructor String LogMsg (); // Create a message for the logfile from the data int GetState (unsigned StateMask); void SetState (unsigned NewState); void ClrState (unsigned NewState); // Get/set/clear bits in State void SetSchleife (int State); void SetAmt (int State, unsigned Amt); void SetInt (int State, unsigned Int); void SetTon (int State); void SetWTon (int State); void SetTFE (int State); void SetRuf (int State); // Set specific matrix states void AddDigit (char Digit); // Add a digit to the phone number if the device is in a state where a digit // is accepted (dialed) void ReplaceDigits (int Count, char C = 'X'); // Replace the given number of trailing digits of the phone number by // the character C. virtual void HandleEvent (Event& E); // Handle incoming events. }; // End of DEVSTATE.H #endif estic-1.61.orig/estic/estic.cc0100644000176100001440000014404107031424722015542 0ustar debacleusers/*****************************************************************************/ /* */ /* ESTIC.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "eventid.h" #include "delay.h" #include "screen.h" #include "environ.h" #include "syserror.h" #include "filepath.h" #include "filesel.h" #include "fviewer.h" #include "program.h" #include "progutil.h" #include "menuitem.h" #include "menue.h" #include "strcvt.h" #include "stdmenue.h" #include "stdmsg.h" #include "memstrm.h" #include "datetime.h" #include "inifile.h" #include "settings.h" #include "winmgr.h" #include "icconst.h" #include "icmsg.h" #include "icevents.h" #include "icerror.h" #include "icconfig.h" #include "icdlog.h" #include "iccom.h" #include "iclog.h" #include "icalias.h" #include "iccron.h" #include "icfile.h" #include "devstate.h" #include "icdevs.h" #include "icident.h" #include "icbaseed.h" #include "icdiag.h" #include "callwin.h" #include "icac.h" #include "iccli.h" #include "icshort.h" #include "cliwin.h" #include "chargwin.h" #ifdef LINUX #include "imon.h" #endif #include "estic.h" /*****************************************************************************/ /* Constants */ /*****************************************************************************/ // Diag mode update static const duOff = 0; static const duOn = 1; static const duAuto = 2; // Update if version <= 1.93 static const char VersionStr [] = "1.50"; static const char VersionID [] = "ESTIC-Version"; /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msAboutInfo = MSGBASE_ISTEC + 60; const u16 msConnMehrgeraete = MSGBASE_ISTEC + 61; const u16 msConnAnlagen = MSGBASE_ISTEC + 62; const u16 msConnUnknown = MSGBASE_ISTEC + 63; const u16 msIstecConfig = MSGBASE_ISTEC + 64; const u16 msLoadFileHeader = MSGBASE_ISTEC + 65; const u16 msSaveFileHeader = MSGBASE_ISTEC + 66; const u16 msComPortNotOpen = MSGBASE_ISTEC + 67; const u16 msIstecTimeout = MSGBASE_ISTEC + 68; const u16 msWriteChanges = MSGBASE_ISTEC + 69; const u16 msPrintHeader = MSGBASE_ISTEC + 71; const u16 msPrintHeader2 = MSGBASE_ISTEC + 72; const u16 msChargeTableHeader = MSGBASE_ISTEC + 73; const u16 msChargeLine = MSGBASE_ISTEC + 74; const u16 msErrorComPortOpen = MSGBASE_ISTEC + 75; const u16 msRecBufOverflow = MSGBASE_ISTEC + 76; const u16 msRecBufUnderflow = MSGBASE_ISTEC + 77; const u16 msInvalidReply = MSGBASE_ISTEC + 78; const u16 msWrongDevice = MSGBASE_ISTEC + 79; const u16 msPrintFileSelHeader = MSGBASE_ISTEC + 80; const u16 msViewLogSelHeader = MSGBASE_ISTEC + 81; const u16 msSettingsFileError = MSGBASE_ISTEC + 82; const u16 msSettingsVersionError = MSGBASE_ISTEC + 83; const u16 msReadCronFile = MSGBASE_ISTEC + 84; const u16 msWriteShortNumbers = MSGBASE_ISTEC + 85; const u16 msCTIError = MSGBASE_ISTEC + 86; const u16 msAskReloadConfig = MSGBASE_ISTEC + 87; const u16 msEEPROMInUse = MSGBASE_ISTEC + 88; const u16 msCronJobProcessing = MSGBASE_ISTEC + 89; const u16 msCronJobError = MSGBASE_ISTEC + 90; const u16 msCLIWinWarning = MSGBASE_ISTEC + 91; /*****************************************************************************/ /* class IstecApp */ /*****************************************************************************/ IstecApp::IstecApp (int argc, char* argv []): Program (argc, argv, CreateMenueBar, CreateStatusLine, "estic"), StatusFlags (0), ComPortName ("COM2"), SettingsFile ("estic.rc"), IstecPresent (0), DayNight (0), Changes (0), ShortNumberChanges (0), Currency (NLSData.CurrStr), VideoMode (vmAsk), ShowDateTime (1), ShowInfoOnStartup (1), DiagModeUpdate (duAuto), LastUpdate (Now ()), DiagModeUpdateCounter (450), // 7.5 min ChargesUpdateCounter (900) // 15 min { // Assume that we don't have an Istec int HaveIstec = 1; // Read the default values of some variables from the ini file ReadIniFile (); // String collection with cron events needed for later Collection CronEvents (5, 5, 1); // Parse the command line int I = 1; while (I < ArgCount) { char* Item = ArgVec [I]; if (*Item == '-') { Item++; switch (*Item) { case 'a': PortBase = atoi (GetArgParam (I)); break; case 'c': CronEvents.Insert (new String (GetArgParam (I))); break; case 'i': PortIRQ = atoi (GetArgParam (I)); break; case 'n': HaveIstec = 0; break; case 'p': ComPortName = GetArgParam (I); break; } } // Next argument I++; } // Now switch the video mode if (VideoMode != vmAsk) { ChangeVideoMode (VideoMode); } // Display date and Time in the upper right corner of the main menu if (ShowDateTime > 0) { DisplayDateTime (Now ()); } // Try to open the debug logfile InitDebugLog (DebugLog); // Open the program option file if (!SettingsFile.IsEmpty ()) { // If we cannot open the settings file, print an error message. // If we could open the file, check for the version string to // make shure, the guys out there don't use old versions of the // file. if (StgOpen (MakeAbsolute (SettingsFile)) != 0) { IstecError (msSettingsFileError); } else { if (!StgEmpty ()) { String Version = StgGetString (VersionID, ""); if (Version != VersionStr) { // Incorrect version, close the file (don't use it) IstecError (msSettingsVersionError); StgClose (); } } else { // This is a new resource - write the version string StgPutString (VersionStr, VersionID); } } } // Try to initialize the com port if this was not prohibited if (HaveIstec) { // Try to open the com port if (OpenComPort (ComPortName) != 0) { // Port could not be opened IstecError (msErrorComPortOpen); } else { // Com port could be opened, check for the istec if (EvalCmd (IstecReady ())) { // Istec is there IstecPresent = 1; } } } // If the istec is online, read the cron file ReadCronFile (); // Read the complete configuration from the istec if possible, else reset // it to a known state InitIstecConfig (); // Load the window manager from the settings file WinMgr = (WindowManager*) StgGet ("WinMgr"); if (WinMgr == NULL) { // Does not exist, create default WinMgr = new WindowManager; } // If the istec is not present, disable some of the menue choices, if // the istec is present, switch to debug mode if requested if (IstecPresent) { // Enable the istec diagnostic messages EnableDiagMode (); // If we have a firmware version < 2.00, disable the short number // access if (FirmwareVersion < 2.00) { DisableCommand (miFileLoadShort); DisableCommand (miFileSaveShort); DisableCommand (miIstecLoadShort); DisableCommand (miIstecSaveShort); DisableCommand (miSwitchDayNight); DisableCommand (miEditShort); } // Set the country code string for the areacode resolver from the // Istec setting if it is not defined until now. if (CountryCode.IsEmpty ()) { CountryCode = U32Str (Config.GetCountryCode ()); } // Execute cron events that were given on the command line if (CronEvents.GetCount () > 0) { // We have some events, pop up a window Window* W = MsgWindow (LoadAppMsg (msCronJobProcessing), "", paCyan); // Execute all events for (I = 0; I < CronEvents.GetCount (); I++) { // Get the command String* S = CronEvents [I]; // Execute it, print a message on errors if (ExecuteCronEvent (*S) == FAILURE) { // Hide the "wait" window - that will look better W->Hide (); // Print an error message ErrorMsg (LoadAppMsg (msCronJobError) + *S); // Show the "wait" window again W->Show (); } } // Delete the window delete W; } } else { // Disable some commands DisableCommand (miIstecLoadConfig); DisableCommand (miIstecSaveConfig); DisableCommand (miIstecLoadShort); DisableCommand (miIstecSaveShort); DisableCommand (miSwitchDayNight); DisableCommand (miReadCronFile); DisableCommand (miMatrixWin); DisableCommand (miCallWin); DisableCommand (miCLIWin); DisableCommand (miCharges); DisableCommand (miChargeWin2); } // Ok, initialization is complete, post an apropriate event ::PostEvent (evInit); // Display the istec configuration if (ShowInfoOnStartup) { ShowIstecConfig (); } } IstecApp::~IstecApp () // Destruct an application object { // Post an event before shutting down ::PostEvent (evExit); // Close the com port CloseComPort (); // Delete the window manager delete WinMgr; // Close the settings file StgClose (); } const char* IstecApp::GetArgParam (int& Index) // Return the parameter for a command line argument. The parameter may // be part of the argument (as in "-cCOM1") or separate (as in "-c COM1"). // If the parameter is separate, Index is incremented, otherwise it's not. // If there is no argument, the function returns NULL. { // Assure that the index is valid PRECONDITION (Index >= 0 && Index < ArgCount); // Check if the parameter is appended if (strlen (ArgVec [Index]) > 2) { // Already found return ArgVec [Index] + 2; } // Parameter is next argument. Check if one exists. if (Index < ArgCount - 1) { // Found Index++; return ArgVec [Index]; } // No parameter found return 0; } void IstecApp::BackgroundWork (const Time& Current) // Idle function. Is used to check for debug messages in the receive queue. // This function contains some hacks. No spunk program should rely on calls // to App::Idle in a regular or even time based manner. But there is no // other way to implement the needed background functions without using // too much CPU resources. So I will do something dirty and use my knowledge // about the internals of the KbdGet() and Delay() functions here... // However, there are other solutions, but none of them is portable between // the supported operating systems. { // Get the system time and check if the time has changed TimeDiff Period = Current - LastUpdate; // Remember the last update time LastUpdate = Current; // Check if we have to talk with the istec if (IstecPresent) { // Check if must update the diag mode if (DiagModeUpdate == duOn || (DiagModeUpdate == duAuto && FirmwareVersion <= 1.93)) { if ((DiagModeUpdateCounter -= Period.GetSec ()) <= 0) { DiagModeUpdateCounter += 15 * 60; UpdateDiagMode (); } } // Check if we must request the charges if ((ChargesUpdateCounter -= Period.GetSec ()) <= 0) { ChargesUpdateCounter += 15 * 60; IstecRequestCharges (); } } } void IstecApp::CronHandler (const Time& T) // Is called from idle every minute, checks periodic events { HandleCronEvent (T); } void IstecApp::DisplayDateTime (const Time& T) // Display the time in the upper right corner { String S = T.DateTimeStr (ShowDateTime > 1); MainMenue->Write (MainMenue->MaxX () - S.Len (), 0, S); } void IstecApp::HandleEvent (Event& E) // Handle incoming events. Calls Update() if the application is idle { // Call the derived function and return if the event is handled Program::HandleEvent (E); if (E.Handled) { return; } // Now look at the event code switch (E.What) { case evIdle: // Poll the istec IstecPoll (); break; case evSecondChange: // Update date&time if (ShowDateTime == 2) { DisplayDateTime (*(Time*)E.Info.O); } // Do some background work BackgroundWork (*(Time*)E.Info.O); break; case evMinuteChange: // Update date&time if (ShowDateTime == 1) { DisplayDateTime (*(Time*)E.Info.O); } // Call the cron handler CronHandler (*(Time*)E.Info.O); break; case evScreenSizeChange: // Will clear the screen - update date&time DisplayDateTime (Now ()); break; case evWinMgrNoWindows: // No more open windows DisableCommand (miClose); DisableCommand (miZoom); DisableCommand (miResize); DisableCommand (miTile); DisableCommand (miCascade); DisableCommand (miCloseAll); break; case evWinMgrFirstOpen: // One open window EnableCommand (miClose); EnableCommand (miZoom); EnableCommand (miResize); EnableCommand (miTile); EnableCommand (miCascade); EnableCommand (miCloseAll); break; case evWinMgrLastClose: // Max count - 1 reached EnableCommand (miOpen); break; case evWinMgrMaxWindows: // Max count of windows reached DisableCommand (miOpen); break; case evEnableCommand: EnableCommand ((i16) E.Info.U); break; case evDisableCommand: DisableCommand ((i16) E.Info.U); break; case evMatrixWinChange: // New count of active matrix windows if (E.Info.U == 0) { // No windows, enable open EnableCommand (miMatrixWin); } else { // Open window, disable more windows DisableCommand (miMatrixWin); } break; case evCallWinChange: // New count of active call windows if (E.Info.U == 0) { // No windows, enable open EnableCommand (miCallWin); } else { // Open window, disable more windows DisableCommand (miCallWin); } break; case evCLIWinChange: // New count of active CLI windows if (E.Info.U == 0) { // No windows, enable open EnableCommand (miCLIWin); } else { // Open window, disable more windows DisableCommand (miCLIWin); } break; case evChargeWinChange: // New count of active matrix windows if (E.Info.U == 0) { // No windows, enable open EnableCommand (miChargeWin1); EnableCommand (miChargeWin2); } else { // Open window, disable more windows DisableCommand (miChargeWin1); DisableCommand (miChargeWin2); } break; case evIMonWinChange: // New count of active imon windows if (E.Info.U == 0) { // No windows, enable open EnableCommand (miIMonWin); } else { // Open window, disable more windows DisableCommand (miIMonWin); } break; case evDayNightChange: if (FirmwareVersion >= 2.00) { MainMenue->SetToggleValue (miSwitchDayNight, E.Info.U); } break; } } void IstecApp::ReadIniFile () // Read default settings from an ini file { // Build the name of the ini file String IniName = GetProgName () + ".ini"; // Search for the ini file in the following directories: // -> the current dir // -> the home directory if $HOME is defined // -> the support path IniFile* F = new IniFile (IniName); if (F->GetStatus () != stOk) { // Not found, try the home dir delete F; String HomeDir = GetEnvVar ("HOME"); AddPathSep (HomeDir); F = new IniFile (HomeDir + IniName); if (F->GetStatus () != stOk) { // Ok, last resort: try the support path delete F; F = new IniFile (GetSupportPath () + IniName); if (F->GetStatus () != stOk) { // No ini file delete F; return; } } } // F points now to a valid ini file. Read the variables static const char EsticSection [] = "ESTIC"; static const char PortSection [] = "Port"; static const char PrintSection [] = "Printing"; static const char WindowSection [] = "Windows"; static const char AreaCodeSection [] = "AreaCode"; static const char LogSection [] = "Call-Logs"; static const char AliasSection [] = "Alias"; static const char CronSection [] = "Cron"; static const char DebugSection [] = "Debug"; static const char FirmwareSection [] = "Firmware"; static const char* ShowDateTimeKeys = "1^1|2^2|0^0|0^NONE|1^MINUTES|2^SECONDS|"; static const char* DiagModeUpdateKeys = "2^2|1^1|0^0|2^AUTO|1^ON|0^OFF|"; String AreaCodeFile; String DialPrefixStr; SettingsFile = F->ReadString (EsticSection, "SettingsFile", SettingsFile); ComPortName = F->ReadString (PortSection, "PortName", ComPortName); PortBase = F->ReadInt (PortSection, "PortBase", PortBase); PortIRQ = F->ReadInt (PortSection, "PortIRQ", PortIRQ); Headline = F->ReadString (PrintSection, "Headline", Headline); Currency = F->ReadString (PrintSection, "Currency", Currency); PricePerUnit = F->ReadFloat (PrintSection, "PricePerUnit", PricePerUnit); VideoMode = F->ReadInt (WindowSection, "VideoMode", VideoMode); ShowDateTime = F->ReadKeyword (WindowSection, "ShowDateTime", ShowDateTimeKeys); ShowInfoOnStartup = F->ReadBool (WindowSection, "ShowInfoOnStartup", ShowInfoOnStartup); AreaCodeFile = F->ReadString (AreaCodeSection, "AreaCodeFile", AreaCodeFile); CountryCode = F->ReadString (AreaCodeSection, "CountryCode", CountryCode); AreaCode = F->ReadString (AreaCodeSection, "AreaCode", AreaCode); DialPrefixStr = F->ReadString (AreaCodeSection, "DialPrefix", DialPrefixStr); OutgoingLog1 = F->ReadString (LogSection, "OutgoingLog1", OutgoingLog1); OutgoingLog2 = F->ReadString (LogSection, "OutgoingLog2", OutgoingLog2); OutgoingLog3 = F->ReadString (LogSection, "OutgoingLog3", OutgoingLog3); IncomingLog1 = F->ReadString (LogSection, "IncomingLog1", IncomingLog1); IncomingLog2 = F->ReadString (LogSection, "IncomingLog2", IncomingLog2); IncomingLog3 = F->ReadString (LogSection, "IncomingLog3", IncomingLog3); LogZeroCostCalls = F->ReadBool (LogSection, "LogZeroCostCalls", LogZeroCostCalls); XDigits = F->ReadInt (LogSection, "XDigits", XDigits); AliasFile = F->ReadString (AliasSection, "AliasFile", AliasFile); AutoReadAliases = F->ReadBool (AliasSection, "AutoReadAliases", AutoReadAliases); CronFile = F->ReadString (CronSection, "CronFile", CronFile); DebugWaitAfterCall = F->ReadInt (DebugSection, "WaitAfterCall", DebugWaitAfterCall); ShortWaitAfterMsg = F->ReadBool (DebugSection, "ShortWaitAfterMsg", ShortWaitAfterMsg); DebugLog = F->ReadString (DebugSection, "DebugLog", DebugLog); AppendDebugLog = F->ReadBool (DebugSection, "AppendDebugLog", AppendDebugLog); ConfigVersionHigh = F->ReadInt (DebugSection, "ConfigVersionHigh", ConfigVersionHigh); ConfigVersionLow = F->ReadInt (DebugSection, "ConfigVersionLow", ConfigVersionLow); DiagModeUpdate = F->ReadKeyword (FirmwareSection, "DiagModeUpdate", DiagModeUpdateKeys); FirmwareVersion = F->ReadFloat (FirmwareSection, "FirmwareVersion", FirmwareVersion); CLINoDiagMode = F->ReadBool (FirmwareSection, "CLINoDiagMode", CLINoDiagMode); // If an aliasfile is defined, read it. Otherwise try to read the aliases // from the ini file. if (AliasFile.IsEmpty ()) { // No aliasfile defined, read the device aliases from the ini file for (unsigned Dev = 21; Dev < 99; Dev++) { String Alias = F->ReadString (AliasSection, U32Str (Dev), ""); if (!Alias.IsEmpty ()) { NewAlias (Dev, Alias); } } } else { // Make the path name absolute AliasFile = MakeAbsolute (AliasFile); // Read the aliasfile ReadAliasFile (); // Enable the "Reread aliases" menu entry MainMenue->ActivateItem (miReadAliases); } // Set some other variables SetAreaCodeFilename (AreaCodeFile); if (DialPrefixStr.Len () > 0) { DialPrefix = DialPrefixStr [0]; } // Now close the ini file delete F; } int IstecApp::LoadConfig () // Calls IstecGetConfig an returns the same codes but displays a message as // this can last some time { // Pop up a window Window* Win = PleaseWaitWindow (); // Load the stuff from the istec int Result = IstecGetConfig (Config); // If we could get the configuration, read also the charges if (Result == ieDone) { Result = IstecGetCharges (); } // Delete the window delete Win; // Return the result return Result; } int IstecApp::StoreConfig () // Calls IstecPutConfig an returns the same codes but displays a message as // this can last some time { // Pop up a window Window* Win = PleaseWaitWindow (); // Load the stuff from the istec int Result = IstecPutConfig (Config); // Delete the window delete Win; if (Result == ieDone) { // Remember that we wrote a configuration Changes = 0; } // Return the result return Result; } int IstecApp::LoadShortNumbers () // Calls IstecGetShortNumbers and returns the same codes but displays // a message as this can last some time { // Pop up a window Window* Win = PleaseWaitWindow (); // Load the stuff from the istec int Result = IstecGetShortNumbers (ShortNumbers); // Delete the window delete Win; // Return the result return Result; } int IstecApp::StoreShortNumbers () // Calls IstecPutShortNumbers and returns the same codes but displays // a message as this can last some time { // Pop up a window Window* Win = PleaseWaitWindow (); // Load the stuff from the istec int Result = IstecPutShortNumbers (ShortNumbers); // Delete the window delete Win; if (Result == ieDone) { // Remember that we wrote the short numbers ShortNumberChanges = 0; } // Return the result return Result; } void IstecApp::InitIstecConfig () // Try to connect to the istec and download the istec configuration. // If this is impossible, initialize the configuration data to known // values. { // Initialize the configuration in any case since the following // LoadConfig will not load all device configurations LoadConfigDefault (Config, 1008); // If we could connect to the istec, try to download the configuration. if (IstecPresent == 0 || EvalCmd (LoadConfig ()) == 0) { // No istec or read error, use defaults IstecPresent = 0; Charges.Clear (); } else { // We did not have an error, load the short number info and current // active configuration if the firmware has such stuff if (FirmwareVersion >= 2.00) { // Load the day/night setting EvalCmd (IstecGetDayNight (DayNight)); // Set the menu item to show the actual setting MainMenue->SetToggleValue (miSwitchDayNight, DayNight); // Put 60 short numbers into the collection for (unsigned I = 1; I < 60; I++) { ShortNumbers.NewShortNumber (I); } EvalCmd (LoadShortNumbers ()); } } } String IstecApp::GetIstecName () // Return the name of the istec, determined by the parameters of the base // configuration. { return ::GetIstecName (Config.IstecID ()); } const char* IstecApp::GetProtocolName (unsigned Prot) // Return the protocol name used by the istec { switch (Prot) { case pr1TR6: return "1TR6"; case prDSS1: return "DSS1"; default: return ""; } } const String& IstecApp::GetConnectionName (unsigned Conn) // Return the connection type of the istec { unsigned MsgNum; switch (Conn) { case coPointToMulti: MsgNum = msConnMehrgeraete; break; case coPointToPoint: MsgNum = msConnAnlagen; break; default: MsgNum = msConnUnknown; break; } return LoadAppMsg (MsgNum); } void IstecApp::ShowIstecConfig () // Show the istec configuration { // Get some strings now to work around a gcc bug String IstecName = GetIstecName (); String ConnectionName = GetConnectionName (Config.GetConnection ()); // Set up the message to display String Msg = FormatStr ( LoadAppMsg (msIstecConfig).GetStr (), IstecName.GetStr (), Config.BaseConfig.VersionHigh, Config.BaseConfig.VersionLow, Config.GetExtS0 (), Config.GetIntS0 (), Config.GetDevCount (), GetProtocolName (Config.GetProtocol ()), ConnectionName.GetStr () ); InformationMsg (Msg); } void IstecApp::DisableCommand (i16 ID) // Disable the command bound to the menue item with the given ID { // Gray the item MainMenue->GrayItem (ID); // Get the accel key of the item Key AccelKey = MainMenue->GetAccelKey (ID); // If this key is registered, unregister it if (AccelKey != kbNoKey && KeyIsRegistered (AccelKey)) { UnregisterKey (AccelKey); } } void IstecApp::EnableCommand (i16 ID) // Enable the command bound to the menue item with the given ID { // Enable the item MainMenue->ActivateItem (ID); // Get the accel key of the item Key AccelKey = MainMenue->GetAccelKey (ID); // If this key is not registered, do it if (AccelKey != kbNoKey && KeyIsRegistered (AccelKey) == 0) { RegisterKey (AccelKey); } } TopMenueBar* IstecApp::CreateMenueBar () { TopMenueBar* M = (TopMenueBar*) App->LoadResource ("@ESTIC.MainMenue"); // Register the accel keys of the submenues App->RegisterKey (M->GetAccelKey (miEstic)); App->RegisterKey (M->GetAccelKey (miFile)); App->RegisterKey (M->GetAccelKey (miIstec)); App->RegisterKey (M->GetAccelKey (miCharges)); App->RegisterKey (M->GetAccelKey (miWindow)); App->RegisterKey (M->GetAccelKey (miOpen)); App->RegisterKey (M->GetAccelKey (miClose)); // Register the accel keys App->RegisterKey (M->GetAccelKey (miQuit)); App->RegisterKey (M->GetAccelKey (miWindowList)); // Gray unused items M->GrayItem (miReadAliases); M->GrayItem (miTile); M->GrayItem (miCascade); M->GrayItem (miCloseAll); M->GrayItem (miZoom); M->GrayItem (miResize); M->GrayItem (miClose); #ifndef LINUX M->GrayItem (miIMonWin); #endif // Return the result return M; } BottomStatusLine* IstecApp::CreateStatusLine () { const u32 Flags = siAltX_Exit; ((IstecApp*) App)->StatusFlags = Flags; return new BottomStatusLine (Flags); } int IstecApp::AskWriteChanges () // If there are differnces between the configuration stored in the istec and // the configuration in memory, ask to store the config data into the istec. // Return 1 if something has been written to the Istec, 0 otherwise. { int Written = 0; if (IstecPresent) { if (Changes) { // We have changes if (AskYesNo (LoadAppMsg (msWriteChanges)) == arYes) { // We should write the changes... if (EvalCmd (StoreConfig ())) { // Done Written = 1; Changes = 0; } } } } else { // No istec present, assume changes are written Changes = 0; } return Written; } int IstecApp::AskWriteShortNumbers () // If there are differnces between the short numbers stored in the istec and // the short numbers in memory, ask to store the numbers into the istec. // Return 1 if something has been written to the Istec, 0 otherwise. { int Written = 0; if (IstecPresent) { if (ShortNumberChanges) { // We have changes if (AskYesNo (LoadAppMsg (msWriteShortNumbers)) == 2) { // We should write the changes... if (EvalCmd (StoreShortNumbers ())) { // Done Written = 1; ShortNumberChanges = 0; } } } } else { // No istec present, assume changes are written ShortNumberChanges = 0; } return Written; } int IstecApp::EvalCmd (int RetCode) // Evaluate the return code of an istec command function. If the return // code denotes an error, an error message is poped up. The function // return 1 if the command has been error free, 0 on errors. { switch (RetCode) { case ieRecBufOverflow: // Receive buffer overflow IstecError (msRecBufOverflow); IstecErrorSync (); return 0; case ieRecBufUnderflow: // Receive buffer underflow IstecError (msRecBufUnderflow); IstecErrorSync (); return 0; case ieInvalidReply: // Invalid replay IstecError (msInvalidReply); IstecErrorSync (); return 0; case ieWrongDevice: // Wrong device number in reply IstecError (msWrongDevice); IstecErrorSync (); return 0; case iePortNotOpen: // COM port not open IstecError (msComPortNotOpen); return 0; case ieTimeout: // Timeout IstecError (msIstecTimeout); return 0; case ieCTIError: // CTI protocol error IstecError (msCTIError); return 0; case ieEEPROMInUse: // EEPROM in use IstecError (msEEPROMInUse); return 0; case ieDone: // Success return 1; default: FAIL ("IstecApp::EvalCmd: Unexpected return code"); } // Never reached return 0; } void IstecApp::SetSaveDir (const String& Path) // Strips the name part from the given filename and stores the remaining part // (the directory) including the trailing path separator into SaveDir. { String Name; FSplit (Path, SaveDir, Name); } void IstecApp::LoadFile () // Load the configuration from a file { // Choose the file name FileSelector FS (LoadAppMsg (msLoadFileHeader), ".ic"); String Sel = FS.GetChoice (SaveDir + "*.ic"); if (!Sel.IsEmpty ()) { // Load the config from a file String Msg = IstecLoadFile (Sel, Config); // Check for errors if (!Msg.IsEmpty ()) { // Error ErrorMsg (Msg); } else { // Remember the directory used SetSaveDir (Sel); // Show the configuration just read ShowIstecConfig (); // Data has been changed Changes = 1; // Ask to write the changes to the istec AskWriteChanges (); } } } void IstecApp::SaveFile () // Save the current configuration to a file { // Choose the file name FileSelector FS (LoadAppMsg (msSaveFileHeader), ".ic", fsFileMayNotExist); String Sel = FS.GetChoice (SaveDir + "*.ic"); if (!Sel.IsEmpty ()) { // Save the config to a file String Msg = IstecSaveFile (Sel, Config); // Check for errors if (!Msg.IsEmpty ()) { // Error ErrorMsg (Msg); } else { // Remember the directory used SetSaveDir (Sel); } } } void IstecApp::LoadShort () // Load the short numbers from a file { // Choose the file name FileSelector FS (LoadAppMsg (msLoadFileHeader), ".sn"); String Sel = FS.GetChoice (SaveDir + "*.sn"); if (!Sel.IsEmpty ()) { // Load the config from a file String Msg = FileLoadShort (Sel, ShortNumbers); // Check for errors if (!Msg.IsEmpty ()) { // Error ErrorMsg (Msg); } else { // Remember the directory used SetSaveDir (Sel); // Data has been changed ShortNumberChanges = 1; // Ask to write the changes to the istec AskWriteShortNumbers (); } } } void IstecApp::SaveShort () // Save the current short numbers to a file { // Choose the file name FileSelector FS (LoadAppMsg (msSaveFileHeader), ".sn", fsFileMayNotExist); String Sel = FS.GetChoice (SaveDir + "*.sn"); if (!Sel.IsEmpty ()) { // Save the config to a file String Msg = FileSaveShort (Sel, ShortNumbers); // Check for errors if (!Msg.IsEmpty ()) { // Error ErrorMsg (Msg); } else { // Remember the directory used SetSaveDir (Sel); } } } void IstecApp::ViewLog () // View a logfile { // Ask for the file name FileSelector FS (LoadAppMsg (msViewLogSelHeader), ".log"); String LogFile = FS.GetChoice (); if (LogFile.IsEmpty ()) { // User abort return; } // Open the file viewer FileViewer* Viewer = new FileViewer (LogFile, Background->GetDesktop (), wfFramed | wfCanMove | wfCanResize, paBlue); // Check for errors, browse the file if (Viewer->GetStatus () != stOk) { // OOPS, error opening the file or something like that ErrorMsg (GetSysErrorMsg (Viewer->GetErrorInfo ())); delete Viewer; } else { // Ok, insert the file into the window manager WinMgr->AddWindow (Viewer); WinMgr->Browse (Viewer); } } void IstecApp::LoadIstec () // Load the configuration from the istec { if (EvalCmd (IstecReady ())) { // Well, we _can_ talk to the istec, try to read the config if (EvalCmd (LoadConfig ())) { // Error free, display the configuration ShowIstecConfig (); // No changes Changes = 0; } } } void IstecApp::SaveIstec () // Save the current config to the istec { EvalCmd (StoreConfig ()); } void IstecApp::SwitchDayNight (unsigned aDayNight) // Switch the current configuration { // If we have changes, allow saving them. Beware: It is not possible to // change day/night directly after writing the configuration (EEPROM // is in use - whatever this means). To prevent this error, wait some // time after we have written anything if (AskWriteChanges ()) { // We have written a configuration Delay (1000); } // Pop up a window Window* Win = PleaseWaitWindow (); // Switch the configuration int Result = IstecPutDayNight (aDayNight); // If all was ok, read it back and remember the current setting if (Result == ieDone) { // Read it back Result = IstecGetDayNight (DayNight); } // Remove the window delete Win; // Set the menu item to show the actual setting MainMenue->SetToggleValue (miSwitchDayNight, DayNight); // Evaluate the result if (EvalCmd (Result)) { // Ask the user if he wants to load the new configuration if (AskYesNo (LoadAppMsg (msAskReloadConfig)) == arYes) { // Load the configuration LoadIstec (); } } } void IstecApp::SysParams () // Edit system parameters { // Edit the parameters int NewChanges = 0; EditBaseConfig (Config, IstecPresent, NewChanges); // Remember if we had changes Changes |= NewChanges; // Ask for writing the changes back if we have new changes if (NewChanges) { AskWriteChanges (); } } void IstecApp::EditShortNumbers () // Edit shortcut numbers { // Edit the parameters int NewChanges = 0; ShortNumberList (ShortNumbers, NewChanges); // Remember if we had changes ShortNumberChanges |= NewChanges; // Ask for writing the changes back if we have new changes if (NewChanges) { AskWriteShortNumbers (); } } void IstecApp::DevParams () // Set the device parameters { // Edit the parameters int NewChanges = 0; DeviceList (Config, NewChanges); // Remember if we had changes Changes |= Changes || NewChanges; // Ask for writing the changes back if we have new changes if (NewChanges) { AskWriteChanges (); } } void IstecApp::Reset () // Reset the istec { if (AskAreYouShure () == 2) { // Reset the device params LoadConfigDefault (Config, Config.IstecID ()); // We have changes now Changes = 1; // Ask to write those changes AskWriteChanges (); } } void IstecApp::LoadCharges () // Reload the charges from the istec { // Pop up a window Window* Win = PleaseWaitWindow (); // Load the stuff from the istec int Result = IstecGetCharges (); // Delete the window delete Win; // Print an error message if needed EvalCmd (Result); } void IstecApp::PrintSettings () // Edit settings for printing charges { // Name of the settings resource static const String StgPosName = "PrintSettings.PrintSettingsMenue.Position"; // Load the menue Menue* M = (Menue*) LoadResource ("@ISTEC.PrintSettingsMenue"); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, M->OuterBounds ().A); M->MoveAbs (Pos); // Remember the old values String OldHeadline = Headline; double OldPricePerUnit = PricePerUnit; // Transfer the current values to the menue M->SetStringValue (1, Headline); M->SetFloatValue (2, PricePerUnit); // Create a new status line PushStatusLine (siAbort | siSelectKeys | siAccept); // Activate the menue M->Activate (); // Accept user input int Done = 0; while (!Done) { // Get a selection int Sel = M->GetChoice (); // Evaluate the selection switch (Sel) { case 1: Headline = M->GetStringValue (1); break; case 2: PricePerUnit = M->GetFloatValue (2); break; case 0: if (M->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (PricePerUnit != OldPricePerUnit || Headline != OldHeadline) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes PricePerUnit = OldPricePerUnit; Headline = OldHeadline; Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } break; } } // Restore the old status line PopStatusLine (); // Save the current window position StgPutPoint (M->OuterBounds ().A, StgPosName); // Delete the menue delete M; } void IstecApp::PrintCharges () // Print the charges { // Choose the file name FileSelector FS (LoadAppMsg (msPrintFileSelHeader), ".geb", fsFileMayNotExist); String Sel = FS.GetChoice (SaveDir + "*.geb"); if (Sel.IsEmpty ()) { // Empty selection means abort return; } // Open the file FILE* F = fopen (Sel.GetStr (), "wt"); if (F == NULL) { ErrorMsg (GetSysErrorMsg (errno)); return; } // Some space fprintf (F, "\n\n"); // Headline String Line = Headline; fprintf (F, "%s\n", Line.OutputCvt ().GetStr ()); // Internal headline String TimeStr = Time ().DateTimeStr (); String IstecName = GetIstecName (); Line = FormatStr (LoadAppMsg (msPrintHeader).GetStr (), IstecName.GetStr (), TimeStr.GetStr ()); fprintf (F, "%s\n", Line.OutputCvt ().GetStr ()); // Divider Line = LoadAppMsg (msPrintHeader2).GetStr (); fprintf (F, "%s\n", Line.OutputCvt ().GetStr ()); // Empty line followed by the table header Line = LoadAppMsg (msChargeTableHeader).GetStr (); fprintf (F, "\n%s\n\n", Line.OutputCvt ().GetStr ()); // Ok, loop through the devices... for (unsigned Dev = 0; Dev < Config.GetDevCount (); Dev++) { Line = LoadAppMsg (msChargeLine); Line = FormatStr (Line.GetStr (), Dev + 21, Charges [Dev]); String Price = FloatStr (Charges [Dev] * PricePerUnit, 4, 2); Price.Pad (String::Left, 7); Line += Price; fprintf (F, "%s\n", Line.OutputCvt ().GetStr ()); } // Close the file fclose (F); // Remember the directory used SetSaveDir (Sel); } void IstecApp::ResetCharges () // Reset all charges { if (AskAreYouShure () == 2) { // Create empty charges IstecCharges Charges; if (IstecPresent) { // Pop up a window cause this could last some time Window* WaitWin = PleaseWaitWindow (); // Send the istec command IstecPutCharges (Charges); // Delete the window delete WaitWin; } } } void IstecApp::OpenCLIWin () // Open a CLI window { // If this is firmware version 2.0 and we have the CLINoDiagMode flag // set, show a warning that diag mode is disabled now. if (CLINoDiagMode) { InformationMsg (LoadAppMsg (msCLIWinWarning)); } // Make a new window and add it to the window manager WinMgr->AddWindow (new CLIWindow); } void IstecApp::CloseAll () // Close all windows { WinMgr->CloseAll (); } void IstecApp::Resize (ItemWindow* Win) // Resize a window { if (Win) { Win->MoveResize (); } } void IstecApp::Zoom (ItemWindow* Win) // Zoom a window { if (Win && Win->CanResize ()) { Win->Zoom (); } } void IstecApp::Close (ItemWindow* Win) // Close a window { if (Win) { WinMgr->DeleteWindow (Win); } } int IstecApp::Run () { // Activate the main menue MainMenue->Activate (); // Main loop while (!Quitting ()) { Key K; // Switch according to the users choice int Choice = MainMenue->GetChoice (); switch (Choice) { case miAbout: InformationMsg (LoadAppMsg (msAboutInfo)); break; case miFileLoadConfig: LoadFile (); break; case miFileSaveConfig: SaveFile (); break; case miFileLoadShort: LoadShort (); break; case miFileSaveShort: SaveShort (); break; case miViewLog: ViewLog (); break; case miReadAliases: ReadAliasFile (); break; case miReadCronFile: ReadCronFile (); break; case miQuit: // Close the windows if (WinMgr->CanClose ()) { // Save the window manager, then close all windows StgPut (WinMgr, "WinMgr"); WinMgr->CloseAll (); // Switch the istec out of diag mode (only if istec present) if (IstecPresent) { DisableDiagMode (); } // End the program. First ask to write any changes back AskWriteChanges (); AskWriteShortNumbers (); // The end... Quit = 1; } break; case miIstecLoadConfig: LoadIstec (); break; case miIstecSaveConfig: SaveIstec (); break; case miIstecLoadShort: LoadShortNumbers (); break; case miIstecSaveShort: StoreShortNumbers (); break; case miSwitchDayNight: SwitchDayNight (0); break; case miSwitchDayNight+1: SwitchDayNight (1); break; case miVersion: ShowIstecConfig (); break; case miEditSysParams: SysParams (); break; case miEditDevParams: DevParams (); break; case miEditShort: EditShortNumbers (); break; case miReset: Reset (); break; case miLoadCharges: LoadCharges (); break; case miChargeWin1: case miChargeWin2: WinMgr->AddWindow (new ChargeWindow); break; case miPrintSettings: PrintSettings (); break; case miPrintCharges: PrintCharges (); break; case miResetCharges: ResetCharges (); break; case miMatrixWin: WinMgr->AddWindow ( new MatrixWindow (Point (10, 10), Config.GetDevCount ())); break; case miCallWin: WinMgr->AddWindow (new CallWindow); break; case miCLIWin: OpenCLIWin (); break; #ifdef LINUX case miIMonWin: WinMgr->AddWindow (new IMonWindow (Point (10, 10))); break; #endif case miTile: WinMgr->Tile (); break; case miCascade: WinMgr->Cascade (); break; case miCloseAll: CloseAll (); break; case miRedraw: RedrawScreen (); break; case miResize: Resize (WinMgr->GetTopWindow ()); break; case miZoom: Zoom (WinMgr->GetTopWindow ()); break; case miClose: Close (WinMgr->GetTopWindow ()); break; case miWindowList: WinMgr->Browse (WinMgr->ChooseWindow ()); break; case 0: K = MainMenue->GetAbortKey (); if (K != vkAbort) { // Window hotkey WinMgr->Browse (WinMgr->FindWindowWithKey (K)); } break; } } // Close the debug logfile DoneDebugLog (); // Return the program exit code return 0; } int main (int argc, char* argv []) { // Set the default language and country DefaultLanguage = laGerman; DefaultCountry = 49; // Declare an application object IstecApp MyApp (argc, argv); // Use it... return MyApp.Run (); } estic-1.61.orig/estic/estic.chg0100644000176100001440000003055107031424722015716 0ustar debacleusers 0.888: * ISTEC 1003 wird unterstützt und kann auch bei nicht vorhandener ISTEC angewählt werden. * Löschen von Gebühren ist ohne Fehlermeldung möglich (das betrifft auch das Kommandozeilenprogramm ICLOAD). * Die OS/2 Version sollte auch an Schnittstellen mit den alten 16450 Chips tun. * Diagnose-Modus implementiert. * Diverse kleinere Änderungen, z.B. "Bitte warten" Fenster wenn eine gewünschte Operation etwas dauert. 0.999: * Fehlerhaften Headerstring im Fileselektor beim Ausdruck korrigiert. * EAZ-Gruppenmenue ist jetzt zugänglich wenn das Protokoll 1TR6 ist. * INI File wurde nicht geschlossen. * Einzelgesprächsnachweis implementiert. * ISDN4Linux Monitor. 1.00: * Fehler im Linux Bildschirm-Modul behoben. Unter Linux ist eine Bildschirmausgabe nicht möglich ohne den Cursor zu bewegen. Das führte dazu, daß der Cursor verloren ging, wenn im Hintergrund Bildschirm- bereiche upgedated wurden (Extremfall: isdn4linux Monitor). * Code im isdn4linux Monitor geändert um den Verbrauch an CPU Resourcen klein zu halten (File wird jetzt nur noch einmal geöffnet, usw.). * File-Browser zum Ansehen der Logfiles innerhalb von ESTIC eingebaut. * Menue-Eintrag "ISDN4Linux Monitor" wurde nicht upgedated, wenn beim Starten das Monitor-Fenster automatisch geöffnet wurde (z.B. durch Eintrag in estic.ini). * Abholen der Gebühren und Einschalten des Debugmodus erfolgte zu oft (Fehler in IstecApp::Idle). * Debug-Log für Kommunikation mit der ISTEC. * Wartezeit vor Abholen der Gebühren nach einem Gespräch. Bei einigen Anwendern wurden immer 0 Einheiten für alle Gespräche geloggt. * FreeBSD-Version. Dank an meinen Provider Seicom (speziell an Peter Dieth, dieth@seicom.net) für den Remote-Account auf einem FreeBSD- Rechner, vielen Dank an Christian Kratzer (ck@toplink.de) für's Testen und für's Bier :-) * Vorbereitet für die neue ROM-Version 1.92, die Kombi-Dienste kann. Nicht getestet, muß im .ini File explizit eingeschaltet werden. * Info-Boxen können auch mit Enter geschlossen werden. * Das Loggen von Gesprächen mit 0 Einheiten (es kam keine Verbindung zustande) kann unterdrückt werden. * Diverse Checks für die einkommenden Debug-Nachrichten sollten dafür sorgen, daß ESTIC bei einem Übertragungsfehler nicht gleich den Löffel schmeißt. * Default Sprache und Land sind jetzt für Linux & FreeBSD auf deutsch bzw. Deutschland gesetzt (unter DOS & OS/2 wird die Default-Einstellung des Betriebssystems benutzt). * Einstellung von Kosten/Einheit wird auch beim Einzelgesprächsnachweis verwendet. * DOS Version jetzt als 32-Bit Version mit Extender wg. Speichermangel. 1.01: * Direkt nach dem Starten von ESTIC erzeugten Diagnose-Meldungen von der ISTEC Fehler im Logfile und wurden so lange nicht ausgewertet, bis das Matrixfenster geöffnet, oder das Gerät einmal aktiv wurde. * Debug-Log erweitert. * Versucht diverse Protokoll-Fehlerchen der ISTEC zu umgehen. Das ist nicht immer möglich, da aufgrund von Fehlern z.T. mehrere Meldungen von der ISTEC auf eine Art und Weise verstümmelt werden, die ein Recovery unmöglich macht. * Einstellung für die Firmware-Version in estic.ini wurde an der letztendlich entscheidenden Stelle ignoriert. Firmware-Version wird jetzt beim Lesen der Konfiguration von der ISTEC gesetzt, d.h. die Variable in estic.ini muß nur noch gesetzt werden, wenn ohne angeschlossene ISTEC .IC Files editiert werden sollen. Default ist Firmware < 1.92 (keine Kombidienste). * Umschaltung auf Text-Modus ist jetzt in ESTIC.INI einstellbar. Der zuvor unter DOS & OS/2 verwendete Modus 80*30 arbeitet nur mit VGA's. 1.10: * Anpassung des isdn4linux Monitors an die neue Version (0.7beta). * Segmentation violation beim Zugriff auf ein Diskettenlaufwerk mit nicht eingelegter Diskette entfernt (OS/2, spunk). * Englische Version. Hier können zum Teil noch Dinge fehlerhaft sein (was wohl "Wahlbewertung" oder "Halbamt" auf englisch heißt? :-) * Die Einstellmöglichkeit für die Update-Frequenz des isdn4linux Monitors gibt es nicht mehr. * Zeit/Datum kann wahlweise rechts oben im Hauptmenue angezeigt werden. * File Viewer schmiert unter Linux nicht mehr ab, wenn versucht wird, Binärdateien anzusehen (spunk). * Wahlweise separate Alias-Datei in der auch Aliase für ausgehende Nummern angegeben werden können. * Aliase können von ESTIC aus erneut eingelesen werden (Voraussetzung ist, daß eine separate Aliasdatei definiert war). * Diverse kleinere Bugfixes. 1.20: * Im Resource File war die deutsche Version des Fensters für die Konfiguration eines einzelnen Endgerätes nicht deutsch sondern englisch. * Vorbereitet für die Version 1.93 der ISTEC Firmware. Das betrifft auch einen Teil der Menues. * Debug-Code eingebaut um einen "index out of bounds" Fehler beim Zugriff auf eine der verwendeten Collections zu lokalisieren. * Neue Option in estic.ini "AutoReadAliases", die bewirkt, daß nach jedem Gespräch, vor der Suche in Alias-Bestand die Alias-Datei neu eingelesen wird. * Defaultpreis für eine Einheit sind jetzt 0.12 statt 0.23 DM. * Anpassung an die Version 1.93 der Istec Firmware, die Firmware wird automatisch erkannt. * Komplettes Redesign der Fenster, Window-Manager. * X Window Version (Linux + FreeBSD). Das ist eigentlich eine Änderung an spunk. * Settings File (spunk) eingebaut. Offene Fenster sowie sämtliche Fenster- größen und Positionen werden gespeichert. * Name für die Logfiles kann jetzt auch die Nummer des Gerätes enthalten, von dem der Anruf ausging. Dadurch lassen sich nach Anschluss getrennte Logfiles erzeugen. * Code zum Laden und Speichern der Konfigurationen an die neue Firmware angepasst. ACHTUNG: Die *.ic Files sind *nicht* mehr kompatibel zu denen von ISTEC.EXE erzeugten. * Kleinere Änderungen am RS232 Code der DOS Version (spunk). Es besteht eine gewisse Wahrscheinlichkeit, daß ESTIC jetzt besser unter Windows und Windows 95 läuft - viel Hoffnung mache ich mir allerdings nicht. * Die DOS Version verwender den DOS4GW Extender statt PMODEW. Das ist ein Test um zu sehen, ob dadurch die DOS Version zu den diversen Speichermanagern und Programmladern kompatibler wird. * Diverse kleinere Änderungen. 1.22: * Die in der Verbindungsmatrix angezeigte Nummer wurde in bestimmten Fällen nach Auflegen des Hörers nicht gelöscht. * Beim Laden der Anlagenkonfiguration wurde in dem Datensatz mit dem ESTIC gearbeitet hat, die TFE immer auf den Wert 33 gesetzt. * Bei der Firmware 1.92 wurden beim Laden der Gerätekonfigurationen Geräte "Kombidienst" zu "Fernsprechen" angepasst (Kombidienst wurde als ungültiger Wert angesehen). * Beim Laden der Gerätekonfigurationen wurden intere Umleitungen falsch übernommen. * ESTIC sollte jetzt auch mit Geräten arbeiten, die mit der Platinen- Revision 3 ausgestattet sind. Diese benötigen zum Betrieb eines zusätzlichen Optokopplers noch aktive Steuerleitungen auf der RS232 zur Stromversorgung. 1.30: * Umstellung auf Event-Steuerung, dadurch weitere Modularisierung. * Änderung einiger Filenamen. * Modul für externes Interface, das nichts weiter macht als einen Event- Handler bereitzustellen. * Falls Fehler beim Öffnen des seriellen Ports auftraten hat die Hinter- grundroutine trotzdem versucht, davon zu lesen. * Der Isdn4Linux-Monitor hatte ein undefiniertes Verhalten wenn beim Öffnen des Files /dev/isdninfo Fehler auftraten. * Das Gebührenfenster ist nicht mehr modal, sondern kann wie die anderen Fenster auf den Desktop gelegt werden und wird upgedated wenn sich die Gebühren ändern. * Der verwendete DOS Extender setzt den DOS Aufruf zur Abfrage der Country Information nicht korrekt um, deshalb wurde unter purem DOS das eingestellte Land nicht erkannt. Diese Abfrage sollte jetzt tun, ein COUNTRY= in CONFIG.SYS ist aber trotzdem notwendig. (spunk) * Die Abfrage auf die eingestellte Sprache unter den *nix Varianten etwas relaxed, es sollten jetzt mehr Einstellungen von LC_CTYPE erkannt werden. (spunk) * Anpasssungen an NetBSD/Amiga (Ralph-Thomas Aussem, 1aussem@informatik.uni-hamburg.de) und Solaris (Martin Helmling, mh@octogon.de). * Wiederholtes Einschalten des Diagnosemodus soll mit neueren Firmware- Versionen nicht mehr notwendig sein (Schalter in ESTIC.INI). * Löschen einer Rufumleitung wurde unter bestimmten Bedingungen von der Istec ignoriert bzw. fehlerhaft eingetragen. * "Änderungen permanent machen" existiert nicht mehr als separater Menuepunkt. Der entsprechende Befehl wird immer abgesetzt, wenn neu programmiert wurde. * Der Anschluß für die externe Musikeinstellung wurde nicht aus dem Eingabefeld im Menue in die Konfigurationsstruktur übernommen. * MSN-Gruppen Menue geändert. * Fehler bei Beendigung des MSN-Gruppen Menues behoben. * Hintere Stellen der Nummern können im Logfile ausge-X-t werden (die Idee ist von Markus Bellenberg (jmb@outbreak.gun.de). * Anpassung an die Firmware 1.95. Emmerich hat (ohne das zu dokumentieren) an die Geräte-Infos noch ein (soweit ich weiß unbenutztes) Byte angehängt. Das wäre ja sonst auch zu einfach gewesen :-) Die Menues zum Einstellen des Anklopfens sind noch ziemlich umständlich weil sie immer wieder zuklappen, aber ich wollte die neue Version draußen haben um die Mailflut zu stoppen. Stay tuned... 1.40: * Fehler beim Zerlegen von Strings in Tokens (spunk), daher fehlerhafte Auswertung von Schlüsselwörtern im ini File. * Falscher Vergleich bei DiagMode=auto (> statt <=, Hinweis von Johannes Eder, eder@elisa.greenie.muc.de). * Windows NT Version (spunk). * Das lange angekündigte Cron Features ist da. * Neue Variable in estic.ini, ShortWaitAfterMsg. Das ist eine Optimierung, von der ich nicht weiss, ob sie in allen Fällen tut. Wenn's Probleme gibt, abschalten. * Falsche Statuszeile bei der Zuordnung der MSN's. * Die Telefonnummer für meinen Linux-Rechner im DOC File ist seit der Version 1.2 falsch gewesen :-( * Die X Versionen sind etwas flexibler, was die Font-Suche angeht (spunk). * -display und -geometry werden unter X unterstützt (spunk). 1.42: * In iccom.cc hat die explizite Instantiierung für CircularBuffer gefehlt, ohne die gcc >= 2.6.0 nicht korrekt arbeitet. Hinweis von Johannes Eder (eder@elisa.greenie.muc.de). * Der C++ Compiler von FreeBSD braucht in devstate.cc einen expliziten Cast um den passenden TimeDiff Konstruktor auszusuchen. Hinweis von Andreas S. Wetzel (mickey@deadline.snafu.de). 1.50: * Kleinere Anpassungen an FreeBSD, Diffs von Oliver von Bueren (Büren?), (ovb@swissmail.com) * Mit Ausnahme des Settings-Files wurde '~' auf *NIX Maschinen nicht durch das Home-Verzeichnis ersetzt. Es sieht so aus, als ob das bei einigen Betriebssystemen die C Library macht, und bei anderen nicht... * Komplettes Hauptmenue umstrukturiert. * Hauptmenue wird jetzt auch aus der Resource geladen. * Tausende von Änderungen/Erweiterungen zur Anpassung an Version 2.0 der Firmware. 1.60: * Der String für den Fehler "CTI Protokoll Fehler" war nicht in der Resource. * Aktive Konfiguration wird eingelesen. * Debug-Log kann beim Start von ESTIC überschrieben werden (neue Variable in estic.ini). * Interne Rufumleitung wurde beim Laden nicht korrekt übernommen. * ESTIC hat aufgrund eines Fehlers nicht mit Firmware-Versionen < 1.93 zusammengearbeitet (Dank an Volker Quetschke, voq@mpqgrav2.amp.uni-hannover.de). * Tag-/Nachtschaltung der FW 2.0 implementiert. Zusätzlicher cron Befehl für diesen Zweck. * Anklopfen extern konnte nicht konfiguriert werden, stattdessen wurde Anklopfen intern gesetzt (Dank an Konstantin Muenning, uzs446@uni-bonn.de). * Der (cron-) Befehl ReadCronFile ist nicht mehr verfügbar. * Auf der Kommandozeile können beliebig viele cron Befehle (ohne Zeit) angegeben werden, die nach Start von ESTIC ausgeführt werden. * Windows 95 Version (spunk). * Areacode Datei mit den Vorwahlen von Österreich (Areacode), dank an Alois Schneider (Alois.Schneider@magnet.at). * Extra Untermenue, in dem auch die Rufumleitungen der Firmware 2.0 eingestellt werden können. Diese werden aber von der Istec nicht gespeichert. estic-1.61.orig/estic/estic.doc0100644000176100001440000014213207031424722015721 0ustar debacleusers ESTIC V 1.60, 05.03.1997 Enhanced Supervisor Tool for ISTEC Configuration Copyright (C) 1995-97 Ullrich von Bassewitz 0. Allgemeines -------------- ESTIC ist ein Konfigurationsprogramm für die ISTEC ISDN-Anlagen der Firma Emmerich. Neben der Konfiguration der Anlage kann ESTIC ein Logfile über die ausgehenden Gespräche zusammen mit Nummer/Zeitpunkt/ Dauer/Kosten führen. Weiterhin ist als zusätzliches "Schmankerl" für ISDN4Linux Benutzer ein ISDN4Linux Monitor integriert. ESTIC basiert auf meiner portablen Klassenbibliothek SPUNK, deshalb sind Versionen für DOS, OS/2, Windows 95/NT, Linux, FreeBSD und diverse andere Unixe verfügbar. Für die Unix-Versionen ist es sinnvoll, bestimmte Environment-Variablen zu setzen (siehe weiter unten, "Betrieb unter den verschiedenen Plattformen"). 1. Ausschluss jeglicher Gewährleistung -------------------------------------- ESTIC basiert auf frei verfügbaren Informationen über die Schnitt- stelle der ISTEC ISDN-Anlagen sowie auf eigenen Forschungen von mir. ESTIC hat *nichts* mit der Firma Emmerich zu tun sondern ist eine Eigenentwicklung, die in keiner Form von Emmerich unterstützt oder gutgeheißen wird. Bei Verwendung von ESTIC trägt der Anwender alle daraus entstehenden Folgen trägt ganz alleine - jegliche Gewährleistung von mir in dieser Richtung ist ausgeschlossen. Ich möchte speziell darauf hinweisen, daß die Software Fehler enthalten kann, die zur Zerstörung oder Unbrauch- barmachung der Anlage führen können. Wer also auf das Funktionieren seiner Anlage *angewiesen* ist, sollte ESTIC auf gar keinen Fall verwenden. (Kleiner Trost: Meine ISTEC 1008 funktioniert nach wie vor einwandfrei - trotz aller Tests mit früheren Versionen von ESTIC). 2. Benutzung ------------ ESTIC ist menuegeführt und relativ einfach bedienbar. Praktisch alle Funktionen des Programms ISTEC.EXE von Emmerich sind in der einen oder anderen Art und Weise vorhanden. Weiter unten steht eine Liste der Einschränkungen. 3. Unterschiede zum Konfigurationsprogramm von Emmerich ------------------------------------------------------- Es gibt einige Unterschiede gegenüber dem Programm ISTEC.EXE von Emmerich. * Passwörter für Admin- und Diagnosemodus fehlen. Alle Funktionen sind ohne Passwörter verfügbar. * Die Aufteilung der Funktionen in den Menues ist anders (in meinen Augen klarer - aber das ist Geschmackssache). Es gibt eine klare Trennung in Anlagenparameter und Parameter für Endgeräte. * Textmodus-Oberfläche, keine Maus und ähnlicher Schnickschnack :-) * Ausdruck ist anders gegliedert, es werden nur reine Textdateien unterstützt. * Format der *.IC Dateien ist anders, diese können (im Gegensatz zu früher) nicht mehr zwischen den beiden Programmen ausgetauscht werden. * Diverse zusätzliche Funktionen. 4. Fähigkeiten von ESTIC ------------------------ 4.1 Diagnosemodus ----------------- Dargestellt wird die intere Verbindungsmatrix der ISTEC, die Schleifen- und Rufzustände der einzelnen Apparate sowie von der ISTEC erkannte Wähl- und Schaltvorgänge. Die Darstellung erfolgt parallel zur eigentlichen Funktion, d.h. alle Funktionen von ESTIC können weiterhin genutzt werden, auch wenn der Diagnosemodus eingeschaltet ist. Mit der Version 1.20 entfällt das bisher vorhandene Statusfenster, die Information über die Wählvorgänge wird direkt im Matrixfenster untergebracht. Das ist wesentlich übersichtlicher, man kann anhand des Fensters auf einen Blick erkennen, wo telefoniert wird, bei ausgehenden Gesprächen auch, wohin. Einschränkungen des Diagnosemodus: * Die unterstützten Funktionen sind rein passiv, da durch eine unsachgemäße Beeinflussung der Matrix von außen die ISTEC evtl. beschädigt werden kann. * Im Diagnosemodus überträgt die ISTEC nur Delta-Werte an ESTIC. D.h. ESTIC kennt den Grundzustand beim Einschalten des Diagnose- modus nicht und nimmt an, daß alle Zuständen auf "aus" bzw. "inaktiv" stehen. Das kann zu Fehlinterpretationen führen wenn der Diagnosemodus zu einem Zeitpunkt eingeschaltet wird, zu dem bereits Funktionen aktiv sind, z.B. nach Abheben eines Hörers. Ein spezielles Problem ist die Angabe der Apparatenummer bei Tonwahl: Die ISTEC überträgt bei erkannter Tonwahl nicht die Nummer des Gerätes (wie bei der Pulswahl), sondern die Nummer des intern durch das Gerät belegten Kanals. Dieser Kanal wird beim Abheben des Hörers (Schleife aktiv) belegt. Wird der Diagnosemodus erst nach Abheben des Hörers gestartet, dann kennt ESTIC die Zuordnung interner Kanal <--> Gerätenummer nicht und gibt folglich die falsche Apparatenummer bei der Tonwahl aus (immer Gerät 21). * Aufgrund von interen Puffer-Überläufen in der Istec-Software kann es bei einem hohen Nachrichtenaufkommen dazu kommen, dass Nachrichten verloren gehen (das bedeutet normalweise auch, daß für dieses Gespräch keine Gebühren erfaßt werden können!). 4.2 Logging ausgehender Anrufe ------------------------------ ESTIC ist in der Lage, sämtliche ausgehenden externen Gespräche zusammen mit Zielrufnummer, verbrauchten Einheiten und angefallenen Kosten mitzuprotokollieren. Das setzt allerdings voraus, daß ESTIC auch läuft, wenn telefoniert wird. Dieses Feature dürfte vor allem für Linux- und FreeBSD Benutzer recht interessant sein. ACHTUNG: Es hat in der Vergangenheit etwas Verwirrung darüber gegeben, was hier möglich ist und was nicht. Tatsache ist, daß ESTIC dazu undokumentierte Features der Istec ausnutzt, und zudem vom korrekten Funktionieren dieser Features abhängig ist. Leider ist es in der Realität so, daß die Istec Firmware je nach Version mehrere Fehler hat, weiterhin ist auch das Verfahren an sich schon recht fehlerträchtig. Es ist deshalb mit einer Fehlerquote bei den erfassten Gesprächen zu rechnen, die (hier bei mir) bei etwa 1-2% der Gespräche liegt. Je nach Konfiguration und Firmware der Istec kann dieser Wert aber auch höher (oder niedriger) sein. ESTIC kann bis zu drei verschiedene Logfiles anlegen, deren Namen sich von der Uhrzeit und vom Datum ableiten können. Dadurch ist es recht einfach möglich, für jeden Tag oder für jeden Monat ein neues Logfile zu erstellen, ohne daß ein Eingriff von außen notwendig ist. Nähere Erläuterungen dazu finden sich in der Datei estic.ini. Um das Logging abzustellen ist bei allen drei Logfiles in der Datei estic.ini ein Leerstring einzutragen. Speziell um die Linux-Benutzer über die Tatsache hinwegzutrösten, daß zum Loggen ein interaktives Programm dauernd laufen muss, habe ich zusätzlich einen kleinen Monitor für ISDN4Linux von Fritz Elfert eingebaut. Wer also unter Linux eine ISTEC und ISDN4Linux verwendet, hat mit ESTIC sein ISDN Equipment im total vollen geilen Zugriff :-) Siehe dazu auch der Abschnitt "ISDN4Linux Monitor". 4.3 Logging eingehender Anrufe ------------------------------ Ab der Firmware Version 2.0 vom November 1996 (ACHTUNG: Es gibt auch ältere Versionen!) kann die Istec eingehende Anrufe über die serielle Schnittstelle melden. ESTIC kann diese Daten zusammen mit einer Information über das Ortsnetz (oder wenn ein Alias vorhanden ist, diesen Text) in einem eigenen Fenster ausgeben und/oder in Logfiles schreiben. Leider wurde dieses Feature von Emmerich so implementiert, daß dazu der Diagnose-Modus, den ESTIC für das Logging ausgehender Rufe und für die Verbindungsmatrix benötigt, abgeschaltet werden muß. ESTIC gibt daher beim Öffnen des Fensters eine Warnung aus. Aus genau diesem Grund funktioniert auch das Loggen in eine Datei nur dann, wenn das Fenster geöffnet (und Diagnosemeldungen abgeschaltet) sind. 4.4 Cron Funktion ----------------- Ab der Version 1.40 besitzt ESTIC eine eingebaute Cron Funktion mit deren Hilfe Ereignisse zu bestimmten Zeiten ausgelöst werden können. Über dieses Feature kann z.B. ein automatisches Speichern und Rücksetzen der Gebühren am Monatsende, oder eine Tag-/Nachtschaltung implementiert werden. Die Verwendung dieses Features setzt voraus, daß ein dauernd laufender Rechner mit ESTIC und einer Verbindung zur Istec vorhanden ist! Zum Aktivieren wird in estic.ini ein Dateiname für die Cron-Datei angegeben. Eine Beispieldatei findet sich in der Distribution, dort ist auch die Syntax erklärt (für Unix-Benutzer: Die Syntax unterscheidet sich fast nicht von derjenigen des Unix crons). Folgende Aktionen können ausgelöst werden: PrintCharges # Speichert die aktuelle Gebühren ClearCharges # Setzt die Gebühren zurück LoadConfig # Lädt neue Einstellungen in die Istec Ring # Läßt den Apparat für Sekunden # klingeln SwitchConfig # Tag-/Nachumschaltung (FW >= 2.0) PrintCharges entspricht dabei nicht der manuellen Funktion "Gebühren drucken", es wird ein etwas einfacheres Format ohne jegliche Header verwendet. Die Weiterverarbeitung dieser Datei ist problemlos mit awk oder ähnlichen Programmen möglich. Ring läßt ein angeschlossenes Telefon im Sekundentakt klingeln, bis die eingestellte Zeit vorbei ist, oder bis der Hörer abgehoben wird. Da ESTIC kein "echtes" Multitasking macht (auch wenn es manchmal so aussieht), und da ESTIC jede Sekunde das Klingelzeichen an- oder abschalten muß ergibt sich eine etwas "ruckelige" Bedienung, wenn Ring aktiv ist. Die Datei estic.ini enthält einen Schalter, ShortWaitAfterMsg, der diesen Effekt etwas mindert, von dem ich aber bisher nicht weiß, ob er ohne Nebenwirkungen ist. ACHTUNG: Ring bitte nicht für Anschlüsse verwenden, an denen kein Telefon hängt! Fehler, die bei der Abarbeitung entstehen (z.B. wenn Dateien nicht geöffnet werden können) werden in's Debug-Log geloggt. Wer neue Einträge in der Cron Datei testet, sollte deshalb auch das Debug-Log aktivieren (siehe Abschnitt "Debug-Log"). 4.5 Aliase für Rufnummern ------------------------- Sowohl für die internen Rufnummern (21...) als auch für externe Rufnummern können Aliase (Namen) vergeben werden. Falls Namen auch für externe Nummern vergeben werden sollen ist eine separate Datei für diese Aliase zwingend notwendig, sollen nur für die eigenen Apparate Namen vergeben werden, so kann das auch in der ini Datei geschehen. Da ESTIC sowohl bei den Kurzwahlen, als auch bei ein- und ausgehenden Rufen wenn möglich die Aliase mit ausgibt empfiehlt es sich, für oft verwendete Nummern Aliase anzulegen. Einige Erläuterungen dazu finden sich in der Datei estic.ini, die Beispieldatei mit Aliasen (alias.dat) enthält Erklärungen zum Format der Datei und einige Beispiel. 4.6 Debug-Log ------------- Um Problemen bei der Kommunikation auf die Spur zu kommen, kann ESTIC ein Logfile mit einem kompletten Trace der Kommunikation zwischen PC und ISTEC erzeugen. Achtung: Wenn ESTIC dauernd läuft, dann kann dieses File recht groß werden. Die bereits recht sprechenden Einträge wurden für die Version 1.40 nochmals erweitert. Ab dieser Version enthält jeder Eintrag nicht nur die versandten Daten, sondern auch eine Beschreibung der Nachricht als Text. Wer sich für die Kommunikationsschnittstelle der Istec interessiert, dem sei die Lektüre des Debug-Logs ans Herz gelegt :-) Wie das Logging eingeschaltet wird steht in der Datei estic.ini. 4.7 ISDN4Linux Monitor ---------------------- Unter Linux ist es möglich, sich den aktuellen Zustand der von ISDN4Linux verwalteten ISDN-Kanäle anzeigen zu lassen. Dazu existiert ein eigenes Monitorfenster. 4.8 Die AreaCode Datenbank -------------------------- ESTIC verwendet ab Version 1.5 eine Datenbank, die alle Vorwahlen für Deutschland und die Schweiz enthält (für Österreich wurden mir auch Nummern versprochen, ich habe bisher jedoch nichts erhalten). Dadurch kann bei der Anzeige von Rufnummern ein Trenner zwischen Vorwahl und eigentlicher Rufnummer eingefügt werden. Bei eingehenden Rufen (erst mit Firmware > 2.0 verfügbar) kann außerdem das Ortsnetz angezeigt werden, von dem der Anruf kam. Weiterhin sind in bestimmten Situationen Fehlerprüfungen möglich (bisher aber nirgendwo genutzt). Die angesprochene Datenbank besteht aus einem in C geschriebenen Modul sowie den eigentlichen Daten. Das Modul liegt im Quellcode vor und darf nach Belieben (auch kommerziell) eingesetzt werden. Den Quellcode und mehr dazu gibt es unter ftp://ftp.musoftware.com/areacode/. 5. Installation & Aufruf ------------------------ ESTIC benötigt zum Laufen die Datei estic.res, entweder * im Verzeichnis, in dem sich estic.exe befindet, oder * im aktuellen Verzeichnis, oder * in einem Verzeichnis, das sich in PATH bzw. DPATH (OS/2) befindet. ESTIC versteht beim Aufruf einige Kommandozeilen-Parameter: -a addr DOS: Adresse des UARTs, falls kein Standard-Port verwendet wird. Diese Angabe ist normalerweise nicht notwendig. Default ist 0x3F8 für COM1, 0x3F8 für COM2, 0x3E8 für COM3, 0x2E8 für COM4. -c cmd Alle Plattformen: cmd ist ein Cron-Befehl (ohne Zeitangabe), der direkt nach dem Starten von ESTIC ausgeführt wird. Beispiel, Umschaltung der Istec auf Tag-Betrieb: estic -c "loadconfig tag.ic" Es können beliebig viele "-c" Parameter angegeben werden, sie werden in der Reihenfolge ihres Auftretens in der Kommandozeile abgearbeitet. -i int DOS: Vom UART verwendeter Interrupt, falls keine Standard-Belegung verwendet wird. Diese Angabe ist normalerweise nicht notwendig. Default ist 0x0C für COM1, 0x0B für COM2, 0x0C für COM3 und 0x0B für COM4. -n ISTEC nicht vorhanden, nur Parameter editieren. -p port PORT kann eine Ziffer, die vollständige Angabe "COMx", oder ein anderes serielles Device sein. Unter Linux wird automatisch /dev/ vorangestellt, wenn der Name kein Verzeichnis enthält. Da der Default (COM2) unter Linux kein vernünftiges Device darstellt, muß unter Linux entweder eine estic.ini Datei erstellt (s.u.) oder der Parameter -p verwendet werden. Alle anderen Parameter werden ohne Fehlermeldung ignoriert! Diverse Vorgaben für ESTIC können in der Datei estic.ini eingestellt werden. Eine Beispieldatei ist vorhanden und sollte auf jeden Fall den lokalen Gegebenheiten angepasst werden. Siehe extra Abschnitt. 6. Die Datei estic.ini ---------------------- Nachdem die Anzahl der einstellbaren Programm-Optionen seit der letzten Version rapide zugenommen hat, ist die Datei estic.ini wichtiger denn je. In der mitgelieferten Beispiel-Datei finden sich genauere Erläuterungen, was eingestellt werden muß/sollte/kann. Trotzdem hier ein kurzer Überlick: * Verwendeter COM-Port * Basisadresse, IRQ usw. (für DOS) * Einstellungen für den Ausdruck * Namen der Logfiles * Aliase für die einzelnen Nummer (21 = "Büro" usw.) * Name der externen Aliasdatei falls gewünscht. Es ist vor dem ersten Betrieb UNBEDINGT notwendig diese Datei durchzusehen und zu editieren! 7. Tasten ---------- Die meisten Tastenkombinationen werden unten in der Statuszeile oder in den Menues angezeigt. Die einzigen Tasten, bei denen das nicht der Fall ist sind diejenigen zum Aktivieren von Fenstern: Alle Fenster, die rechts oben eine Ziffer zwischen 1 und 9 anzeigen können mittels Alt+ aktiviert werden, wobei die angezeigte Ziffer ist. Alternativ kann Alt+0 zur Anzeige der Fensterliste verwendet werden über die das jeweilige Fenster dann ausgewählt werden kann. 8. Betrieb unter den verschiedenen Plattformen ---------------------------------------------- 8.1 DOS ------- Die DOS Version von ESTIC ist ein 32-bit Programm, das unter dem DOS4GW Extender läuft. Benötigt wird deshalb als Minimum ein 80386. Ich habe auf ftp://linux01.gwdg.de/pub/isdn/estic noch den früher verwendeten DOS Extender PMODE/W abgelegt. Wer Probleme hat, der kann sich diese Datei besorgen. Sie enthält - außer dem Extender selber - auch ein Programm, um den DOS4GW Extender gegen PMODE/W auszutauschen. PMODE/W braucht weniger Speicher und ist geringfügig schneller, deshalb lohnt sich ein Versuch z.B. für DOS Rechner mit nur 2MB Speicher, auf denen ESTIC mit DOS4GW oft nicht läuft. Andererseits hat PMODE/W Probleme an anderen Stellen, so kann es mit PMODE/W z.B. passieren, daß ESTIC bei zu wenig Speicher einfach abschmiert - nicht weil ESTIC das nicht erkennen würde, sondern weil PMODE/W diese Bedingung nicht korrekt behandelt. 8.2 OS/2 -------- Die OS/2 Version ist ein 32-bit Programm, das ab Version 2.0 aufwärts läuft. 8.3 Windows 95/NT ----------------- Michael Peschel (mipe@ibb.schwaben.com) hat spunk auf Windows-NT portiert, deshalb gibt es ab der Version 1.40 von ESTIC auch eine Windows-NT Version. Ab Version 1.60 von ESTIC ist das Executable auch unter Windows 95 ausführbar. ACHTUNG: ESTIC ist auch unter Windows 95/NT ein Textmodus- (bzw. Console-) Programm! Bitte keine Bug-Reports "ich kann die Menues nicht öffnen"! Einfach die Maus weglegen und die Tastatur benutzen. Unter Windows werden im Fullscreen-Modus zur Zeit keine anderen Auflösungen als 80x25 unterstützt. Im Grafikmodus kann das Fenster (fast) beliebig in der Größe verändert werden. 8.4 Linux, FreeBSD und andere Unixe ----------------------------------- Durch die Vielzahl möglicher Terminaltypen ist die Installation leider nicht ganz so einfach wie unter DOS & OS/2 (aber auch nicht wesentlich komlexer). Völlig ohne Einstellungen kommt ESTIC beim Betrieb auf der Console aus. Bei Terminals muß u.U. der Zeichensatz eingestellt werden. Im Gegensatz zu früheren Versionen ist die Default-Sprache von ESTIC jetzt auch unter FreeBSD und Linux deutsch, es sind also keine weiteren Einstellungen für die Sprache notwendig. Einstellungen für die Ein-/Ausgabe sowie der Betrieb in Farbe: SPUNK_COLOR Mögliche Werte: "yes", "no", "1", "0". Bestimmt ob ESTIC bei der Ausgabe Farben verwendet. ESTIC verwendet ohne die Angabe Farben auf der Console, aber nicht auf sonstigen Terminals. SPUNK_CP437 Gibt an, ob das Ausgabegerät die IBM Codepage 437 unterstützt. Mögliche Werte: "yes", "no", "1", "0". Wird die Codepage 437 unterstützt, dann wird PC-kompatible Liniengrafik anstelle von +|- verwendet. Diese Einstellung ist bei Verwendung eines PC- Terminalprogramms sinnvoll. Tastenbelegung unter Linux und FreeBSD: ESTIC verwendet soweit möglich dieselbe Tastenbelegung wie unter DOS & OS/2. Für den Fall, daß Tasten auf dem jeweiligen Terminal nicht existieren gibt es Ersatz-Codes. Diese werden dann in der Statuszeile anstelle der normalen Tastenbelegungen angezeigt. Damit das funktioniert ist es aber wichtig, daß das Terminal richtig gesetzt ist. Wer sich z.B. per Modem auf seinem Linux-Rechner ein- wählt darf nicht nur das Terminalprogramm auf 'vt100' einstellen, sondern muß auch die TERM Environment Variable korrekt auf 'vt100' setzen. Steht diese anstelle von 'vt100' auf 'linux', dann entnimmt ESTIC dem Termcap-Eintrag, daß die Funktionstasten F1-F10 verfügbar sind - und verwendet diese auch! Die Folge ist, daß Änderungen mit F10 bestätigt werden müssen - und F10 ist bei einer echten vt100 Emulation nicht vorhanden. Leider sind einige von ESTIC verwendete Tasten unter Linux nur mit großen Problemen verfügbar. Stattdessen existieren Ersatztasten, die aber nicht so eingängig sind. Die Ersatztasten sind Aktion Orginal Ersatz auf Terminals ------------------------------------------------------------------ Schließen Alt+F3 Alt+Ctrl+C Esc-Ctrl+C Resize Ctrl+F5 Alt+Ctrl+R Esc-Ctrl+R Resize-Up Ctrl+Up Ctrl+W Ctrl+W Resize-Down Ctrl+Down Ctrl+Z Ctrl+Z Resize-Left Ctrl+Left Ctrl+A Ctrl+A Resize-Right Ctrl+Right Ctrl+F Ctrl+F Move-Up Cursor-Up Cursor-Up Ctrl+E Move-Down Cursor-Down Cursor-Down Ctrl+X Move-Left Cursor-Left Cursor-Left Ctrl+S Move-Right Cursor-Right Cursor-Right Ctrl+D ACHTUNG: Das gilt nur für die Textmode-Versionen von ESTIC. Unter X sind (nach korrekter Installation) praktisch durchgängig die unter "Orginal" aufgeführten Tasten vorhanden. Umlaute: Wird die Codepage 437 verwendet (wie auf der Console), dann werden Umlaute immer korrekt dargestellt. Bei Terminals, die den ISO-8859-1 Zeichensatz verstehen, sollte die Variable LC_CTYPE auf den Wert "iso_8859_1" gesetzt werden. ESTIC verwendet dann die entsprechenden Codierungen für die deutschen Umlaute. Wer LC_CTYPE schon anders eingestellt hat, kann ersatzweise auch SPUNK_CTYPE verwenden, der Wert in dieser Variable überschreibt den in LC_CTYPE. Und noch ein Tip: Wer einen Termcap-Eintrag für Minicom hat, kann auch bei einer Telnet-Session von einem Linux-PC auf einen anderen Farben und Liniengrafik verwenden. Beispiel-Session: uz@moppi:~$ rlogin wuschel uz@wuschel:~$ export TERM=mc uz@wuschel:~$ export SPUNK_COLOR=yes uz@wuschel:~$ export SPUNK_CP437=yes uz@wuschel:~$ estic Es macht natürlich Sinn, obige Einstellungen in Abhängigkeit vom Login-Terminal in .profile zu verewigen. Areacode Datenfile: Es macht u.U. Sinn, das areacode Datenfile als /usr/lib/areacodes systemweit zu installieren. Ich wollte eigentlich eine eigene Installationsroutine dafür schreiben (die Datenfiles haben einen Build-Stempel, wodurch sichergestellt werden kann, dass kein neues durch ein älteres File überschrieben wird), bin jedoch sowieso mehrere Monate hinter meinem Zeitplan her und habe gerade einfach keine Lust mehr :-( Unter Linux verwendet das neue isdnlog (frag mich bloss gerade keiner nach der Version, irgendwas > 2.5) auch dieses Datenfile, d.h. wer es in /usr/lib installiert braucht es nur einmal. 8.5 X Window System ------------------- Für Linux und FreeBSD gibt es auch eine X Version von ESTIC. Das spunk X Backend hat derzeit noch ein paar Einschränkungen. Es folgen einige Hinweise zum Verhalten/Betrieb. * Das Executable trägt als einziges den Namen xestic, damit es neben einem "normalen" estic her existieren kann. Der Name der Resource- und INI-Files ändert sich nicht. * Das X Backend von spunk wertet zwei Kommandozeilenparameter aus, -display und -geometry. Weitere, X-spezifische Parameter existieren nicht. Eine der nächsten Versionen wird dahingehend erweitert werden, daß sich das X Backend Größe und Position des Fensters selber merkt - dann wird das unsägliche -geometry überflüssig. * Die Fenstergröße kann zwischen 80*25 und 100*50 stufenlos eingestellt werden. * Auf Workstations mit mehr als 4 Farbplanes (> 16 Farben) wird ein Display mit 16 Farben für den Text emuliert. Sind weniger Farbebenen, aber mehr als eine vorhanden, dann wird ein Display mit 3 Farbstufen (schwarz/grau/weiß) emuliert. Auf monochromen Servern erfolgt die Ausgabe in schwarz/weiß. Der Versuch einer Ausgabe mit 16 Farben läßt sich durch Setzen von SPUNK_COLOR=yes erzwingen, dürfte bei einem 16-Farb Server aber nicht sehr hübsch aussehen (habe ich nicht probiert). * Spunk sucht nach den folgenden Fonts in der angegebenen Reihenfolge: vga fixed 8x13 Der vga Font ist auf Linux-Systemen normalerweise vorhanden, weil er von DOSEMU verwendet wird. Mit diesem Font kann die Codepage 437, d.h. Liniengrafik verwendet werden. Ist keiner der oben angegebenen Fonts vorhanden, oder soll ein anderer Font verwendet werden, dann kann mit SPUNK_XFONT= auf einen anderen Font umgeschaltet werden. Es muß sich dabei um einen Fixed Font handeln! Spunk nimmt bei Fonts, deren Namen nicht mit "VGA" anfängt an, daß es sich um ISO-8859-1 Fonts handelt und setzt die Ausgabe entsprechend um. Trotzdem wird die Verwendung des VGA Fonts dringend empfohlen (sieht _viel_ hübscher aus). * Die graue und monochrome Anzeige können mit SPUNK_XINVERTMONO=yes invertiert werden. Das kann vor allem bei der monochromen Anzeige sinnvoll sein. * Spunk verwendet mod4 für die linke Alt-Taste. Das ist - falls notwendig - entsprechend anzupassen. * Manche Linux-Systeme schalten die rechte und linke Alt-Taste parallel (mod5). Das ist dann der Fall, wenn die sonst nur mit der Alt-Gr Taste erreichbaren Zeichen (z.B. '@') auch mit der linken Alt-Taste erzeugt werden können. Spunk kann in dem Fall bestimmte Alt-Kombinationen nicht erkennen, es empfiehlt sich das Abschalten dieses Features, bei mir war dazu die Eingabe von xmodmap -e "remove mod5 = Alt_L" notwendig. * Window-Manager haben die unangenehme Eigenschaft, sich recht viele Tasten für irgendwelche Hotkeys zu belegen. Diese Tasten stehen für spunk nicht mehr zur Verfügung (das gilt z.B. für fvwm und die Cursor Keys zusammen mit allen(!) Modifier Tasten). Wen das stört, der sollte entweder seinem Window-Manager andere Tastenkombinationen beibringen, oder die Ersatzcodes von spunk verwenden (siehe weiter oben, oder auch spunk/xsrc/console.cc). * Und bevor ich's vergesse: Maus-Bedienung ist nicht möglich, da spunk derzeit keine Mäuse unterstützt. 9. Andere Sprachen ------------------ Derzeit unterstützt ESTIC die Sprachen Deutsch und Englisch. Unter Linux/FreeBSD ist der Default Deutsch, unter OS/2 und DOS wird die aktuelle Landeseinstellung ausgewertet. Falls das eingestellte Land nicht unterstützt wird ist der Default USA/Englisch. Land/Sprache läßt sich durch Setzen von Environment-Variablen beeinflussen: set SPUNK_LANGUAGE= set SPUNK_COUNTRY= Unter Linux & FreeBSD gehört jeweils eine entsprechende "export"- Anweisung für die Variable dazu. Verfügbare Ländercodes (falls die dazugehörige Sprache nicht verfügbar ist wird zumindest die Zeit/Datumsdarstellung umgeschaltet): 001 USA 031 Niederlande 039 Italien 041 Schweiz 044 England 049 Deutschland Verfügbare Sprachen (für ESTIC) 1 Deutsch 2 Englisch Übersetzungen in weitere Sprachen sind möglich, ohne die ausführbare Datei zu ändern (Erweiterung von estic.res). Da sich meine Fremdsprachenkenntnisse auf Englisch und etwas (unnützes) Latein beschränken, würde ich mich freuen, wenn mir jemand bei der Übersetzung in andere Sprachen behilflich ist. 10. Bekannte Fehler und Unzulänglichkeiten ------------------------------------------ Folgende Fehler/Unzulänglichkeiten sind in der aktuellen Version bereits bekannt: * Gespräche, die intern weitervermittelt wurden (oder bei denen eine Weitervermittlung versucht wurde) werden nicht korrekt protokolliert (die angegebene Anzahl Einheiten ist fehlerhaft). Das könnte auch bei gemakelten Gesprächen so sein, habe ich nicht probiert. * Die Istec schaltet ab und zu ohne weiteren Grund den Diagnose-Modus ab und ignoriert dann weitere Befehle zum Einschalten desselben. Deshalb passiert es leider, daß bei dauernd laufendem ESTIC ab und zu die Erfassung der Gespräche ausfällt. Das ist ein Bug der Istec Firmware gegen den ich leider machtlos bin. Dieser Fehler ist - soweit ich das prüfen konnte - ab Firmware 1.95 behoben. * Unter bestimmten Bedingungen zerstört sich ESTIC selber das Settings-File. Symptom dafür sind Access-Violations oder Core-Dumps direkt beim Start. Manchmal erscheint auch eine Fehlermeldung "Internal error: Call to abstract method". Das passiert dann, wenn entweder zwei Kopien von ESTIC in verschiedenen Sessions gestartet werden, oder wenn der Rechner heruntergefahren wird, ohne ESTIC korrekt zu beenden. Abhilfe ist möglich durch Löschen des Settings-Files (estic.rc unter DOS, OS/2 & Windows, ~/.esticrc unter *nix). * Die Behandlung von internationalen Rufnummern ist praktisch überhaupt nicht getestet (u.a. weil's nicht ganz billig ist :-). Das betrifft vor allem das Einfügen von Trennzeichen (wenn die areacode Datenbank vorhanden ist, dann kann ESTIC einen Trenner zwischen Vorwahl und eigentlicher Rufnummer einfügen). * Bei der Verwendung der Tag-/Nachtumschaltung der Istec kann es zu Problemen bei einer der nachfolgenden Befehle kommen. Grund dafür ist (wie so oft) ein Fehler in der Istec, die ab und zu den Umschaltungsbefehl zweifach beantwortet. Die folgenden Punkte gelten nur für die Version 2.0 der Firmware. Hier hat die Istec das Problem, dass bestimmte Daten zwar von ESTIC korrekt abgeschickt, aber von der Istec nicht gespeichert werden. es ist zwar anscheinend möglich, mit horrendem Aufwand um die Probleme der Istec herumzuprogrammieren, das habe ich mir aber gespart. Einige Dinge lassen sich deshalb innerhalb von ESTIC einstellen, sind aber nach dem Speichern verloren (siehe auch Abschnitt 19.). * Die Version 2.0 der Firmware kann eigentlich die Rufumleitung von verschiedenen Bedingungen abhängig machen. Das ist zwar von ESTIC implementiert, funktioniert nicht, weil die Istec das, was ESTIC sendet nicht speichert. Unbedingte Umleitungen funktionieren. * Das Einstellen von Rufsignale für die verschiedenen MSNs ist von ESTIC implementiert, die Änderungen werden von der Istec aber nicht gespeichert. * Die mit der Firmware 2.0 hinzugekommenen Kurzwahlnummern sind von der Konfiguration her eine mittlere Katastrophe. So kann für jeden einzelnen Speicherplatz eingestellt werden, - ob die Nummer für bestimmte Endgeräte auf "Babyruf" (Direktwahl nach Abheben) konfiguriert werden soll, - gleichzeitig(!) kann die Nummer als Kurzwahl für andere oder dasselbe Gerät dienen (was im Falle der Anwahl desselben Gerätes passiert wissen wohl nur die Götter), - wahlweise kann die Nummer aber auch als Sperre geschaltet werden (unabhängig davon, ob sie als Babyruf Verwendung findet), - und weiterhin kann für die festgelegte Nummern noch ein Klingelsignal ausgewählt werden, d.h. die Nummer wird dann nicht bei ausgehenden, sondern bei eingehenden Rufen ausgewertet, und zwar unabhängig von der Einstellung bei ausgehendem Ruf oder Babyruf. Dabei sind die festgelegten Endgeräte unerheblich, das Klingelsignal gilt für alle Endgeräte. - Wenn die Nummer als Sperre konfiguriert ist, dann sind auch unvollständige Nummern zulässig. - Die Nummer braucht, wenn sie als Kurzwahl konfiguriert ist (im Gegensatz zu der Nummer, die bei einer Rufumleitung angegeben wird) die Amts-Null. Da bei einkommenden Rufen damit auch das Klingelsignal eingestellt wird, wird die führende 0 anscheinend von der Firmware entfernt, ausserdem braucht die Erkennung für einkommende Anrufe immer die Vorwahl. Das wiederum kann zu Problemen führen, wenn die Nummer als Sperre definiert ist, hier ist die tatsächlich gewählte Nummer interessant, nicht die komplette Nummer mit Vorwahl, wie sie für die Erkennung eingehender Rufe benötigt wird. Was wiederum bedeutet, dass eine Nummer, die gesperrt werden soll, mehrfach eingetragen werden muß: Einmal ohne Vorwahl einmal mit Vorwahl, und vermutlich sogar nochmal mit Landes- kennung. Wer das jetzt nicht ganz verstanden hat braucht sich keine Sorgen machen, ich habe mehr als eine Stunde gebraucht um das alles zu testen und alle Details zu durchschauen. Da das nicht nur für den Benutzer, sondern noch viel mehr softwaretechnisch eine Katastrophe darstellt habe ich das Verhalten etwas modifiziert, auch wenn dadurch Kombinationsmöglichkeiten bei der Konfiguration verloren gehen: Einem Speicherplatz im Kurzwahlspeicher kann eine Nummer, sowie für ausgehende Rufe ein Verwendungszweck zugeordnet werden. Dieser Verwendungszweck ist eines der folgenden: o Babyruf o Kurzwahl o Sperre Weiterhin kann für eingehende Rufe derselben Nummer noch das Klingelsignal festgelegt werden. Das bedeutet zwar gegenüber dem Konfigurationsprogramm vom Emmerich eine geradezu verschwenderischen Umgang mit den Kurzwahlspeichern (ESTIC braucht zum Teil 2 Einträge für denselben Zweck wie das Konfigurationsprogramm von Emmerich), andererseits sind 60 Plätze eine ganze Menge, und der Vorteil, daß die Features dadurch erst bedienbar werden ist nicht zu unterschätzen. Außerdem kann ESTIC dadurch auf Fehler prüfen, weil die Rahmenbedingungen eingeengt werden. Weiterhin wird die Tatsache, dass die Istec Firmware eine führende '0' vor der eigentlichen Nummer braucht, vor dem Benutzer versteckt. ESTIC entfernt diese Ziffer beim Laden und fügt sie vor dem Speichern wieder an. Wenn die areacode Datenbank verfügbar ist, dann wird automatisch ein Trenner zwischen Vorwahl und eigentlicher Nummer eingefügt. ACHTUNG: ESTIC passt die Kurzwahlen beim Laden an obige Einschränkungen an. Damit werden aber per ISTEC.EXE eingestellte Kurzwahlnummern verändert. Das ist solange unkritisch, wie die Nummern nicht in die Anlage zurückgespeichert werden. Die einfachste Lösung ist, entweder nur ESTIC zu verwenden, oder auch unter ISTEC.EXE nicht mehrfache Features auf eine Kurzwahl zu legen. 11. Andere ISTEC Anlagen ------------------------ Aufgrund der geringen Anzahl von Rückmeldungen, zusammen mit der Tatsache, daß ESTIC sowieso immer komplexer wird, weil immer mehr verschiedene Firmware-Versionen unterstützt werden müssen, habe ich beschlossen, in Zukunft bei der Programmierung ohne Rücksicht auf andere Emmerich Anlagen vorzugehen. ESTIC war ursprünglich für die Unterstützung von anderen Anlagen vorbereitet. Ich werde diese Unterstützung (soweit sie nach außen hin sichbar ist) soweit wie möglich für eine der nächsten Versionen entfernen. 12. Programmiertechnisches -------------------------- Ich werde ab der Version 1.30 von ESTIC nur noch Binaries für DOS, OS/2, Linux und Windows bereitstellen, weil ich nur diese auch wirklich testen kann. Trotzdem fände ich es sehr sinnvoll, wenn es für möglichst viele Plattformen Binaries gäbe. Es gibt eine Menge Leute (vor allem im Unix- Bereich) die prinzipiell alles selber übersetzt haben müssen. Eine sehr große Anzahl von Benutzern weiß aber offenbar auch vorcompilierte Versionen zu schätzen - zudem ist das für den Anwender, der keine Lust oder Zeit hat, sich mit 5 verschiedenen Compiler-Versionen rumzuschlagen eine sehr bequeme Lösung. Wer also zur ersten Gruppe der "Selber-Übersetzer" gehört, und dem Rest der Welt einen Gefallen tun will, der kann mir (nach Rückfrage!) das entsprechende Binary zusenden, ich werde es auf die entsprechenden Server legen oder legen lassen. Speziell für die etwas selteneren Unix-Varianten gilt: Ports machen nur dann Sinn, wenn der Port aktiv in Benutzung ist und von jemand anderem gewartet wird. Das ist derzeit nur für FreeBSD der Fall, hier gibt es (dank Julian H. Stacey, jhs@freebsd.org) inzwischen eine Version von ESTIC die in den offiziellen FreeBSD Baum integriert ist. Alle anderen Unix-Versionen (mit Ausnahme von Linux) sind von mir ab sofort auf Eis gelegt, bis sich jemand findet, der sie auch wartet. 12.1 Allgemeines ---------------- Das Modul icei.cc (EI = External Interface) ist dafür gedacht, ohne großen Aufwand eigene Erweiterungen in ESTIC einzubauen. Alle Gesprächsdaten werden intern über Messages weitergeleitet. Im Modul icei befindet sich ein Objekt, das jede Message empfängt. Die entsprechende Case-Struktur muß nur noch um eigenen Code zur Verarbeitung der Message mit den Gesprächsdaten erweitert werden. Wer also ESTIC schon immer mal erweitern wollte, vor der Komplexität von spunk aber zurückgeschreckt ist hat hier die Möglichkeit, recht einfach eigene Ideen auszuprobieren. 12.2 FreeBSD ------------ Für FreeBSD gibt es einen "offiziellen" Port von Julian H. Stacy (jhs@freebsd.org). 12.3 Linux ---------- Das a.out Format wird nicht mehr unterstützt. 12.4 Unix-Systeme ----------------- Ports auf bisher nicht unterstützte Unix-System sollten kein allzu großes Problem sein. Am einfachsten ist der Port der X-Version, für die Textmodus-Version wird zwingend Termcap benötigt, das nicht auf allen Maschinen vorhanden ist. Das Define GENERIC_UNIX ist ein guter Startpunkt für andere Unix- Versionen. Siehe auch den Abschnitt weiter oben (Wartung der Ports). 12.5 DOS und OS/2, Windows -------------------------- Die Version ist mit dem Watcom Compiler übersetzt, braucht aber das Borland-Make! Das liegt daran, daß das Watcom Make etwas komisch und das (mir vorliegende) GNU Make buggy ist (nur die OS/2 Version). 13. Nutzungsbestimmungen und Weitergabe --------------------------------------- Die Software (sowohl die Quellcodes, als auch die Binaries) werden ohne jegliche Zusagen/Garantien bezüglich Funktionalität oder Funktionsfähigkeit abgegeben. Weder die Autoren noch die Distributoren übernehmen eine Verantwortung für Schäden, die durch die Benutzung der Software verursacht werden. Die Software darf frei verwendet und weitergegeben werden, wobei "frei" ausdrücklich auch eine kommerzielle Nutzung/Weitergabe einschließt, *vorausgesetzt* die folgenden Bedingungen werden eingehalten: 1. Die Herkunft der Software muß - wenn überhaupt - dann korrekt angegeben werden. Es ist nicht erlaubt, die Software als Werk eines anderen auszugeben. Wird die Software in Teilen oder als Ganzes in einem Produkt benutzt, dann würde ich mich über einen Hinweis auf die Herkunft in der Dokumentation freuen. Ein solcher Hinweis ist aber nicht zwingend notwendig. 2. Geänderte Quellcodes müssen deutlich als solche gekennzeichnet werden und dürfen nicht ohne einen expliziten Hinweis auf die durchgeführten Änderungen weiterverteilt werden. 3. Die Bedingungen über die Nutzung/Weitergabe dürfen nicht entfernt oder geändert werden. Speziell für ESTIC gilt noch der folgende Hinweis: * Die Bestimmungen des Datenschutzes sind zu beachten! Das Logging-Feature kann speziell bei Anwendung im kommerziellen Bereich gegen Datenschutzbestimmungen verstoßen! 14. Verfügbarkeit ----------------- 14.1 Namensgebung der Files --------------------------- Ich bin von der alten esXXXyyy Namensgebung abgekommen, weil man die vielen Versionen praktisch nicht mehr auseinanderhalten konnte. Stattdessen werden sprechende Namen im Format estic-1.30-linux-386-aout-x.zip verwendet. Mit diesen Namen braucht es hoffentlich keine "Übersetzungs-Tabelle" mehr :-) 14.2 Modem-Login auf wuschel.ibb.schwaben.com --------------------------------------------- Zugriff auf die ESTIC Files gibt es über zwei Logins auf meinem Linux-Rechner. Telefon: 0711/7676185 Login: sauger Passwort: sauger Verzeichnis: /pub/ESTIC Dieser Zugang ist interaktiv, d.h. wer sich mit der o.g. Kennung einloggt bekommt eine ganz normale Unix-Shell. Da das für viele ein echtes Problem zu sein scheint (die Logfiles können einen manchmal wirklich schaudern machen), gibt es auch einen nicht- interaktiven Login, über den die Files per Menue-Auswahl angeboten werden: Telefon: 0711/7676185 Login: estic Der ISDN Login unter derselben Nummer wurde wegen Problemen mit der verwendeten ISDN Software bis auf weiteres abgeschaltet. 14.3 FTP-Sites -------------- ESTIC ist auf folgenden FTP Sites verfügbar: ftp://ftp.gwdg.de/pub/misc/isdn/linux/estic/ ftp://ftp.franken.de/pub/isdn4linux/estic/ (1) ftp://ftp.musoftware.com/pub/estic/ (1) Das isdn4linux Verzeichnis auf franken.de wird von diversen anderen ftp Servern gespiegelt. ESTIC sollte auch auf allen Mirror-Sites verfügbar sein. Ich habe keinen Zugang mehr auf ftp.seicom.net, was dort herumliegt sind alte Versionen, die ich - mangels Zugriff - auch nicht löschen kann. 14.4 WWW-Sites -------------- Neben dem Zugriff über die ESTIC Homepage (s.u.) ist ESTIC auch über die Web Page von Uli Mittermaier zu beziehen: http://www.fast.de/~uli/isdn 15. ESTIC Web-Page ------------------ ESTIC hat seit einiger Zeit auch eine Home-Page im WWW. Dort finden sich allgemeine Infos zu ESTIC und zur ISTEC, die ESTIC-FAQ, Ausblicke auf neue Versionen, Informationen zur Klassenbibliothek spunk (s.u.), Links auf die aktuellen Binaries, sowie auf weitere Sites mit ergänzenden Informationen. Für die Web-Page hätte ich noch Interesse an weiteren Links, speziell Bezugsmöglichkeiten (über's Internet) von anderen ISTEC Konfigurationsprogrammen. Die URL der ESTIC Home-Page: http://www.musoftware.com/estic/ 16. Bug-Reports --------------- Bug-Reports bitte mit einer _genauen_ Beschreibung unter Angabe des Betriebssystems, ESTIC-Version und ISTEC Firmware-Version. Falls es sich um Kommunikationsfehler handelt, bitte die relevanten Teile (und nur diese!) des Debug-Logs mitschicken. Fehler-Reports bekomme ich am liebsten per Mail MIT GÜLTIGER ABSENDER- ADRESSE (warum ich das wohl groß schreibe?). Wer unbedingt meint, mir ein Fax schicken zu müssen, der soll wenigstens dafür sorgen, daß sein eigenes Fax korrekt konfiguriert ist! Ich habe mir mehrfach die Mühe gemacht, auf solche Faxe zu antworten, meine Antwortfaxe sind aber nie angekommen (mit an Sicherheit grenzender Wahrscheinlichkeit wegen einer falsch eingestellten Dienste-Kennung). Wer also seinen Fax-Anschluß nicht auf "Fax" konfiguriert hat, kann sich einen Fehler- Report per Fax sparen oder braucht zumindest keine Antwort zu erwarten (sorry, aber sowas ist _ziemlich_ nervig!). 17. Anmerkung zu SPUNK ---------------------- SPUNK ist eine C++ Klassenbibliothek für Textmodus Applikationen. Neben den Klassen/Funktionen für die Oberfläche enthält SPUNK noch viele weitere allgemein anwendbare Routinen (Klassen für Strings, Listen etc). SPUNK implementiert persistente Objekte - alle Menues, Strings usw. sind persistent, sie werden interaktiv über einen Resourcen-Editor erstellt und zur Laufzeit aus einem Resourcen-File geladen. Der Vorteil ist kürzerer Code, einfache Möglichkeit der Übersetzung in andere Sprachen und die Möglichkeit, alle Resourcen interaktiv zu erstellen. SPUNK ist (relativ) portabel, für eine Portierung müssen nur wenige systemabhängige Module neu geschrieben, sowie einige Header-Files angepasst werden. SPUNK ist derzeit verfügbar für DOS (16 und 32-Bit mit Extender), OS/2, Linux, Windows NT (das sind die Betriebssysteme, die ich hier am laufen habe), für Windows 95, FreeBSD und diverse andere Unixe verfügbar. Ich würde SPUNK gerne auf mehr Plattformen portieren. Wenn mir jemand dabei behilflich sein kann und will, bitte kurze Mail an mich. 18. Danksagungen ---------------- Bei der Entwicklung von ESTIC haben mir eine Menge Leute direkt oder indirekt geholfen. Leider habe ich in den vorigen Versionen nur einen Teil dieser Leute namentlich erwähnt. Hier also eine etwas komplettere Liste (die aber leider immer noch unvollständig ist): Mein Dank geht an: Hergen Lehmann (HERGEN_LEHMANN@TBX.BerliNet.DE), für die Entschlüsslung des Istec-Protokolls. Peter Dieth (dieth@seicom.net), für den Account auf einem FreeBSD-Rechner bei Seicom, der den FreeBSD-Port erst möglich gemacht hat. Terry Lambert (terry@cs.weber.edu), für die freundlichen und ausführlichen Erklärungen zur "xn" Termcap Capability. Jürgen Egeling (ry90@jecalpha.ka.sub.org) für das ROM mit der Firmware-Version 1.92. Ralf W. Stephan (ralf@ark.franken.de) für die Hinweise/Änderungen zur Übersetzung von spunk mit den neueren GNU Compilern, sowie die diversen anderen Anregungen zu spunk. Norbert Kluge (nkl@scharl.hb.north.de) für das ("die" müßte man korrekterweise sagen :-) Eprom mit der Firmware-Version 1.93, für die diversen Tips und Infos. Christian Kratzer (ck@toplink.de), für den Test der FreeBSD-Version, das Bier, und für den FreeBSD- Account. Torsten Blum (torstenb@tlk.de) für einige nützliche Hinweise, u.a. zu FreeBSD. Ralph-Thomas Aussem (1aussem@informatik.uni-hamburg.de) für den NetBSD (Amiga 68030) Port. Markus Bellenberg (jmb@outbreak.gun.de) für die Anregungen und das log2xxx Programm, dessen Funktionalität inzwischen in ESTIC drinsteckt. Michael Peschel (mipe@ibb.schwaben.com), für die Vorarbeiten zum seriellen Modul für OS/2 und den NT Port. Oliver von Bueren (ovb@swissmail.com), Julian H. Stacey (jhs@freebsd.org), für Tips, Hinweise, Diffs und Arbeit am FreeBSD Port. Oliver Daudey (oliver@xs4all.nl), für die Korrektur der niederländischen Texte in spunk und für seine Anregungen zu ESTIC. Norbert Richter (nr@prog-link.com), für viele Tips und nützliche Hinweise. ... und natürlich an alle anderen, die mir mit Bug-Reports, oder auch Lob&Tadel geholfen haben. Falls ich jemanden hier vergessen haben sollte, dann ist das keine böse Absicht. Ich bekomme zeitenweise recht viel Mail zu ESTIC und wenn ich noch andere Dinge um die Ohren habe kann sowas gut mal passieren. In dem Fall einfach kurze Mail an mich. 19. Und zum Schluß... --------------------- Das hier (d.h. die Version 1.6) ist die letzte Version von ESTIC, die es von mir geben wird. Um einer Vielzahl von Anfragen per Mail vorzubeugen ist hier eine kurze Auflistung meiner Gründe: 1. ESTIC macht eine Menge Arbeit und es ist nicht das einzige Freeware Projekt, in das ich gerne Arbeit investieren würde. 2. Es macht seit geraumer Zeit keinen Spaß mehr, Erweiterungen für ESTIC zu programmieren. Das Interface zur Istec ist eine mittlere Katastrophe, die Istec Firmware fehlerhaft und neue Feature sind oft extrem kompliziert zu programmieren. Verbesserungsvorschläge oder andere Hinweise an Emmerich werden dort fast durchweg ignoriert. Kontakt zu Emmerich habe ich praktisch nicht (mehr), ich habe auch nicht das Gefühl, daß Emmerich Interesse an einem solchen Kontakt hat. Die Anpassung für die Firmware 2.0 kam nur zustande, weil ein Benutzer mir eine Beta eines Nachfolgers der Firmware 2.0 zur Verfügung gestellt hat. Das ist ein Grund, warum ich, vor die Wahl gestellt, welches Projekt ich einstelle, ausgerechnet ESTIC gewählt habe. 3. Die neue Politik von Emmerich, für Firmware-Updates Geld zu verlangen ärgert mich etwas. Ich bin niemand mit einer übertriebenen "Featuritis", d.h. ich brauche eigentlich neue Firmware-Versionen nicht (Ausnahme: Bugfixes). Der Hauptgrund für eine neue Firmware ist bisher durchweg ESTIC gewesen. Wenn ich aber jetzt jedesmal Geld dafür ausgeben muß um ESTIC up-to-date zu halten, dann verliere ich recht schnell die Lust. 4. Während bei den alten Firmware-Versionen (1.90 bis 1.96) von Version zu Version eine leichte Besserung eintrat, was Fehler und Features anging, so ist die Version 2.0 ein großer Rückschritt. Erstens hat die Version bereits in der Funktion Fehler (den hier in d.c.i.tk-anlage diskutierten Fehler "Anlage erzeugt keine Klingelzeichen mehr" durfte ich bereits genießen. Weiterhin bekomme ich in regelmäßigen Abständen keinen Amtston, wenn ich den Hörer abhebe, meist nach längeren Gesprächen). Schon das alleine rückt die Benutzung der Firmware 2.0 (für mich) an die Grenze der Unzumutbarkeit. Zweitens setzt sich dieses Verhalten auch bei der Programmierung der Anlage nahtlos fort: * Manche Einstellungen werden von der Anlage nur unter äußerst komplizierten, für den Programmierer nicht nachvollziehbaren Bedingungen gespeichert (Speichern der Länge für die externe Nummer tut nur, wenn zuvor die Meldung "Istec bereit?" abgesetzt wurde und ähnliches). Die Istec meldet aber bei jeder Programmierung selbstverständlich "Ok" zurück. Zum Teil sind diese Bedingungen aber noch nicht mal reproduzierbar. Norbert Richter hat in tagelanger Arbeit eine Abfolge ausgetüftelt, bei der sein Programm PMIstec die Istec veranlasst, bestimmte Konfigurationsdaten zu speichern - bei mir tut diese Abfolge nicht, zumindest nicht für alle Daten (dank dem oben erwähnten Trick von Norbert speichert die Istec jetzt wenigstens die Länge der externen Rufumleitung). Die Konfigurationssoftware von Emmerich löst dieses Problem offensichtlich durch eine immense Redundanz der übermittelten Daten. Es werden nicht nur zwischen den Datensätzen der verschiedenen Geräte diverse Bereitschaftsabfragen, Setzen von Tag-/Nacht, Setzen der Alarme eingestreut, anscheinend (so wurde mir mitgeteilt) werden auch die Daten für die einzelnen Geräte sporadisch mehrfach geschrieben. * Fehlercodes sind zwar definiert, werden aber nicht zurückgeliefert, stattdessen kommt Müll zurück (z.B. gültige Nachricht mit leerem Inhalt). * Neue Features sind zum Teil extrem umständlich zu programmieren und in sich nicht schlüssig. Ein Beispiel sind die Kurzwahlen (s.o.). * In vielen Details verbergen sich weitere Umständlichkeiten: So werden (um nur ein Beispiel zu nennen) die MSN und die Rufumleitungen BCD-codiert in der Konfiguration gespeichert, das Low-Nibble zuerst. Bei den Kurzwahlen dagegen erfolgt die Speicherung umgekehrt, High-Nibble zuerst. Das ist an sich nicht so tragisch, leider gibt es aber viel zu viele von diesen Umständlichkeiten (Apparate sind manchmal als 1..8 und manchmal als 21..28 codiert, die eine Firmware beendet eine Rufnummer mit einem 0xF Nibble, die andere führt ein separates Längenbyte für dieselbe Einstellung ein, in der Firmware 2.0 gibt es insgesamt 3(!) verschiedene Protokolle, mit denen Daten von und zum Konfigurationsprogramm übertragen werden, das alte Protokoll, das neue (CTI-) Protokoll, und nochmal ein separates Protokoll für die Meldung der eingehenden Anrufe usw. usf.) Das alles (speziell meine Meinung über Emmerich und die Istec Firmware) ist natürlich nur meine eigene ganz private, persönliche Meinung, die ich mir gebildet, als ich tagelang versucht habe, bestimmte Features zum Laufen zu bekommen. Ich erhebe keinen Anspruch auf absolute Wahrheit, insbesondere beruhen einige (wenige) Aussagen auf Mitteilungen anderer, klangen für mich aufgrund eigener Erfahrungen plausibel, und wurden von mir nicht nochmal überprüft. Wer meint, ich sei nur zu blöd, um anständige Programme zu schreiben (schließlich funktioniert das Konfigurationsprogamm von Emmerich so einigermaßen), dem werde ich nicht widersprechen. Wenn jemand Lust hat, ESTIC zu übernehmen, dann bin ich gerne bereit, diesen Jemand bei der Einarbeitung in spunk zu unterstützen. Das (Teil-) Modul Areacode werde ich weiterpflegen. estic-1.61.orig/estic/estic.h0100644000176100001440000002247107031424722015406 0ustar debacleusers/*****************************************************************************/ /* */ /* ISTEC.H */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ESTIC_H #define _ESTIC_H #include "program.h" #include "icconfig.h" #include "icshort.h" /*****************************************************************************/ /* Menue items */ /*****************************************************************************/ const i16 miNone = 1; const i16 miEstic = 1000; const i16 miAbout = 1100; const i16 miFile = 2000; const i16 miFileLoadConfig = 2100; const i16 miFileSaveConfig = 2200; const i16 miFileLoadShort = 2300; const i16 miFileSaveShort = 2400; const i16 miViewLog = 2500; const i16 miReadAliases = 2600; const i16 miReadCronFile = 2700; const i16 miQuit = 2800; const i16 miIstec = 3000; const i16 miIstecLoadConfig = 3100; const i16 miIstecSaveConfig = 3200; const i16 miIstecLoadShort = 3300; const i16 miIstecSaveShort = 3400; const i16 miVersion = 3500; const i16 miEditSysParams = 3600; const i16 miEditDevParams = 3700; const i16 miEditShort = 3800; const i16 miReset = 3900; const i16 miSwitchDayNight = 3950; const i16 miCharges = 4000; const i16 miLoadCharges = 4100; const i16 miChargeWin1 = 4200; const i16 miPrintSettings = 4300; const i16 miPrintCharges = 4400; const i16 miResetCharges = 4500; const i16 miWindow = 5000; const i16 miOpen = 5100; const i16 miChargeWin2 = 5110; const i16 miMatrixWin = 5120; const i16 miCallWin = 5130; const i16 miCLIWin = 5140; const i16 miIMonWin = 5150; const i16 miTile = 5200; const i16 miCascade = 5300; const i16 miCloseAll = 5400; const i16 miRedraw = 5500; const i16 miZoom = 5600; const i16 miResize = 5700; const i16 miClose = 5800; const i16 miWindowList = 5900; /*****************************************************************************/ /* class IstecApp */ /*****************************************************************************/ // Forwards class IstecOptions; class ComPort; class IstecApp: public Program { private: static TopMenueBar* CreateMenueBar (); static BottomStatusLine* CreateStatusLine (); protected: u32 StatusFlags; // statusline flags String ComPortName; // Device name String SettingsFile; // Name of options file int IstecPresent; unsigned DayNight; // Current active config int Changes; // True if we have changes IstecConfig Config; ShortNumberColl ShortNumbers; int ShortNumberChanges; // Files String SaveDir; // Default load/save directory String DebugLog; // Debug log file name // Printing String Headline; String Currency; // Screen & Windows unsigned VideoMode; int ShowDateTime; int ShowInfoOnStartup; // Update related int DiagModeUpdate; Time LastUpdate; int DiagModeUpdateCounter; int ChargesUpdateCounter; const char* GetArgParam (int& Index); // Return the parameter for a command line argument. The parameter may // be part of the argument (as in "-cCOM1") or separate (as in "-c COM1"). // If the parameter is separate, Index is incremented, otherwise it's not. // If there is no argument, the function returns NULL. void CronHandler (const Time& T); // Is called from idle every minute, checks periodic events void DisplayDateTime (const Time& T); // Display the time in the upper right corner void ReadIniFile (); // Read default settings from an ini file int LoadConfig (); // Calls IstecGetConfig an returns the same codes but displays a message as // this can last some time int StoreConfig (); // Calls IstecPutConfig an returns the same codes but displays a message as // this can last some time int LoadShortNumbers (); // Calls IstecGetShortNumbers and returns the same codes but displays // a message as this can last some time int StoreShortNumbers (); // Calls IstecPutShortNumbers and returns the same codes but displays // a message as this can last some time void InitIstecConfig (); // Try to connect to the istec and download the istec configuration. // If this is impossible, initialize the configuration data to known // values. int AskWriteChanges (); // If there are differnces between the configuration stored in the istec and // the configuration in memory, ask to store the config data into the istec. // Return 1 if something has been written to the Istec, 0 otherwise. int AskWriteShortNumbers (); // If there are differnces between the short numbers stored in the istec and // the short numbers in memory, ask to store the numbers into the istec. // Return 1 if something has been written to the Istec, 0 otherwise. String GetIstecName (); // Return the name of the istec, determined by the parameters of the base // configuration. const char* GetProtocolName (unsigned Prot); // Return the protocol name used by the istec const String& GetConnectionName (unsigned Conn); // Return the connection type of the istec void ShowIstecConfig (); // Show the base configuration int EvalCmd (int RetCode); // Evaluate the return code of an istec command function. If the return // code denotes an error, an error message is poped up. The function // return 1 if the command has been error free, 0 on errors. void SetSaveDir (const String& Path); // Strips the name part from the given filename and stores the remaining part // (the directory) including the trailing path separator into SaveDir. void LoadFile (); // Load the configuration from a file void SaveFile (); // Save the current configuration to a file void LoadShort (); // Load the short numbers from a file void SaveShort (); // Save the current short numbers to a file void ViewLog (); // View a logfile void LoadIstec (); // Load the configuration from the istec void SaveIstec (); // Save the current config to the istec void SwitchDayNight (unsigned aDayNight); // Switch the current configuration void SysParams (); // Edit istec system parameters void DevParams (); // Set the device parameters void EditShortNumbers (); // Edit shortcut numbers void Reset (); // Reset the istec void LoadCharges (); // Reload the charges from the istec void PrintSettings (); // Edit settings for printing charges void PrintCharges (); // Print the charges void ResetCharges (); // Reset all charges void CloseAll (); // Close all windows void Resize (ItemWindow* Win); // Resize a window void Zoom (ItemWindow* Win); // Zoom a window void Close (ItemWindow* Win); // Close a window void BackgroundWork (const Time& Current); // Idle function. Is used to check for debug messages in the receive queue void OpenCLIWin (); // Open a CLI window public: IstecApp (int argc, char* argv []); // Construct an application object virtual ~IstecApp (); // Destruct an application object virtual int Run (); // Run the application void HandleEvent (Event& E); // Handle incoming events. Calls Update() if the application is idle virtual void DisableCommand (i16 ID); // Disable the command bound to the menue item with the given ID virtual void EnableCommand (i16 ID); // Enable the command bound to the menue item with the given ID }; // End of ESTIC.H #endif estic-1.61.orig/estic/estic.res0100644000176100001440000070171707031424722015757 0ustar debacleusersAnnaĻÜs5PPP   p pEtSpTpIpCp p pDtaptpepip p pItsptpepcp p pGtepbpphprpepnp p pFtepnpsptpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p prčEESTIC ESTIC 6P fŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p ptbpeprp pEpSpTpIpCp.p.p.p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL ber ESTIC... ber ESTIC... rŠD Datei Datei 6P& % HŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pKpopnpfpipgpuprpaptpipopnp pltapdpepnp.p.p.p p p p p p³p³p pKpopnpfpipgpuprpaptpipopnp pstppepipcphpeprpnp.p.p.p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pKpuprpzpwpaphplpepnp plpatdpepnp.p.p.p p p p p p p p p³p³p pKpuprpzpwpaphplpepnp pspptepipcphpeprpnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotgpfpiplpep papnpspephpepnp.p.p.p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pAplpipapspdpaptpepip petipnplpepspepnp p p p p p p p p³p³p pCtrpopnp pDpaptpepip pepipnplpepspepnp p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pQtupiptp p p p p p p p p p p p p p p p p pAplptp+pXp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p4LKonfiguration laden... Konfiguration laden... pSKonfiguration speichern... Konfiguration speichern... püA Kurzwahlen laden... Kurzwahlen laden... p` P Kurzwahlen speichern... Kurzwahlen speichern... pÄ OLogfile ansehen... Logfile ansehen... p( E Aliasdatei einlesen Aliasdatei einlesen p  CCron Datei einlesen Cron Datei einlesen p š Q4Quit Quit Alt+X s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄrø I%Istec Istec 6P/. @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pKpopnpfpipgpuprpaptpipopnp pltapdpepnp p p p p p p p p p p³p³p pKpopnpfpipgpuprpaptpipopnp pstppepipcphpeprpnp p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pKpuprpzpwpaphplpepnp plpatdpepnp p p p p p p p p p p p p p³p³p pKpuprpzpwpaphplpepnp pspptepipcphpeprpnp p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApkptpipvpep pKpotnpfpipgpuprpaptpipopnp p p p p pTpapgp p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVteprpspipopnp p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApntlpapgpepnpppaprpapmpeptpeprp p„pnpdpeprpnp.p.p.p p p p³p³p pEtnpdpgpeprp„ptpepppaprpapmpeptpeprp p„pnpdpeprpnp.p.p.p p³p³p pKtuprpzpwpaphplpnpupmpmpeprpnp p„pnpdpeprpnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtuprppcpkpspeptpzpepnp p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpp LKonfiguration laden Konfiguration laden p€ SKonfiguration speichern Konfiguration speichern pä A Kurzwahlen laden Kurzwahlen laden pH P Kurzwahlen speichern Kurzwahlen speichern wnOAktive Konfiguration Aktive Konfiguration Tag  Tag TagNachtp¬ VVersion Version p NAnlagenparameter „ndern... Anlagenparameter „ndern... p !tEEndger„teparameter „ndern...! Endger„teparameter „ndern... p ŲKKurzwahlnummern „ndern... Kurzwahlnummern „ndern... p<Z Zurcksetzen Zurcksetzen s2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs4u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄr  G"Gebhren Gebhren 6P0 /  ŌŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pGpepbpphprpepnp pltapdpepnp p p p p p p p p p³p³p pGpepbpphprpepnp patnpzpepipgpepnp p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pDprpupcpkp-pEtipnpsptpeplplpupnpgpepnp.p.p.p p³p³p pGpepbpphprpepnp pdtrpupcpkpepnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pGpepbpphprpepnp prtpcpkpspeptpzpepnp p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL Gebhren laden Gebhren laden phA Gebhren anzeigen Gebhren anzeigen pĢEDruck-Einstellungen... Druck-Einstellungen... s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp0D Gebhren drucken... Gebhren drucken... s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp”R Gebhren rcksetzen Gebhren rcksetzen r F!Fenster Fenster 6P ?!> &ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p™tfpfpnpepnp p p p p p p p p p p p p p p p p p p p pp p³p³p pKtapcphpeplpnp p p p p p p p p p p p p p p p p p p p p p³p³p pKpapspkpapdtep p p p p p p p p p p p p p p p p p p p p p³p³p pAtlplpep pspcphplpipepįpepnp p p p p p p p p p p p p p p³p³p pBtiplpdpspcphpiprpmp pnpepup papupfpbpapupepnp p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtopopmp p p p p p p p p p p p p p p p p p p p p pFp5p p³p³p pPtopspiptpipopnp/pGprp”pįpep p p p p p pCptprplp+pFp5p p³p³p pStcphplpipepįpepnp p p p p p p p p p p p pAplptp+pFp3p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pFtepnpsptpeprplpipsptpep p p p p p p p p p pAplptp+p0p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp qģ™2™ffnen ™ffnen  6P    PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pGtepbpphprpepnp p p p p p p p p p p p p p³p³p pVteprpbpipnpdpupnpgpspmpaptprpipxp p p p p³p³p pAtupspgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pEtipnpgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pItspdpnp4pLpipnpupxp pMpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöGGebhren Gebhren pVVerbindungsmatrix Verbindungsmatrix p AAusgehende Gespr„che Ausgehende Gespr„che pEEingehende Gespr„che Eingehende Gespr„che pIIsdn4Linux Monitor Isdn4Linux Monitor pPKKacheln Kacheln p´DKaskade Kaskade pAAlle schlieįen Alle schlieįen p|BBildschirm neu aufbauen Bildschirm neu aufbauen s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpąZ0Zoom Zoom F5 pDP3Position/Gr”įe Position/Gr”įe Ctrl+F5 pØS1 Schlieįen Schlieįen Alt+F3 s 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp  F Fensterliste Fensterliste Alt+0 6P%$ HŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pKpopnpfpipgpuprpaptpipopnp pltapdpepnp.p.p.p p p p p p³p³p pKpopnpfpipgpuprpaptpipopnp pstppepipcphpeprpnp.p.p.p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pKpuprpzpwpaphplpepnp plpatdpepnp.p.p.p p p p p p p p p³p³p pKpuprpzpwpaphplpepnp pspptepipcphpeprpnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotgpfpiplpep papnpspephpepnp.p.p.p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pAplpipapspdpaptpepip petipnplpepspepnp p p p p p p p p³p³p pCtrpopnp pDpaptpepip pepipnplpepspepnp p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pQtupiptp p p p p p p p p p p p p p p p p pAplptp+pXp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p4LKonfiguration laden... Konfiguration laden... pSKonfiguration speichern... Konfiguration speichern... püA Kurzwahlen laden... Kurzwahlen laden... p` P Kurzwahlen speichern... Kurzwahlen speichern... pÄ OLogfile ansehen... Logfile ansehen... p( E Aliasdatei einlesen Aliasdatei einlesen p  CCron Datei einlesen Cron Datei einlesen p š Q4Quit Quit Alt+X s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P    fŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p ptbpeprp pEpSpTpIpCp.p.p.p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL ber ESTIC... ber ESTIC... 6P&% &ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p™tfpfpnpepnp p p p p p p p p p p p p p p p p p p p pp p³p³p pKtapcphpeplpnp p p p p p p p p p p p p p p p p p p p p p³p³p pKpapspkpapdtep p p p p p p p p p p p p p p p p p p p p p³p³p pAtlplpep pspcphplpipepįpepnp p p p p p p p p p p p p p p³p³p pBtiplpdpspcphpiprpmp pnpepup papupfpbpapupepnp p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtopopmp p p p p p p p p p p p p p p p p p p p p pFp5p p³p³p pPtopspiptpipopnp/pGprp”pįpep p p p p p pCptprplp+pFp5p p³p³p pStcphplpipepįpepnp p p p p p p p p p p p pAplptp+pFp3p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pFtepnpsptpeprplpipsptpep p p p p p p p p p pAplptp+p0p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp qģ™2™ffnen ™ffnen  6P    PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pGtepbpphprpepnp p p p p p p p p p p p p p³p³p pVteprpbpipnpdpupnpgpspmpaptprpipxp p p p p³p³p pAtupspgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pEtipnpgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pItspdpnp4pLpipnpupxp pMpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöGGebhren Gebhren pVVerbindungsmatrix Verbindungsmatrix p AAusgehende Gespr„che Ausgehende Gespr„che pEEingehende Gespr„che Eingehende Gespr„che pIIsdn4Linux Monitor Isdn4Linux Monitor pPKKacheln Kacheln p´DKaskade Kaskade pAAlle schlieįen Alle schlieįen p|BBildschirm neu aufbauen Bildschirm neu aufbauen s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpąZ0Zoom Zoom F5 pDP3Position/Gr”įe Position/Gr”įe Ctrl+F5 pØS1 Schlieįen Schlieįen Alt+F3 s 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp  F Fensterliste Fensterliste Alt+0 6P " ! PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pGtepbpphprpepnp p p p p p p p p p p p p p³p³p pVteprpbpipnpdpupnpgpspmpaptprpipxp p p p p³p³p pAtupspgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pEtipnpgpephpepnpdpep pGpepsppprp„pcphpep p³p³p pItspdpnp4pLpipnpupxp pMpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöGGebhren Gebhren pVVerbindungsmatrix Verbindungsmatrix p AAusgehende Gespr„che Ausgehende Gespr„che pEEingehende Gespr„che Eingehende Gespr„che pIIsdn4Linux Monitor Isdn4Linux Monitor 6P $ # ŌŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pGpepbpphprpepnp pltapdpepnp p p p p p p p p p³p³p pGpepbpphprpepnp patnpzpepipgpepnp p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pDprpupcpkp-pEtipnpsptpeplplpupnpgpepnp.p.p.p p³p³p pGpepbpphprpepnp pdtrpupcpkpepnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pGpepbpphprpepnp prtpcpkpspeptpzpepnp p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL Gebhren laden Gebhren laden phA Gebhren anzeigen Gebhren anzeigen pĢEDruck-Einstellungen... Druck-Einstellungen... s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp0D Gebhren drucken... Gebhren drucken... s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp”R Gebhren rcksetzen Gebhren rcksetzen 6P'& @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pKpopnpfpipgpuprpaptpipopnp pltapdpepnp p p p p p p p p p p³p³p pKpopnpfpipgpuprpaptpipopnp pstppepipcphpeprpnp p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pKpuprpzpwpaphplpepnp plpatdpepnp p p p p p p p p p p p p p³p³p pKpuprpzpwpaphplpepnp pspptepipcphpeprpnp p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApkptpipvpep pKpotnpfpipgpuprpaptpipopnp p p pNpapcphptp p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVteprpspipopnp p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApntlpapgpepnpppaprpapmpeptpeprp p„pnpdpeprpnp.p.p.p p p p³p³p pEtnpdpgpeprp„ptpepppaprpapmpeptpeprp p„pnpdpeprpnp.p.p.p p³p³p pKtuprpzpwpaphplpnpupmpmpeprpnp p„pnpdpeprpnp.p.p.p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtuprppcpkpspeptpzpepnp p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpp LKonfiguration laden Konfiguration laden p€ SKonfiguration speichern Konfiguration speichern pä A Kurzwahlen laden Kurzwahlen laden pH P Kurzwahlen speichern Kurzwahlen speichern wnOAktive Konfiguration Aktive Konfiguration Nacht Nacht TagNachtp¬ VVersion Version p NAnlagenparameter „ndern... Anlagenparameter „ndern... p !tEEndger„teparameter „ndern...! Endger„teparameter „ndern... p ŲKKurzwahlnummern „ndern... Kurzwahlnummern „ndern... p<Z Zurcksetzen Zurcksetzen s2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs4u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ„ Ŗ¨ ESTIC Version 1.60 (Enhanced Supervisor Tool for ISTEC Configuration) (C) Copyright 1995-97 Ullrich von Bassewitz  <Mehrger„teanschluį=Anlagenanschluį>Unbekannte Anschluįart?™ Typ: %s Software Version: %d.%d %-2d S0-Schnittstellen extern %-2d S0-Schnittstellen intern %-2d ab-Schnittstellen Protokoll: %s Anschluį: %s @ Konfiguration laden A Konfiguration speichern BCOM Port ist nicht offenC+Timeout bei der Kommunikation mit der ISTECD"ˇnderungen in der ISTEC speichern?EGebhrenausdruck %s %33sG@----------------------------------------------------------------H2 Ger„t Einheiten KostenI+ #%2d %4d J6Fehler beim Initialisieren der seriellen SchnittstelleKEmpfangspuffer-berlauf!L.Zu wenig Zeichen in der empfangenen Nachricht!M Ungltige Antwort von der ISTEC!NGFalsche Ger„tenummer in der ISTEC Antwort. Kommando wird abgebrochen.!O Drucken nach Datei P Logfile ansehen Q(Fehler beim ™ffnen der EinstellungsdateiR‡Ungltige Version der Settings-Datei! Die Datei muį gel”scht werden um das Feature zu nutzen. Die existierende Datei wird ignoriert!S@Cron Datei einlesenT,Ge„nderte Kurzwahlen in der Istec speichern?UCTI ProtokollfehlerVKonfiguration neu einlesen?WEEPROM ist verriegeltXMoment bitte, Cron Job l„uft...Y/Fehler beim Ausfhren des folgenden Cron Jobs: Ze Aufgrund von Beschr„nkungen der Istec muį fr die Meldung eingehender Anrufe der Diagnosemodus abgeschaltet werden. Das bedeutet, daį weder das Loggen ausgehender Anrufe, noch die Verbindungsmatrix funktionieren, solange das Fenster "Eingehende Anrufe" ge”ffnet ist. Weiterhin ist dieses Feature nicht bei allen Versionen der Firmware 2.0 implementiert. [ isdn4linux Monitor d/ Dr Ch Ein/Aus Dienst Nummer e/-----------------------------------------------fEingAush---iRawjModemkNetzlSprachemFaxn UnbekanntoFehler beim ™ffnen von %sp;Fehler beim Lesen von %s - isdn4linux Monitor wird beendet!q$OOPS - Interner Fehler! (ignoriert)Č ISTEC XXXX, ISTEC 1003- ISTEC 1008. ISTEC 1016/ ISTEC 10240 ISTEC 20161 ISTEC 20242 ISTEC 24003 ISTEC 24164 ISTEC 24245Keine Inland ‘Ort ’Halbamt “Nichtamt ”Fernsprechen •Fax Gruppe 3 –Daten/Modem —Datex-J/Modem Anrufbeantworter ™Kombidienste  An › Aus  ------ ¯ Extern ˛ Ger„t #%d  Nummer fehlt! :Fr diese Bedingung sind nur interne Umleitungen zul„ssig!#Anzahl Klingelzeichen ist ungltig!¢p Zur Erweiterung der Anlagen mit 16 a/b-Teilnehmern auf 24 a/b-Teilnehmer lesen Sie bitte im Handbuch nach. ō Verbindungsmatrix X@ Nr. Amt1 Amt2 Int1 Int2 Int3 Ton WTon TFE Ruf Nummer YDoppelter Alias fr Nummer %s¼#Fehler beim ™ffnen der Alias-Datei!½#Syntaxfehler im Aliasfile, Zeile %d¾ isdn4linux Monitor / Dr Ch Ein/Aus Dienst Nummer !/-----------------------------------------------"Ein#Aus$---%Raw&Modem'Netz(Sprache)Fax* Unbekannt+Fehler beim ™ffnen von %s,;Fehler beim Lesen von %s - isdn4linux Monitor wird beendet!-%Fehler beim ™ffnen des Debug Logfiles„ Ausgehende Gespr„che LNNr. Alias Datum Startzeit L„nge Nummer Einh. DM MNÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄN Gebhren ° Nr. Einheiten±"Fehler beim ™ffnen der CRON Datei!!Cron File, Zeile %d: Syntaxfehler2Cron File, Zeile %d: Kommando/Parameter fehlerhaftMoment bitte, Cron Job l„uft... Eingehende Gespr„che x0Datum Zeit Rufnummer InfoyNÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄzUnbekannter FehlercodeÜAllgemeiner ProtokollfehlerŻUngltige WahlzifferŽUngltige SpeicherstelleßUngltige KanalnummerąUngltiger Tag/Nacht WertįEEPROM ist zur Zeit gesperrtā"Tag/Nacht erfolgreich umgeschaltetć Daten aus Grundkonfiguration (?)ä$Tag/Tag oder Nacht/Nacht Umschaltungå Falsche Version der Config-Daten@%Fehler beim ™ffnen des Config-Files: AStandard¤Signal 1Signal 2¦Signal 3§AusØ Kurzwahl %d ©Fehler beim ™ffnen der Datei: ŖFalsche Version der Daten!« Unbenutzt¬Kurzwahl­Babyruf®SperreÆ6P - ,  Abfragestellen  ŚpÄpÄpÄpÄpÄpÄpÄpÄp pApbpfprpapgpepsptpeplplpepnp pÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p1t.p pApbpfprpapgpepsptpeplplpep p p p p p p p p p p p p p2p1p p³p³p p2t.p pApbpfprpapgpepsptpeplplpep p p p p p p p p p p p p p2p1p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpt!11. Abfragestelle! 1. Abfragestelle 21 ōt!22. Abfragestelle! 2. Abfragestelle 21 ō6P D C Anlagenparameter  vŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pApnplpapgpepnpppaprpapmpeptpeprp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpyppp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopkpoplplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pDpSpSp1p p³p³p pAtupspbpapupsptpupfpep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApnpstcphplpupįp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pApnplpapgpepnpapnpspcphplpupįp p³p³p p1t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p2t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pTtFpEp pZpupoprpdpnpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pApbpftrpapgpepsptpeplplpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMpSpNp petipnpgpepbpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pWtaprptpepmpupspipkp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pApupsp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 I ISTEC Typ ...7 ISTEC Typ ... w7P Protokoll7 Protokoll DSS1 DSS11TR6DSS1u7AAusbaustufe ...7 Ausbaustufe ... w72SAnschluį7 Anschluį Anlagenanschluį  Anlagenanschluį$Mehrger„teanschluį Anlagenanschluį}7<1 1. Rufnummer7 1. Rufnummer ˙ }7F2 2. Rufnummer7 2. Rufnummer ˙ t7PT TFE Zuordnung7 TFE Zuordnung 21 cp 7ZFAbfragestellen ...7 Abfragestellen ... p 7dEMSN eingeben ...7 MSN eingeben ... p 7nGMSN Gruppenbildung ...7 MSN Gruppenbildung ... p 7xGEAZ Gruppenbildung ...7 EAZ Gruppenbildung ... x7(W Wartemusik7 Wartemusik Aus AusAus Ans70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P D C Anlagenparameter  Z ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pApnplpapgpepnpppaprpapmpeptpeprp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpyppp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopkpoplplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p1pTpRp6p p³p³p pAtupspbpapupsptpupfpep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApnpstcphplpupįp p p p p p p p p p p p p p p p p p p p p p p p p p p pMpephprpgpeprp„ptpepapnpspcphplpupįp p³p³p pLtapnpdpepspkpepnpnpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p4p9p p³p³p p1t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p2t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pTtFpEp pZpupoprpdpnpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pApbpftrpapgpepsptpeplplpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMpSpNp petipnpgpepbpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pWtaprptpepmpupspipkp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pEpxptpeprpnp p³p³p pMtupspipkpepipnpspppepipspupnpgp papupfp pGpeprp„ptp p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 I ISTEC Typ ...7 ISTEC Typ ... w7P Protokoll7 Protokoll 1TR6 1TR61TR6DSS1u7AAusbaustufe ...7 Ausbaustufe ... w72SAnschluį7 Anschluį Mehrger„teanschluį Mehrger„teanschluį$Mehrger„teanschluį Anlagenanschluįt7L Landeskennung7 Landeskennung 49 1ē}7<1 1. Rufnummer7 1. Rufnummer ˙ }7F2 2. Rufnummer7 2. Rufnummer ˙ t 7PT TFE Zuordnung7 TFE Zuordnung 21 cp 7ZFAbfragestellen ...7 Abfragestellen ... p 7dEMSN eingeben ...7 MSN eingeben ... p 7nGMSN Gruppenbildung ...7 MSN Gruppenbildung ... p7xGEAZ Gruppenbildung ...7 EAZ Gruppenbildung ... w7(W Wartemusik7 Wartemusik Extern Extern AusInternExternt7‚MMusikeinspeisung auf Ger„t7 Musikeinspeisung auf Ger„t 21 cs70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P D C Anlagenparameter  Ģ ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pApnplpapgpepnpppaprpapmpeptpeprp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpyppp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopkpoplplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pDpSpSp1p p³p³p pAtupspbpapupsptpupfpep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApnpstcphplpupįp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pApnplpapgpepnpapnpspcphplpupįp p³p³p pLtapnpdpepspkpepnpnpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p4p9p p³p³p p1t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p2t.p pRpupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pTtFpEp pZpupoprpdpnpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pApbpftrpapgpepsptpeplplpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMpSpNp petipnpgpepbpepnp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pGtrpupppppepnpbpiplpdpupnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pRtupfpspipgpnpaplpep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pWtaprptpepmpupspipkp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pIpnptpeprpnp p³p³p pMtupspipkpepipnpspppepipspupnpgp papupfp pGpeprp„ptp p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 I ISTEC Typ ...7 ISTEC Typ ... w7P Protokoll7 Protokoll DSS1 DSS11TR6DSS1u7AAusbaustufe ...7 Ausbaustufe ... w72SAnschluį7 Anschluį Anlagenanschluį  Anlagenanschluį$Mehrger„teanschluį Anlagenanschluįt7L Landeskennung7 Landeskennung 49 1ē}7<1 1. Rufnummer7 1. Rufnummer ˙ }7F2 2. Rufnummer7 2. Rufnummer ˙ t 7PT TFE Zuordnung7 TFE Zuordnung 21 cp 7ZFAbfragestellen ...7 Abfragestellen ... p 7dEMSN eingeben ...7 MSN eingeben ... p 7nGMSN Gruppenbildung ...7 MSN Gruppenbildung ... p7xGEAZ Gruppenbildung ...7 EAZ Gruppenbildung ... p7–RRufsignale ...7 Rufsignale ... w7(W Wartemusik7 Wartemusik Intern Intern AusInternExternt7‚MMusikeinspeisung auf Ger„t7 Musikeinspeisung auf Ger„t 21 cs70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P : 9 EAZ Gruppenbildung  xŚpÄpÄpÄpÄpÄpÄpÄp pEpApZp pGprpupppppepnpbpiplpdpupnpgp pÄpÄpÄpÄpÄpÄpÄpÄpæp³p pEpApZp p#p0p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p1p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p2p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p3p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p4p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p5p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p6p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p7p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p8p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p9p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpZw ˙˙ - --1w ˙˙ - --1w !˙˙ - --1w 1˙˙ - --1w A˙˙ - --1w Q˙˙ - --1w a˙˙ - --1w q˙˙ - --1w ˙˙ - --1w ‘˙˙ - --1w ˙˙ - --2w ˙˙ - --2w #˙˙ - --2w 3˙˙ - --2w C˙˙ - --2w S˙˙ - --2w c˙˙ - --2w s˙˙ - --2w ˙˙ - --2w “˙˙ - --2w˙˙ - --3w˙˙ - --3w%˙˙ - --3w5˙˙ - --3wE˙˙ - --3wU˙˙ - --3we˙˙ - --3wu˙˙ - --3w…˙˙ - --3w •˙˙ - --3w˙˙ - --4w˙˙ - --4w'˙˙ - --4w7˙˙ - --4wG˙˙ - --4wW˙˙ - --4wg˙˙ - --4ww˙˙ - --4w‡˙˙ - --4w —˙˙ - --4w ˙˙ - --5w˙˙ - --5w)˙˙ - --5w9˙˙ - --5wI˙˙ - --5wY˙˙ - --5wi˙˙ - --5wy˙˙ - --5w‰˙˙ - --5w ™˙˙ - --5w ˙˙ - --6w˙˙ - --6w+˙˙ - --6w;˙˙ - --6wK˙˙ - --6w[˙˙ - --6wk˙˙ - --6w{˙˙ - --6w‹˙˙ - --6w ›˙˙ - --6w ˙˙ - --7w˙˙ - --7w-˙˙ - --7w=˙˙ - --7wM˙˙ - --7w]˙˙ - --7wm˙˙ - --7w}˙˙ - --7w¨˙˙ - --7w ¯˙˙ - --7w˙˙ - --8w˙˙ - --8w/˙˙ - --8w?˙˙ - --8wO˙˙ - --8w_˙˙ - --8wo˙˙ - --8w˙˙ - --8w¸˙˙ - --8w ˙˙ - --8`#Š˙˙EAZ #0:`#Ń˙˙EAZ #1:`#Ņ˙˙EAZ #2:`#Ó˙˙EAZ #3:`#Ō˙˙EAZ #4:`#Õ˙˙EAZ #5:`#Ö˙˙EAZ #6:`#×˙˙EAZ #7:`#Ų˙˙EAZ #8:` #Ł˙˙EAZ #9:6P 5 4 MSN eingeben  pŚpÄpÄpÄpÄpÄp pMpSpNp pepipnpgpepbpepnp pÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p1t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p2t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p3t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p4t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p5t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p6t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p7t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p8t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p9t:p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp }0MSN #0: MSN #0: ˙ }1MSN #1: MSN #1: ˙ }2MSN #2: MSN #2: ˙ }3MSN #3: MSN #3: ˙ }4MSN #4: MSN #4: ˙ }5MSN #5: MSN #5: ˙ }6MSN #6: MSN #6: ˙ }7MSN #7: MSN #7: ˙ } 8MSN #8: MSN #8: ˙ }  9MSN #9: MSN #9: ˙ 6P F E MSN Gruppenbildung  øŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pMpSpNp pGprpupppppepnpbpiplpdpupnpgp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p1p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p2p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p3p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p4p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p5p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p6p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p7p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p8p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p9p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpZw˙˙ -- ----21w˙˙ -- ----21w!˙˙ -- ----21w1˙˙ -- ----21wA˙˙ -- ----21wQ˙˙ -- ----21wa˙˙ -- ----21wq˙˙ -- ----21w˙˙ -- ----21w ‘˙˙ -- ----21w˙˙ -- ----22w˙˙ -- ----22w#˙˙ -- ----22w3˙˙ -- ----22wC˙˙ -- ----22wS˙˙ -- ----22wc˙˙ -- ----22ws˙˙ -- ----22w˙˙ -- ----22w “˙˙ -- ----22w!˙˙ -- ----23w!˙˙ -- ----23w!%˙˙ -- ----23w!5˙˙ -- ----23w!E˙˙ -- ----23w!U˙˙ -- ----23w!e˙˙ -- ----23w!u˙˙ -- ----23w!…˙˙ -- ----23w! •˙˙ -- ----23w%˙˙ -- ----24w%˙˙ -- ----24w%'˙˙ -- ----24w%7˙˙ -- ----24w%G˙˙ -- ----24w%W˙˙ -- ----24w%g˙˙ -- ----24w%w˙˙ -- ----24w%‡˙˙ -- ----24w% —˙˙ -- ----24w) ˙˙ -- ----25w)˙˙ -- ----25w))˙˙ -- ----25w)9˙˙ -- ----25w)I˙˙ -- ----25w)Y˙˙ -- ----25w)i˙˙ -- ----25w)y˙˙ -- ----25w)‰˙˙ -- ----25w) ™˙˙ -- ----25w- ˙˙ -- ----26w-˙˙ -- ----26w-+˙˙ -- ----26w-;˙˙ -- ----26w-K˙˙ -- ----26w-[˙˙ -- ----26w-k˙˙ -- ----26w-{˙˙ -- ----26w-‹˙˙ -- ----26w- ›˙˙ -- ----26w1 ˙˙ -- ----27w1˙˙ -- ----27w1-˙˙ -- ----27w1=˙˙ -- ----27w1M˙˙ -- ----27w1]˙˙ -- ----27w1m˙˙ -- ----27w1}˙˙ -- ----27w1¨˙˙ -- ----27w1 ¯˙˙ -- ----27w5˙˙ -- ----28w5˙˙ -- ----28w5/˙˙ -- ----28w5?˙˙ -- ----28w5O˙˙ -- ----28w5_˙˙ -- ----28w5o˙˙ -- ----28w5˙˙ -- ----28w5¸˙˙ -- ----28w5 ˙˙ -- ----28pč˙˙MSN #0 MSN #0 pé˙˙MSN #1 MSN #1 pź˙˙MSN #2 MSN #2 pė˙˙MSN #3 MSN #3 pģ˙˙MSN #4 MSN #4 pķ˙˙MSN #5 MSN #5 pī˙˙MSN #6 MSN #6 pļ˙˙MSN #7 MSN #7 pš˙˙MSN #8 MSN #8 p ń˙˙MSN #9 MSN #9 6P 5 4 Rufsignale  ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pRpupfpspipgpnpaplpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p1t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p2t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p3t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p4t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p5t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p6t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p7t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p8t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³p³p pMpSpNp p#p9t p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdpspipgpnpaplp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp w) 0MSN #0) MSN #0 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)1MSN #1) MSN #1 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)2MSN #2) MSN #2 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)(3MSN #3) MSN #3 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)24MSN #4) MSN #4 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)<5MSN #5) MSN #5 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)F6MSN #6) MSN #6 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)P7MSN #7) MSN #7 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw)Z8MSN #8) MSN #8 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signalw )d9MSN #9) MSN #9 Standardsignal StandardsignalFStandardsignal Signal 1 Signal 2 Signal 3 Kein Signal6P! /" . Typ  4ŚpÄpÄpÄp pTpyppp pÄpÄpÄpÄpæp³p pIpSpTpEpCp p1p0p0p3p p³p³p pIpSpTpEpCp p1p0p0p8p p³p³p pIpSpTpEpCp p1p0p1p6p p³p³p pIpSpTpEpCp p1p0p2p4p p³p³p pIpSpTpEpCp p2p0p1p6p p³p³p pIpSpTpEpCp p2p0p2p4p p³p³p pIpSpTpEpCp p2p4p0p0p p³p³p pIpSpTpEpCp p2p4p1p6p p³p³p pIpSpTpEpCp p2p4p2p4p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p š˙˙ ISTEC 1008 ISTEC 1008 p ų˙˙ ISTEC 1016 ISTEC 1016 p ˙˙ ISTEC 1024 ISTEC 1024 p ą˙˙ ISTEC 2016 ISTEC 2016 p č˙˙ ISTEC 2024 ISTEC 2024 p ` ˙˙ ISTEC 2400 ISTEC 2400 p p ˙˙ ISTEC 2416 ISTEC 2416 p x ˙˙ ISTEC 2424 ISTEC 2424 p ė˙˙ ISTEC 1003 ISTEC 1003 6P1 0 Gebhren  ųŚpÄpÄpÄp pGpepbpphprpepnp pÄpÄpÄpæp³p p p p p p p p p p p p p p p p p³p³p pNprp.p p pEpipnphpepiptpepnp p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙ Nr. Einheiten6P ? > <ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pWtaphplpbpepwpeprptpupnpgp p p p p p p p p p p p p p p p p p p p p pNpipcphptpapmptp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p pFpeprpnpsppprpepcphpepnp p³p³p pRtupfpupmplpepiptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pGtepbpphprpepnpepipnpspppepipspupnpgp p p p p p p p p p p p p p p p p p p p p pApnp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, W Wahlbewertung, Wahlbewertung Nichtamt Nichtamt( Keine Inland Ort HalbamtNichtamtw,SService, Service Fernsprechen  FernsprechenP Fernsprechen Fax Gruppe 3 Daten/Modem Datex-J/ModemAnrufbeantworter},R Rufumleitung, Rufumleitung ˙x,(GGebhreneinspeisung, Gebhreneinspeisung An  AnAus An},2PPIN, PIN ˙6P ? > <ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pWtaphplpbpepwpeprptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p pKpepipnpep p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p pFpeprpnpsppprpepcphpepnp p³p³p pRtupfpupmplpepiptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pGtepbpphprpepnpepipnpspppepipspupnpgp p p p p p p p p p p p p p p p p p p p pApupsp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, W Wahlbewertung, Wahlbewertung Keine  Keine( Keine Inland Ort HalbamtNichtamtw,SService, Service Fernsprechen  Fernsprechen` Fernsprechen Fax Gruppe 3 Daten/Modem Datex-J/ModemAnrufbeantworter Kombidienste},R Rufumleitung, Rufumleitung ˙x,(GGebhreneinspeisung, Gebhreneinspeisung Aus AusAus An},2PPIN, PIN ˙6P ? > ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pWtaphplpbpepwpeprptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p pKpepipnpep p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p pFpeprpnpsppprpepcphpepnp p³p³p pRtupfpupmplpepiptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pGtepbpphprpepnpepipnpspppepipspupnpgp p p p p p p p p p p p p p p p p p p p pApupsp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pApuptpopmpaptpipspcphpep pAtmptpsphpoplpupnpgp p p p p p p p p p p p p p p p pApupsp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, W Wahlbewertung, Wahlbewertung Keine  Keine( Keine Inland Ort HalbamtNichtamtw,SService, Service Fernsprechen  Fernsprechen` Fernsprechen Fax Gruppe 3 Daten/Modem Datex-J/ModemAnrufbeantworter Kombidienste},R Rufumleitung, Rufumleitung ˙x,(GGebhreneinspeisung, Gebhreneinspeisung Aus AusAus An},2PPIN, PIN ˙x,<A Automatische Amtsholung, Automatische Amtsholung Aus AusAus An6P? > ¬ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pWtaphplpbpepwpeprptpupnpgp p p p p p p p p p p p p p p p p p p p p p pHpaplpbpapmptp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p pFpapxp pGprpupppppep p3p p³p³p pRtupfpupmplpepiptpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pGtepbpphprpepnpepipnpspppepipspupnpgp p p p p p p p p p p p p p p p p p p p p pApnp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pApuptpopmpaptpipspcphpep pAtmptpsphpoplpupnpgp p p p p p p p p p p p p p p p p pApnp p³p³p pApnpkplpopppfpepnp pitnptpeprpnp p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p pApnpkplpopppfpepnp petxptpeprpnp p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p pApnpkplpopppfpepnp pTtFpEp p p p p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp w, W Wahlbewertung, Wahlbewertung Halbamt  Halbamt( Keine Inland Ort HalbamtNichtamtw,SService, Service Fax Gruppe 3  Fax Gruppe 3` Fernsprechen Fax Gruppe 3 Daten/Modem Datex-J/ModemAnrufbeantworter Kombidiensteu,dR Rufumleitung, Rufumleitung x,(GGebhreneinspeisung, Gebhreneinspeisung An  AnAus An},2PPIN, PIN ˙x,<A Automatische Amtsholung, Automatische Amtsholung An  AnAus Anq,FI Anklopfen intern, Anklopfen intern  6P0/ Anklopfen intern  XŚpÄpÄpÄpÄpÄp pApnpkplpopppfpepnp pipnptpeprpnp pÄpÄpÄpÄpÄpæp³p pApppppaprpaptp p2p1p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p2p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p3p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p4p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p5p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p6p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p7p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p8p p p p p p p p p p p p p p pJpap p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpyč˙˙ Apparat 21 Apparat 21 Ja  JaNein Jayņ˙˙ Apparat 22 Apparat 22 Ja  JaNein Jayü˙˙ Apparat 23 Apparat 23 Ja  JaNein Jay˙˙ Apparat 24 Apparat 24 Ja  JaNein Jay˙˙ Apparat 25 Apparat 25 Ja  JaNein Jay˙˙ Apparat 26 Apparat 26 Ja  JaNein Jay$˙˙ Apparat 27 Apparat 27 Ja  JaNein Jay.˙˙ Apparat 28 Apparat 28 Ja  JaNein Jaq,PE Anklopfen extern, Anklopfen extern  6P.- Anklopfen extern   ŚpÄpÄpÄpÄp pApnpkplpopppfpepnp pepxptpeprpnp pÄpÄpÄpÄpæp³p pMpSpNp p0p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p4p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p5p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p6p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p7p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p8p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p9p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp yL˙˙MSN 0 MSN 0 Nein NeinNein JayV˙˙MSN 1 MSN 1 Nein NeinNein Jay`˙˙MSN 2 MSN 2 Nein NeinNein Jayj˙˙MSN 3 MSN 3 Nein NeinNein Jayt˙˙MSN 4 MSN 4 Nein NeinNein Jay~˙˙MSN 5 MSN 5 Nein NeinNein Jay˙˙MSN 6 MSN 6 Nein NeinNein Jay’˙˙MSN 7 MSN 7 Nein NeinNein Jay˙˙MSN 8 MSN 8 Nein NeinNein Jay ¦˙˙MSN 9 MSN 9 Nein NeinNein Jaq ,ZT Anklopfen TFE, Anklopfen TFE  6P.- Anklopfen TFE  PŚpÄpÄpÄpÄpÄp pApnpkplpopppfpepnp pTpFpEp pÄpÄpÄpÄpÄpÄpæp³p pTpFpEp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p4p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpy°˙˙TFE 1 TFE 1 Nein NeinNein Jayŗ˙˙TFE 2 TFE 2 Nein NeinNein JayÄ˙˙TFE 3 TFE 3 Nein NeinNein JayĪ˙˙TFE 4 TFE 4 Nein NeinNein Ja6P & % Anklopfen extern   ŚpÄpÄpÄpÄp pApnpkplpopppfpepnp pepxptpeprpnp pÄpÄpÄpÄpæp³p pMpSpNp p0p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p4p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p5p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p6p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p7p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p8p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p9p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp yL˙˙MSN 0 MSN 0 Nein NeinNein JayV˙˙MSN 1 MSN 1 Nein NeinNein Jay`˙˙MSN 2 MSN 2 Nein NeinNein Jayj˙˙MSN 3 MSN 3 Nein NeinNein Jayt˙˙MSN 4 MSN 4 Nein NeinNein Jay~˙˙MSN 5 MSN 5 Nein NeinNein Jay˙˙MSN 6 MSN 6 Nein NeinNein Jay’˙˙MSN 7 MSN 7 Nein NeinNein Jay˙˙MSN 8 MSN 8 Nein NeinNein Jay ¦˙˙MSN 9 MSN 9 Nein NeinNein Ja6P ( ' Anklopfen intern  XŚpÄpÄpÄpÄpÄp pApnpkplpopppfpepnp pipnptpeprpnp pÄpÄpÄpÄpÄpæp³p pApppppaprpaptp p2p1p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p2p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p3p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p4p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p5p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p6p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p7p p p p p p p p p p p p p p pJpap p³p³p pApppppaprpaptp p2p8p p p p p p p p p p p p p p pJpap p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpyč˙˙ Apparat 21 Apparat 21 Ja  JaNein Jayņ˙˙ Apparat 22 Apparat 22 Ja  JaNein Jayü˙˙ Apparat 23 Apparat 23 Ja  JaNein Jay˙˙ Apparat 24 Apparat 24 Ja  JaNein Jay˙˙ Apparat 25 Apparat 25 Ja  JaNein Jay˙˙ Apparat 26 Apparat 26 Ja  JaNein Jay$˙˙ Apparat 27 Apparat 27 Ja  JaNein Jay.˙˙ Apparat 28 Apparat 28 Ja  JaNein Ja6P & % Anklopfen TFE  PŚpÄpÄpÄpÄpÄp pApnpkplpopppfpepnp pTpFpEp pÄpÄpÄpÄpÄpÄpæp³p pTpFpEp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p4p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpy°˙˙TFE 1 TFE 1 Nein NeinNein Jayŗ˙˙TFE 2 TFE 2 Nein NeinNein JayÄ˙˙TFE 3 TFE 3 Nein NeinNein JayĪ˙˙TFE 4 TFE 4 Nein NeinNein Ja6PPO Ger„te-Einstellungen  ĄŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pGpeprp„ptpep-pEpipnpsptpeplplpupnpgpepnp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pNprp.p p pWpaphplpbpepwpeprptpupnpgp p pSpeprpvpipcpep p p p p p p p p p p pUpmplpepiptpupnpgp p p p p p p p p p p p pGpepbp.p-pPpuplpsp p p pPpIpNp p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙K Nr. Wahlbewertung Service Umleitung Geb.-Puls PIN6P 4 3 Rufumleitung  ¤ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pRpupfpupmplpepiptpupnpgp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pNtupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pBtepdpipnpgpupnpgp p p p p p p p p p p p p p p p p p p p p p p p p p pnpipep p³p³p pAtnpzpaphplp pKplpipnpgpeplpspipgpnpaplpep p p p p p p p p p p p p p p p p3p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp}( NNummer( Nummer Ø˙w(B Bedingung( Bedingung nie  nie@ nie immer bei besetztx Klingelsignalet(AAnzahl Klingelsignale( Anzahl Klingelsignale 3  6P D C ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pRtupfpnpupmpmpeprp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pApupspgpephpepnpdpep pRpupfpep:p p p p p p p p p p p p pEpipnpgpephpepnpdpep pRpupfpep:p p p p p p p p p p p³p³p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p³p³p pVteprpwpepnpdpupnpgp p p p p p pUpnpbpepnpuptpzptp p p pKtlpipnpgpeplpspipgpnpaplp p p p pSpipgpnpaplp p3p p³p³p pEpnpdpgpeprp„ptp p2p1t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p2t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p3t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p4t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p5t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p6t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p7t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpnpdpgpeprp„ptp p2p8t p p p p p p p p p p p pApnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp}7 R Rufnummer7 Rufnummer  ˙wV Verwendung Verwendung Unbenutzt Unbenutzt 4 Unbenutzt Kurzwahl BabyrufNummernsperrexn1 Endger„t 21 Endger„t 21 An  AnAus Anxx2 Endger„t 22 Endger„t 22 An  AnAus Anx ‚3 Endger„t 23 Endger„t 23 An  AnAus Anx 4 Endger„t 24 Endger„t 24 An  AnAus Anx –5 Endger„t 25 Endger„t 25 An  AnAus Anx  6 Endger„t 26 Endger„t 26 An  AnAus Anx Ŗ7 Endger„t 27 Endger„t 27 An  AnAus Anx´8 Endger„t 28 Endger„t 28 An  AnAus AnwK Klingelsignal Klingelsignal Signal 3 Signal 3(StandardSignal 1Signal 2Signal 3 Aus`%č˙˙Eingehende Rufe:`%é˙˙Ausgehende Rufe:s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs50u˙˙5ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6PPO Kurzwahlnummern   ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pKpuprpzpwpaphplpnpupmpmpeprpnp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pNprp.p p pNpupmpmpeprp p p p p p p p p p p p p p p p pAplpipapsp p p p p p p p p p p p p pVpeprpwpepnpdpupnpgp p p pGpeprp„ptpep p p p pSpipgpnpaplp p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙K Nr. Nummer Alias Verwendung Ger„te Signal6P C B Einstellungen fr den Ausdruck  ”ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pEpipnpsptpeplplpupnpgpepnp pfpprp pdpepnp pApupspdprpupcpkp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pKtopppfpzpepiplpep p p p p p                                      p³p³p pPtrpepipsp ppprpop pGpepbpphprpepnpepipnphpepiptp p p p p p p p p p p p p p p p p p p 0,01    p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp3K% Kopfzeile#3ž‘3PPreis pro Gebhreneinheit0,01-,3|®Gįz„?|®Gįz„?ĄX@6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpfpapdp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pDtaptpepipepnp p p p p p p p p p p p p p p p p p p pVteprpzpepipcphpnpipspspep p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6D Dateien`6V/ Verzeichnisse2N1Name( 3ž`6é˙˙Pfadb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp p p p p p pBpepnpuptpzpeprpnpapmpep p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprptp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KBenutzer-ID Benutzername Passwort Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pItDp p p p p p p p p p p p p p p                       p³p³p pBpepnpuptpzpeprp-pNtapmpep p p                                 p³p³p pPtapspspwpoprptp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStipcphpeprphpepiptpsp-pEpbpepnpep p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/I  Benutzer-ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N 1 Benutzer-Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPasswort "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSicherheits-Ebene0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprptp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp— ˙˙ Passwort:  6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ Benutzer-ID: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōHilfe bernehmen Abbruch Ende Weiter ˇndern Drucken Grafik  Einfgen L”schen Auswahl Best„tigen Bewegen Login Logout Ende Zoom  Schliessen ™ffnen Gr”įe  Speichern  ~~ Auswahl  ~ÄŁ~ Auswahl  ~ Bild-~ Bl„ttern  ~~ Bewegen  ~Ctrl+~ Gr”įe Sind Sie sicher?dWirklich Ende?eˇnderungen verwerfen?fˇnderungen sichern?g @Ja @Neinh @Nein @Jai Fehler Č Information É Systemfehler Ź Best„tigen ŅAbbruch Ó Ignorieren Ō Wiederholen ÕEnde ÖEinen Moment bitte...×Ungltige Eingabe,Zu viele Nachkommastellen-"Wert ist zu klein (Minimum ist %g).!Wert ist zu groį (Maximum ist %g)/#Wert ist zu klein (Minimum ist %ld)0"Wert ist zu groį (Maximum ist %ld)1Leereingabe ist unzul„ssig2Keine Datei-Erweiterung erlaubt3Aus AnNein Ja‘Wert ist zu groįōWert ist zu kleinõFehlerhafte Eingabeö2%s: Sektion %s, %s nicht gefunden oder fehlerhaft.X*Fehler beim ™ffnen der Passwort-Datei^(%s)¼)Fehler beim Lesen der Passwort-Datei^(%s)½1Fehler beim Schreiben auf die Passwort-Datei^(%s)¾)Es muį eine Benutzer-ID angegeben werden!æ)Es muį ein Benutzername angegeben werden!Ą%Es muį ein Passwort angegeben werden!Į-Ein Benutzer mit dieser ID existiert bereits!Ā/Ungltige Benutzer-ID oder ungltiges Passwort!ĆSonntag Montag!Dienstag"Mittwoch# Donnerstag$Freitag%Samstag&So'Mo(Di)Mi*Do+Fr,Sa-Januar.Februar/M„rz0April1Mai2Juni3Juli4August5 September6Oktober7November8Dezember9Jan:Feb;M„r<Apr=Mai>Jun?Jul@AugASepBOktCNovDDezEKeine Hilfe verfgbar„ Keine Hilfe fr dieses Stichwort… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+Bild-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Bild-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Bild-™Alt+Ende Alt+Bild- Alt+Einfg¢Alt+Entf£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-EndeEsc-PgDn Esc-Einfg¢Esc-Entf£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Verzeichnis 5 Fehler %d: %süKein Fehler (OOPS!)żDatei oder Pfad nicht gefundenžNicht genug Speicher˙Zugriff verweigert Zu viele offene Files 9Nicht gengend Speicherplatz auf dem angesprochenen Ger„t %Tempor„rer Fehler - nochmal versuchen Ger„t/Datei ist in Benutzung Datei ist zu groį I/O Fehler Datei ist ein Verzeichnis Datei ist kein Verzeichnis Zu viele Links 'Operation nur mit Block Devices m”glich &Operation nur mit Char Devices m”glich Device existiert nicht 4Operation ist nur fr den Besitzer der Datei m”glich Broken Pipe Dateisystem ist readonly +Seek kann nicht auf Pipes ausgefhrt werden Prozess existiert nicht Ausfhrbare Datei ist busy Name ist zu lang Keine Locks verfgbar Verzeichnis ist nicht leer Datei nicht gefunden Pfad nicht gefunden Laufwerk ist ungltig 0Aktuelles Verzeichnis kann nicht gel”scht werden Datei existiert bereits Unbekannter Fehler (%d) "Es sind zu viele Fenster ge”ffnet!Ä 6P > = Fensterliste  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pFpepnpsptpeprplpipsptpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙5PPP   p pEtSpTpIpCp p pFtiplpep p pItsptpepcp p pCthpaprpgpepsp p pWtipnpdpopwp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p prčEESTIC ESTIC 6P lŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pAtbpopuptp pEpSpTpIpCp.p.p.p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppLAAbout ESTIC... About ESTIC... rŠF File File 6P& % HŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcpopnpfpipgpuprpaptpipopnp.p.p.p p p p p p p³p³p pStapvpep pcpopnpfpipgpuprpaptpipopnp.p.p.p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotapdp psphpoprptpcpuptp pnpupmpbpeprpsp.p.p.p p p p³p³p pSpatvpep psphpoprptpcpuptp pnpupmpbpeprpsp.p.p.p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVtipepwp plpopgpfpiplpep.p.p.p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepapdp paplpipapsp pfpiplpep p p p p p p p p p p p p³p³p pRpepapdp pctrpopnp pfpiplpep p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pQtupiptp p p p p p p p p p p p p p p p p pAplptp+pXp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p4LLoad configuration... Load configuration... pSSave configuration... Save configuration... püOLoad shortcut numbers... Load shortcut numbers... p` ASave shortcut numbers... Save shortcut numbers... pÄ VView logfile... View logfile... p( RRead alias file Read alias file p  CRead cron file Read cron file p š Q4Quit Quit Alt+X s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄrø I%Istec Istec 6P.- @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p p³p³p pStapvpep pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotapdp psphpoprptpcpuptp pnpupmpbpeprpsp p p p p p p p p³p³p pSpatvpep psphpoprptpcpuptp pnpupmpbpeprpsp p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApcptpipvpep pctopnpfpipgpuprpaptpipopnp p p p p pDpapyp p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVteprpspipopnp.p.p.p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpdpiptp pspytsptpepmp pppaprpapmpeptpeprpsp.p.p.p p p p p³p³p pEpdpiptp pdtepvpipcpep pppaprpapmpeptpeprpsp.p.p.p p p p p³p³p pEpdpiptp psphpoprptpcpuptp pntupmpbpeprpsp.p.p.p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepspeptp pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpp LLoad configuration Load configuration p€ SSave configuration Save configuration pä OLoad shortcut numbers Load shortcut numbers pH ASave shortcut numbers Save shortcut numbers p¬ V Version... Version... p YEdit system parameters... Edit system parameters... p !tDEdit device parameters...! Edit device parameters... p ŲNEdit shortcut numbers... Edit shortcut numbers... p<RReset configuration Reset configuration s2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs4u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄwnCActive configuration Active configuration Day  Day DayNightr  C"Charges Charges 6P/ .  ŌŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcphpaprpgpepsp p p p p p p p p p p p³p³p pSthpopwp pcphpaprpgpepsp.p.p.p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pPtrpipnptp pspeptptpipnpgpsp.p.p.p p p p p p p³p³p pPprpipnptp pcthpaprpgpepsp.p.p.p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepspeptp pcphpaprpgpepsp p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL Load charges Load charges phSShow charges... Show charges... pĢPPrint settings... Print settings... s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp0CPrint charges... Print charges... s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp”R Reset charges Reset charges rW!Window Window 6P=< &ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pOtppepnp p p p p p p p p p p p p p p p p p p p p p pp p³p³p pTtiplpep p p p p p p p p p p p p p p p p p p p p p p p p³p³p pCtapspcpapdpep p p p p p p p p p p p p p p p p p p p p p³p³p pCplpopspep patlplp p p p p p p p p p p p p p p p p p p p³p³p pRtepfprpepsphp pspcprpepepnp p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtopopmp p p p p p p p p p p p p p p p p p p p p pFp5p p³p³p pPtopspiptpipopnp/pspipzpep p p p p p p pCptprplp+pFp5p p³p³p pCtlpopspep p p p p p p p p p p p p p p p pAplptp+pFp3p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pWtipnpdpopwp plpipsptp p p p p p p p p p p pAplptp+p0p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp qģO2Open Open  6P    PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pCthpaprpgpepsp p p p p p p p p p p p p p p³p³p pCpopnpnpepcptpipopnp pmtaptprpipxp p p p p³p³p pOtuptpgpopipnpgp pcpaplplpsp p p p p p p p³p³p pItnpcpopmpipnpgp pcpaplplpsp p p p p p p p³p³p pItspdpnp4pLpipnpupxp pmpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöCCharges Charges pM Connection matrix Connection matrix p OOutgoing calls Outgoing calls pIIncoming calls Incoming calls pIIsdn4Linux monitor Isdn4Linux monitor pPTTile Tile p´CCascade Cascade pA Close all Close all p|RRefresh screen Refresh screen s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpąZ0Zoom Zoom F5 pDP3 Position/size Position/size Ctrl+F5 pØC1Close Close Alt+F3 s 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp  W Window list Window list Alt+0 6P%$ HŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcpopnpfpipgpuprpaptpipopnp.p.p.p p p p p p p³p³p pStapvpep pcpopnpfpipgpuprpaptpipopnp.p.p.p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotapdp psphpoprptpcpuptp pnpupmpbpeprpsp.p.p.p p p p³p³p pSpatvpep psphpoprptpcpuptp pnpupmpbpeprpsp.p.p.p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVtipepwp plpopgpfpiplpep.p.p.p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepapdp paplpipapsp pfpiplpep p p p p p p p p p p p p³p³p pRpepapdp pctrpopnp pfpiplpep p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pQtupiptp p p p p p p p p p p p p p p p p pAplptp+pXp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p4LLoad configuration... Load configuration... pSSave configuration... Save configuration... püOLoad shortcut numbers... Load shortcut numbers... p` ASave shortcut numbers... Save shortcut numbers... pÄ VView logfile... View logfile... p( RRead alias file Read alias file p  CRead cron file Read cron file p š Q4Quit Quit Alt+X s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P    lŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pAtbpopuptp pEpSpTpIpCp.p.p.p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppLAAbout ESTIC... About ESTIC... 6P&% &ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pOtppepnp p p p p p p p p p p p p p p p p p p p p p pp p³p³p pTtiplpep p p p p p p p p p p p p p p p p p p p p p p p p³p³p pCtapspcpapdpep p p p p p p p p p p p p p p p p p p p p p³p³p pCplpopspep patlplp p p p p p p p p p p p p p p p p p p p³p³p pRtepfprpepsphp pspcprpepepnp p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pZtopopmp p p p p p p p p p p p p p p p p p p p p pFp5p p³p³p pPtopspiptpipopnp/pspipzpep p p p p p p pCptprplp+pFp5p p³p³p pCtlpopspep p p p p p p p p p p p p p p p pAplptp+pFp3p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pWtipnpdpopwp plpipsptp p p p p p p p p p p pAplptp+p0p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp qģO2Open Open  6P    PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pCthpaprpgpepsp p p p p p p p p p p p p p p³p³p pCpopnpnpepcptpipopnp pmtaptprpipxp p p p p³p³p pOtuptpgpopipnpgp pcpaplplpsp p p p p p p p³p³p pItnpcpopmpipnpgp pcpaplplpsp p p p p p p p³p³p pItspdpnp4pLpipnpupxp pmpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöCCharges Charges pM Connection matrix Connection matrix p OOutgoing calls Outgoing calls pIIncoming calls Incoming calls pIIsdn4Linux monitor Isdn4Linux monitor pPTTile Tile p´CCascade Cascade pA Close all Close all p|RRefresh screen Refresh screen s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpąZ0Zoom Zoom F5 pDP3 Position/size Position/size Ctrl+F5 pØC1Close Close Alt+F3 s 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp  W Window list Window list Alt+0 6P " ! PŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pCthpaprpgpepsp p p p p p p p p p p p p p p³p³p pCpopnpnpepcptpipopnp pmtaptprpipxp p p p p³p³p pOtuptpgpopipnpgp pcpaplplpsp p p p p p p p³p³p pItnpcpopmpipnpgp pcpaplplpsp p p p p p p p³p³p pItspdpnp4pLpipnpupxp pmpopnpiptpoprp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppöCCharges Charges pM Connection matrix Connection matrix p OOutgoing calls Outgoing calls pIIncoming calls Incoming calls pIIsdn4Linux monitor Isdn4Linux monitor 6P $ # ŌŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcphpaprpgpepsp p p p p p p p p p p p³p³p pSthpopwp pcphpaprpgpepsp.p.p.p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pPtrpipnptp pspeptptpipnpgpsp.p.p.p p p p p p p³p³p pPprpipnptp pcthpaprpgpepsp.p.p.p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepspeptp pcphpaprpgpepsp p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppL Load charges Load charges phSShow charges... Show charges... pĢPPrint settings... Print settings... s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp0CPrint charges... Print charges... s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄp”R Reset charges Reset charges 6P'& @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLtopapdp pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p p³p³p pStapvpep pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pLpotapdp psphpoprptpcpuptp pnpupmpbpeprpsp p p p p p p p p³p³p pSpatvpep psphpoprptpcpuptp pnpupmpbpeprpsp p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pApcptpipvpep pctopnpfpipgpuprpaptpipopnp p p p p pDpapyp p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pVteprpspipopnp.p.p.p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpdpiptp pspytsptpepmp pppaprpapmpeptpeprpsp.p.p.p p p p p³p³p pEpdpiptp pdtepvpipcpep pppaprpapmpeptpeprpsp.p.p.p p p p p³p³p pEpdpiptp psphpoprptpcpuptp pntupmpbpeprpsp.p.p.p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pRtepspeptp pcpopnpfpipgpuprpaptpipopnp p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpp LLoad configuration Load configuration p€ SSave configuration Save configuration pä OLoad shortcut numbers Load shortcut numbers pH ASave shortcut numbers Save shortcut numbers p¬ V Version... Version... p YEdit system parameters... Edit system parameters... p !tDEdit device parameters...! Edit device parameters... p ŲNEdit shortcut numbers... Edit shortcut numbers... p<RReset configuration Reset configuration s2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs3u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs4u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄwnCActive configuration Active configuration Day  Day DayNightz  ¨ ESTIC Version 1.60 (Enhanced Supervisor Tool for ISTEC Configuration) (C) Copyright 1995-97 Ullrich von Bassewitz  <Point to multi point=Point to point>Unknown connection?† Type: %s Software version: %d.%d %-2d external S0 ports %-2d internal S0 ports %-2d ab ports Protocol: %s Connection: %s @ Load configuration A Save configuration BCOM Port is not openCCommunication timeoutD$Store changed config into the ISTEC?EMake changes permanent?FCost printout %s %36sG@----------------------------------------------------------------H1 Device Charge units CostI+ #%2d %4d J#Error initialising the serial port!KReceive buffer overflow!LReceived message is too short!MInvalid answer from the ISTEC!N<Got invalid device number from the ISTEC. Aborting command!O Print to file P View logfile QError opening the settings fileRrInvalid settings file version! You must delete this file to use the feature since the existing file is ignored!SRead @cron fileT.Store changed shortcut numbers into the Istec?UCTI protocol errorVLoad current configuration?WEEPROM is in useX Running Cron job, please wait...Y4There was an error with the following Cron command: ZC Because of internal restrictions of the Istec firmware, ESTIC has to disable the diagnostic mode. This means that logging of outgoing calls and the connection matrix will not work, while the window "Incoming calls" is open. Apart from that, incoming call notification is not available with all versions of firmware 2.0. [ isdn4linux monitor d/ Dr Ch In/Out Service Phone e/-----------------------------------------------f!OOPS - Internal error! (ignored)Č ISTEC XXXX, ISTEC 1003- ISTEC 1008. ISTEC 1016/ ISTEC 10240 ISTEC 20161 ISTEC 20242 ISTEC 24003 ISTEC 24164 ISTEC 24245All Domestic ‘City ’Incoming “Internal ”Telephone •Fax G3 –Data/Modem —Datex-J/Modem Answering machine ™Combined services  On › Off  ------ ¯ External ˛ Device #%d Phone number is missing! 8Only internal redirects are allowed with this condition!Ring count is invalid!¢p Zur Erweiterung der Anlagen mit 16 a/b-Teilnehmern auf 24 a/b-Teilnehmer lesen Sie bitte im Handbuch nach. ō Connection matrix X@ Dev Ext1 Ext2 Int1 Int2 Int3 Ton DTon TFE Cal Phone Y#Duplicate alias for phone number %s¼Error opening the alias file!½!Alias file, line %d: Syntax error¾ isdn4linux monitor / Dr Ch In/Out Service Phone !/-----------------------------------------------"In #Out$---%Raw&Modem'Network(Voice)Fax*Unknown+Error opening %s,2Error reading %s - terminating isdn4linux monitor!-Error opening the debug logfile„ Outgoing calls LNExt Alias Date Time Duration Phone Units Cost MNÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄN Charges ° Dev Units±Error opening the CRON file! CRON file, line %d: Syntax error+CRON file, line %d: command/parameter error Running Cron job, please wait... Incoming calls x0Date Time Caller ID InfoyNÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄzUnknown error codeÜGeneric protocol errorŻ Invalid digitŽInvalid memory locationßInvalid channel numberą"Invalid value for day/night switchįEEPROM is lockedāDay/night switch okćDefault values (?)äDay/day or night/night switchåWrong config data version@Error opening the config file: AStandard¤Signal 1Signal 2¦Signal 3§OffØ Dial shortcut %d ©Error opening the file: Ŗ&Cannot handle this data version, sorry«Unused¬Shortcut­ Auto dial®LockÆ6P - ,  Operator terminals  ŚpÄpÄpÄpÄpÄpÄp pOpppeprpaptpoprp ptpeprpmpipnpaplpsp pÄpÄpÄpÄpÄpÄpÄpæp³p pTpeprpmpipnpaplp p1t p p p p p p p p p p p p p p p p p p p2p1p p³p³p pTpeprpmpipnpaplp p2t p p p p p p p p p p p p p p p p p p p2p1p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpt!1 Terminal 1! Terminal 1 21 ōt!2 Terminal 2! Terminal 2 21 ō6P D C System parameters  vŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pSpypsptpepmp pppaprpapmpeptpeprpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpypppep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopcpoplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pDpSpSp1p p³p³p pEtxptpepnpspipopnpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pCtopnpnpepcptpipopnp ptpypppep p p p p p p p p p p p p p p p p p pppopipnptp ptpop pmpuplptpip pppopipnptp p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p1t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p2t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDtopoprp psptpaptpipopnp pepxptpepnpspipopnp pnpupmpbpeprp p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pOtppeprpaptpoprp ptpeprpmpipnpaplpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpdpiptp pMtSpNp'psp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMtupspipcp popnp phpoplpdp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pApupsp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 IISTEC Type ...7 ISTEC Type ... w7PProtocol7 Protocol DSS1 DSS11TR6DSS1u7EExtensions ...7 Extensions ... w72CConnection type7 Connection type point to multi point point to multi point(point to multi point point to point}7<1DDI base number 17 DDI base number 1 ˙ }7F2DDI base number 27 DDI base number 2 ˙ t7PDDoor station extension number7 Door station extension number 21 cp 7ZOOperator terminals ...7 Operator terminals ... p 7dMEdit MSN's ...7 Edit MSN's ... p 7nGMSN grouping ...7 MSN grouping ... p 7xGEAZ grouping ...7 EAZ grouping ... s70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄx7(M Music on hold7 Music on hold Aus AusAus An6P D C System parameters  Z ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pSpypsptpepmp pppaprpapmpeptpeprpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpypppep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopcpoplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p1pTpRp6p p³p³p pEtxptpepnpspipopnpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pCtopnpnpepcptpipopnp ptpypppep p p p p p p p p p p p p p p p p p p p p p p p pppopipnptp ptpop pppopipnptp p³p³p pCpotupnptprpyp pcpopdpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p1p p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p1t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p2t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDtopoprp psptpaptpipopnp pepxptpepnpspipopnp pnpupmpbpeprp p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pOtppeprpaptpoprp ptpeprpmpipnpaplpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpdpiptp pMtSpNp'psp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMtupspipcp popnp phpoplpdp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pIpnptpeprpnpaplp p³p³p pEpxttpeprpnpaplp pmpupspipcp pppoprptp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 IISTEC Type ...7 ISTEC Type ... w7PProtocol7 Protocol 1TR6 1TR61TR6DSS1u7EExtensions ...7 Extensions ... w72CConnection type7 Connection type point to point  point to point(point to multi point point to pointt7O Country code7 Country code 1 ē}7<1DDI base number 17 DDI base number 1 ˙ }7F2DDI base number 27 DDI base number 2 ˙ t 7PDDoor station extension number7 Door station extension number 21 cp 7ZOOperator terminals ...7 Operator terminals ... p 7dMEdit MSN's ...7 Edit MSN's ... p 7nGMSN grouping ...7 MSN grouping ... p7xGEAZ grouping ...7 EAZ grouping ... w7(M Music on hold7 Music on hold Internal Internal OffInternalExternalt7‚XExternal music port7 External music port 21 cs70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P D C System parameters  Ģ ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pSpypsptpepmp pppaprpapmpeptpeprpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pItSpTpEpCp pTpypppep p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPtrpoptpopcpoplp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pDpSpSp1p p³p³p pEtxptpepnpspipopnpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pCtopnpnpepcptpipopnp ptpypppep p p p p p p p p p p p p p p p p p pppopipnptp ptpop pmpuplptpip pppopipnptp p³p³p pCpotupnptprpyp pcpopdpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p1p p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p1t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpDpIp pbpapspep pnpupmpbpeprp p2t p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDtopoprp psptpaptpipopnp pepxptpepnpspipopnp pnpupmpbpeprp p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p pOtppeprpaptpoprp ptpeprpmpipnpaplpsp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpdpiptp pMtSpNp'psp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMpSpNp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pEpApZp pgtrpopupppipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pStipgpnpaplpipnpgp p.p.p.p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pMtupspipcp popnp phpoplpdp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pEpxptpeprpnpaplp p³p³p pEpxttpeprpnpaplp pmpupspipcp pppoprptp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p2p1p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpu7 IISTEC Type ...7 ISTEC Type ... w7PProtocol7 Protocol DSS1 DSS11TR6DSS1u7EExtensions ...7 Extensions ... w72CConnection type7 Connection type point to multi point point to multi point(point to multi point point to pointt7O Country code7 Country code 1 ē}7<1DDI base number 17 DDI base number 1 ˙ }7F2DDI base number 27 DDI base number 2 ˙ t 7PDDoor station extension number7 Door station extension number 21 cp 7ZOOperator terminals ...7 Operator terminals ... p 7dMEdit MSN's ...7 Edit MSN's ... p 7nGMSN grouping ...7 MSN grouping ... p7xGEAZ grouping ...7 EAZ grouping ... p7–S Signaling ...7 Signaling ... w7(M Music on hold7 Music on hold External External OffInternalExternalt7‚XExternal music port7 External music port 21 cs70u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs71u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs 72u˙˙7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6P : 9 EAZ grouping  xŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pEpApZp pgprpopupppipnpgp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pEpApZp p#p0p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p1p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p2p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p3p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p4p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p5p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p6p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p7p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p8p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³p³p pEpApZp p#p9p:p p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p-p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpZw ˙˙ - --1w ˙˙ - --1w !˙˙ - --1w 1˙˙ - --1w A˙˙ - --1w Q˙˙ - --1w a˙˙ - --1w q˙˙ - --1w ˙˙ - --1w ‘˙˙ - --1w ˙˙ - --2w ˙˙ - --2w #˙˙ - --2w 3˙˙ - --2w C˙˙ - --2w S˙˙ - --2w c˙˙ - --2w s˙˙ - --2w ˙˙ - --2w “˙˙ - --2w˙˙ - --3w˙˙ - --3w%˙˙ - --3w5˙˙ - --3wE˙˙ - --3wU˙˙ - --3we˙˙ - --3wu˙˙ - --3w…˙˙ - --3w •˙˙ - --3w˙˙ - --4w˙˙ - --4w'˙˙ - --4w7˙˙ - --4wG˙˙ - --4wW˙˙ - --4wg˙˙ - --4ww˙˙ - --4w‡˙˙ - --4w —˙˙ - --4w ˙˙ - --5w˙˙ - --5w)˙˙ - --5w9˙˙ - --5wI˙˙ - --5wY˙˙ - --5wi˙˙ - --5wy˙˙ - --5w‰˙˙ - --5w ™˙˙ - --5w ˙˙ - --6w˙˙ - --6w+˙˙ - --6w;˙˙ - --6wK˙˙ - --6w[˙˙ - --6wk˙˙ - --6w{˙˙ - --6w‹˙˙ - --6w ›˙˙ - --6w ˙˙ - --7w˙˙ - --7w-˙˙ - --7w=˙˙ - --7wM˙˙ - --7w]˙˙ - --7wm˙˙ - --7w}˙˙ - --7w¨˙˙ - --7w ¯˙˙ - --7w˙˙ - --8w˙˙ - --8w/˙˙ - --8w?˙˙ - --8wO˙˙ - --8w_˙˙ - --8wo˙˙ - --8w˙˙ - --8w¸˙˙ - --8w ˙˙ - --8`#Š˙˙EAZ #0:`#Ń˙˙EAZ #1:`#Ņ˙˙EAZ #2:`#Ó˙˙EAZ #3:`#Ō˙˙EAZ #4:`#Õ˙˙EAZ #5:`#Ö˙˙EAZ #6:`#×˙˙EAZ #7:`#Ų˙˙EAZ #8:` #Ł˙˙EAZ #9:6P 5 4 Edit MSN's  pŚpÄpÄpÄpÄpÄpÄp pEpdpiptp pMpSpNp'psp pÄpÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p1t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p2t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p3t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p4t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p5t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p6t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p7t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p8t:p p p p p p p p p p p p p p p p p³p³p pMpSpNp p#p9t:p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp }0MSN #0: MSN #0: ˙ }1MSN #1: MSN #1: ˙ }2MSN #2: MSN #2: ˙ }3MSN #3: MSN #3: ˙ }4MSN #4: MSN #4: ˙ }5MSN #5: MSN #5: ˙ }6MSN #6: MSN #6: ˙ }7MSN #7: MSN #7: ˙ } 8MSN #8: MSN #8: ˙ }  9MSN #9: MSN #9: ˙ 6P F E MSN grouping  øŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pMpSpNp pgprpopupppipnpgp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p1p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p2p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p3p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p4p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p5p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p6p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p7p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p8p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³p³p pMpSpNp p#p9p p p p p p p p p p p p p p p p p p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p-p-p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpZw˙˙ -- ----21w˙˙ -- ----21w!˙˙ -- ----21w1˙˙ -- ----21wA˙˙ -- ----21wQ˙˙ -- ----21wa˙˙ -- ----21wq˙˙ -- ----21w˙˙ -- ----21w ‘˙˙ -- ----21w˙˙ -- ----22w˙˙ -- ----22w#˙˙ -- ----22w3˙˙ -- ----22wC˙˙ -- ----22wS˙˙ -- ----22wc˙˙ -- ----22ws˙˙ -- ----22w˙˙ -- ----22w “˙˙ -- ----22w!˙˙ -- ----23w!˙˙ -- ----23w!%˙˙ -- ----23w!5˙˙ -- ----23w!E˙˙ -- ----23w!U˙˙ -- ----23w!e˙˙ -- ----23w!u˙˙ -- ----23w!…˙˙ -- ----23w! •˙˙ -- ----23w%˙˙ -- ----24w%˙˙ -- ----24w%'˙˙ -- ----24w%7˙˙ -- ----24w%G˙˙ -- ----24w%W˙˙ -- ----24w%g˙˙ -- ----24w%w˙˙ -- ----24w%‡˙˙ -- ----24w% —˙˙ -- ----24w) ˙˙ -- ----25w)˙˙ -- ----25w))˙˙ -- ----25w)9˙˙ -- ----25w)I˙˙ -- ----25w)Y˙˙ -- ----25w)i˙˙ -- ----25w)y˙˙ -- ----25w)‰˙˙ -- ----25w) ™˙˙ -- ----25w- ˙˙ -- ----26w-˙˙ -- ----26w-+˙˙ -- ----26w-;˙˙ -- ----26w-K˙˙ -- ----26w-[˙˙ -- ----26w-k˙˙ -- ----26w-{˙˙ -- ----26w-‹˙˙ -- ----26w- ›˙˙ -- ----26w1 ˙˙ -- ----27w1˙˙ -- ----27w1-˙˙ -- ----27w1=˙˙ -- ----27w1M˙˙ -- ----27w1]˙˙ -- ----27w1m˙˙ -- ----27w1}˙˙ -- ----27w1¨˙˙ -- ----27w1 ¯˙˙ -- ----27w5˙˙ -- ----28w5˙˙ -- ----28w5/˙˙ -- ----28w5?˙˙ -- ----28w5O˙˙ -- ----28w5_˙˙ -- ----28w5o˙˙ -- ----28w5˙˙ -- ----28w5¸˙˙ -- ----28w5 ˙˙ -- ----28pč˙˙MSN #0 MSN #0 pé˙˙MSN #1 MSN #1 pź˙˙MSN #2 MSN #2 pė˙˙MSN #3 MSN #3 pģ˙˙MSN #4 MSN #4 pķ˙˙MSN #5 MSN #5 pī˙˙MSN #6 MSN #6 pļ˙˙MSN #7 MSN #7 pš˙˙MSN #8 MSN #8 p ń˙˙MSN #9 MSN #9 6P 5 4 Signaling  ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pSpipgpnpaplpipnpgp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pMpSpNp p#p0t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p1t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p2t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p3t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p4t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p5t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p6t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p7t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p8t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³p³p pMpSpNp p#p9t p p p p p p p p p p p p p p p p p p p p p p p p pSptpapnpdpaprpdp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp w) 0MSN #0) MSN #0 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)1MSN #1) MSN #1 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)2MSN #2) MSN #2 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)(3MSN #3) MSN #3 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)24MSN #4) MSN #4 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)<5MSN #5) MSN #5 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)F6MSN #6) MSN #6 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)P7MSN #7) MSN #7 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw)Z8MSN #8) MSN #8 Standard Standard(Standard Type 1 Type 2 Type 3 No ringw )d9MSN #9) MSN #9 Standard Standard(Standard Type 1 Type 2 Type 3 No ring6P! /" . Type  4ŚpÄpÄpÄp pTpypppep pÄpÄpÄpæp³p pIpSpTpEpCp p1p0p0p3p p³p³p pIpSpTpEpCp p1p0p0p8p p³p³p pIpSpTpEpCp p1p0p1p6p p³p³p pIpSpTpEpCp p1p0p2p4p p³p³p pIpSpTpEpCp p2p0p1p6p p³p³p pIpSpTpEpCp p2p0p2p4p p³p³p pIpSpTpEpCp p2p4p0p0p p³p³p pIpSpTpEpCp p2p4p1p6p p³p³p pIpSpTpEpCp p2p4p2p4p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp p š˙˙ ISTEC 1008 ISTEC 1008 p ų˙˙ ISTEC 1016 ISTEC 1016 p ˙˙ ISTEC 1024 ISTEC 1024 p ą˙˙ ISTEC 2016 ISTEC 2016 p č˙˙ ISTEC 2024 ISTEC 2024 p ` ˙˙ ISTEC 2400 ISTEC 2400 p p ˙˙ ISTEC 2416 ISTEC 2416 p x ˙˙ ISTEC 2424 ISTEC 2424 p ė˙˙ ISTEC 1003 ISTEC 1003 6P1 0 Charges  ųŚpÄpÄpÄp pCphpaprpgpepsp pÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p³p³p pDpepvp.p p p pUpnpiptpsp p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙ Dev. Units6P ? > <ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pOtuptpdpipaplp pppeprpmpipspspipopnpsp p p p p p p p p p p p p p p pDpopmpepsptpipcp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p p p pDpaptpap/pMpopdpepmp p³p³p pRtepdpiprpepcptpipopnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMteptpeprp pppuplpspep p p p p p p p p p p p p p p p p p p p p p p p p p p p p pApnp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, OOutdial permissions, Outdial permissions Domestic Domestic( AllDomestic CityIncomingInternalw,SService, Service Data/Modem  Data/ModemU Telephone Fax G3 Data/Modem Datex-J/ModemAnswering machine},R Redirection, Redirection ˙x,(M Meter pulse, Meter pulse An  AnAus An},2PPIN, PIN ˙6P ? > <ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pOtuptpdpipaplp pppeprpmpipspspipopnpsp p p p p p p p p p p p p p p p p p p pCpiptpyp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p pCpopmpbpipnpepdp pspeprpvpipcpepsp p³p³p pRtepdpiprpepcptpipopnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMteptpeprp pppuplpspep p p p p p p p p p p p p p p p p p p p p p p p p p p p pApupsp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, OOutdial permissions, Outdial permissions City  City( AllDomestic CityIncomingInternalw,SService, Service Combined services Combined servicesf Telephone Fax G3 Data/Modem Datex-J/ModemAnswering machineCombined services},R Redirection, Redirection ˙x,(M Meter pulse, Meter pulse Aus AusAus An},2PPIN, PIN ˙6P ? > ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pOtuptpdpipaplp pppeprpmpipspspipopnpsp p p p p p p p p p p p p p p p p p p pCpiptpyp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p pCpopmpbpipnpepdp pspeprpvpipcpepsp p³p³p pRtepdpiprpepcptpipopnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMteptpeprp pppuplpspep p p p p p p p p p p p p p p p p p p p p p p p p p p p pApupsp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pAtuptpopmpaptpipcp pepxptpeprpnpaplp pdpipaplpipnpgp p p p p p p p p p p p p pApupsp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpw, OOutdial permissions, Outdial permissions City  City( AllDomestic CityIncomingInternalw,SService, Service Combined services Combined servicesf Telephone Fax G3 Data/Modem Datex-J/ModemAnswering machineCombined services},R Redirection, Redirection ˙x,(M Meter pulse, Meter pulse Aus AusAus An},2PPIN, PIN ˙x,<AAutomatic external dialing, Automatic external dialing Aus AusAus An6P? > ¬ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pOtuptpdpipaplp pppeprpmpipspspipopnpsp p p p p p p p p p p p p p p pIpnpcpopmpipnpgp p³p³p pSteprpvpipcpep p p p p p p p p p p p p p p p p p p p p p p p p p pTpeplpeppphpopnpep p³p³p pRtepdpiprpepcptpipopnp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pMteptpeprp pppuplpspep p p p p p p p p p p p p p p p p p p p p p p p p p p p p pOpnp p³p³p pPtIpNp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pAtuptpopmpaptpipcp pepxptpeprpnpaplp pdpipaplpipnpgp p p p p p p p p p p p p p pOpnp p³p³p pItnptpeprpnpaplp pkpnpopcpkp p p p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p pEtxptpeprpnpaplp pkpnpopcpkp p p p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p pKtnpopcpkp pfprpopmp pdpopoprp p p p p p p p p p p p p p p p p p p p p p p p p p pp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp w, OOutdial permissions, Outdial permissions Incoming Incoming( AllDomestic CityIncomingInternalw,SService, Service Telephone  Telephonef Telephone Fax G3 Data/Modem Datex-J/ModemAnswering machineCombined servicesu,dR Redirection, Redirection x,(M Meter pulse, Meter pulse On  OnOff On},2PPIN, PIN ˙x,<AAutomatic external dialing, Automatic external dialing On  OnOff Onq,FIInternal knock, Internal knock  6P0/ Internal knock  XŚpÄpÄpÄpÄpÄpÄp pIpnptpeprpnpaplp pkpnpopcpkp pÄpÄpÄpÄpÄpÄpæp³p pDpepvpipcpep p2p1p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p2p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p3p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p4p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p5p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p6p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p7p p p p p p p p p p p p p p p pNpop p³p³p pDpepvpipcpep p2p8p p p p p p p p p p p p p p p pNpop p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpyč˙˙ Device 21 Device 21 No  No NoYesyņ˙˙ Device 22 Device 22 No  No NoYesyü˙˙ Device 23 Device 23 No  No NoYesy˙˙ Device 24 Device 24 No  No NoYesy˙˙ Device 25 Device 25 No  No NoYesy˙˙ Device 26 Device 26 No  No NoYesy$˙˙ Device 27 Device 27 No  No NoYesy.˙˙ Device 28 Device 28 No  No NoYesq,PEExternal knock, External knock  6P.- External knock   ŚpÄpÄpÄpÄpÄp pEpxptpeprpnpaplp pkpnpopcpkp pÄpÄpÄpÄpÄpæp³p pMpSpNp p0p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p1p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p2p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p3p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p4p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p5p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p6p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p7p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p8p p p p p p p p p p p p p p p p p pNpop p³p³p pMpSpNp p9p p p p p p p p p p p p p p p p p pNpop p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp yL˙˙MSN 0 MSN 0 No  No NoYesyV˙˙MSN 1 MSN 1 No  No NoYesy`˙˙MSN 2 MSN 2 No  No NoYesyj˙˙MSN 3 MSN 3 No  No NoYesyt˙˙MSN 4 MSN 4 No  No NoYesy~˙˙MSN 5 MSN 5 No  No NoYesy˙˙MSN 6 MSN 6 No  No NoYesy’˙˙MSN 7 MSN 7 No  No NoYesy˙˙MSN 8 MSN 8 No  No NoYesy ¦˙˙MSN 9 MSN 9 No  No NoYesq ,ZKKnock from door, Knock from door  6P.- Knock from door  PŚpÄpÄpÄpÄp pKpnpopcpkp pfprpopmp pdpopoprp pÄpÄpÄpÄpÄpæp³p pTpFpEp p1p p p p p p p p p p p p p p p p p pNpop p³p³p pTpFpEp p2p p p p p p p p p p p p p p p p p pNpop p³p³p pTpFpEp p3p p p p p p p p p p p p p p p p p pNpop p³p³p pTpFpEp p4p p p p p p p p p p p p p p p p p pNpop p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpy°˙˙TFE 1 TFE 1 No  No NoYesyŗ˙˙TFE 2 TFE 2 No  No NoYesyÄ˙˙TFE 3 TFE 3 No  No NoYesyĪ˙˙TFE 4 TFE 4 No  No NoYes6P & % External knock   ŚpÄpÄpÄpÄpÄp pEpxptpeprpnpaplp pkpnpopcpkp pÄpÄpÄpÄpÄpæp³p pMpSpNp p0p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p4p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p5p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p6p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p7p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p8p p p p p p p p p p p p p p p pNpepipnp p³p³p pMpSpNp p9p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp yL˙˙MSN 0 MSN 0 Nein NeinNein JayV˙˙MSN 1 MSN 1 Nein NeinNein Jay`˙˙MSN 2 MSN 2 Nein NeinNein Jayj˙˙MSN 3 MSN 3 Nein NeinNein Jayt˙˙MSN 4 MSN 4 Nein NeinNein Jay~˙˙MSN 5 MSN 5 Nein NeinNein Jay˙˙MSN 6 MSN 6 Nein NeinNein Jay’˙˙MSN 7 MSN 7 Nein NeinNein Jay˙˙MSN 8 MSN 8 Nein NeinNein Jay ¦˙˙MSN 9 MSN 9 Nein NeinNein Ja6P ( ' Internal knock  XŚpÄpÄpÄpÄpÄpÄp pIpnptpeprpnpaplp pkpnpopcpkp pÄpÄpÄpÄpÄpÄpæp³p pDpepvpipcpep p2p1p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p2p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p3p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p4p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p5p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p6p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p7p p p p p p p p p p p p p pNpepipnp p³p³p pDpepvpipcpep p2p8p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpyč˙˙ Device 21 Device 21 Nein NeinNein Jayņ˙˙ Device 22 Device 22 Nein NeinNein Jayü˙˙ Device 23 Device 23 Nein NeinNein Jay˙˙ Device 24 Device 24 Nein NeinNein Jay˙˙ Device 25 Device 25 Nein NeinNein Jay˙˙ Device 26 Device 26 Nein NeinNein Jay$˙˙ Device 27 Device 27 Nein NeinNein Jay.˙˙ Device 28 Device 28 Nein NeinNein Ja6P & % Knock from door  PŚpÄpÄpÄpÄp pKpnpopcpkp pfprpopmp pdpopoprp pÄpÄpÄpÄpÄpæp³p pTpFpEp p1p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p2p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p3p p p p p p p p p p p p p p p pNpepipnp p³p³p pTpFpEp p4p p p p p p p p p p p p p p p pNpepipnp p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpy°˙˙TFE 1 TFE 1 Nein NeinNein Jayŗ˙˙TFE 2 TFE 2 Nein NeinNein JayÄ˙˙TFE 3 TFE 3 Nein NeinNein JayĪ˙˙TFE 4 TFE 4 Nein NeinNein Ja6PPO Device settings  ĄŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pDpepvpipcpep pspeptptpipnpgpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvp.p pOpuptpdpipaplp pppeprpmp.p p pSpeprpvpipcpep p p p p p p p p p p pRpepdpiprpepcptp p p p p p p p p p p p p pMpeptpeprp-pPp.p p p p pPpIpNp p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙K Dev. Outdial perm. Service Redirect Meter-P. PIN6P 4 3 Redirection  ¤ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pRpepdpiprpepcptpipopnp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPthpopnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pCtopnpdpiptpipopnp p p p p p p p p p p p p p p p p p p p p p p p pnpepvpeprp p³p³p pRtipnpgp pcpopupnptp p p p p p p p p p p p p p p p p p p p p p p p p p p p3p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp}( PPhone( Phone Ø˙w(C Condition( Condition never never 4 never always if busyafter x ringst(R Ring count( Ring count 3  6P D C ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pPthpopnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pOpuptpgpopipnpgp pcpaplplpsp:p p p p p p p p p p p p p pIpnpcpopmpipnpgp pcpaplplpsp:p p p p p p p p p p p p³p³p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p p pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp p³p³p pUtspapgpep p p p p p p p p p p p p p pUpnpupspepdp p p pStipgpnpaplpipnpgp p p p p p p p pSpipgpnpaplp p3p p³p³p pDpepvpipcpep p2p1t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p2t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p3t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p4t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p5t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p6t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p7t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvpipcpep p2p8t p p p p p p p p p p p p pApupsp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp}7 PPhone7 Phone  ˙wUUsage Usage Unused Unused $ Unused ShortcutAuto dial Lockxn1 Device 21 Device 21 Aus AusAus Anxx2 Device 22 Device 22 Aus AusAus Anx ‚3 Device 23 Device 23 Aus AusAus Anx 4 Device 24 Device 24 Aus AusAus Anx –5 Device 25 Device 25 Aus AusAus Anx  6 Device 26 Device 26 Aus AusAus Anx Ŗ7 Device 27 Device 27 Aus AusAus Anx´8 Device 28 Device 28 Aus AusAus AnwS Signaling Signaling Signal 3 Signal 3(StandardSignal 1Signal 2Signal 3 None`%č˙˙Incoming calls:`%é˙˙Outgoing calls:s1u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs2u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs50u˙˙5ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ6PPO Shortcut numbers   ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pSphpoprptpcpuptp pnpupmpbpeprpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepvp p pPphpopnpep p p p p p p p p p p p p p p p p pAplpipapsp p p p p p p p p p p p p pUpspapgpep p p p p p p p pDpepvpipcpepsp p p pSpipgpnpaplp p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙`^d˙˙K Dev Phone Alias Usage Devices Signal6P C B Print settings  ”ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pPprpipnptp pspeptptpipnpgpsp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pHtepapdplpipnpep p p p p p p                                      p³p³p pPtrpipcpep pppeprp pcphpaprpgpep pupnpiptp p p p p p p p p p p p p p p p p p p p p p p 0,01    p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp3H#Headline#3ž‘3PPrice per charge unit0,01-,3|®Gįz„?|®Gįz„?ĄX@6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpaptphp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pFtiplpepsp p p p p p p p p p p p p p p p p p p p p pDtiprpepcptpoprpipepsp p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6F!Files`6D  Directories2N1Name( 3ž`6é˙˙Pathb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp p p p p p p p p p pUpspeprp pNpapmpep p p p p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprpdp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KUser ID User Name Password Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pItDp p p p p p p p p p p p p p p p p p p                       p³p³p pUpspeprp pNtapmpep p p p p p p                                 p³p³p pPtapspspwpoprpdp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStepcpuprpiptpyp pLpepvpeplp p p p p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/IUser ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N1 User Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPassword "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSecurity Level0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  6P :9 ŲŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp” ˙˙User ID:  ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōHelpAccept Abort End Proceed Change Print  Graphics Insert Delete Select Confirm Move Login Logout Exit Zoom Close Open Resize Save  ~~ Select  ~ÄŁ~ Select  ~ PgDn PgUp~ Browse  ~~ Move  ~Ctrl-~ Resize Are you shure?d Really quit?eDiscard changes?f Save changes?g@Yes @Noh@No @Yesi Error Č Information É Fatal Error ŹConfirm ŅAbort ÓIgnore ŌRetry ÕEnd ÖOne moment please...× Invalid input,Too many trailing digits-"Value is too small (minimum is %g)."Value is too large (maximum is %g)/#Value is too small (minimum is %ld)0#Value is too large (maximum is %ld)1Input cannot be empty2No filename extension allowed3Off On NoYes‘Value is too largeōValue is too smallõ Invalid inputö,%s: Section %s, key %s not found or invalid.X$Error opening the password file^(%s)¼$Error reading the password file^(%s)½'Error writing to the password file^(%s)¾The user id cannot be empty!æThe user name cannot be empty!ĄAn empty password is invalid!Į'A user with this ID does already exist!Ā$Invalid user id or invalid password!ĆSunday Monday!Tuesday" Wednesday#Thursday$Friday%Saturday&Sun'Mon(Tue)Wed*Thu+Fri,Sat-January.February/March0April1May2June3July4August5 September6October7November8December9Jan:Feb;Mar<Apr=May>Jun?Jul@AugASepBOctCNovDDecENo help available„No help on this topic… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+PgUp™Alt+EndAlt+PgDnAlt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Error %d: %süNo error (OOPS!)żFile or path not foundžNot enough memory˙ Access denied Too many open files No space left on device Try again Device or file is busy File is too large I/O error File is a directory File is no directory Too many links Block device required Char device required Device does not exist !You are not the owner of the file Broken pipe File system is readonly Cannot seek on pipes Process does not exist Text file is busy Name is too long No locks available Directory is not empty File not found Path not found Drive is invalid Cannot remove current directory File exists Unknown error (%d) There are too many windows open!Ä 6P > = Window list  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pWpipnpdpopwp plpipsptp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙š ōHelp Overnemen  Afbreken Einde Verder  Veranderen  Afdrukken Grafiek  Invoegen  Verwijderen Keuze Bevestigen Bewegen Login Logout Einde Zoom Sluiten Openen Grootte Opslaan  ~~ Keuze  ~ÄŁ~ Keuze  ~ Beeld-~ bladeren  ~~ Bewegen  ~Ctrl+~ Groote  Bent U zeker?dEcht verlaten?eWijzigingen ongedaan maken?fVeranderinge schrijven?g@Ja @Neeh@Nee @Jai Fout Č Informatie É Systeemfout Ź Bevestigen Ņ Ophouden ÓNegeren Ō Herhalen ÕEinde ÖEven wachten a.u.b...×Ongeldige invoer,Te veel cijfers na de Komma-"Waarde is te klein (Minimum is %g)."Waarde is te groot (Maximum is %g)/#Waarde is te klein (Minimum is %ld)0#Waarde is te groot (Maximum is %ld)1Lege invoer is niet toegelaten2Geen Bestand ending toegelaten3UitAanNeeJaa‘Waarde is te grootōWaarde is te klijnõ Foute invoerö(%s: Sektie %s, %s niet gevonden of fout.X5Fout bij het openen van het wachtwoorden-bestand^(%s)¼4Fout bij het lezen van het wachtwoorden-bestand^(%s)½8Fout bij het schrijven van het wachtwoorden-bestand^(%s)¾"De User-ID moet aangegeven worden!æ#De Usernaam moet aangegeven worden!Ą&Een wachtwoord moet aangegeven worden!Į Een User met deze ID bestaat al!Ā*Ongeldige User-ID of ongeldige wachtwoord!ĆZondag Maandag!Dinsdag"Woensdag# Donderdag$Vrijdag%Zaterdag&So'Ma(Di)Wo*Do+Fr,Za-Januari.Februari/Maart0April1Mei2Juni3Juli4Augustus5 September6Oktober7November8December9Jan:Feb;Maa<Apr=Mai>Jun?Jul@AugASepBOktCNovDDecEGeen Hulp beschikbaar„Geen Hulp voor dit Steekword… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpatieCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+Pg-v Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pg-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+Pg-™Alt+EndAlt+Pg-Alt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+EscAlt+spacetoutsCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Fout %d: %süGeen fout (OOPS!)żBestand of pad niet gevondenžTe weinig geheugen˙Ingreep geweigerd Te veel geopende bestanden ,Te weinig ruimte op het angesproken apparaat &Tijdelijke fout - Probeer het nog eens Apparaat/Bestand is in gebruik Bestand te groot I/O Fout Bestand is een directory Bestand is geen directory Te veel links *Operatie alleen mogelijk met block devices )Operatie alleen mogelijk met char devices Device bestaat niet <Operatie is alleen voor de eigenaar van dit bestand mogelijk Broken Pipe Bestandsysteem is alleen-lezen (Seek kan niet op Pipes uitgevoerd worden Proces bestaat niet !Uitvourbare bestand is in gebruik Naam is te lang Geen lockings beschikbaar Directory is niet leeg Bestand niet gevonden Path niet gevonden Schijf is onjuist ,Huidige directory kan niet verwijderd worden Bestand bestaat al Onbekende fout (%d) Te veel vensters geopend!Ä p x@ESTIC @Di ESTIC...@File @Carica file @Salva file @Visualizza logfile Ca@rica ISTEC Sa@lva ISTEC@Leggi il file degli alias@Esci@Configurazione @Versione@Parametri centralino@Parametri apparecchi@ResetC@osti C@arica costi@Visualizza costi Configurazione @stampante! Stampa @costi" @Reset costi# F@inestra(@Apri)@Matrice collegamenti*@Costi+Chiamate @eseguite,@Isdn4Linux Monitor- A@ffiancate. @In cascata/ Chiudi @tutte0@Schermo nuovo1@Posizione/dimensione2@Zoom3@Chiudi4@Lista finestre5‚ ESTIC Version 1.30 (Enhanced Supervisor Tool for ISTEC Configuration) (C) 1995 Ullrich von Bassewitz  < Accesso base=Accesso primario>Accesso sconosciuto?‘ Typ: %s Versione software: %d.%d %-2d Interfacce S0 esterne %-2d Interfacce S0 interne %-2d Interfaccie ab Protocollo: %s Accesso: %s @ Carica configurazione A Salva configurazione BCOM port non apertaC-Timeout durante la comunicazione con la ISTECDSalvare modifiche nella ISTEC?ERendere modifiche permanenti?FStampa costi %s %33sG@----------------------------------------------------------------H2 Appar Scatti Costi I+ #%2d %4d J-Errore d'inizializzazione della porta serialeKReceive buffer overflow!L0Non abbastanza caratteri nel messaggio ricevuto!M Risposta non valida della ISTEC!NGNumero device sbagliato nella risposta della ISTEC. Comando annullato!O Stampa in file P Visulizza logfile Q-Errore di apertura del file di configurazioneR"OOPS - Errore interno! (ignorato)Č ISTEC XXXX, ISTEC 1003- ISTEC 1008. ISTEC 1016/ ISTEC 10240 ISTEC 20161 ISTEC 20242 ISTEC 24003 ISTEC 24164 ISTEC 24245Accesso pieno Nazionale ‘Urbano ’Solo Ricezione “Solo Interni ”Telefonia •Fax gruppo 3 –Data/modem —Datex-J/modem Segreteria tel. ™Servizi combinati  On › Off  ------ ¯ Esterno ˛ Interno:%2d Device #%d  ^ Per ampliare i centralini da 16 utenti a/b a a 24 utenti a/b bisogna leggere il manuale. ō Matrice collegamenti X@ Nr. Lin1 Lin2 Int1 Int2 Int3 Suo WSuo Acc Chia Numero YAlias doppio per numero %s¼)Errore di apertura del file degli alias !½0Errore di sintassi nel file degli alias, riga %d¾ isdn4linux Monitor / Dr Ch On/Off Servizio Numero !/-----------------------------------------------"On#Off$---%Raw&Modem'Rete(Voice)Fax* Sconosciuto+Errore di apertura %s,:Errore di lettura %s - isdn4linux monitor viene terminato!-/Errore di apertura del file di log per il debug„ Chiamate eseguite LNNr. Alias Data Inizio Durata Numero Scat. Lit MNÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄN Costi ° Nr. scatti±6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p zIpDp puptpepnptpep:p z z z z                       z³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ ID utente: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōGuida Accetta Annulla Termina  Continua  Modifica Stampa Grafica  Inserisci  Cancella Seleziona Conferma Muovi Login Logout Termina Zoom Chiudi Apri  Dimensione Salva  ~~ Seleziona  ~ÄŁ~ Seleziona  ~ Pag-~ sfoglia  ~~ Muovi  ~Ctrl+~ Dimensione E' proprio sicuro?dProprio terminare?eAnnullare modifiche?fSalvare modifiche?g@S¨ @Noh@No @S¨i Errore Č Informazione É Errore di sistema Ź Conferma ŅAnnulla ÓIgnora ŌRipeti ÕFine Ö Un momento...×Valore non valido,Troppi zero dopo la virgola-$Valore troppo piccolo (al minimo %g).$Valore troppo grande (al massimo %g)/%Valore troppo piccolo (al minimo %ld)0%Valore troppo grande (al massimo %ld)1Ci vuole qualcosa!2Estensione file non ammessa3Off OnNoS¨‘Valore troppo grandeōValore troppo piccoloõValore sbagliatoö+%s: sezione %s, %s non trovata o sbagliata.X/Errore di apertura del file delle password (%s)¼.Errore di lettura del file delle password (%s)½0Errore di scrittura del file delle password (%s)¾Ci vuole un ID utente!æCi vuole un nome utente!ĄCi vuole una password!Į#Un utente con questo ID esiste gi…!Ā ID utente o password non validi!ĆDomenica Luned¨!Marted¨" Mercoled¨#Gioved¨$Venerd¨%Sabato&Do'Lu(Ma)Me*Gi+Ve,Sa-Gennaio.Febbraio/Marzo0Aprile1Maggio2Giugno3Luglio4Agosto5 Settembre6Ottobre7Novembre8Dicembre9Gen:Feb;Mar<Apr=Mag>Giu?Lug@AgoASetBOttCNovDDicEGuida non disponibile„.Guida non disponibile per questa parola chiave… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+Pag-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pag-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Pag-™Alt+Fine Alt+Pag-Alt+Ins¢Alt+Canc£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-FineEsc-PgDnEsc-Ins¢Esc-Canc£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Byte 4 Directory 5 Errore %d: %süNessun errore (OOPS!)żFile o path non trovatižMemoria insufficiente˙Accesso negato Troppi files aperti ,Memoria insufficiente sul device indirizzato Errore temporaneo - riprovare Device/file in uso File troppo grande Errore di I/O Il file una directory Il file non una directory Troppi links /L'operazione possibile solo con block devices .L'operazione possibile solo con char devices Device non esistente :L'operazione possibile solo per il proprietario del file Broken Pipe $Il file di sistema e' a sola lettura %Seek non pu• essere eseguito su pipes Processo non esistente File eseguibile impegnato Nome troppo lungo Nessun lock disponibile La directory non vuota File non trovato Path non trovato Drive non valido .La directory attuale non pu• essere cancellata Il file esiste gi… Errore sconosciuto (%d) Sono aperte troppe finestre!Ä 6P > = Lista finestre  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pLpipsptpap pfpipnpepsptprpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯3˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙33˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ ˙˙˙˙˙˙˙˙˙˙!˙˙˙˙˙˙˙˙˙˙"˙˙˙˙˙˙˙˙˙˙#˙˙˙˙˙˙˙˙˙˙$˙˙˙˙˙˙˙˙˙˙%˙˙˙˙˙˙˙˙˙˙&˙˙˙˙˙˙˙˙˙˙'˙˙˙˙˙˙˙˙˙˙(˙˙˙˙˙˙˙˙˙˙)˙˙˙˙˙˙˙˙˙˙*˙˙˙˙˙˙˙˙˙˙+˙˙˙˙˙˙˙˙˙˙,˙˙˙˙˙˙˙˙˙˙-˙˙˙˙˙˙˙˙˙˙.˙˙˙˙˙˙˙˙˙˙/˙˙˙˙˙˙˙˙˙˙0˙˙˙˙˙˙˙˙˙˙1˙˙˙˙˙˙˙˙˙˙2˙˙˙˙˙˙˙˙˙˙3˙˙˙˙˙˙˙˙˙˙4˙˙˙˙˙˙˙˙˙˙5˙˙˙˙˙˙˙˙˙˙6˙˙˙˙˙˙˙˙˙˙7˙˙˙˙˙˙˙˙˙˙8˙˙˙˙˙˙˙˙˙˙9˙˙˙˙˙˙˙˙˙˙:˙˙˙˙˙˙˙˙˙˙;˙˙˙˙˙˙˙˙˙˙<˙˙˙˙˙˙˙˙˙˙=˙˙˙˙˙˙˙˙˙˙>˙˙˙˙˙˙˙˙˙˙?˙˙˙˙˙˙˙˙˙˙°¯˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ @€˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,./:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° .,-:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAA¸€EEEIIIA¸E’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨ˇ†‘‘“”•–—™›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° BEF.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙!"#$%&˙()*+,˙./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU›¯˛AIOUNN¦§Ø©Ŗ«¬­®Æ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüż˙˙° F ,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° ˛.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° L..,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° Fr'...,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙ČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚ¨ŪÜŻŽßąįāćä<=>?@ABCDEFGHIJ !"#$%&'()KLMNOPQ RST4U3 VWX6Y oZp–\ ]—_`abcdefghi™›klmn¯qrstuvw˛xyz{|}~ ¢£¤¦§Ø©€‚Ŗ«…¬­®Æ°†±²³´µ¶·ø¹ŗ‰»¼½¾ˇæ¸ĄĮĀ“”° ,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° SEK.,-.;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° DM.,.:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° mk ,..;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° >< ^ >< ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ° »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±> "001.@ICBASEED.Abfragestellen-MenueŠP" "001.@ICBASEED.BaseConfigMenue-1.92ņR+ "001.@ICBASEED.BaseConfigMenue-1.93b  "001.@ICBASEED.BaseConfigMenue-2.00*sß 001.@ICBASEED.EAZ-GruppenMenue …P 001.@ICBASEED.MSN-EingabemenueY™ 001.@ICBASEED.MSN-GruppenMenueóŽ 001.@ICBASEED.MSN-RufsignaleŃø 001.@ICBASEED.TypeMenueļĆ0 001.@ICDEVS.ChargesWindowĒg 001.@ICDEVS.ConfigMenue-1.90†É. 001.@ICDEVS.ConfigMenue-1.92´Ļ> 001.@ICDEVS.ConfigMenue-1.93ņÕ 001.@ICDEVS.ConfigMenue-2.00ŻÖ -001.@ICDEVS.ConfigMenue-2.00.Anklopfen-ExternŁōL -001.@ICDEVS.ConfigMenue-2.00.Anklopfen-Intern%ū *001.@ICDEVS.ConfigMenue-2.00.Anklopfen-TFEµõ 001.@ICDEVS.DeviceListWindowŖw 001.@ICDEVS.RerouteMenue! x 001.@ICSHORT.ShortNumberEdit™² 001.@ICSHORT.ShortNumberWindowKŅ 001.@ISTEC.PrintSettingsMenue'‚ 001.FILESEL.FileSelectorWindow*c 001.PASSWORD.Editorwindow5į 001.PASSWORD.EntryEditwindowćEį 001.PASSWORD.Password-WindowÄI" 001.PASSWORD.UserID-WindowęJ‚ 001.PROGRAM.MessageshL» 001.WINMGR.ChooseWindow#h 002.@ESTIC.MainMenue7l 002.@ESTIC.MainMenue.Dateiæ¤ 002.@ESTIC.MainMenue.ESTICc‘ć 002.@ESTIC.MainMenue.FensterF’Ü $002.@ESTIC.MainMenue.Fenster.Oeffnen"›É 002.@ESTIC.MainMenue.Gebuehrenė¯Ą 002.@ESTIC.MainMenue.Istec«Ą 002.@ESTIC.MessageskŖM "002.@ICBASEED.Abfragestellen-Menueøŗ "002.@ICBASEED.BaseConfigMenue-1.92ҼK "002.@ICBASEED.BaseConfigMenue-1.93Ģ- "002.@ICBASEED.BaseConfigMenue-2.00JŻž 002.@ICBASEED.EAZ-GruppenMenueHļJ 002.@ICBASEED.MSN-Eingabemenue’ 002.@ICBASEED.MSN-GruppenMenue* Ų 002.@ICBASEED.MSN-Rufsignale#µ 002.@ICBASEED.TypeMenue·,1 002.@ICDEVS.ChargesWindowč/d 002.@ICDEVS.ConfigMenue-1.90L21 002.@ICDEVS.ConfigMenue-1.92}8B 002.@ICDEVS.ConfigMenue-1.93æ> 002.@ICDEVS.ConfigMenue-2.00×E¸ -002.@ICDEVS.ConfigMenue-2.00.Anklopfen-Externf]J -002.@ICDEVS.ConfigMenue-2.00.Anklopfen-Intern°c† *002.@ICDEVS.ConfigMenue-2.00.Anklopfen-TFE6i÷ 002.@ICDEVS.DeviceListWindow-lr 002.@ICDEVS.RerouteMenueu\ 002.@ICSHORT.ShortNumberEditūx 002.@ICSHORT.ShortNumberWindowz†Ó 002.@ISTEC.PrintSettingsMenueM¸m 002.FILESEL.FileSelectorWindowŗ’_ 002.PASSWORD.Editorwindow¯į 002.PASSWORD.EntryEditwindowś­Ö 002.PASSWORD.Password-Windowб" 002.PASSWORD.UserID-Windowņ²f 002.PROGRAM.MessagesX´ć 002.WINMGR.ChooseWindow;Ī 004.PROGRAM.MessagesNŅe 006.@ESTIC.Messages³ķW 006.PASSWORD.Password-Window ś" 006.PASSWORD.UserID-Window,ū€ 006.PROGRAM.Messages¬ü? 006.WINMGR.ChooseWindowė @ICBASEED.Default-1003£ @ICBASEED.Default-1008¤ £ @ICBASEED.Default-1016G%£ @ICBASEED.Default-1024ź)£ @ICBASEED.Default-2016¨.£ @ICBASEED.Default-202403£ @ICBASEED.Default-2400Ó7£ @ICBASEED.Default-2416v<£ @ICBASEED.Default-2424A£ NATIONAL.001¼E& NATIONAL.003āH& NATIONAL.031L& NATIONAL.032.O& NATIONAL.033TR& NATIONAL.034zU& NATIONAL.039 X& NATIONAL.041Ę[& NATIONAL.044ģ^& NATIONAL.046b& NATIONAL.0498e& NATIONAL.061^h& NATIONAL.099„k& NATIONAL.358Ŗn& SCREEN.7BIT-ASCII-TableŠq SCREEN.ISO-8859-1-TableÖrestic-1.61.orig/estic/icac.cc0100644000176100001440000001165207031424723015334 0ustar debacleusers/*****************************************************************************/ /* */ /* ICAC.CC */ /* */ /* (C) 1997 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is the ESTIC interface to the area code module #include "chartype.h" #include "../areacode/areacode.h" #include "icac.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Code for the country we say we are in String CountryCode = ""; // Code for the area, we say we are in String AreaCode = "711"; // The digit that is used as a dial prefix (usually '0') char DialPrefix = '0'; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void SetAreaCodeFilename (const String& Name) // Set the name of the areacode data file { unsigned Len = Name.Len (); if (Len > 0) { acFileName = strcpy (new char [Len+1], Name.GetStr ()); } } String GetFullyQualifiedPhone (const String& Phone) // Return a fully qualified phone number from the given number. { const char IntPrefix [3] = { DialPrefix, DialPrefix }; const char AreaPrefix [2] = { DialPrefix }; // Try to build a fully qualified number from the given phone number. String FQP = Phone; if (FQP.Cut (0, 2) == IntPrefix) { // This number is already fully qualified. Remove the dial prefix. FQP.Del (0, 2); } else if (FQP.Cut (0, 1) == AreaPrefix) { // The number has an area code. Remove the dial prefix and add the // country code. FQP.Del (0, 1); FQP.Ins (0, CountryCode); } else { // This is a local number. Add the area code and the country code. FQP = CountryCode + AreaCode + FQP; } // Return the result return FQP; } String IstecGetAreaCodeInfo (const String& Phone, unsigned& AreaCodeLen) // Return an info string for the given phone number. The phone number is // expected to use the usual national conventions, that is: // // * if it is prefixed by two DialPrefix chars, it is assumed to be // "fully qualified", that means, it starts with a country code. // * if it is prefixed by one DialPrefix chars, it is assumed to be // a number with an area code but without a country code. // * if it does not start with any DialPrefix chars, it is assumed to // be a local number. // // The function returns the info string found and sets AreaCodeLen to the // length of the area code in Phone. If no info is found, AreaCodeLen is set // to zero. { // Try to build a fully qualified number from the given phone number, // since this is, what the areacode module expects. String FQP = GetFullyQualifiedPhone (Phone); // Use the areacode module to search for an info. acInfo Info; GetAreaCodeInfo (&Info, FQP.GetStr ()); // Check if we did find anything if (Info.AreaCodeLen == 0) { // OOPS, we did not find anything AreaCodeLen = 0; return ""; } // We found an info. Return the data found AreaCodeLen = int (Info.AreaCodeLen) - (FQP.Len () - Phone.Len ()); return InputCvt (Info.Info); } unsigned IstecGetAreaCodeLen (const String& Phone) // Return the length of the area code for the given phone number. The phone // number is expected to use the usual national conventions, that is: // // * if it is prefixed by two DialPrefix chars, it is assumed to be // "fully qualified", that means, it starts with a country code. // * if it is prefixed by one DialPrefix chars, it is assumed to be // a number with an area code but without a country code. // * if it does not start with any DialPrefix chars, it is assumed to // be a local number. // // If no info is found, zero is returned. { unsigned AreaCodeLen; String Dummy = IstecGetAreaCodeInfo (Phone, AreaCodeLen); return AreaCodeLen; } String IstecBeautifyPhone (const String& Phone) // Try to "beautify" the phone number by putting a separator between the // areacode and the local number { // Be careful here: If we do not find the number in the database, // don't change anything, leave all separators in place if (Phone.NotEmpty ()) { String S = CleanPhone (Phone);; unsigned AreaCodeLen = IstecGetAreaCodeLen (S); if (AreaCodeLen == 0) { // Return the original string unchanged return Phone; } else { S.Ins (AreaCodeLen, '/'); return S; } } else { return Phone; } } String CleanPhone (const String& Phone) // Remove all unwanted characters from the given phone number and return the // result. { String TmpPhone = Phone; TmpPhone.Remove ("+-/()", rmAll); return TmpPhone; } estic-1.61.orig/estic/icac.h0100644000176100001440000000551107031424723015173 0ustar debacleusers/*****************************************************************************/ /* */ /* ICAC.H */ /* */ /* (C) 1997 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is the ESTIC interface to the area code module #ifndef _ICAC_H #define _ICAC_H #include "str.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Code for the country we say we are in extern String CountryCode; // Code for the area, we say we are in extern String AreaCode; // The digit that is used as a dial prefix (usually '0') extern char DialPrefix; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void SetAreaCodeFilename (const String& Name); // Set the name of the areacode data file String IstecGetAreaCodeInfo (const String& Phone, unsigned& AreaCodeLen); // Return an info string for the given phone number. The phone number is // expected to use the usual national conventions, that is: // // * if it is prefixed by two DialPrefix chars, it is assumed to be // "fully qualified", that means, it starts with a country code. // * if it is prefixed by one DialPrefix chars, it is assumed to be // a number with an area code but without a country code. // * if it does not start with any DialPrefix chars, it is assumed to // be a local number. // // The function returns the info string found and sets AreaCodeLen to the // length of the area code in Phone. If no info is found, AreaCodeLen is set // to zero. unsigned IstecGetAreaCodeLen (const String& Phone); // Return the length of the area code for the given phone number. The phone // number is expected to use the usual national conventions, that is: // // * if it is prefixed by two DialPrefix chars, it is assumed to be // "fully qualified", that means, it starts with a country code. // * if it is prefixed by one DialPrefix chars, it is assumed to be // a number with an area code but without a country code. // * if it does not start with any DialPrefix chars, it is assumed to // be a local number. // // If no info is found, zero is returned. String IstecBeautifyPhone (const String& Phone); // Try to "beautify" the phone number by putting a separator between the // areacode and the local number String CleanPhone (const String& Phone); // Remove all unwanted characters from the given phone number and return the // result. // End of ICAC.H #endif estic-1.61.orig/estic/icalias.cc0100644000176100001440000002156107031424723016042 0ustar debacleusers/*****************************************************************************/ /* */ /* ICALIAS.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "chartype.h" #include "coll.h" #include "str.h" #include "strcvt.h" #include "strparse.h" #include "stdmsg.h" #include "progutil.h" #include "icmsg.h" /*****************************************************************************/ /* Message Constants */ /*****************************************************************************/ const u16 msDuplicateNumber = MSGBASE_ICALIAS + 0; const u16 msOpenError = MSGBASE_ICALIAS + 1; const u16 msSyntaxError = MSGBASE_ICALIAS + 2; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name of the alias file, default is the empty string String AliasFile = ""; // If true, reread the alias file before trying to resolve call data int AutoReadAliases = 0; /*****************************************************************************/ /* class DevAlias */ /*****************************************************************************/ class DevAlias: public Streamable { public: String Number; String Alias; DevAlias (const String& aNumber, const String& aAlias); }; DevAlias::DevAlias (const String& aNumber, const String& aAlias): Number (aNumber), Alias (aAlias) { } /*****************************************************************************/ /* class AliasColl */ /*****************************************************************************/ class AliasColl: public SortedCollection { protected: virtual int Compare (const String* Key1, const String* Key2); virtual const String* KeyOf (const DevAlias* Item); public: AliasColl (); // Create a AliasColl virtual DevAlias* At (int Index); // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING }; int AliasColl::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } const String* AliasColl::KeyOf (const DevAlias* Item) { return &Item->Number; } AliasColl::AliasColl (): SortedCollection (25, 25, 1) { } DevAlias* AliasColl::At (int Index) // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING { // Check range if (Index < 0 || Index >= Count) { FAIL ("AliasColl::At: Index out of bounds"); return NULL; } return SortedCollection::At (Index); } /*****************************************************************************/ /* Data */ /*****************************************************************************/ static AliasColl AliasBase; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void CleanupNumber (String& Number) // Remove all non-digit characters from the given number { // Remove all non-digit characters from the number unsigned I = 0; while (I < Number.Len ()) { if (!IsDigit (Number [I])) { // No digit, delete it Number.Del (I, 1); } else { // Next char I++; } } } void NewAlias (String Number, const String& Alias) // Create a new number alias. { // Remove invalid digits CleanupNumber (Number); // If the number is empty now, return silently if (Number.IsEmpty ()) { return; } // Check if there is already an alias for this device int Index; if (AliasBase.Search (&Number, Index) != 0) { // OOPS - this should not happen. Print an error message ErrorMsg (FormatStr (LoadAppMsg (msDuplicateNumber).GetStr (), Number.GetStr ())); return; } // Create a new object instance DevAlias* DA = new DevAlias (Number, Alias); // Insert it into the AliasBase AliasBase.Insert (DA); } void NewAlias (unsigned char Dev, const String& Alias) // Create a new device alias. The valid range for dev is 21... { // Convert the device number to a string. Use a temporary variable // because gcc will not work correctly otherwise :-( String Number = U32Str (Dev); NewAlias (Number, Alias); } const String& GetAlias (String Number) // Return the alias of a number. Return an empty string if there is no alias. { // Remove invalid digits CleanupNumber (Number); // If the number is empty now, we do not have an alias if (Number.IsEmpty ()) { return EmptyString; } // Search for the entry int Index; if (AliasBase.Search (&Number, Index) == 0) { // No entry, return an empty string return EmptyString; } else { // Found, return the alias return AliasBase [Index]->Alias; } } const String& GetAlias (unsigned char Dev) // Return the alias of a device. Return an empty string if there is no alias. // The valid range for Dev is 21... { // Convert the device number to a string. Use a temporary variable // because gcc will not work correctly otherwise :-( String Number = U32Str (Dev); return GetAlias (Number); } void ReadAliasFile () // Delete all existing aliases and read in the aliasfile with the given name. // The function does nothing if there is nov external aliasfile defined. { // Bail out if there is no valid alias file name if (AliasFile.IsEmpty ()) { return; } // Delete all existing aliases AliasBase.DeleteAll (); // Try to open the file FILE* F = fopen (AliasFile.GetStr (), "rt"); if (F == NULL) { // OOPS, file open error ErrorMsg (LoadAppMsg (msOpenError)); return; } // Ok, file is open now, read it unsigned LineCount = 0; char Buf [512]; while (fgets (Buf, sizeof (Buf), F) != NULL) { // Got a new line LineCount++; // Put the line into a string and convert it to the internally used // character set String S (Buf); S.InputCvt (); // Delete the trailing newline if any int Len = S.Len (); if (Len > 0 && S [Len-1] == '\n') { Len--; S.Trunc (Len); } // Ignore empty and comment lines if (S.IsEmpty () || S [0] == ';') { continue; } // Set up a string parser for the string StringParser SP (S, StringParser::SkipWS); // Extract the first token (the number) String Number; if (SP.GetToken (Number) != 0) { // Error ErrorMsg (FormatStr (LoadAppMsg (msSyntaxError).GetStr (), LineCount)); continue; } // Remove all non-digit characters from the number CleanupNumber (Number); // The number must not be empty now if (Number.IsEmpty ()) { // Error ErrorMsg (FormatStr (LoadAppMsg (msSyntaxError).GetStr (), LineCount)); continue; } // Now get the alias String Alias; if (SP.GetString (Alias) != 0) { // Error ErrorMsg (FormatStr (LoadAppMsg (msSyntaxError).GetStr (), LineCount)); continue; } // Ok, done. Insert the alias into the alias database NewAlias (Number, Alias); } // Close the file fclose (F); } estic-1.61.orig/estic/icalias.h0100644000176100001440000000436107031424723015703 0ustar debacleusers/*****************************************************************************/ /* */ /* ICALIAS.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module holds aliases for devices #ifndef _ICALIAS_H #define _ICALIAS_H #include "str.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name of the alias file, default is the empty string extern String AliasFile; // If true, reread the alias file before trying to resolve call data extern int AutoReadAliases; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NewAlias (String Number, const String& Alias); // Create a new number alias. void NewAlias (unsigned char Dev, const String& Alias); // Create a new device alias. The valid range for dev is 21... const String& GetAlias (String Number); // Return the alias of a number. Return an empty string if there is no alias. const String& GetAlias (unsigned char Dev); // Return the alias of a device. Return an empty string if there is no alias. // The valid range for Dev is 21... void ReadAliasFile (); // Delete all existing aliases and read in the aliasfile with the given name // The function does nothing if there is no external aliasfile defined. // End of ICALIAS.H #endif estic-1.61.orig/estic/icbaseed.cc0100644000176100001440000005711407031424723016177 0ustar debacleusers/*****************************************************************************/ /* */ /* ICBASEED.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "cont.h" #include "progutil.h" #include "menue.h" #include "menuitem.h" #include "statline.h" #include "stdmenue.h" #include "stdmsg.h" #include "settings.h" #include "crcstrm.h" #include "memstrm.h" #include "icmsg.h" #include "icerror.h" #include "icconfig.h" #include "icident.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msExtLevel = MSGBASE_ICBASEED + 0; const u16 msNumberTooLong = MSGBASE_ICBASEED + 1; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void EditQueryLoc (IstecBaseConfig& Cfg) { // Name of the settings resource static const String StgPosName = "EditQueryLoc.Abfragestellen-Menue.Position"; // Remember the old config, remember the CRC u32 OldCRC = GetCRC (Cfg); MemoryStream SaveStream; SaveStream << Cfg; SaveStream.Seek (0); // Load the menue Menue* Win = (Menue*) LoadResource ("@ICBASEED.Abfragestellen-Menue"); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, Win->OuterBounds ().A); Win->MoveAbs (Pos); // Get pointers to the items LongItem* QL1 = (LongItem*) Win->ForcedItemWithID (1); LongItem* QL2 = (LongItem*) Win->ForcedItemWithID (2); // Transfer data into the menue QL1->SetValue (Cfg.QueryLoc1); QL2->SetValue (Cfg.QueryLoc2); // Set the limits QL1->SetMinMax (21, 20 + Cfg.DevCount); QL2->SetMinMax (21, 20 + Cfg.DevCount); // Activate the menue Win->Activate (); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // Edit the menue int Done = 0; while (!Done) { // Get a selection switch (Win->GetChoice ()) { case 1: Cfg.QueryLoc1 = QL1->GetValue (); break; case 2: Cfg.QueryLoc2 = QL2->GetValue (); break; case 0: // Check the abort key if (Win->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (GetCRC (Cfg) != OldCRC) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes, reload the data from the stream SaveStream >> Cfg; Done = 1; } } else { // No changes Done = 1; } } else if (Win->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } break; } } // Save the current window position StgPutPoint (Win->OuterBounds ().A, StgPosName); // Pop statusline, delete the menue PopStatusLine (); delete Win; } static void EditMSN (IstecBaseConfig& Config) // Edit the MSN's { // Name of the settings resource static const String StgPosName = "EditMSN.MSN-Eingabemenue.Position"; // Remember the old config, remember the CRC u32 OldCRC = GetCRC (Config); MemoryStream SaveStream; SaveStream << Config; SaveStream.Seek (0); // Load the menue Menue* Win = (Menue*) LoadResource ("@ICBASEED.MSN-Eingabemenue"); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, Win->OuterBounds ().A); Win->MoveAbs (Pos); // Transfer data into the menue for (unsigned I = 0; I < 10; I++) { Win->SetStringValue (I+1, FromBCD (Config.MSN [I], sizeof (Config.MSN [I]))); } // Activate the menue Win->Activate (); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // Edit the menue int Done = 0; while (!Done) { // Get a selection int Choice = Win->GetChoice (); // const char* S; switch (Choice) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: S = Win->GetStringValue (Choice).GetStr (); ToBCD (S, Config.MSN [Choice-1], sizeof (Config.MSN [0])); break; case 0: if (Win->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (GetCRC (Config) != OldCRC) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes, reload the data from the stream SaveStream >> Config; Done = 1; } } else { // No changes Done = 1; } } else if (Win->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } break; } } // Save the current window position StgPutPoint (Win->OuterBounds ().A, StgPosName); // Pop statusline, delete the menue PopStatusLine (); delete Win; } static void EditMSNGroups (IstecBaseConfig& Cfg, const String& ResName) // Edit the MSN or EAZ grouping { // Name of the settings resource const String StgPosName = "EditMSNGroups." + ResName + ".Position"; // Load the menue Menue* M = (Menue*) LoadResource (ResName); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, M->OuterBounds ().A); M->MoveAbs (Pos); // Make a copy of the MSN groups unsigned char OldGroups [sizeof (Cfg.MSNGroups)]; memcpy (OldGroups, Cfg.MSNGroups, sizeof (OldGroups)); // Set up the menue for (unsigned I = 0; I < 10; I++) { // Set the MSN if the item for the MSN is available (otherwise it is // the EAZ grouping menue which has no MS numbers to show) StringItem* Item = (StringItem*) M->ItemWithID (1000 + I); if (Item != NULL) { String MSN = FromBCD (Cfg.MSN [I], sizeof (Cfg.MSN [I])); Item->SetItemText (Item->GetItemText () + " (" + MSN + ")"); } // Set the grouping unsigned Mask = 0x01; for (unsigned J = 0; J < 8; J++) { M->SetToggleValue (I*16+J*2+1, (Cfg.MSNGroups [I] & Mask) != 0); Mask <<= 1; } } // New statusline PushStatusLine (siAbort | siAccept | siSelectKeys | siChange); // Activate the menue M->Activate (); // Allow editing int Done = 0; while (!Done) { // Get a selection unsigned Sel = M->GetChoice (); // Check for abort if (Sel == 0) { if (M->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (memcmp (OldGroups, Cfg.MSNGroups, sizeof (OldGroups)) != 0) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes memcpy (Cfg.MSNGroups, OldGroups, sizeof (OldGroups)); Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } } else { unsigned MSN = (Sel - 1) / 16; unsigned Mask = 0x01 << (((Sel - 1) % 16) / 2); if (Sel & 0x0001) { // Switch off Cfg.MSNGroups [MSN] &= ~Mask; } else { // Switch on Cfg.MSNGroups [MSN] |= Mask; } } } // Old status line PopStatusLine (); // Save the current window position StgPutPoint (M->OuterBounds ().A, StgPosName); // Discard the menue delete M; } static void EditSignaling (IstecBaseConfig& Cfg, const Point& Pos) // Edit the signal types for the different MSN's { // Load the menue Menue* M = (Menue*) LoadResource ("@ICBASEED.MSN-Rufsignale"); // Move the menue near to the given position M->PlaceNear (Pos); // Make a copy of the MSN signaling unsigned char OldSignaling [sizeof (Cfg.Signaling)]; memcpy (OldSignaling, Cfg.Signaling, sizeof (Cfg.Signaling)); // Set up the menue for (unsigned I = 0; I < bcMSNCount; I++) { // Put the MSN into the name ToggleItem* T = (ToggleItem*) M->ItemWithID ((I+1) * 10); String MSN = FromBCD (Cfg.MSN [I], sizeof (Cfg.MSN [I])); T->SetItemText (T->GetItemText () + " (" + MSN + ")"); T->SetValue (Cfg.Signaling [I]); } // New statusline PushStatusLine (siAbort | siAccept | siSelectKeys | siChange); // Activate the menue M->Activate (); // Allow editing int Done = 0; while (!Done) { // Get a selection unsigned Sel = M->GetChoice (); // Check for abort if (Sel == 0) { if (M->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (memcmp (OldSignaling, Cfg.Signaling, sizeof (OldSignaling)) != 0) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes memcpy (Cfg.Signaling, OldSignaling, sizeof (OldSignaling)); Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } } else { // A value has changed unsigned MSN = (Sel / 10) - 1; unsigned Val = Sel % 10; Cfg.Signaling [MSN] = Val; } } // Old status line PopStatusLine (); // Discard the menue delete M; } void LoadConfigDefault (IstecConfig& Config, unsigned IstecType) // Load the default parameter settings for the given istec type. { // Construct the resource name String ResName = FormatStr ("@ICBASEED.Default-%u", IstecType); // Load the container with the default data Container* C = (Container*) LoadResource (ResName); // Get a pointer to the data. Cast to char*. const unsigned char* Data = (const unsigned char*) C->GetData (); // Copy the data for both config structs. Data is always in old format! Config.BaseConfig.Unpack (Data); Data += 93; for (unsigned I = 0; I < Config.GetDevCount (); I++) { Config.GetDevConfig (I).Unpack (Data, 1.7); Data += 17; } // Discard the container delete C; } static unsigned NewIstecType (WindowItem* Item) // Get a new istec type { // Load the menue Menue* M = (Menue*) LoadResource ("@ICBASEED.TypeMenue"); // Place it near the item M->PlaceNear (Item); // Get a choice unsigned Sel = M->GetChoice (); // Delete the menue delete M; // Return the selection return Sel; } void EditBaseConfig (IstecConfig& Config, int IstecPresent, int& Changed) // Allow editing the istec base configuration. If the istec is not present, // the type of the istec can be changed, resulting in a load of the default // for this istec type. If Config has been changed, Changed is set to 1, // otherwise, Changed is left untouched. { // ID's of menue items for EditBaseConfig const miIstecType = 10; const miProtocol = 20; const miExtLevel = 30; const miMusic = 40; const miConnection = 50; const miNumber1 = 60; const miNumber2 = 70; const miTFEAssignment = 80; const miQueryLoc = 90; const miMSN = 100; const miMSNGroups = 110; const miEAZGroups = 120; const miExternalMusicPort = 130; const miCountryCode = 140; const miSignaling = 150; // Values for the miMusic toggle item const musOff = 0; const musInternal = 1; const musExternal = 2; // Name of the settings resource static const String StgPosName = "EditBaseConfig.BaseConfigMenue.Position"; // Remember the configuration (save it into a memory stream). Remember // the old CRC. u32 OldCRC = GetCRC (Config); MemoryStream SaveStream; SaveStream << Config; SaveStream.Seek (0); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // INitialize variables needed below int Done = 0; int NeedConfig = 1; unsigned IstecType = 0; // Initialize it to make gcc happy LongItem* ExternalMusicPort = NULL; Menue* Win = NULL; // Loop... while (!Done) { if (NeedConfig) { // If there is a menue, store the current position into the // settings, then delete it if (Win != NULL) { // Save the current window position StgPutPoint (Win->OuterBounds ().A, StgPosName); delete Win; } // Reload the window from the resource if (FirmwareVersion < 1.93) { Win = (Menue*) LoadResource ("@ICBASEED.BaseConfigMenue-1.92"); } if (FirmwareVersion < 2.00) { Win = (Menue*) LoadResource ("@ICBASEED.BaseConfigMenue-1.93"); } else { Win = (Menue*) LoadResource ("@ICBASEED.BaseConfigMenue-2.00"); } // If there is a stored window position, move the window to that // position Point Pos = StgGetPoint (StgPosName, Win->OuterBounds ().A); Win->MoveAbs (Pos); // Get the type of the istec IstecType = Config.IstecID (); // Transfer data into the menue Win->SetStringValue (miIstecType, GetIstecName (IstecType)); Win->SetToggleValue (miProtocol, Config.GetProtocol () != pr1TR6); ExternalMusicPort = (LongItem*) Win->ItemWithID (miExternalMusicPort); if (ExternalMusicPort == NULL) { Win->SetToggleValue (miMusic, Config.GetMusic () != 0); } else { if (Config.GetMusic () != 0) { Win->SetToggleValue (miMusic, musInternal); Win->GrayItem (miExternalMusicPort); } else { if (Config.GetMusicPort () == 0) { Win->SetToggleValue (miMusic, musOff); ExternalMusicPort->SetValue (21); Win->GrayItem (miExternalMusicPort); } else { Win->SetToggleValue (miMusic, musExternal); ExternalMusicPort->SetValue (Config.GetMusicPort () + 20); } } } Win->SetToggleValue (miConnection, Config.GetConnection () != coPointToMulti); Win->SetStringValue (miNumber1, Config.GetNumber1 ()); Win->SetStringValue (miNumber2, Config.GetNumber2 ()); Win->SetLongValue (miTFEAssignment, Config.GetTFEAssignment ()); if (Win->ItemWithID (miCountryCode) != NULL) { Win->SetLongValue (miCountryCode, Config.GetCountryCode ()); } // Enable/disable menue items dependent on the system if (IstecPresent) { Win->GrayItem (miIstecType); } if (Config.GetProtocol () == pr1TR6) { Win->GrayItem (miMSN); Win->GrayItem (miMSNGroups); } else if (Config.GetProtocol () == prDSS1) { Win->GrayItem (miEAZGroups); } switch (IstecType) { case 1003: case 1008: if (IstecPresent) { // Protocol is hard wired in the istec Win->GrayItem (miProtocol); } Win->GrayItem (miExtLevel); if (Config.GetConnection () == coPointToMulti) { Win->GrayItem (miNumber1); } Win->GrayItem (miNumber2); Win->GrayItem (miQueryLoc); break; case 1016: Win->GrayItem (miConnection); Win->GrayItem (miNumber2); break; case 1024: Win->GrayItem (miExtLevel); Win->GrayItem (miConnection); Win->GrayItem (miNumber2); break; case 2016: Win->GrayItem (miConnection); break; case 2024: Win->GrayItem (miExtLevel); Win->GrayItem (miConnection); break; case 2400: Win->GrayItem (miExtLevel); if (Config.GetConnection () == coPointToMulti) { Win->GrayItem (miNumber1); Win->GrayItem (miNumber2); } break; case 2416: Win->GrayItem (miConnection); break; case 2424: Win->GrayItem (miExtLevel); Win->GrayItem (miConnection); break; } // Activate the menue Win->Activate (); // Config done NeedConfig = 0; } // Get a selection int Choice = Win->GetChoice (); // String Num; unsigned NewType; switch (Choice) { case miIstecType: NewType = NewIstecType (Win->ItemWithID (miIstecType)); if (NewType != 0 && NewType != IstecType) { // Got a new selection, load the default NeedConfig = 1; LoadConfigDefault (Config, NewType); } break; case miProtocol: Config.BaseConfig.Protocol = pr1TR6; Win->GrayItem (miMSN); Win->GrayItem (miMSNGroups); Win->ActivateItem (miEAZGroups); break; case miProtocol+1: Config.BaseConfig.Protocol = prDSS1; Win->ActivateItem (miMSN); Win->ActivateItem (miMSNGroups); Win->GrayItem (miEAZGroups); break; case miExtLevel: InformationMsg (LoadAppMsg (msExtLevel)); break; case miMusic+musOff: Config.BaseConfig.Music = 0; Config.BaseConfig.MusicPort = 0; if (ExternalMusicPort != NULL) { Win->GrayItem (miExternalMusicPort); } break; case miMusic+musInternal: Config.BaseConfig.Music = 1; if (ExternalMusicPort != NULL) { Win->GrayItem (miExternalMusicPort); } break; case miMusic+musExternal: Config.BaseConfig.Music = 0; Config.BaseConfig.MusicPort = Win->GetLongValue (miExternalMusicPort) - 20; Win->ActivateItem (miExternalMusicPort); break; case miConnection: Config.BaseConfig.Connection = coPointToMulti; Win->GrayItem (miNumber1); Win->GrayItem (miNumber1); break; case miConnection+1: Config.BaseConfig.Connection = coPointToPoint; Win->ActivateItem (miNumber1); if (Config.GetExtS0 () > 1) { Win->ActivateItem (miNumber2); } break; case miNumber1: Config.SetNumber1 (Win->GetStringValue (miNumber1)); break; case miNumber2: Config.SetNumber2 (Win->GetStringValue (miNumber2)); break; case miTFEAssignment: Config.BaseConfig.TFEAssignment = Win->GetLongValue (miTFEAssignment); break; case miQueryLoc: EditQueryLoc (Config.BaseConfig); break; case miMSN: EditMSN (Config.BaseConfig); break; case miMSNGroups: EditMSNGroups (Config.BaseConfig, "@ICBASEED.MSN-GruppenMenue"); break; case miEAZGroups: EditMSNGroups (Config.BaseConfig, "@ICBASEED.EAZ-GruppenMenue"); break; case miExternalMusicPort: Config.BaseConfig.MusicPort = Win->GetLongValue (miExternalMusicPort) - 20; break; case miCountryCode: Config.BaseConfig.CountryCode = Win->GetLongValue (miCountryCode); break; case miSignaling: { Point Pos = Win->ForcedItemWithID (miSignaling)->Pos (); Win->Absolute (Pos); EditSignaling (Config.BaseConfig, Pos); } break; case 0: if (Win->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (GetCRC (Config) != OldCRC) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes, reload the data from the stream SaveStream >> Config; Done = 1; } } else { // No changes Done = 1; } } else if (Win->GetAbortKey () == vkAccept) { // Accept the changes, set the Changed flag if (GetCRC (Config) != OldCRC) { // We have changes Changed = 1; } Done = 1; } break; } } // Delete the menue, restore old statusline delete Win; PopStatusLine (); } estic-1.61.orig/estic/icbaseed.h0100644000176100001440000000316107031424723016032 0ustar debacleusers/*****************************************************************************/ /* */ /* ICBASEED.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICBASEED_H #define _ICBASEED_H #include "icconfig.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ void LoadConfigDefault (IstecConfig& Config, unsigned IstecType); // Load the default parameter settings for the given istec type. void EditBaseConfig (IstecConfig& Config, int IstecPresent, int& Changed); // Allow editing the istec base configuration. If the istec is not present, // the type of the istec can be changed, resulting in a load of the default // for this istec type. If Config has been changed, Changed is set to 1, // otherwise, Changed is left untouched. // End of ICBASEED.H #endif estic-1.61.orig/estic/iccli.cc0100644000176100001440000001014607031424724015516 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCLI.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Calling line identification stuff #include "chartype.h" #include "national.h" #include "progutil.h" #include "icevents.h" #include "icalias.h" #include "icac.h" #include "iccli.h" /*****************************************************************************/ /* class CLI */ /*****************************************************************************/ String CLI::LogMsg () // Return a log message for the CLI { String Msg (80); // Convert date and time and pad them to the correct length Msg += T.DateStr().Pad (String::Right, 10); Msg += " "; Msg += T.TimeStr().Pad (String::Right, 8); Msg += " "; // Pad the incoming number String Phone = Number; Msg += Phone.Pad (String::Right, 20); Msg += " "; // Create the additional info. If we have an alias, use it for the // additional info. If we don't have an alias, use the prefix info String S = Alias; if (S.IsEmpty ()) { S = AreaCodeInfo; } Msg += S.Trunc (34); // Return the complete line return Msg; } /*****************************************************************************/ /* Code */ /*****************************************************************************/ void HandleCLIMsg (const unsigned char* Data, unsigned Size) // Handle a CLI message { // Do some checks PRECONDITION (Size >= 6); // Create a new CLI object CLI* C = new CLI; // Extract the info fields C->TypeOfNumber = Data [3] - '0'; C->PresInd = Data [4] - '0'; // If we have a number, handle it if (C->PresInd == piPresAllowed) { // Copy the number from the given data into the string. To avoid problems // with garbage characters, and to handle the FF/CR trailer, drop all // control characters. for (unsigned I = 5; I < Size; I++) { char Digit = (char) Data [I]; if (!IsCntrl (Digit)) { C->Number += Digit; } } // Make a universal number (include the country code if needed) String Phone = C->Number; if (C->TypeOfNumber == ntNational) { // Add a leading dial prefix to the number (for display) C->Number.Ins (0, DialPrefix); } else if (C->TypeOfNumber == ntInternational) { // Add two dial prefixes const char Prefix [3] = { DialPrefix, DialPrefix }; C->Number.Ins (0, Prefix); } // Get the areacode info from the number unsigned AreaCodeLen; C->AreaCodeInfo = IstecGetAreaCodeInfo (C->Number, AreaCodeLen); // Get the number alias. if (AutoReadAliases) { ReadAliasFile (); } C->Alias = GetAlias (C->Number); // If we have an areacode info, we can insert a '/' in the correct place. if (AreaCodeLen > 0) { C->Number.Ins (AreaCodeLen, '/'); } } // Create the log message for the incoming call String Msg = C->LogMsg (); // Post an event with the CLI object as parameter, THIS WILL DELETE IT! PostEvent (evIncomingCall, C); // Post an event with the log message PostEvent (evIncomingLogMsg, new String (Msg)); } estic-1.61.orig/estic/iccli.h0100644000176100001440000000532507031424724015363 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCLI.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Calling line identification stuff #ifndef _ICCLI_H #define _ICCLI_H #include "datetime.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Constants for the TypeOfNumber field const unsigned ntUnknown = 0; const unsigned ntInternational = 1; const unsigned ntNational = 2; const unsigned ntNetworkDependent = 3; const unsigned ntClientSpecific = 4; const unsigned ntInvalid = 6; const unsigned ntReserved = 9; // Constants for the "PresInd" field const unsigned piPresAllowed = 0; const unsigned piPresRestricted = 1; const unsigned piNoNumber = 2; /*****************************************************************************/ /* class CLI */ /*****************************************************************************/ class CLI: public Object { public: String Number; // Calling partys number String AreaCodeInfo; // Info on prefix String Alias; // Alias for the given number unsigned TypeOfNumber; unsigned PresInd; // Presentation indicatior Time T; // Time of call public: String LogMsg (); // Return a log message for the CLI }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void HandleCLIMsg (const unsigned char* Data, unsigned Size); // Handle a CLI message // End of ICCLI.H #endif estic-1.61.orig/estic/iccom.cc0100644000176100001440000010431507031424724015527 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCOM.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "check.h" #include "delay.h" #include "sercom.h" #include "circbuf.h" #include "progutil.h" #include "icmsg.h" #include "icevents.h" #include "icconfig.h" #include "istecmsg.h" #include "icdlog.h" #include "icdiag.h" #include "iccli.h" #include "iccti.h" #include "iccom.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Port address and irq used unsigned PortBase = 0; unsigned PortIRQ = 0; // Flag for short or long wait after sending a message int ShortWaitAfterMsg = 1; // Counter for enabling/disabling diag mode static int DiagModeCounter = 1; // Version of the config program (for firmware 2.0 and above) unsigned char ConfigVersionHigh = 2; unsigned char ConfigVersionLow = 0; // Current ISTEC charges IstecCharges Charges; // Some flags that are used when we receive config or charge messages static int ChargeUpdate = 0; //static int BaseConfigUpdate = 0; //static int DevConfigUpdate = 0; // Com port instance static ComPort* Port = NULL; // Variables for the read routine static enum { stIdle, // No current message stInBlock, // Currently reading a block stGotBlock, // Got a complete block stInLastBlock, // Currently reading the last block of a msg stFillBytes // Reading the fill bytes of the last block } ICReadStat = stIdle; // Buffers and counters static unsigned ICBlockCount = 0; static unsigned ICReadCount = 0; static unsigned ICFillCount = 0; static unsigned ICMsgCount = 0; static unsigned char ICReadBuf [512]; // The last non diag message received static IstecMsg* LastIstecMsg = NULL; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class CircularBuffer; #endif /*****************************************************************************/ /* Com port related code */ /*****************************************************************************/ void CloseComPort () // Close the com port { if (Port) { if (Port->IsOpen ()) { // Switch off DTR Port->DTROff (); } // Delete the port object delete Port; Port = NULL; } } int OpenComPort (const String& PortName) // Try to open the com port. If the port is already open, it is closed and // reopened. The function returns 0 on success and an error code on failure. { // Close the port in case it is open CloseComPort (); // Ok, now reopen it. Use 9600 8N1 without handshaking Port = new ComPort (PortName, 9600, 8, 'N', 1, 'D', 'D', PortBase, PortIRQ); int Result = Port->Open (); if (Result != 0) { // Error, maybe the device does not exist or is already in use CloseComPort (); return Result; } // Set the timeout value for sending and receiving Port->SetRXTimeout (3.0); Port->SetTXTimeout (3.0); // Make the RTS line active. This is needed for the new PCB of the istec // (beginning from version #3). Port->RTSOn (); // Success return 0; } int ComPortAvail () // Return 1 if the com port is open, 0 if not { return Port != NULL; } /*****************************************************************************/ /* Helper functions */ /*****************************************************************************/ static int MapCTIError (unsigned CTIError) // Map a CTI error to one of the ieXXX function return codes { switch (CTIError) { case CTI_RC_ERROR: return ieCTIError; case CTI_RC_INVALID_NUMBER: return ieCTIError; case CTI_RC_INVALID_SP_STELLE: return ieCTIError; case CTI_RC_INVALID_CHANNEL: return ieCTIError; case CTI_RC_INVALID_DAY_NIGHT: return ieCTIError; case CTI_RC_EEPROM_IN_USE: return ieEEPROMInUse; case CTI_RC_DAY_NIGHT_CHANGED: return ieDone; case CTI_RC_DEFAULT_VALUES: return ieCTIError; case CTI_RC_DAY_NIGHT_SAME: return ieDone; default: return ieCTIError; } } /*****************************************************************************/ /* Low level ISTEC specific code */ /*****************************************************************************/ static void UpdateCharges (const IstecMsg* Msg) // Copy the charges { // Unpack the new charges into the static area Charges.Unpack (&Msg->Data [1]); // We did receive a charge update ChargeUpdate = 1; // Post an appropriate event PostEvent (evChargeUpdate); } static void IstecWrite (const unsigned char* Msg, unsigned BufSize) // Recode the binary message into the istec format and send it via the port. { // A static buffer to hold outgoing messages static CircularBuffer MsgBuf; // Check the parameters PRECONDITION (Msg != NULL && BufSize > 0); // If the port is unavailable, we have nothing to do if (Port == NULL) { return; } // Create a message from the given data IstecMsg* IM = new IstecMsg (BufSize, Msg); // Insert the message into the output buffer MsgBuf.Put (IM, 0); // Now have a look at the semaphore variable. If it is already set, // someone is currently executing this code and will take care of // our message in the buffer. static int Running = 0; if (Running) { // Someone is alredy executing this routine return; } // No one executing, block it Running = 1; // Send all message in the buffer while (!MsgBuf.IsEmpty ()) { // Get the next message IstecMsg* IM = MsgBuf.Get (); // Determine the real message size from the message unsigned Size = SendMsgSize (IM->Data, IM->Size); // Log the outgoing message WriteDebugLog ("Outgoing: " + IM->AsciiData ()); // Get a pointer to the message data unsigned char* Msg = IM->Data; // Send the message char Buf [4]; // ## should be unsigned while (Size) { // Set up the length of the paket unsigned BytesToSend = Size > 3 ? 3 : Size; Size -= BytesToSend; // Time to wait after chunk (the times used here are the times the // ISTEC software uses: 40ms after a chunk and an additional 60ms // [making a total of 100ms] after the last chunk) unsigned DelayTime = 40; // Set up the header byte Buf [0] = BytesToSend; if (Size == 0) { // Last chunk, mark it Buf [0] |= 0x80; // If ShortWaitAfterMsg is *not* set, use the long delay to // give the istec time to swallow the command. if (!ShortWaitAfterMsg) { DelayTime = 100; } } // Copy parameter bytes unsigned I = 0; while (I < BytesToSend) { I++; Buf [I] = *Msg++; } // Fill rest with 0x00 while (I < sizeof (Buf) - 1) { I++; Buf [I] = '\0'; } // Send the paket for (I = 0; I < sizeof (Buf); I++) { if (Port->TimedSend (Buf [I]) == -1) { // Timeout WriteDebugLog ("Error: Timeout on outgoing message!"); // Try the next message break; } } if (DelayTime) { Delay (DelayTime); } } // Delete the message we've just sent delete IM; } // All messages sent. Reset the flag Running = 0; } static IstecMsg* IstecReadChar (unsigned char C) // Is called when a character is available on the serial line. According // to the status in ICReadStat, the character is handled. If the received // message is complete, a copy of the message is returned in a buffer allocated // with new. { // Check the status switch (ICReadStat) { case stIdle: case stGotBlock: // We got a complete block and are waiting for the header of a // new one. C contains the byte count of the new block. if (C & 0x80) { // This one is the last block ICReadStat = stInLastBlock; ICBlockCount = C & 0x7F; ICFillCount = 3 - ICBlockCount; } else { ICReadStat = stInBlock; ICBlockCount = C; } // If we get a block with an invalid block size, we are in // trouble (this may happen if we are connected to the wrong // port). Ignore the block and go back into idle state hoping // that a timeout will clear things. if (ICBlockCount == 0 || ICBlockCount > 3) { ICReadStat = stIdle; } break; case stInBlock: // We are currently reading a block. ICBlockCount contains the // count of outstanding characters for this block. Place the // received character into the receive buffer. if (ICReadCount < sizeof (ICReadBuf)) { ICReadBuf [ICReadCount++] = C; } ICBlockCount--; if (ICBlockCount == 0) { // Got that block ICReadStat = stGotBlock; } break; case stInLastBlock: // We are currently reading the last block. ICBlockCount contains // the count of outstanding characters for this block. Place the // received character into the receive buffer. if (ICReadCount < sizeof (ICReadBuf)) { ICReadBuf [ICReadCount++] = C; } ICBlockCount--; if (ICBlockCount == 0) { // Got that block. Receive fill bytes or end if (ICFillCount > 0) { ICReadStat = stFillBytes; } else { // Got a complete message ICReadStat = stIdle; ICMsgCount++; } } break; case stFillBytes: // We are reading the fill bytes of the last block. Ignore the // bytes and wait for the end of the message ICFillCount--; if (ICFillCount == 0) { // Got the fill bytes ICReadStat = stIdle; ICMsgCount++; } break; default: FAIL ("IstecReadChar: Invalid machine state"); break; } // Check if we did receive a complete message while (ICMsgCount > 0) { // Create an istec message from the buffer. Check if there is more than // one message in the buffer (this seems to be a bug in the istec // firmware) // If the proposed length is greater than the amount of bytes read, // we can only use what we have. If the proposed length is smaller, // assume that we received more than one message in a chunk and // use only part of the data. unsigned ProposedLen = RecMsgSize (ICReadBuf, ICReadCount); IstecMsg* IM; if (ProposedLen == ICReadCount) { // We received the amount of bytes, we expected. IM = new IstecMsg (ICReadCount, ICReadBuf); ICReadCount = 0; ICMsgCount = 0; } else if (ICReadCount > ProposedLen) { // We got more bytes than we expected. Assume that there is more // than one message in the chunk. Since we try to handle this // condition silently, we will not set an error code. String Msg = FormatStr ("Error: Message length does not match. " "Expected %d, got %d bytes: ", ProposedLen, ICReadCount); WriteDebugLog (Msg + AsciiData (ICReadBuf, ICReadCount)); // Create the message IM = new IstecMsg (ProposedLen, ICReadBuf); // Delete the bytes we read from the buffer but leave ICMsgCount // untouched since there are bytes left ICReadCount -= ProposedLen; memmove (ICReadBuf, &ICReadBuf [ProposedLen], ICReadCount); } else { // We got less byte then we expected. This is clearly an error as // we have not enough bytes to handle. String Msg = FormatStr ("Error: Message length does not match. " "Expected %d, got %d bytes: ", ProposedLen, ICReadCount); WriteDebugLog (Msg + AsciiData (ICReadBuf, ICReadCount)); // Create the message IM = new IstecMsg (ICReadCount, ICReadBuf); // Set the error code IM->SetError (ieRecBufUnderflow); // Delete the bytes we read from the buffer ICReadCount = 0; ICMsgCount = 0; } // Log the received message WriteDebugLog ("Incoming: " + IM->AsciiData ()); // Look for special messages and handle them directly (don't return // those messages to the caller) if (IM->IsDiagMsg ()) { // The message is a diagnostic message HandleDiagMsg (IM->Data); delete IM; IM = NULL; } else if (IM->IsCLIMsg ()) { // The message is a calling line information HandleCLIMsg (IM->Data, IM->Size); delete IM; IM = NULL; } else if (IM->IsChargeInfo ()) { // The message is a charge info message UpdateCharges (IM); delete IM; IM = NULL; } else { // Cannot handle the message - return it return IM; } } // No complete message left, return a NULL pointer return NULL; } static IstecMsg* IstecRead () // Read and return a complete message from the istec. { IstecMsg* IM; // Check if there is an already received message if (LastIstecMsg != NULL) { // There is an already received message - grab it IM = LastIstecMsg; LastIstecMsg = NULL; } else { // No message, try to receive one do { // Get a char with timeout int C = Port->TimedReceive (); if (C == -1) { // Timeout IM = new IstecMsg (0); IM->SetError (ieTimeout); return IM; } // Handle the char, receive a complete message if available IM = IstecReadChar (C); } while (IM == NULL); } // Return the message. return IM; } void IstecPoll () // Poll the istec for incoming diag messages. If we get a real message, store // it in LastIstecMsg (there should be only one outstanding real message at a // time). { // If we don't have a valid port, ignore the call if (Port == NULL) { return; } // Handle all characters in the receive queue unsigned Count; while ((Count = Port->RXCount ()) > 0) { while (Count--) { // Get a char and handle it int C = Port->TimedReceive (); CHECK (C != -1); IstecMsg* IM = IstecReadChar (C); // If we have a message, save it into the message buffer if (IM) { // This is not a diagnose message. As we have only room to // buffer one message, delete the buffer contents before // storing (can happen only if the ISTEC does not work // correctly, ESTIC should not crash because of that). if (LastIstecMsg) { // OOPS - there is a message already waiting WriteDebugLog ("Error: Overwriting waiting message: " + AsciiData (LastIstecMsg->Data, LastIstecMsg->Size)); delete LastIstecMsg; } LastIstecMsg = IM; } } } } static int IstecReadAck (unsigned char Ack) // Wait for an ack from the istec { // Assume no errors // Wait for the acknowledgement IstecMsg* Reply = IstecRead (); int RetCode = Reply->GetError (); if (RetCode == ieDone) { // We received the message successfully, check the ack code if (Reply->At (0) != Ack) { // OOPS - got wrong answer WriteDebugLog (FormatStr ("Error: Got wrong ACK: Expected 0x%02X, got 0x%02X", Ack, Reply->At (0))); RetCode = ieInvalidReply; } } // Delete the message and return the result delete Reply; return RetCode; } /*****************************************************************************/ /* High level ISTEC specific code */ /*****************************************************************************/ void IstecErrorSync () // Try to resync the istec after an error { // First, wait some time. IstecPoll will be called in this time Delay (250); // Call IstecPoll to fetch all characters that are currently in the // incoming buffer. IstecPoll (); // If we have a waiting message now, throw it away if (LastIstecMsg) { // Log the facts WriteDebugLog ("ErrorSync: Killing waiting message: " + LastIstecMsg->AsciiData ()); // Delete the message delete LastIstecMsg; LastIstecMsg = NULL; } } int IstecReady () // Check if the istec answers the "Ready" message. { // Old firmware versions expect one byte here, newer version (2.0 and // above) expect three bytes. It seems as if the old versions ignore // additional bytes, so I will send three bytes in any case. This must // be changed if there are problems. unsigned char Msg [3] = { 0x02 }; // Put the version into bytes 1 and 2 Msg [1] = ConfigVersionHigh; Msg [2] = ConfigVersionLow; // Send the command to the istec IstecWrite (Msg, sizeof (Msg)); // Ok, now wait for the reply return IstecReadAck (0x12); } void IstecRequestCharges () // Request the device charges from the istec. This function is different from // the "Get" functions as it does not wait for a reply. The charge messages // from the ISTEC are handled by the IstecPoll function in the background. // If new charges are available, they are passed to the function NewChargeInfo // of the application object. { // ISTEC Command static unsigned char Msg [1] = { 0x06 }; // Send the command to the istec IstecWrite (Msg, sizeof (Msg)); } int IstecGetCharges () // Get the device charges from the istec. This function calls the "Request" // function and waits until a timeout occurs or we get a reply. { // Reset the flag ChargeUpdate = 0; // Send the command to the istec IstecRequestCharges (); // Wait for the new charges unsigned I = 0; do { Delay (200); } while (++I < 10 && ChargeUpdate == 0); // Check for a timeout if (ChargeUpdate == 0) { // Timeout, return an error code return ieTimeout; } else { return ieDone; } } void IstecPutCharges (const IstecCharges& NewCharges) // Write the given charges to the istec { // First byte is opcode, charges are parameters unsigned char Buf [ChargeSize + 1]; Buf [0] = 0x05; NewCharges.Pack (&Buf [1]); // Write it out if (FirmwareVersion < 2.00) { // Old versions write charges for 64 devices IstecWrite (Buf, 1 + 64 * sizeof (u16)); } else { // New versions write charges for 8 devices IstecWrite (Buf, 1 + 8 * sizeof (u16)); } // Use the new charges Charges = NewCharges; // Post an appropriate event PostEvent (evChargeUpdate); } static int IstecGetDevConfig (IstecConfig& Config) // Request the device configurations from the istec. { // ISTEC Command static unsigned char Msg [1] = { 0x08 }; // Send the command to the istec IstecWrite (Msg, sizeof (Msg)); // Determine how many device infos come from the istec. Note: this depends // on the firmware version! unsigned DevCount = FirmwareVersion < 1.93? IstecDevCount : Config.GetDevCount (); // Ok, now we get many replys for (unsigned I = 0; I < DevCount; I++) { IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); // If the return code is ok, check the message code if (Result == ieDone) { // Check the return message code if (Reply->At (0) != 0x16) { WriteDebugLog ("Error: Got invalid reply on request 0x08: " + Reply->AsciiData ()); Result = ieInvalidReply; } else { // Ok, we got the answer from the istec. Copy the data into the config // struct Config.UnpackDevConfig (*Reply); } } // Delete the message delete Reply; // If the return code is not ok, bail out if (Result != ieDone) { return Result; } } // Got it return ieDone; } static int IstecGetBaseConfig (IstecConfig& Config) // Request the basic configuration from the istec. { // ISTEC Command static unsigned char Msg [1] = { 0x0A }; // Send the command to the istec IstecWrite (Msg, sizeof (Msg)); // Ok, now wait for the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the return message opcode if (Reply->At (0) != 0x17) { WriteDebugLog ("Error: Got invalid reply on request 0x0A: " + Reply->AsciiData ()); Result = ieInvalidReply; } else { // Ok, we got the answer from the istec. Copy the data into the config // struct, update the save firmware version from the istec data and // return a success code to the caller Config.UnpackBaseConfig (*Reply); FirmwareVersion = Config.GetFirmwareVersion(); } } // Delete the message, return the result code delete Reply; return Result; } int IstecGetConfig (IstecConfig& Config) // Get the complete configuration from the istec { int Result; // Read the base configuration if ((Result = IstecGetBaseConfig (Config)) != ieDone) { return Result; } // Read the device configurations if ((Result = IstecGetDevConfig (Config)) != ieDone) { return Result; } // Ok, all done return ieDone; } static int IstecPutDevConfig (const IstecConfig& Config) // Write a set of device configuration data to the istec. { unsigned DevCount = Config.GetDevCount (); for (unsigned I = 0; I < DevCount; I++) { int Result; // Set up the command unsigned char Buf [DevConfigSize + 1]; Buf [0] = 0x07; Config.PackDevConfig (I, &Buf [1]); // Write it out IstecWrite (Buf, sizeof (Buf)); // Wait for the reply IstecMsg* Reply = IstecRead (); Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (Reply->At (0) != 0x18) { Result = ieInvalidReply; } else if (Reply->At (1) != I) { // Reply has the wrong device number Result = ieWrongDevice; } } // Delete the message delete Reply; // Bail out if we had an error if (Result != ieDone) { return Result; } } // Ok, all done return ieDone; } static void IstecPutBaseConfig (const IstecConfig& Config) // Write a base configuration to the istec { unsigned char Buf [BaseConfigSize + 1]; // First byte is opcode, base config is parameter Buf [0] = 0x09; Config.PackBaseConfig (&Buf [1]); // Write it out IstecWrite (Buf, sizeof (Buf)); } static int IstecMakePermanent () // Send the command to the istec to store the current configuration into the // EEPROM. { // Send the command static unsigned char Msg [1] = { 0x0C }; IstecWrite (Msg, sizeof (Msg)); // Wait for the acknowledgement return IstecReadAck (0x11); } int IstecPutConfig (const IstecConfig& Config) // Write the complete configuration to the istec and make it permanent. To // make things short, the number of devices is given as an parameter { int Result; // According to Norbert Richter, the firmware version 2.0 needs an // "are you there" request *immidiately* before storing the base // configuration, otherwise data that is present only in version 2.0 // will not be stored in EEPROM. if (FirmwareVersion >= 2.0) { if ((Result = IstecReady ()) != ieDone) { return Result; } } // Write the base configuration (there's no return code for this one) IstecPutBaseConfig (Config); // Write the device configurations if ((Result = IstecPutDevConfig (Config)) != ieDone) { return Result; } // Make the changes permanent if ((Result = IstecMakePermanent ()) != ieDone) { return Result; } // Ok, all done return ieDone; } int IstecGetShortNumbers (ShortNumberColl& ShortNumbers) // Read the short numbers from the istec. The function may not be called if // the firmware version is < 2.00! { PRECONDITION (FirmwareVersion >= 2.00); unsigned char Buf [5] = { CTI_START, CTI_QUERY, CTI_LOAD_NUMBER, 0, CTI_STOP }; for (int I = 0; I < ShortNumbers.GetCount (); I++) { // Get a pointer to the info ShortNumberInfo* Info = ShortNumbers [I]; // Insert the memory address into the message Buf [3] = Info->GetMemory (); // Send the message IstecWrite (Buf, sizeof (Buf)); // Get the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (!Reply->IsCTIMsg ()) { Result = ieInvalidReply; } else if (Reply->At (1) != CTI_ACK || Reply->At (2) != CTI_LOAD_NUMBER || Reply->At (3) != Info->GetMemory ()) { Result = ieCTIError; } else { // We got a valid reply, put it into the info struct Info->Unpack (*Reply); } } // Delete the message delete Reply; // Bail out if we had an error if (Result != ieDone) { return Result; } } // Success return ieDone; } int IstecPutShortNumbers (const ShortNumberColl& ShortNumbers) // Store the short numbers into the istec. The function may not be called if // the firmware version is < 2.00! { PRECONDITION (FirmwareVersion >= 2.00); for (int I = 0; I < ShortNumbers.GetCount (); I++) { // Get a pointer to the info const ShortNumberInfo* Info = ShortNumbers [I]; // Create a message from the info IstecMsg Msg (0); Info->Pack (Msg); // Send the message IstecWrite (Msg.Data, Msg.Size); // Get the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (!Reply->IsCTIMsg ()) { Result = ieInvalidReply; } else if (Reply->At (1) != CTI_ACK || Reply->At (2) != CTI_STORE_NUMBER || Reply->At (3) != CTI_STOP) { Result = ieCTIError; } } // Delete the message delete Reply; // Bail out if we had an error if (Result != ieDone) { return Result; } } // Success return ieDone; } int IstecGetDayNight (unsigned& DayNight) // Read the day/night setting from the istec. If the current firmware does // not support this, return CTI_VAL_DAY, else return the setting { static const unsigned char Msg [4] = { CTI_START, CTI_QUERY, CTI_DAY_NIGHT, CTI_STOP }; // Set the DayNight flag to day, in case an error occurs DayNight = CTI_VAL_DAY; // Check for firmware < 2.0 if (FirmwareVersion < 2.0) { // Return day return ieDone; } // Send the message IstecWrite (Msg, sizeof (Msg)); // Get the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (!Reply->IsCTIMsg ()) { Result = ieInvalidReply; } else if (Reply->Size != 5 || Reply->At (1) != CTI_ACK || Reply->At (2) != CTI_DAY_NIGHT || Reply->At (4) != CTI_STOP) { Result = ieCTIError; } else { // This is a valid message, retrieve the day/night setting DayNight = Reply->At (3)? 1 : 0; } } // Delete the message delete Reply; // Return the result of the operation return Result; } int IstecPutDayNight (unsigned DayNight) // Set the active configuration. If the current firmware does not support // this, ignore the command (return ieDone). { unsigned char Msg [5] = { CTI_START, CTI_CONF, CTI_DAY_NIGHT, 0, CTI_STOP }; // Check for firmware < 2.0 if (FirmwareVersion < 2.0) { // Nothing to do return ieDone; } // Put the value into the message Msg [3] = DayNight? CTI_VAL_NIGHT : CTI_VAL_DAY; // Send the message IstecWrite (Msg, sizeof (Msg)); // Get the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (!Reply->IsCTIMsg ()) { Result = ieInvalidReply; } else if (Reply->Size != 5 || Reply->At (1) != CTI_ACK || Reply->At (2) != CTI_DAY_NIGHT || Reply->At (4) != CTI_STOP) { Result = ieCTIError; } else { Result = MapCTIError (Reply->At (3)); } } // Delete the message delete Reply; // Return the result of the operation return Result; } int IstecPutAlarm (unsigned Alarm) // Set the alarm byte. If the current firmware does not support this, ignore // the command (return ieDone). { unsigned char Msg [5] = { CTI_START, CTI_CONF, CTI_ALARM, CTI_VAL_ALARM_OFF, CTI_STOP }; // Check for firmware < 2.0 if (FirmwareVersion < 2.0) { // Nothing to do return ieDone; } // Put the value into the message Msg [3] = (unsigned char) Alarm; // Send the message IstecWrite (Msg, sizeof (Msg)); // Get the reply IstecMsg* Reply = IstecRead (); int Result = Reply->GetError (); if (Result == ieDone) { // Check the reply if (!Reply->IsCTIMsg ()) { Result = ieInvalidReply; } else if (Reply->Size != 4 || Reply->At (1) != CTI_ACK || Reply->At (2) != CTI_ALARM || Reply->At (3) != CTI_STOP) { Result = ieCTIError; } } // Delete the message delete Reply; // Return the result of the operation return Result; } static void IstecDiagOn () // Switch the istec into diag mode { static unsigned char Msg [6] = { 0xdd, 0x00, 0x69, 0x5a, 0x96, 0xa5 }; IstecWrite (Msg, sizeof (Msg)); } static void IstecDiagOff () // Disable diag mode { static unsigned char Msg [6] = { 0xdd, 0x01, 0x00, 0x00, 0x00, 0x00 }; IstecWrite (Msg, sizeof (Msg)); } void EnableDiagMode () // This will decrement the diag mode counter. If it is zero, the command for // diag mode enable will be sent to the istec. { // If the counter is zero, we have a problem... CHECK (DiagModeCounter > 0); // Decrement the counter, enable diag mode if (--DiagModeCounter == 0) { IstecDiagOn (); } } void UpdateDiagMode () // Send a "diag mode on" command to the istec if diag mode is currently // enabled. { if (DiagModeCounter == 0) { IstecDiagOn (); } } void DisableDiagMode () // Increment the diag mode counter. If there is a transition from 0 to 1, // send the "diag mode off" command to the istec. { // The counter may not be less than zero PRECONDITION (DiagModeCounter >= 0); // Increment the counter, disable diag mode if (++DiagModeCounter == 1) { IstecDiagOff (); } } void IstecRingOn (unsigned char Device) // Ring a phone. Device is 0..n { static unsigned char Msg [6] = { 0xdd, 0x03, 0x00, 0x00, 0x01, 0x00 }; Msg [2] = Device; IstecWrite (Msg, sizeof (Msg)); } void IstecRingOff (unsigned char Device) // Bell off. Device is 0..n { static unsigned char Msg [6] = { 0xdd, 0x03, 0x00, 0x00, 0x00, 0x00 }; Msg [2] = Device; IstecWrite (Msg, sizeof (Msg)); } estic-1.61.orig/estic/iccom.h0100644000176100001440000001341107031424724015365 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCOM.H */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICCOM_H #define _ICCOM_H #include "str.h" #include "icconfig.h" #include "icshort.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Port address and irq used extern unsigned PortBase; extern unsigned PortIRQ; // Flag for short or long wait after sending a message extern int ShortWaitAfterMsg; // Version of the config program (for firmware 2.0 and above) extern unsigned char ConfigVersionHigh; extern unsigned char ConfigVersionLow; // Current ISTEC charges and a flag that is set to 1 on an update extern IstecCharges Charges; /*****************************************************************************/ /* Com port related code */ /*****************************************************************************/ void CloseComPort (); // Close the com port int OpenComPort (const String& PortName); // Try to open the com port. If the port is already open, it is closed and // reopened. The function returns 0 on success and an error code on failure. int ComPortAvail (); // Return 1 if the com port is open, 0 if not /*****************************************************************************/ /* Low level ISTEC specific code */ /*****************************************************************************/ void IstecPoll (); // Poll the istec for incoming debug messages. If we get a real message, store // it in LastIstecMsg (there should be only one outstanding real message at a // time). /*****************************************************************************/ /* High level ISTEC specific code */ /*****************************************************************************/ // All of the following functions may return a return code as specified below: // // 0 Done // 1 Receive buffer overlow (ESTIC error - should not happen) // 2 Receive buffer underflow (ESTIC error - should not happen) // 3 Wrong device number in reply // 4 Invalid reply code // 5 Port is not open // 6 Timeout // 7 CTI error // const int ieDone = 0; const int ieRecBufOverflow = 1; const int ieRecBufUnderflow = 2; const int ieWrongDevice = 3; const int ieInvalidReply = 4; const int iePortNotOpen = 5; const int ieTimeout = 6; const int ieCTIError = 7; const int ieEEPROMInUse = 8; void IstecErrorSync (); // Try to resync the istec after an error int IstecReady (); // Check if the istec answers the "Ready" message. void IstecRequestCharges (); // Request the device charges from the istec. This function is different from // the "Get" functions as it does not wait for a reply. The charge messages // from the ISTEC are handled by the IstecPoll function in the background. // If new charges are available, they are copied to Charges and the // ChargeUpdate flag is set. int IstecGetCharges (); // Get the device charges from the istec. This function calls the "Request" // function and waits until a timeout occurs or we get a reply. void IstecPutCharges (const IstecCharges& Charges); // Write the given charges to the istec and to Charges int IstecGetConfig (IstecConfig& Config); // Get the complete configuration from the istec int IstecPutConfig (const IstecConfig& Config); // Write the complete configuration to the istec. int IstecGetShortNumbers (ShortNumberColl& ShortNumbers); // Read the short numbers from the istec. The function may not be called if // the firmware version is < 2.00! int IstecPutShortNumbers (const ShortNumberColl& ShortNumbers); // Store the short numbers into the istec. The function may not be called if // the firmware version is < 2.00! int IstecGetDayNight (unsigned& DayNight); // Read the day/night setting from the istec. If the current firmware does // not support this, return CTI_VAL_DAY, else return the setting int IstecPutDayNight (unsigned DayNight); // Set the active configuration. If the current firmware does not support // this, ignore the command (return ieDone). int IstecPutAlarm (unsigned Alarm); // Set the alarm byte. If the current firmware does not support this, ignore // the command (return ieDone). void EnableDiagMode (); // This will decrement the diag mode counter. If it is zero, the command for // diag mode enable will be sent to the istec. void UpdateDiagMode (); // Send a "diag mode on" command to the istec if diag mode is currently // enabled. void DisableDiagMode (); // Increment the diag mode counter. If there is a transition from 0 to 1, // send the "diag mode off" command to the istec. void IstecRingOn (unsigned char Device); // Ring a phone. Device is 0..n void IstecRingOff (unsigned char Device); // Bell off. Device is 0..n // End of ICCOM.H #endif estic-1.61.orig/estic/icconfig.cc0100644000176100001440000010424607031426137016221 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCONFIG.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "check.h" #include "chartype.h" #include "str.h" #include "strcvt.h" #include "icobjid.h" #include "iccti.h" #include "icac.h" #include "icerror.h" #include "icdlog.h" #include "icconfig.h" // Register the classes LINK (IstecBaseConfig, ID_IstecBaseConfig); LINK (IstecDevConfig, ID_IstecDevConfig); LINK (IstecDevColl, ID_IstecDevColl); LINK (IstecConfig, ID_IstecConfig); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class SortedCollection; template class Collection; #endif /*****************************************************************************/ /* class IstecBaseConfig */ /*****************************************************************************/ IstecBaseConfig::IstecBaseConfig (): Connection (coPointToMulti), DevCount (8), Protocol (prDSS1), VersionHigh (1), VersionLow (70), TFEAssignment (FirstDev), Music (0), IntS0 (0), ExtS0 (1), QueryLoc1 (0), QueryLoc2 (0), MusicPort (0), CountryCode (49), AlarmTone (0) // Constructor { memset (MSN, 0, sizeof (MSN)); memset (Number1, 0, sizeof (Number1)); memset (Number2, 0, sizeof (Number2)); memset (MSNGroups, 0xFF, sizeof (MSNGroups)); memset (TFELoc, 0, sizeof (TFELoc)); memset (Signaling, 0, sizeof (Signaling)); memset (Reserved, 0, sizeof (Reserved)); } void IstecBaseConfig::Load (Stream& S) // Load the object from a stream { if (S.GetStatus () != stOk) { // Stream has an error return; } S >> Connection >> DevCount >> Protocol >> VersionHigh >> VersionLow; S >> TFEAssignment; S.Read (MSN, sizeof (MSN)); S >> Music >> IntS0 >> ExtS0 >> QueryLoc1 >> QueryLoc2; S.Read (Number1, sizeof (Number1)); S.Read (Number2, sizeof (Number2)); S.Read (MSNGroups, sizeof (MSNGroups)); S >> MusicPort >> CountryCode; S.Read (TFELoc, sizeof (TFELoc)); S >> AlarmTone; S.Read (Signaling, sizeof (Signaling)); S.Read (Reserved, sizeof (Reserved)); } void IstecBaseConfig::Store (Stream& S) const // Store the object into a stream { if (S.GetStatus () != stOk) { // Stream has an error return; } S << Connection << DevCount << Protocol << VersionHigh << VersionLow; S << TFEAssignment; S.Write (MSN, sizeof (MSN)); S << Music << IntS0 << ExtS0 << QueryLoc1 << QueryLoc2; S.Write (Number1, sizeof (Number1)); S.Write (Number2, sizeof (Number2)); S.Write (MSNGroups, sizeof (MSNGroups)); S << MusicPort << CountryCode; S.Write (TFELoc, sizeof (TFELoc)); S << AlarmTone; S.Write (Signaling, sizeof (Signaling)); S.Write (Reserved, sizeof (Reserved)); } u16 IstecBaseConfig::StreamableID () const // Return the stream ID { return ID_IstecBaseConfig; } Streamable* IstecBaseConfig::Build () // Return a new instance { return new IstecBaseConfig (Empty); } unsigned char* IstecBaseConfig::Pack (unsigned char* Buf) const // Pack the data of struct IstecBaseConfig into an array ready for // transmission. The function returns Buf. { unsigned I; unsigned char* B = Buf; // Clear the complete buffer memset (B, 0, BaseConfigSize); // Copy the values *B++ = Connection; *B++ = DevCount; *B++ = Protocol; *B++ = VersionHigh; *B++ = VersionLow; *B++ = TFEAssignment; for (I = 0; I < bcMSNCount; I++) { memcpy (B, MSN [I], sizeof (MSN [I])); B += sizeof (MSN [I]); } *B++ = Music; *B++ = IntS0; *B++ = ExtS0; *B++ = QueryLoc1; *B++ = QueryLoc2; memcpy (B, Number1, sizeof (Number1)); B += sizeof (Number1); memcpy (B, Number2, sizeof (Number2)); B += sizeof (Number2); memcpy (B, MSNGroups, sizeof (MSNGroups)); B += sizeof (MSNGroups); // Version 1.93 extensions follow. unsigned Version = unsigned (VersionHigh) * 100 + unsigned (VersionLow); if (Version >= 193) { *B++ = MusicPort; *B++ = (unsigned char) (CountryCode & 0x00FF); *B++ = (unsigned char) ((CountryCode >> 8) & 0x00FF); memcpy (B, TFELoc, sizeof (TFELoc)); B += sizeof (TFELoc); if (Version >= 200) { *B++ = AlarmTone; for (I = 0; I < bcMSNCount; I++) { *B++ = OutSignal (Signaling [I]); } } } // Return the prepared buffer return Buf; } IstecBaseConfig& IstecBaseConfig::Unpack (const unsigned char* Buf) // Unpack an array of char that contains data for an IstecBaseConfig struct. // The function returns this. { unsigned I; if ((Connection = *Buf++) > coMax) { WriteDebugLog (FormatStr ("IstecBaseConfig::Unpack: Got invalid value for connection: %02X", Connection)); Connection = coPointToMulti; } DevCount = *Buf++; if ((Protocol = *Buf++) > prMax) { WriteDebugLog (FormatStr ("IstecBaseConfig::Unpack: Got invalid value for protocol: %02X", Protocol)); Protocol = prDSS1; } VersionHigh = *Buf++; VersionLow = *Buf++; TFEAssignment = *Buf++; if ((TFEAssignment != 0) && (TFEAssignment < 21 || TFEAssignment > LastDev)) { WriteDebugLog (FormatStr ("IstecBaseConfig::Unpack: Got invalid value for TFE assignment: %02X", TFEAssignment)); TFEAssignment = FirstDev; } for (I = 0; I < bcMSNCount; I++) { memcpy (MSN [I], Buf, sizeof (MSN [I])); Buf += sizeof (MSN [I]); } Music = (*Buf++ != 0); IntS0 = *Buf++; ExtS0 = *Buf++; QueryLoc1 = *Buf++; QueryLoc2 = *Buf++; memcpy (Number1, Buf, sizeof (Number1)); Buf += sizeof (Number1); memcpy (Number2, Buf, sizeof (Number2)); Buf += sizeof (Number2); memcpy (MSNGroups, Buf, sizeof (MSNGroups)); Buf += sizeof (MSNGroups); // Version 1.93 extensions follow unsigned Version = unsigned (VersionHigh) * 100 + unsigned (VersionLow); if (Version >= 193) { MusicPort = *Buf++; CountryCode = unsigned (Buf [1]) * 0x100 + unsigned (Buf [0]); Buf += 2; memcpy (TFELoc, Buf, sizeof (TFELoc)); Buf += sizeof (TFELoc); if (Version >= 200) { AlarmTone = *Buf++; for (I = 0; I < bcMSNCount; I++) { Signaling [I] = InSignal (*Buf++); } memcpy (Reserved, Buf, sizeof (Reserved)); } else { // Use defaults for the additional fields AlarmTone = 0; for (I = 0; I < bcMSNCount; I++) { Signaling [I] = siStandard; } memset (Reserved, 0, sizeof (Reserved)); } } else { // This is an old version, clear out the additional fields MusicPort = 0; // None CountryCode = 49; // Germany memset (TFELoc, 0, sizeof (TFELoc)); AlarmTone = 0; // Off for (I = 0; I < bcMSNCount; I++) { Signaling [I] = siStandard; } memset (Reserved, 0, sizeof (Reserved)); } // Return the prepared struct return *this; } IstecBaseConfig& IstecBaseConfig::Unpack (const IstecMsg& Msg) // Unpack an array of char that contains data for an IstecBaseConfig struct. // The function returns this. { PRECONDITION (Msg.Size >= 94 && Msg.At (0) == 0x17); return Unpack (&Msg.Data [1]); } int operator == (const IstecBaseConfig& lhs, const IstecBaseConfig& rhs) { // For simplicity, convert to an array, then do a memcmp unsigned char Left [BaseConfigSize], Right [BaseConfigSize]; return memcmp (lhs.Pack (Left), rhs.Pack (Right), BaseConfigSize) == 0; } int operator != (const IstecBaseConfig& lhs, const IstecBaseConfig& rhs) { // For simplicity, convert to an array, then do a memcmp unsigned char Left [BaseConfigSize], Right [BaseConfigSize]; return memcmp (lhs.Pack (Left), rhs.Pack (Right), BaseConfigSize) != 0; } unsigned IstecBaseConfig::IstecID () const // Return the type of the istec, determined by the parameters of the base // configuration. The return value is 0 if the istec type could not be // identified, 1008 for an istec 1008 etc. { if (ExtS0 == 1) { // It is a 10XX type switch (DevCount) { case 3: return 1003; case 8: return 1008; case 16: return 1016; case 24: return 1024; } } else if (ExtS0 == 2) { // Type 20XX or 24XX if (IntS0 == 0) { // It is a 20XX type switch (DevCount) { case 16: return 2016; case 24: return 2024; } } else if (IntS0 == 4) { // It is a 24XX type switch (DevCount) { case 0: return 2400; case 16: return 2416; case 24: return 2424; } } } // Unknown type if it comes here... return 0; } /*****************************************************************************/ /* class IstecDevConfig */ /*****************************************************************************/ IstecDevConfig::IstecDevConfig (unsigned char aDevNum): DevNum (aDevNum), DialCaps (dcKeine), Service (svFernsprechen), Reroute (0), ChargePulse (0), TerminalMode (0), InternalKnock (0), ExternalKnock (0), ExtNumLen (0), RerouteIfBusy (0), RerouteDelayed (0), RingsUntilReroute (0) // Create an IstecDevConfig { memset (PIN, 0xFF, sizeof (PIN)); } void IstecDevConfig::Load (Stream& S) // Load the object from a stream { if (S.GetStatus () != stOk) { // Stream error return; } S >> DevNum >> DialCaps >> Service >> Reroute >> ChargePulse; S.Read (PIN, sizeof (PIN)); S >> ExtNum >> TerminalMode >> InternalKnock >> ExternalKnock; S >> ExtNumLen; S >> RerouteIfBusy >> RerouteDelayed >> RingsUntilReroute; } void IstecDevConfig::Store (Stream& S) const // Store the object into a stream { if (S.GetStatus () != stOk) { // Stream error return; } S << DevNum << DialCaps << Service << Reroute << ChargePulse; S.Write (PIN, sizeof (PIN)); S << ExtNum << TerminalMode << InternalKnock << ExternalKnock; S << ExtNumLen; S << RerouteIfBusy << RerouteDelayed << RingsUntilReroute; } u16 IstecDevConfig::StreamableID () const // Return the stream ID { return ID_IstecDevConfig; } Streamable* IstecDevConfig::Build () // Return a new instance { return new IstecDevConfig (Empty); } String IstecDevConfig::GetPIN () const // Get the PIN as a string { return FromBCD (PIN, sizeof (PIN)); } void IstecDevConfig::SetPIN (const String& aPIN) // Set the PIN from a string { ToBCD (aPIN.GetStr (), PIN, sizeof (PIN)); } void IstecDevConfig::SetReroute (const String& Phone, unsigned Cond) // Set the reroute according to Phone and Cond. If Cond is the default // (rcUnconditional) and Phone is empty, Cond is corrected to rcNone // (this simplifies handling of reroutes). { // Create a copy with all all unneeded chars removed String TmpPhone = CleanPhone (Phone); // Check if the number is an internal number unsigned Internal = InternalPhone (TmpPhone); // Check the condition switch (Cond) { case rcNone: ExtNum.Clear (); Reroute = 0; RerouteIfBusy = 0; RerouteDelayed = 0; RingsUntilReroute = 0; return; case rcUnconditional: if (TmpPhone.IsEmpty ()) { ExtNum.Clear (); Reroute = 0; } else { if (Internal) { Reroute = Internal + 20; } else { ExtNum = IstecBeautifyPhone (TmpPhone); Reroute = 1; } } RerouteIfBusy = 0; RerouteDelayed = 0; RingsUntilReroute = 0; break; case rcBusy: CHECK (Internal != 0); ExtNum.Clear (); Reroute = 0; RerouteIfBusy = Internal; RerouteDelayed = 0; RingsUntilReroute = 0; break; case rcDelayed: CHECK (Internal != 0); ExtNum.Clear (); Reroute = 0; RerouteIfBusy = 0; RerouteDelayed = Internal; break; default: FAIL ("IstecDevConfig::SetReroute: Invalid value for Cond"); } } String IstecDevConfig::GetReroute () const // Get the reroute number { if (Reroute == 1) { // External reroute return ExtNum; } if (Reroute >= FirstDev && Reroute <= LastDev) { // Internal reroute return U32Str (Reroute); } if (Reroute == 0) { if (RerouteIfBusy) { return U32Str (RerouteIfBusy + 20); } else if (RerouteDelayed) { return U32Str (RerouteDelayed + 20); } else { // No reroute return EmptyString; } } // This line must never be reached FAIL ("IstecDevConfig::GetReroute: Invalid reroute value"); return EmptyString; } unsigned IstecDevConfig::GetRerouteCondition () const // Get the current setting for the reroute condition { if (Reroute != 0) { return rcUnconditional; } if (FirmwareVersion < 2.00) { // With FW before 2.0, a value 0 in Reroute means "no reroute" return rcNone; } // Firmware 2.0 has some more complex way of determining reroutes if (RerouteIfBusy != 0) { return rcBusy; } else if (RerouteDelayed != 0) { return rcDelayed; } else { return rcNone; } } unsigned IstecDevConfig::GetRerouteRings () const // Get the "rings until reroute" value { if (Reroute == 0 && RerouteIfBusy == 0 && RerouteDelayed != 0) { return RingsUntilReroute; } else { return 0; } } void IstecDevConfig::SetRerouteRings (unsigned Rings) // Set the "rings until reroute" value { if (Reroute == 0 && RerouteIfBusy == 0 && RerouteDelayed != 0) { if (Rings < 2) { Rings = 2; } else if (Rings > 9) { Rings = 9; } RingsUntilReroute = Rings; } else { RingsUntilReroute = 0; } } unsigned char* IstecDevConfig::Pack (unsigned char* Buf, double FirmwareVersion) const // Pack the data of struct IstecDevConfig into an array ready for transmission. // The function returns Buf. { // Clear the complete buffer memset (Buf, 0, DevConfigSize); // Get a temp pointer to the buffer unsigned char* B = Buf; *B++ = DevNum; *B++ = DialCaps; *B++ = Service; *B++ = Reroute; *B++ = ChargePulse; *B++ = PIN [0]; *B++ = PIN [1]; if (Reroute == 1) { // Create a copy of the phone number and remove unwanted stuff String Phone = CleanPhone (ExtNum); // Convert to BCD ToBCD (Phone.GetStr (), B, 10); } else { memset (B, 0xFF, 10); } B += 10; // Version 1.93+1.94 extensions follow if (FirmwareVersion > 1.92) { // This is a new version config record *B++ = TerminalMode; if (FirmwareVersion > 1.93) { *B++ = InternalKnock; *B++ = Fill1; // Fill byte *B++ = ExternalKnock & 0xFF; *B++ = (ExternalKnock >> 8) & 0xFF; if (FirmwareVersion > 1.97) { *B++ = ExtNum.Len (); *B++ = RerouteIfBusy; *B++ = RerouteDelayed; if (Reroute == 0 && RerouteIfBusy == 0 && RerouteDelayed != 0) { *B++ = RingsUntilReroute; } else { *B++ = 0; } } } } // Return the prepared buffer return Buf; } IstecDevConfig& IstecDevConfig::Unpack (const unsigned char* Buf, double FirmwareVersion) // Unpack an array of char that contains data for a IstecDevConfig struct. // The function returns *this and corrects invalid raw values. { unsigned svMax = FirmwareVersion < 1.92? svAnrufbeantworter : svKombi; DevNum = *Buf++; if ((DialCaps = *Buf++) > dcMax) { WriteDebugLog (FormatStr ("IstecDevConfig::Unpack: Got invalid value for DialCaps: %02X", DialCaps)); DialCaps = dcKeine; } if ((Service = *Buf++) > svMax) { WriteDebugLog (FormatStr ("IstecDevConfig::Unpack: Got invalid value for Service: %02X", Service)); Service = svFernsprechen; } Reroute = *Buf++; if (Reroute != 0 && Reroute != 1 && (Reroute < FirstDev || Reroute > LastDev)) { WriteDebugLog (FormatStr ("IstecDevConfig::Unpack: Got invalid value for Reroute: %02X", Reroute)); Reroute = 0; } ChargePulse = (*Buf++ != 0); PIN [0] = *Buf++; PIN [1] = *Buf++; if (Reroute == 1) { // External reroute, read the number ExtNum = FromBCD (Buf, 10); } Buf += 10; // Version 1.93+1.94 extensions follow if (FirmwareVersion > 1.92) { // This is a new version config record TerminalMode = (*Buf++ != 0); if (FirmwareVersion > 1.93) { InternalKnock = *Buf++; Fill1 = *Buf++; // Skip next byte ExternalKnock = Buf [0] + 256 * Buf [1]; Buf += 2; if (FirmwareVersion > 1.97) { ExtNum.Trunc (*Buf++); RerouteIfBusy = *Buf++; RerouteDelayed = *Buf++; RingsUntilReroute = *Buf++; } else { ExtNumLen = 0; RerouteIfBusy = 0; RerouteDelayed = 0; RingsUntilReroute = 0; } } else { // Clear out the additional fields InternalKnock = 0; Fill1 = 0; ExternalKnock = 0; ExtNumLen = 0; RerouteIfBusy = 0; RerouteDelayed = 0; RingsUntilReroute = 0; } } else { // Clear out the additional fields TerminalMode = 0; InternalKnock = 0; Fill1 = 0; ExternalKnock = 0; ExtNumLen = 0; RerouteIfBusy = 0; RerouteDelayed = 0; RingsUntilReroute = 0; } // Beautify the external reroute phone number ExtNum = IstecBeautifyPhone (ExtNum); // Return the prepared struct return *this; } IstecDevConfig& IstecDevConfig::Unpack (const IstecMsg& Msg, double aFirmware) // Unpack an array of char that contains data for a IstecDevConfig struct. // The function returns *this and corrects invalid raw values. { PRECONDITION (Msg.Size >= 18 && Msg.At (0) == 0x16); return Unpack (&Msg.Data [1], aFirmware); } int operator == (const IstecDevConfig& lhs, const IstecDevConfig& rhs) { // For simplicity, convert to an array, then do a memcmp unsigned char Left [DevConfigSize], Right [DevConfigSize]; return memcmp (lhs.Pack (Left), rhs.Pack (Right), DevConfigSize) == 0; } int operator != (const IstecDevConfig& lhs, const IstecDevConfig& rhs) { // For simplicity, convert to an array, then do a memcmp unsigned char Left [DevConfigSize], Right [DevConfigSize]; return memcmp (lhs.Pack (Left), rhs.Pack (Right), DevConfigSize) != 0; } /*****************************************************************************/ /* class IstecDevColl */ /*****************************************************************************/ int IstecDevColl::Compare (const unsigned char* Key1, const unsigned char* Key2) { if (*Key1 < *Key2) { return -1; } else if (*Key1 > *Key2) { return 1; } else { return 0; } } const unsigned char* IstecDevColl::KeyOf (const IstecDevConfig* Item) // Helpers for managing sort order { return &Item->DevNum; } IstecDevColl::IstecDevColl (StreamableInit): SortedCollection (Empty) // Build constructor { } IstecDevColl::IstecDevColl (): SortedCollection (8, 8, 1) // Create a IstecDevColl { } u16 IstecDevColl::StreamableID () const // Return the stream ID { return ID_IstecDevColl; } Streamable* IstecDevColl::Build () // Return a new instance { return new IstecDevColl (Empty); } IstecDevConfig& IstecDevColl::NewDev (unsigned char Dev) // Create and insert a new device with the given number { // Create a new entry IstecDevConfig* Cfg = new IstecDevConfig (Dev); // Insert the new entry... Insert (Cfg); // ... and return it return *Cfg; } /*****************************************************************************/ /* class IstecConfig */ /*****************************************************************************/ IstecConfig::IstecConfig () // Create an IstecConfig object { // Insert the devices into the collection for (unsigned I = 0; I < GetDevCount (); I++) { DevColl.NewDev (I); } } IstecConfig::IstecConfig (StreamableInit): BaseConfig (Empty), DevColl (Empty) // Build constructor { } void IstecConfig::Load (Stream& S) // Load the object from a stream { S >> BaseConfig >> DevColl; } void IstecConfig::Store (Stream& S) const // Store the object into a stream { S << BaseConfig << DevColl; } u16 IstecConfig::StreamableID () const // Return the stream ID { return ID_IstecConfig; } Streamable* IstecConfig::Build () // Return a new instance { return new IstecConfig (Empty); } IstecDevConfig& IstecConfig::GetDevConfig (unsigned char Dev) // Get the config for the specified device. If it does not exist, it is created { // Search for the index int Index; if (DevColl.Search (&Dev, Index) == 0) { // No entry til now, create one return DevColl.NewDev (Dev); } else { // Found an entry, return it return *DevColl [Index]; } } const IstecDevConfig& IstecConfig::GetDevConfig (unsigned char Dev) const // Get the config for the specified device. If it does not exist, // FAIL is called { // Unfortunately, the collection member functions are not made const // as needed, and changing them now will break lots of old code. So // do it the ugly way and cast away the constness of this. IstecConfig* THIS = (IstecConfig*) (this); // Search for the index int Index; if (THIS->DevColl.Search (&Dev, Index) == 0) { // No entry til now, this must not happen! FAIL ("IstecConfig::GetDevConfig: Device does not exist!"); } return *DevColl.At (Index); } void IstecConfig::UnpackDevConfig (const IstecMsg& Msg, double aFirmware) // Unpack a device config from an istec message { PRECONDITION (Msg.Size >= 18 && Msg.At (0) == 0x16); IstecDevConfig& DevConfig = GetDevConfig (Msg.Data [1]); DevConfig.Unpack (&Msg.Data [1], aFirmware); } void IstecConfig::UnpackBaseConfig (const IstecMsg& Msg) // Unpack the base configuguration from an istec message { BaseConfig.Unpack (Msg); } void IstecConfig::PackDevConfig (unsigned char Dev, unsigned char* Buf, double aFirmware) const // Pack a device config { const IstecDevConfig& DevConfig = GetDevConfig (Dev); DevConfig.Pack (Buf, aFirmware); } void IstecConfig::PackBaseConfig (unsigned char* Buf) const // Pack the base configuration { BaseConfig.Pack (Buf); } String IstecConfig::GetNumber1 () const // Get the numbers from the base configuration { char Buf [sizeof (BaseConfig.Number1)]; FromPascal (Buf, BaseConfig.Number1, sizeof (Buf)); return Buf; } String IstecConfig::GetNumber2 () const // Get the numbers from the base configuration { char Buf [sizeof (BaseConfig.Number2)]; FromPascal (Buf, BaseConfig.Number2, sizeof (Buf)); return Buf; } void IstecConfig::SetNumber1 (const String& Num) // Set the number in the base configuration { ToPascal (Num.GetStr (), BaseConfig.Number1, sizeof (BaseConfig.Number1)); } void IstecConfig::SetNumber2 (const String& Num) // Set the number in the base configuration { ToPascal (Num.GetStr (), BaseConfig.Number2, sizeof (BaseConfig.Number2)); } /*****************************************************************************/ /* class IstecCharges */ /*****************************************************************************/ void IstecCharges::Clear () // Clear the charges { for (unsigned I = 0; I < IstecDevCount; I++) { Charges [I] = 0; } } unsigned& IstecCharges::operator [] (unsigned Device) // Return a reference to the charges of a specific device { PRECONDITION (Device < IstecDevCount); return Charges [Device]; } const unsigned& IstecCharges::operator [] (unsigned Device) const // Return a reference to the charges of a specific device { PRECONDITION (Device < IstecDevCount); return Charges [Device]; } unsigned char* IstecCharges::Pack (unsigned char* Buf) const // Pack the data of IstecCharges into an array ready for transmission. // The function returns Buf. { unsigned DevCount = FirmwareVersion < 2.00? IstecDevCount : 8; unsigned char* B = Buf; for (unsigned I = 0; I < DevCount; I++) { // Check range CHECK (Charges [I] <= 0xFFFF); // Get the value u16 Val = (u16) Charges [I]; // Store the value into the array in little endian format *B++ = (unsigned char) Val; *B++ = (unsigned char) (Val / 256); } // Return the prepared buffer return Buf; } IstecCharges& IstecCharges::Unpack (const unsigned char* Buf) // Unpack an array of char that contains data for an IstecCharges struct. // The function returns this. { unsigned DevCount = FirmwareVersion < 2.00? IstecDevCount : 8; for (unsigned I = 0; I < DevCount; I++) { // Convert the value from little endian format Charges [I] = Buf [0] + (unsigned)Buf [1] * 256; // Next one Buf += 2; } // Return the prepared struct return *this; } int operator == (const IstecCharges& lhs, const IstecCharges& rhs) { unsigned DevCount = FirmwareVersion < 2.00? IstecDevCount : 8; for (unsigned I = 0; I < DevCount; I++) { if (lhs.Charges [I] != rhs.Charges [I]) { return 0; } } return 1; } int operator != (const IstecCharges& lhs, const IstecCharges& rhs) { unsigned DevCount = FirmwareVersion < 2.00? IstecDevCount : 8; for (unsigned I = 0; I < DevCount; I++) { if (lhs.Charges [I] == rhs.Charges [I]) { return 0; } } return 1; } /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned char* ToBCD (const char* S, unsigned char* T, unsigned TSize, int LowFirst) // Convert the number string in S to a BCD representation in T, filling unused // digits with 'F'. The function returns T. When LowFirst is set, decoding // order is low/high, when LowFirst is zero it's the other way round. { // Check the parameters PRECONDITION (S != NULL && (T != NULL || TSize == 0)); // Calculate the maximum digit count and make shure, T is big enough unsigned Count = TSize * 2; unsigned Len = strlen (S); if (Len > Count) { // OOPS - S is too long, what now? IstecError (msErrorIntIgnored); Len = Count; } // Pre-fill the target string with FF memset (T, 0xFF, TSize); // Convert to BCD and store unsigned char* P = T; int LowNibble = LowFirst; if (LowFirst) { while (Len--) { if (LowNibble) { *P = (*S - '0') | 0xF0; LowNibble = 0; } else { *P = ((*S - '0') << 4) | (*P & 0x0F); LowNibble = 1; P++; } S++; } } else { while (Len--) { if (LowNibble) { *P = (*P & 0xF0) | ((*S - '0') & 0x0F); LowNibble = 0; P++; } else { *P = ((*S - '0') << 4) | 0x0F; LowNibble = 1; } S++; } } // Return the target buffer return T; } char* FromBCD (char* S, const unsigned char* T, unsigned TSize, int LowFirst) // Convert the BCD string in T into an ASCII representation in S. Conversion // stops if an invalid BCD char or TSize is reached. A trailing zero is added // to S. It is assumed that S is big anough to hold the resulting string (S // must be TSize*2+1 chars in size). When LowFirst is set, decoding order // is low/high, when LowFirst is zero it's the other way round. // The function returns S. { // Check the parameters PRECONDITION (S != NULL && (T != NULL || TSize == 0)); // Calculate the nibble count TSize *= 2; // Conversion loop char* Q = S; unsigned LowNibble = LowFirst; while (TSize--) { int C; if (LowNibble) { C = *T & 0x0F; LowNibble = 0; if (!LowFirst) { T++; } } else { C = (*T & 0xF0) >> 4; LowNibble = 1; if (LowFirst) { T++; } } if (C < 10) { *Q++ = '0' + C; } else { // Invalid char, end reached break; } } // Add a trailing zero *Q = '\0'; // return the result return S; } String FromBCD (const unsigned char* T, unsigned TSize, int LowFirst) // Convert the BCD string in T into an ASCII representation. Conversion // stops if an invalid BCD char or TSize is reached. When LowFirst is set, // decoding order is low/high, when LowFirst is zero it's the other way round. // The resulting string is returned. { // Allocate memory for the result char* Buf = new char [TSize * 2 + 1]; // Convert the string String S = FromBCD (Buf, T, TSize, LowFirst); // Delete the buffer memory delete [] Buf; // Return the result return S; } unsigned char* ToPascal (const char* S, unsigned char* T, unsigned TSize) // Convert the C style string in S to the pascal string in T and return T. { // Check parameters PRECONDITION (S != NULL && T != NULL && TSize > 0); // Copy the string unsigned char* Q = T + 1; unsigned Length = 0; while (*S && TSize--) { *Q++ = *S++; Length++; } // Pad the target string with zeros while (TSize--) { *Q++ = '\0'; } // Set the string length *T = Length; // Return the result return T; } char* FromPascal (char* S, const unsigned char* T, unsigned SSize) // Convert the pascal style string in T into a C like string in S and return S. { // Check parameters PRECONDITION (S != NULL && T != NULL && SSize > 0); // Get the string length and restrict it if S is not big enough unsigned Length = *T++; if (Length > SSize-1) { Length = SSize-1; } // Copy the string char* Q = S; while (Length--) { *Q++ = *T++; } // Add a trailing zero *Q = '\0'; // Return the result return S; } unsigned char InSignal (unsigned char Type) // Convert the given signal type into the internally used representation { switch (Type) { case CTI_VAL_SIGNAL_1: return siSignal1; case CTI_VAL_SIGNAL_2: return siSignal2; case CTI_VAL_SIGNAL_3: return siSignal3; case CTI_VAL_SIGNAL_NONE: return siNone; default: return siStandard; } } unsigned char OutSignal (unsigned char Type) // Convert the given signal type into the representation used by the istec { switch (Type) { case siStandard: return CTI_VAL_SIGNAL_STANDARD; case siSignal1: return CTI_VAL_SIGNAL_1; case siSignal2: return CTI_VAL_SIGNAL_2; case siSignal3: return CTI_VAL_SIGNAL_3; case siNone: return CTI_VAL_SIGNAL_NONE; default: FAIL ("OutSignal: Unknown signal type"); return 0; } } unsigned InternalPhone (const String& Phone) // If the given phone number is an internal number, return the code of this // device (1..8). If it is not an internal number, return 0. { // Remove unwanted stuff from the number String TmpPhone = CleanPhone (Phone); // Check the number if (TmpPhone.Len () == 2 && TmpPhone [0] == '2' && TmpPhone [1] >= '1' && TmpPhone [1] <= '8') { // This is an internal number return DigitValue (TmpPhone [1]); } else { // No internal number return 0; } } estic-1.61.orig/estic/icconfig.h0100644000176100001440000005047707031426137016071 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCONFIG.H */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICCONFIG_H #define _ICCONFIG_H #include #include "coll.h" #include "icver.h" #include "istecmsg.h" /*****************************************************************************/ /* Constants */ /*****************************************************************************/ // Possible values for IstecBaseConfig.Connection const unsigned coPointToMulti = 0; const unsigned coPointToPoint = 1; const unsigned coMax = 1; // Possible values for IstecBaseConfig.Protocol const unsigned pr1TR6 = 0; const unsigned prDSS1 = 1; const unsigned prMax = 1; // Possible values for IstecBaseConfig.DialCaps const unsigned dcKeine = 0; const unsigned dcInland = 1; const unsigned dcOrt = 2; const unsigned dcHalbamt = 3; const unsigned dcNichtamt = 4; const unsigned dcMax = 4; // Possible values for IstecBaseConfig.Service const unsigned svFernsprechen = 0; const unsigned svFaxG3 = 1; const unsigned svDatenModem = 2; const unsigned svDatexJModem = 3; const unsigned svAnrufbeantworter = 4; const unsigned svKombi = 5; // Flags for the internal and external knock bitsets const unsigned knInt21 = 0x0001; const unsigned knInt22 = 0x0002; const unsigned knInt23 = 0x0004; const unsigned knInt24 = 0x0008; const unsigned knInt25 = 0x0010; const unsigned knInt26 = 0x0020; const unsigned knInt27 = 0x0040; const unsigned knInt28 = 0x0080; const unsigned knMSN0 = 0x0001; const unsigned knMSN1 = 0x0002; const unsigned knMSN2 = 0x0004; const unsigned knMSN3 = 0x0008; const unsigned knMSN4 = 0x0010; const unsigned knMSN5 = 0x0020; const unsigned knMSN6 = 0x0040; const unsigned knMSN7 = 0x0080; const unsigned knMSN8 = 0x0100; const unsigned knMSN9 = 0x0200; const unsigned knTFE1 = 0x0400; const unsigned knTFE2 = 0x0800; const unsigned knTFE3 = 0x1000; const unsigned knTFE4 = 0x2000; // Signaling const unsigned siStandard = 0; const unsigned siSignal1 = 1; const unsigned siSignal2 = 2; const unsigned siSignal3 = 3; const unsigned siNone = 4; // Reroute conditions const unsigned rcNone = 0; const unsigned rcUnconditional = 1; const unsigned rcBusy = 2; const unsigned rcDelayed = 3; // Count of MSN's const unsigned bcMSNCount = 10; // Maximum count of devices const unsigned IstecDevCount = 64; // Short number count (default) const unsigned ShortNumberCount = 60; // Number of first and last usable device const unsigned FirstDev = 21; const unsigned LastDev = 28; // Raw sizes of the transmission data buffers. The actual space occupied from // the date maybe less, depending on the istec firmware version. const unsigned BaseConfigSize = 116; const unsigned DevConfigSize = 26; const unsigned ChargeSize = 128; /*****************************************************************************/ /* class IstecBaseConfig */ /*****************************************************************************/ // Basic ISTEC configuration struct class IstecBaseConfig: public Streamable { public: unsigned char Connection; unsigned char DevCount; unsigned char Protocol; unsigned char VersionHigh; unsigned char VersionLow; unsigned char TFEAssignment; unsigned char MSN [bcMSNCount] [5]; // MSN in BCD unsigned char Music; // 0 == off, 1 == on unsigned char IntS0; unsigned char ExtS0; unsigned char QueryLoc1; unsigned char QueryLoc2; unsigned char Number1 [11]; // Number 1, pascal style unsigned char Number2 [11]; // Number 2, pascal style unsigned char MSNGroups [10]; // ---------------------------------------- // 1.93 and up unsigned char MusicPort; u16 CountryCode; unsigned char TFELoc [4]; // TFE Location (bitmap) // ---------------------------------------- // 2.00 and up unsigned char AlarmTone; // Unused according to E. docs unsigned char Signaling [bcMSNCount]; unsigned char Reserved [5]; IstecBaseConfig (); // Constructor IstecBaseConfig (StreamableInit); // Build constructor virtual void Load (Stream& S); // Load the object from a stream virtual void Store (Stream& S) const; // Store the object into a stream virtual u16 StreamableID () const; // Return the stream ID static Streamable* Build (); // Return a new instance unsigned char* Pack (unsigned char* Buf) const; // Pack the data of struct IstecBaseConfig into an array ready for // transmission. The function returns Buf. IstecBaseConfig& Unpack (const unsigned char* Buf); IstecBaseConfig& Unpack (const IstecMsg& Msg); // Unpack an array of char that contains data for an IstecBaseConfig struct. // The function returns *this and corrects invalid raw values. friend int operator == (const IstecBaseConfig&, const IstecBaseConfig&); friend int operator != (const IstecBaseConfig&, const IstecBaseConfig&); // Compare two structs double GetFirmwareVersion () const; // Return the firmware version from this base configuration unsigned IstecID () const; // Return the type of the istec, determined by the parameters of the base // configuration. The return value is 0 if the istec type could not be // identified, 1008 for an istec 1008 etc. }; inline IstecBaseConfig::IstecBaseConfig (StreamableInit) // Build constructor { } inline double IstecBaseConfig::GetFirmwareVersion () const // Return the firmware version from this base configuration { return double (VersionHigh) + double (VersionLow) / 100; } /*****************************************************************************/ /* class IstecDevConfig */ /*****************************************************************************/ // Configuration of the devices device class IstecDevConfig: public Streamable { public: unsigned char DevNum; unsigned char DialCaps; unsigned char Service; unsigned char Reroute; unsigned char ChargePulse; unsigned char PIN [2]; String ExtNum; // --------------------------------- // 1.93 and up unsigned char TerminalMode; // --------------------------------- // 1.94 and up unsigned char InternalKnock; unsigned char Fill1; u16 ExternalKnock; // --------------------------------- // 1.95 and up unsigned char ExtNumLen; // Length of external number // --------------------------------- // 2.00 and up unsigned char RerouteIfBusy; unsigned char RerouteDelayed; unsigned char RingsUntilReroute; IstecDevConfig (unsigned char aDevNum); // Create an IstecDevConfig IstecDevConfig (StreamableInit); // Build constructor virtual void Load (Stream& S); // Load the object from a stream virtual void Store (Stream& S) const; // Store the object into a stream virtual u16 StreamableID () const; // Return the stream ID static Streamable* Build (); // Return a new instance String GetPIN () const; // Get the PIN as a string void SetPIN (const String& aPIN); // Set the PIN from a string void SetReroute (const String& Phone, unsigned Cond = rcUnconditional); // Set the reroute according to Phone and Cond. If Cond is the default // (rcUnconditional) and Phone is empty, Cond is corrected to rcNone // (this simplifies handling of reroutes). String GetReroute () const; // Get the reroute number unsigned GetRerouteCondition () const; // Get the current setting for the reroute condition unsigned GetRerouteRings () const; // Get the "rings until reroute" value void SetRerouteRings (unsigned Rings); // Set the "rings until reroute" value unsigned char* Pack (unsigned char* Buf, double aFirmwareVersion = FirmwareVersion) const; // Pack the data of struct IstecDevConfig into an array ready for // transmission. The function returns Buf. IstecDevConfig& Unpack (const unsigned char* Buf, double aFirmware = FirmwareVersion); IstecDevConfig& Unpack (const IstecMsg& Msg, double aFirmware = FirmwareVersion); // Unpack an array of char that contains data for a IstecDevConfig struct. // The function returns this. friend int operator == (const IstecDevConfig&, const IstecDevConfig&); friend int operator != (const IstecDevConfig&, const IstecDevConfig&); // Compare two structs int GetIntKnock (unsigned Bit) const; // Return true if the internal knock bit is set int GetExtKnock (unsigned Bit) const; // Return true if the external knock bit is set void SetIntKnock (unsigned Bit); // Set the interal knock to true void SetExtKnock (unsigned Bit); // Set the external knock to true void ClrIntKnock (unsigned Bit); // Set the interal knock to false void ClrExtKnock (unsigned Bit); // Set the external knock to false }; inline IstecDevConfig::IstecDevConfig (StreamableInit): ExtNum (Empty) // Build constructor { } inline int IstecDevConfig::GetIntKnock (unsigned Bit) const // Return true if the internal knock bit is set { return (InternalKnock & Bit) != 0; } inline int IstecDevConfig::GetExtKnock (unsigned Bit) const // Return true if the external knock bit is set { return (ExternalKnock & Bit) != 0; } inline void IstecDevConfig::SetIntKnock (unsigned Bit) // Set the interal knock to true { InternalKnock |= Bit; } inline void IstecDevConfig::SetExtKnock (unsigned Bit) // Set the external knock to true { ExternalKnock |= Bit; } inline void IstecDevConfig::ClrIntKnock (unsigned Bit) // Set the interal knock to false { InternalKnock &= ~Bit; } inline void IstecDevConfig::ClrExtKnock (unsigned Bit) // Set the external knock to false { ExternalKnock &= ~Bit; } /*****************************************************************************/ /* class IstecDevColl */ /*****************************************************************************/ class IstecDevColl: public SortedCollection { protected: virtual int Compare (const unsigned char* Key1, const unsigned char* Key2); virtual const unsigned char* KeyOf (const IstecDevConfig* Item); // Helpers for managing sort order public: IstecDevColl (); // Create a IstecDevColl IstecDevColl (StreamableInit); // Build constructor virtual u16 StreamableID () const; // Return the stream ID static Streamable* Build (); // Return a new instance IstecDevConfig& NewDev (unsigned char Dev); // Create and insert a new device with the given number }; /*****************************************************************************/ /* class IstecConfig */ /*****************************************************************************/ class IstecConfig: public Streamable { private: IstecConfig (StreamableInit); // Build constructor public: IstecBaseConfig BaseConfig; IstecDevColl DevColl; IstecConfig (); // Create an IstecConfig object virtual void Load (Stream& S); // Load the object from a stream virtual void Store (Stream& S) const; // Store the object into a stream virtual u16 StreamableID () const; // Return the stream ID static Streamable* Build (); // Return a new instance IstecDevConfig& GetDevConfig (unsigned char Dev); // Get the config for the specified device. If the entry does not exist, // it is created. const IstecDevConfig& GetDevConfig (unsigned char Dev) const; // Get the config for the specified device. If the entry does not exist, // FAIL is called. unsigned GetDevCount () const; // Return the device count void UnpackDevConfig (const IstecMsg& Msg, double aFirmware = FirmwareVersion); // Unpack a device config from an istec message void UnpackBaseConfig (const IstecMsg& Msg); // Unpack the base configuration from an istec message void PackDevConfig (unsigned char Dev, unsigned char* Buf, double aFirmware = FirmwareVersion) const; // Pack a device config void PackBaseConfig (unsigned char* Buf) const; // Pack the base configuration double GetFirmwareVersion () const; // Return the firmware version from the base config unsigned IstecID () const; // Return the type of the istec, determined by the parameters of the base // configuration. The return value is 0 if the istec type could not be // identified, 1008 for an istec 1008 etc. unsigned GetExtS0 () const; // Return the count of external S0 busses unsigned GetIntS0 () const; // Return the count of internal S0 busses unsigned GetProtocol () const; // Return the protocol used by the istec unsigned GetConnection () const; // Get the connection value from the base configuration unsigned GetMusic () const; // Get the music value from the base configuration unsigned GetMusicPort () const; // Get the music port from the base configuration unsigned GetCountryCode () const; // Get the country code from the base configuration unsigned GetTFEAssignment () const; // Get the TFE assignment from the base configuration String GetNumber1 () const; String GetNumber2 () const; // Get the numbers from the base configuration void SetNumber1 (const String& Num); void SetNumber2 (const String& Num); // Set the number in the base configuration }; inline unsigned IstecConfig::GetDevCount () const { return BaseConfig.DevCount; } inline double IstecConfig::GetFirmwareVersion () const // Return the firmware version from the base config { return BaseConfig.GetFirmwareVersion (); } inline unsigned IstecConfig::IstecID () const // Return the type of the istec, determined by the parameters of the base // configuration. The return value is 0 if the istec type could not be // identified, 1008 for an istec 1008 etc. { return BaseConfig.IstecID (); } inline unsigned IstecConfig::GetExtS0 () const // Return the count of external S0 busses { return BaseConfig.ExtS0; } inline unsigned IstecConfig::GetIntS0 () const // Return the count of internal S0 busses { return BaseConfig.IntS0; } inline unsigned IstecConfig::GetProtocol () const // Return the protocol used by the istec { return BaseConfig.Protocol; } inline unsigned IstecConfig::GetConnection () const // Get the connection value from the base configuration { return BaseConfig.Connection; } inline unsigned IstecConfig::GetMusic () const // Get the music value from the base configuration { return BaseConfig.Music; } inline unsigned IstecConfig::GetMusicPort () const // Get the music port from the base configuration { return BaseConfig.MusicPort; } inline unsigned IstecConfig::GetCountryCode () const // Get the country code from the base configuration { return BaseConfig.CountryCode; } inline unsigned IstecConfig::GetTFEAssignment () const // Get the TFE assignment from the base configuration { return BaseConfig.TFEAssignment; } /*****************************************************************************/ /* class IstecCharges */ /*****************************************************************************/ class IstecCharges { unsigned Charges [IstecDevCount]; public: IstecCharges (); // Constructor - clears the charges on startup void Clear (); // Clear the charges unsigned& operator [] (unsigned Device); // Return a reference to the charges of a specific device const unsigned& operator [] (unsigned Device) const; // Return a reference to the charges of a specific device unsigned char* Pack (unsigned char* Buf) const; // Pack the data of IstecCharges into an array ready for transmission. // The function returns Buf. IstecCharges& Unpack (const unsigned char* Buf); // Unpack an array of char that contains data for an IstecCharges struct. // The function returns this. friend int operator == (const IstecCharges&, const IstecCharges&); friend int operator != (const IstecCharges&, const IstecCharges&); // Compare two structs }; inline IstecCharges::IstecCharges () // Constructor - clears the charges on startup { Clear (); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned char* ToBCD (const char* S, unsigned char* T, unsigned TSize, int LowFirst = 1); // Convert the number string in S to a BCD representation in T, filling unused // digits with 'F'. The function returns T. When LowFirst is set, decoding // order is low/high, when LowFirst is zero it's the other way round. char* FromBCD (char* S, const unsigned char* T, unsigned TSize, int LowFirst = 1); // Convert the BCD string in T into an ASCII representation in S. Conversion // stops if an invalid BCD char or TSize is reached. A trailing zero is added // to S. It is assumed that S is big anough to hold the resulting string (S // must be TSize*2+1 chars in size). When LowFirst is set, decoding order // is low/high, when LowFirst is zero it's the other way round. // The function returns S. String FromBCD (const unsigned char* T, unsigned TSize, int LowFirst = 1); // Convert the BCD string in T into an ASCII representation. Conversion // stops if an invalid BCD char or TSize is reached. When LowFirst is set, // decoding order is low/high, when LowFirst is zero it's the other way round. // The resulting string is returned. unsigned char* ToPascal (const char* S, unsigned char* T, unsigned TSize); // Convert the C style string in S to the pascal string in T and return T. char* FromPascal (char* S, const unsigned char* T, unsigned SSize); // Convert the pascal style string in T into a C like string in S and return S. unsigned char InSignal (unsigned char Type); // Convert the given signal type into the internally used representation unsigned char OutSignal (unsigned char Type); // Convert the given signal type into the representation used by the istec unsigned InternalPhone (const String& Phone); // If the given phone number is an internal number, return the code of this // device (1..8). If it is not an internal number, return 0. // End of ICCONFIG.H #endif estic-1.61.orig/estic/icconst.h0100644000176100001440000000232707031424724015741 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCONST.H */ /* */ /* (C) 1997 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICCONST_H #define _ICCONST_H /*****************************************************************************/ /* Data */ /*****************************************************************************/ /* Somes values for returning success and failure from functions. Use this * values instead of 0/1, -1/0 or similar. The values are designed to be * interchangeable, so you may use whatever fits best in the given context. * It is explicitly allowed to test a function result stated as SUCCESS/FAILURE * against OK, if this is more readable in the given situation. */ #define SUCCESS 1 #define FAILURE 0 #define TRUE SUCCESS #define FALSE FAILURE #define OK SUCCESS #define ERROR FAILURE #define YES SUCCESS #define NO FAILURE // End of ICCONST.H #endif estic-1.61.orig/estic/iccprint.cc0100644000176100001440000000353407031424724016251 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCPRINT.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Print the charges #include #include #include "str.h" #include "syserror.h" #include "datetime.h" #include "progutil.h" #include "icident.h" #include "iccom.h" #include "iclog.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String PrintCharges (const String& Filename) // Print the charges and return an error string. If all is ok, the empty // String is returned. { // Open the file FILE* F = fopen (Filename.GetStr (), "wt"); if (F == NULL) { // An error return GetSysErrorMsg (errno); } // Ok, loop through the devices... for (unsigned Dev = 0; Dev < IstecDevCount; Dev++) { unsigned Units = Charges [Dev]; fprintf (F, "%d %4d %6.2f\n", Dev +21, Units, Units * PricePerUnit); } // Close the file fclose (F); // Return success return ""; } estic-1.61.orig/estic/iccprint.h0100644000176100001440000000247107031424724016112 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCPRINT.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Print the charges #ifndef _ICCPRINT_H #define _ICCPRINT_H #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String PrintCharges (const String& Filename); // Print the charges and return an error string. If all is ok, the empty // String is returned. // End of ICCPRINT.H #endif estic-1.61.orig/estic/iccron.cc0100644000176100001440000005453707031424724015724 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCRON.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "bitset.h" #include "chartype.h" #include "coll.h" #include "str.h" #include "strcvt.h" #include "strparse.h" #include "stdmsg.h" #include "progutil.h" #include "icconst.h" #include "icmsg.h" #include "icevents.h" #include "icdlog.h" #include "icerror.h" #include "iccom.h" #include "iccprint.h" #include "icconfig.h" #include "icfile.h" #include "iccron.h" /*****************************************************************************/ /* Message Constants */ /*****************************************************************************/ const u16 msOpenError = MSGBASE_ICCRON + 0; const u16 msSyntaxError = MSGBASE_ICCRON + 1; const u16 msCmdError = MSGBASE_ICCRON + 2; const u16 msCronJobProcessing = MSGBASE_ICCRON + 3; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; #endif /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name of the cron file, default is the empty string String CronFile = ""; // Names of internal commands and there IDs enum { icPrintCharges, icClearCharges, icLoadConfig, icSwitchConfig, icRing, icCount }; static const char* InternalCommands [icCount] = { "PRINTCHARGES", "CLEARCHARGES", "LOADCONFIG", "SWITCHCONFIG", "RING" }; /*****************************************************************************/ /* class CronEvent */ /*****************************************************************************/ class CronEvent: public Streamable { private: BitSet Minute; // Time BitSet Hour; BitSet WeekDay; BitSet MonthDay; BitSet Month; int Cmd; // Which command to execute? // Arguments String Filename; // Filename argument u32 Device; // Device argument u32 Duration; // Duration argument unsigned DayNight; // Day/night argument static int FindCmdID (String Cmd); // Search for the given command in the command table and return the ID. If // the command is not found, -1 is returned. static int InBounds (const BitSet& B, i32 Num); // Check if a given number is in bounds for the bitfield. Return YES or NO. int ParseRingArgs (const String& Args); // Parse the numeric arguments for the RING command. Return SUCCESS or // FAILURE. static int ParseTimeExpr (BitSet& B, const String& S); // Parse a cron time expression in the string S and set the time in the // bitset B. It is assumed that S is non empty. The function returns // SUCCESS or FAILURE. int ParseTime (BitSet& B, const String& S); // Parse a cron time expression in the string S and set the time in the // bitset B. It is assumed that S is non empty. The function returns // SUCCESS or FAILURE. String ExpandFilename (const Time& T); // Expand the file name spec to a real file name. int CronPrintCharges (const Time& T); // Execute the PrintCharges command. Return SUCCESS or FAILURE. int CronClearCharges (); // Execute the ClearCharges command. Return SUCCESS or FAILURE. int CronLoadConfig (const Time& T); // Execute the LoadConfig command. Return SUCCESS or FAILURE. int CronSwitchConfig (); // Execute the SwitchConfig command. Return SUCCESS or FAILURE. int CronRing (); // Execute the Ring command. Return SUCCESS or FAILURE. public: CronEvent (); // Constructor int TimeMatch (unsigned aMinute, unsigned aHour, unsigned aMonthDay, unsigned aMonth, unsigned aWeekDay); // Return true if the cron event has a time match for the given time // values. Return YES or NO. int ParseTimeSpec (String& Line); // Parse the time spec of the given cron file line. If the time spec is // valid, the internal time fields of the CronEvent object are filled // with the retrieved values, the time spec is removed from Line, and the // function returns SUCCESS. If the time spec is invalid, the function // returns FAILURE. int ParseCmdSpec (const String& Line); // Parse the command specification of the given cron command. If the // command and its parameters are valid, the internal variables of the // object are set to these values and the function returns SUCCESS. If the // command and/or the parameters are invalid, the function returns FAILURE. int Execute (const Time& T); // Execute a cron event. The error code (SUCCESS/FAILURE) of the command // actually executed is returned. The function does *no* time checks! }; CronEvent::CronEvent (): Minute (60), Hour (24), WeekDay (7), MonthDay (31, 1), Month (12, 1), Cmd (icCount) // To be shure it's wrong { } int CronEvent::FindCmdID (String Cmd) // Search for the given command in the command table and return the ID. If // the command is not found, -1 is returned. { // Make the command upper case Cmd.ToUpper (); // This is a linear search, since the count of commands is very small for (int I = 0; I < icCount; I++) { if (strcmp (InternalCommands [I], Cmd.GetStr ()) == 0) { // Found return I; } } // Not found return -1; } int CronEvent::InBounds (const BitSet& B, i32 Num) // Check if a given number is in bounds for the bitfield { return (Num >= B.Low () && Num <= B.High ())? YES : NO; } int CronEvent::ParseRingArgs (const String& Args) // Parse the numeric arguments for the RING command. The function returns // SUCCESS or FAILURE. { // Create a string parser StringParser SP (Args, StringParser::SkipWS); // Read the device if (SP.GetU32 (Device) != 0 || Device < FirstDev || Device > LastDev) { // Device parameter invalid return FAILURE; } // Read the duration if (SP.GetU32 (Duration) != 0 || Duration == 0 || Duration > 5*60) { // Duration parameter invalid return FAILURE; } // Success return SUCCESS; } int CronEvent::ParseTimeExpr (BitSet& B, const String& S) // Parse a cron time expression in the string S and set the time in the // bitset B. It is assumed that S is non empty. The function returns // SUCCESS or FAILURE. { PRECONDITION (!S.IsEmpty ()); // Set up a string parser StringParser SP (S, 0); // Read a number u32 Start; if (SP.GetU32 (Start) != 0 || !InBounds (B, Start)) { return FAILURE; } // Check if end of string is reached, if yes, set the bit and bail out if (SP.EOS ()) { B += (int) Start; return SUCCESS; } // If the string did not end, we expect a range expression if (S [SP.GetPos ()] != '-') { // Some error return FAILURE; } SP.SetPos (SP.GetPos () + 1); // Read the end of the range u32 End; if (SP.GetU32 (End) != 0 || !InBounds (B, End)) { return FAILURE; } // End must be greater than Start if (End < Start) { return FAILURE; } // Maybe we have an additional space operator u32 Space = 1; if (!SP.EOS ()) { if (S [SP.GetPos ()] != '/') { // Some error return FAILURE; } SP.SetPos (SP.GetPos () + 1); // Read the space number if (SP.GetU32 (Space) != 0) { return FAILURE; } // String must be empty now if (!SP.EOS ()) { return FAILURE; } } // Now insert the range into the bitset while (Start <= End) { B += (int) Start; Start += Space; } // Done return SUCCESS; } int CronEvent::ParseTime (BitSet& B, const String& S) // Parse a cron time expression in the string S and set the time in the // bitset B. It is assumed that S is non empty. The function returns // SUCCESS or FAILURE. { PRECONDITION (!S.IsEmpty ()); // Handle non-digit expression '*' if (S == "*") { // '* Means: At each full X B.SetAll (); return SUCCESS; } // Set up a string parser StringParser SP (S, 0); // Read a list of tokens separated by ',' and evaluate each of those // tokens String Tok; CharSet Separator = ","; while (SP.GetToken (Tok, Separator) == 0) { // Parse the token if (ParseTimeExpr (B, Tok) == FAILURE) { // Parse error return FAILURE; } // Skip the token separators SP.Skip (Separator); } // String must be empty now if (!SP.EOS ()) { return FAILURE; } // Done with success return SUCCESS; } inline String CronEvent::ExpandFilename (const Time& T) // Expand the file name spec to a real file name. { return T.DateTimeStr (Filename); } int CronEvent::CronPrintCharges (const Time& T) // Execute the PrintCharges command. Return SUCCESS or FAILURE. { // Assume an error int Result = FAILURE; // Expand the filename String Name = ExpandFilename (T); // Print the charges String Msg = PrintCharges (Name); if (Msg.IsEmpty ()) { // No error Msg = "Done"; Result = SUCCESS; } // Log the result WriteDebugLog (FormatStr ("CRON PrintCharges (%s): %s", Name.GetStr (), Msg.GetStr())); // Return the result return Result; } int CronEvent::CronClearCharges () // Execute the ClearCharges command. Return SUCCESS or FAILURE. { // Create an empty charge object IstecCharges Charges; // Send the charges IstecPutCharges (Charges); // Log the action to the debug log WriteDebugLog ("CRON ClearCharges (): Done"); // We return always SUCCESS here since the command for clearing the // charges is put out in the background and we have no way of checking // if the Istec did accept it. return SUCCESS; } int CronEvent::CronLoadConfig (const Time& T) // Execute the LoadConfig command. Return SUCCESS or FAILURE. { // Assume an error int Result = FAILURE; // Expand the filename String Name = ExpandFilename (T); // Try to load the config file with the given name IstecConfig Config; String Msg = IstecLoadFile (Name, Config); if (Msg.IsEmpty ()) { // No error. Send the stuff to the istec int Res = IstecPutConfig (Config); // Make an error message from the return code if (Res == ieDone) { Msg = "Done"; Result = SUCCESS; } else { Msg = FormatStr ("Error #%d", Res); } } // Log the result WriteDebugLog (FormatStr ("CRON LoadConfig (%s): %s", Name.GetStr (), Msg.GetStr ())); // Return the result return Result; } int CronEvent::CronSwitchConfig () // Execute the SwitchConfig command. Return SUCCESS or FAILURE. { String Msg; // Assume an error int Result = FAILURE; // Switch configuration, post an event, make an error message from the // return code int RC = IstecPutDayNight (DayNight); if (RC == ieDone) { PostEvent (evDayNightChange, DayNight); Msg = "Done"; Result = SUCCESS; } else { Msg = FormatStr ("Error #%d", RC); } // Log the result WriteDebugLog (FormatStr ("CRON SwitchConfig: %s", Msg.GetStr ())); // Return the result return Result; } int CronEvent::CronRing () // Execute the Ring command. Return SUCCESS or FAILURE. { // Make one long from the device and duration u32 Parm = Duration * 256 + Device; // Posts an event and hope someone will notice :-) PostEvent (evForcedRing, Parm); // Log the succes of the action WriteDebugLog (FormatStr ("CRON Ring (%d, %d): Done", Device, Duration)); // We return always SUCCESS here since the command is executed in the // background and we have no way checking if the Istec did accept it. return SUCCESS; } int CronEvent::TimeMatch (unsigned aMinute, unsigned aHour, unsigned aMonthDay, unsigned aMonth, unsigned aWeekDay) // Return true if the cron event has a time match for the given time // values. Return YES or NO. { return Minute [aMinute] != 0 && Hour [aHour] != 0 && MonthDay [aMonthDay] != 0 && Month [aMonth] != 0 && WeekDay [aWeekDay] != 0; } int CronEvent::ParseTimeSpec (String& Line) // Parse the time spec of the given cron file line. If the time spec is // valid, the internal time fields of the CronEvent object are filled // with the retrieved values, the time spec is removed from Line, and the // function returns SUCCESS. If the time spec is invalid, the function // returns FAILURE. { // Set up a string parser for the string StringParser SP (Line, StringParser::SkipWS); // Extract the tokens in the order minute, hour, day, month, weekday String SMinute, SHour, SMonthDay, SMonth, SWeekDay; if (SP.GetToken (SMinute) != 0 || SP.GetToken (SHour) != 0 || SP.GetToken (SMonthDay) != 0 || SP.GetToken (SMonth) != 0 || SP.GetToken (SWeekDay) != 0) { // Error return FAILURE; } // Parse the time items and set the time bitsets if (ParseTime (Minute, SMinute) == FAILURE || ParseTime (Hour, SHour) == FAILURE || ParseTime (MonthDay, SMonthDay) == FAILURE || ParseTime (Month, SMonth) == FAILURE || ParseTime (WeekDay, SWeekDay) == FAILURE) { // Error return FAILURE; } // Successful. Skip additional white space, then remove the time spec // from the string SP.SkipWhite (); Line.Del (0, SP.GetPos ()); // Done return SUCCESS; } int CronEvent::ParseCmdSpec (const String& Line) // Parse the command specification of the given cron command. If the // command and its parameters are valid, the internal variables of the // object are set to these values and the function returns SUCCESS. If the // command and/or the parameters are invalid, the function returns FAILURE. { // Set up a string parser for the string StringParser SP (Line, StringParser::SkipWS); // Read the next token from the line, this must be the command String SCommand; if (SP.GetToken (SCommand) != 0) { // No token there return FAILURE; } // The remainder of the line are arguments SP.SkipWhite (); String Args = Line.Cut (SP.GetPos (), Line.Len () - SP.GetPos ()); // Search for the command in the internal command table, translate it to // a command id which is simpler to handle Cmd = FindCmdID (SCommand); // Parse the commands for the command switch (Cmd) { case icPrintCharges: case icLoadConfig: // Commands with a filename argument. Remove leading and // trailing spaces Args.Remove (" \t", rmLeading | rmTrailing); if (Args.IsEmpty ()) { return FAILURE; } Filename = Args; break; case icSwitchConfig: // One argument, "day" or "night". Remove whitespace Args.Remove (" \t", rmLeading | rmTrailing); Args.ToUpper (); if (Args == "DAY") { DayNight = 0; } else if (Args == "NIGHT") { DayNight = 1; } else { return FAILURE; } break; case icClearCharges: // Commands with no arguments break; case icRing: // Two numeric arguments if (ParseRingArgs (Args) == FAILURE) { return FAILURE; } break; case -1: // Unknown command return FAILURE; } // Success return SUCCESS; } int CronEvent::Execute (const Time& T) // Execute a cron event. The error code (SUCCESS/FAILURE) of the command // actually executed is returned. The function does *no* time checks! { // Execute the function switch (Cmd) { case icPrintCharges: return CronPrintCharges (T); case icClearCharges: return CronClearCharges (); case icLoadConfig: return CronLoadConfig (T); case icSwitchConfig: return CronSwitchConfig (); case icRing: return CronRing (); default: FAIL ("CronEvent::Execute: Unknown event code"); } // Never reached... return FAILURE; } /*****************************************************************************/ /* class CronEventColl */ /*****************************************************************************/ class CronEventColl: public Collection { public: CronEventColl (); // Constructor }; CronEventColl::CronEventColl (): Collection (25, 25, 1) { } /*****************************************************************************/ /* Data */ /*****************************************************************************/ static CronEventColl CronEvents; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void HandleCronEvent (const Time& T) // Execute all events that match the given time { // Lock the function against recursive calls that may happen if the // execution of one command lasts too long static int Running = 0; if (Running) { return; } Running = 1; // Convert the given time to separate values unsigned Sec, Minute, Hour, WeekDay, MonthDay, Month, Year; T.GetDateTime (Year, Month, MonthDay, WeekDay, Hour, Minute, Sec); // A window notifying the user Window* Win = 0; // Loop through all events, checking if there is a match for (int I = 0; I < CronEvents.GetCount (); I++) { // Get the specific event CronEvent* E = CronEvents [I]; // Ignore the event if we don't have a match if (!E->TimeMatch (Minute, Hour, MonthDay, Month, WeekDay)) { // No match, continue continue; } // If this is the first match, pop up a window, notifying the user if (Win == 0) { Win = MsgWindow (LoadAppMsg (msCronJobProcessing), "", paCyan); } // Execute the function E->Execute (T); } // If we have a window open, close it delete Win; // Unlock the function Running = 0; } void ReadCronFile () // Delete all existing cron events and reread the cron file. The function // does nothing if there is no cron file defined. { // Bail out if there is no valid cron file name if (CronFile.IsEmpty ()) { return; } // Delete all existing aliases CronEvents.DeleteAll (); // Try to open the file FILE* F = fopen (CronFile.GetStr (), "rt"); if (F == NULL) { // OOPS, file open error IstecError (msOpenError); return; } // Ok, file is open now, read it unsigned LineCount = 0; char Buf [512]; while (fgets (Buf, sizeof (Buf), F) != NULL) { // Got a new line LineCount++; // Put the line into a string and convert it to the internally used // character set String S (Buf); S.InputCvt (); // Delete the trailing newline if any int Len = S.Len (); if (Len > 0 && S [Len-1] == '\n') { Len--; S.Trunc (Len); } // Ignore empty and comment lines if (S.IsEmpty () || S [0] == ';') { continue; } // Create a new cron event CronEvent* E = new CronEvent; // Parse the time specification in the line. When successful, this // will remove the time spec just parsed. if (E->ParseTimeSpec (S) == FAILURE) { // Some sort of error ErrorMsg (FormatStr (LoadAppMsg (msSyntaxError).GetStr (), LineCount)); delete E; continue; } // Parse the command in the line if (E->ParseCmdSpec (S) == FAILURE) { // Error ErrorMsg (FormatStr (LoadAppMsg (msCmdError).GetStr (), LineCount)); delete E; continue; } // Insert the cron event into the collection CronEvents.Insert (E); } // Close the file fclose (F); } int ExecuteCronEvent (const String& Event) // Execute the cron event (without time spec!) given in event. If there are // parse errors on Event, the function returns FAILURE and the event is not // executed. Otherwise the event is executed and the function returns the // result of the execution. { // Create a new cron event CronEvent E; // Parse the given command if (E.ParseCmdSpec (Event) == FAILURE) { // Error return FAILURE; } // Execute the command return E.Execute (Now ()); } estic-1.61.orig/estic/iccron.h0100644000176100001440000000377707031424724015566 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCRON.H */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Cron for ESTIC #ifndef _ICCRON_H #define _ICCRON_H #include "datetime.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name of the cron file, default is the empty string extern String CronFile; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void HandleCronEvent (const Time& T); // Execute all events that match the given time void ReadCronFile (); // Delete all existing cron events and reread the cron file. The function // does nothing if there is no cron file defined. int ExecuteCronEvent (const String& Event); // Execute the cron event (without time spec!) given in event. If there are // parse errors on Event, the function returns FAILURE and the event is not // executed. Otherwise the event is executed and the function returns the // result of the execution. // End of ICCRON.H #endif estic-1.61.orig/estic/iccti.cc0100644000176100001440000000645607031424724015537 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCTI.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Definitions for CTI messages #include "progutil.h" #include "icmsg.h" #include "iccti.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Message constants const u16 msCTI_RC_UNKNOWN = MSGBASE_ICCTI + 0; const u16 msCTI_RC_ERROR = MSGBASE_ICCTI + 1; const u16 msCTI_RC_INVALID_NUMBER = MSGBASE_ICCTI + 2; const u16 msCTI_RC_INVALID_SP_STELLE = MSGBASE_ICCTI + 3; const u16 msCTI_RC_INVALID_CHANNEL = MSGBASE_ICCTI + 4; const u16 msCTI_RC_INVALID_DAY_NIGHT = MSGBASE_ICCTI + 5; const u16 msCTI_RC_EEPROM_IN_USE = MSGBASE_ICCTI + 6; const u16 msCTI_RC_DAY_NIGHT_CHANGED = MSGBASE_ICCTI + 7; const u16 msCTI_RC_DEFAULT_VALUES = MSGBASE_ICCTI + 8; const u16 msCTI_RC_DAY_NIGHT_SAME = MSGBASE_ICCTI + 9; /*****************************************************************************/ /* Code */ /*****************************************************************************/ const String& GetCTIErrorDesc (unsigned char RC) // Return a textual representation of the given error code { unsigned MsgNum; switch (RC) { case CTI_RC_ERROR: MsgNum = msCTI_RC_ERROR; break; case CTI_RC_INVALID_NUMBER: MsgNum = msCTI_RC_INVALID_NUMBER; break; case CTI_RC_INVALID_SP_STELLE:MsgNum = msCTI_RC_INVALID_SP_STELLE;break; case CTI_RC_INVALID_CHANNEL: MsgNum = msCTI_RC_INVALID_CHANNEL; break; case CTI_RC_INVALID_DAY_NIGHT:MsgNum = msCTI_RC_INVALID_DAY_NIGHT;break; case CTI_RC_EEPROM_IN_USE: MsgNum = msCTI_RC_EEPROM_IN_USE; break; case CTI_RC_DAY_NIGHT_CHANGED:MsgNum = msCTI_RC_DAY_NIGHT_CHANGED;break; case CTI_RC_DEFAULT_VALUES: MsgNum = msCTI_RC_DEFAULT_VALUES; break; case CTI_RC_DAY_NIGHT_SAME: MsgNum = msCTI_RC_DAY_NIGHT_SAME; break; default: MsgNum = msCTI_RC_UNKNOWN; break; } return LoadAppMsg (MsgNum); } String CTIMsgDesc (const unsigned char* Data, unsigned Size) // Return a string describing the CTI message. This is for debug purposes // only, the string is hardcoded, not loaded from the resource. { PRECONDITION (Size >= 1 && Data [0] == CTI_START); String S = "CTI message"; return S; } estic-1.61.orig/estic/iccti.h0100644000176100001440000000632607031424724015375 0ustar debacleusers/*****************************************************************************/ /* */ /* ICCTI.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Definitions for CTI messages #ifndef _ICCTI_H #define _ICCTI_H #include "str.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ const unsigned char CTI_START = 0xCC; const unsigned char CTI_STOP = 0xFF; const unsigned char CTI_CONF = 0x05; const unsigned char CTI_QUERY = 0x06; const unsigned char CTI_ERROR = 0x07; const unsigned char CTI_ACK = 0x08; const unsigned char CTI_LOAD_NUMBER = 0x03; const unsigned char CTI_ALARM = 0x05; const unsigned char CTI_DAY_NIGHT = 0x07; const unsigned char CTI_STORE_NUMBER = 0x09; const unsigned char CTI_RC_ERROR = 0x00; // Generic error const unsigned char CTI_RC_INVALID_NUMBER = 0x01; const unsigned char CTI_RC_INVALID_SP_STELLE = 0x02; const unsigned char CTI_RC_INVALID_CHANNEL = 0x03; const unsigned char CTI_RC_INVALID_DAY_NIGHT = 0x04; const unsigned char CTI_RC_EEPROM_IN_USE = 0x05; const unsigned char CTI_RC_DAY_NIGHT_CHANGED = 0x06; const unsigned char CTI_RC_DEFAULT_VALUES = 0x07; const unsigned char CTI_RC_DAY_NIGHT_SAME = 0x08; const unsigned char CTI_VAL_DAY = 0x00; const unsigned char CTI_VAL_NIGHT = 0x01; const unsigned char CTI_VAL_ALARM_OFF = 0x00; const unsigned char CTI_VAL_SIGNAL_STANDARD = 0x00; const unsigned char CTI_VAL_SIGNAL_1 = 0x01; const unsigned char CTI_VAL_SIGNAL_2 = 0x02; const unsigned char CTI_VAL_SIGNAL_3 = 0x04; const unsigned char CTI_VAL_SIGNAL_NONE = 0x03; /*****************************************************************************/ /* Code */ /*****************************************************************************/ const String& GetCTIErrorDesc (unsigned char RC); // Return a textual representation of the given error code String CTIMsgDesc (const unsigned char* Data, unsigned Size); // Return a string describing the CTI message. This is for debug purposes // only, the string is hardcoded, not loaded from the resource. // End of ICCTI.H #endif estic-1.61.orig/estic/icdevs.cc0100644000176100001440000006516407031424724015722 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDEVS.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "listbox.h" #include "progutil.h" #include "menue.h" #include "menuitem.h" #include "statline.h" #include "strcvt.h" #include "stdmsg.h" #include "stdmenue.h" #include "settings.h" #include "crcstrm.h" #include "memstrm.h" #include "icconst.h" #include "icmsg.h" #include "icac.h" #include "icconfig.h" #include "icalias.h" #include "icdevs.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msKeine = MSGBASE_ICDEVS + 0; const u16 msInland = MSGBASE_ICDEVS + 1; const u16 msOrt = MSGBASE_ICDEVS + 2; const u16 msHalbamt = MSGBASE_ICDEVS + 3; const u16 msNichtamt = MSGBASE_ICDEVS + 4; const u16 msFernsprechen = MSGBASE_ICDEVS + 5; const u16 msFaxG3 = MSGBASE_ICDEVS + 6; const u16 msDatenModem = MSGBASE_ICDEVS + 7; const u16 msDatexJModem = MSGBASE_ICDEVS + 8; const u16 msAnrufbeantworter = MSGBASE_ICDEVS + 9; const u16 msKombiDienste = MSGBASE_ICDEVS + 10; const u16 msOn = MSGBASE_ICDEVS + 11; const u16 msOff = MSGBASE_ICDEVS + 12; const u16 msNoReroute = MSGBASE_ICDEVS + 13; const u16 msExtReroute = MSGBASE_ICDEVS + 14; const u16 msDeviceHeader = MSGBASE_ICDEVS + 15; const u16 msNoReroutePhone = MSGBASE_ICDEVS + 16; const u16 msInternalRerouteOnly = MSGBASE_ICDEVS + 17; const u16 msInvalidRings = MSGBASE_ICDEVS + 18; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListBox; #endif /*****************************************************************************/ /* class DevListBox */ /*****************************************************************************/ class DevListBox: public ListBox { private: static const String& DialCapsName (unsigned DialCaps); // Map the number of a dial capability to a name of fixed length static const String& ServiceName (unsigned Service); // Map the number of a service to a name of fixed length static String RerouteName (const String& Num); // Map the reroute capability to a string with fixed length static const String& BoolName (unsigned B); // Map a boolean flag to a string with fixed length protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: DevListBox (i16 aID, const Point& aSize, WindowItem* NextItem = NULL); }; DevListBox::DevListBox (i16 aID, const Point& aSize, WindowItem* NextItem): ListBox ("", aID, aSize, atEditNormal, atEditBar, atEditHigh, NextItem) { } const String& DevListBox::DialCapsName (unsigned DialCaps) // Map the number of a dial capability to a name of fixed length { unsigned MsgNum = msKeine; switch (DialCaps) { case dcKeine: MsgNum = msKeine; break; case dcInland: MsgNum = msInland; break; case dcOrt: MsgNum = msOrt; break; case dcHalbamt: MsgNum = msHalbamt; break; case dcNichtamt: MsgNum = msNichtamt; break; } return LoadAppMsg (MsgNum); } const String& DevListBox::ServiceName (unsigned Service) // Map the number of a service to a name of fixed length { unsigned MsgNum = msFernsprechen; switch (Service) { case svFernsprechen: MsgNum = msFernsprechen; break; case svFaxG3: MsgNum = msFaxG3; break; case svDatenModem: MsgNum = msDatenModem; break; case svDatexJModem: MsgNum = msDatexJModem; break; case svAnrufbeantworter: MsgNum = msAnrufbeantworter; break; case svKombi: MsgNum = msKombiDienste; break; } return LoadAppMsg (MsgNum); } String DevListBox::RerouteName (const String& Num) // Map the reroute capability to a string with fixed length { const StringLength = 18; const PadLength = 21; String Res (PadLength); if (Num.IsEmpty ()) { // No reroute Res = LoadAppMsg (msNoReroute); } else { // Try to get an alias Res = GetAlias (Num); if (Res.IsEmpty ()) { // No alias, use the number Res = Num; } // Check the length if (Res.Len () > StringLength) { // Too long for display Res = LoadAppMsg (msExtReroute); } } // Pad to length and return the string return Res.Pad (String::Right, PadLength); } const String& DevListBox::BoolName (unsigned B) // Map a boolean flag to a string with fixed length { return LoadAppMsg (B ? msOn : msOff); } void DevListBox::Print (int Index, int X, int Y, u16 Attr) { // Get the entry IstecDevConfig* Info = Coll->At (Index); // Create a string with the correct length String Line (Size.X); // Build the line String PIN = Info->GetPIN (); PIN.Pad (String::Left, 4); Line = FormatStr (" %2u ", Info->DevNum + 21); Line += DialCapsName (Info->DialCaps); Line += ServiceName (Info->Service); Line += RerouteName (Info->GetReroute ()); Line += BoolName (Info->ChargePulse); Line += PIN; // Pad the line Line.Pad (String::Right, Size.X - 1); Line += ' '; // Print the name Owner->Write (X, Y, Line, Attr); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int ExtRerouteOk (const String& Phone, unsigned RCond, unsigned Rings) // Check if the given extended reroute settings are ok. If so, return YES, if // not give an error message and return NO. { // Remove unwanted stuff from the phone number String TmpPhone = CleanPhone (Phone); // Check if the given phone number is an internal number unsigned Internal = InternalPhone (Phone); // If we have no reroute, we are done immidiately if (RCond == rcNone) { return YES; } // So we have a reroute given, we must also have a phone number if (TmpPhone.IsEmpty ()) { ErrorMsg (LoadAppMsg (msNoReroutePhone)); return NO; } // If we have one of the special reroutes, we must have an internal number if ((RCond == rcBusy || RCond == rcDelayed) && Internal == 0) { ErrorMsg (LoadAppMsg (msInternalRerouteOnly)); return NO; } // If we have delayed reroute, we must have a valid ring count if (RCond == rcDelayed && (Rings < 2 || Rings > 9)) { ErrorMsg (LoadAppMsg (msInvalidRings)); return NO; } // Seems to be ok... return YES; } static void EditExtReroute (const Point& Pos, IstecDevConfig& Config) // Edit the extended reroute capabilities of FW 2.0 in a separate menu { const miPhone = 10; const miCondition = 20; const miRingCount = 30; // Load the menu Menue* M = (Menue*) LoadResource ("@ICDEVS.RerouteMenue"); // Move the menu to the correct position M->PlaceNear (Pos); // Get the current reroute condition from the configuration String OldPhone = Config.GetReroute (); unsigned OldRCond = Config.GetRerouteCondition (); unsigned OldRings = Config.GetRerouteRings (); // Disable the ring count if the current condition is not "delayed" if (OldRCond != rcDelayed) { M->GrayItem (miRingCount); } else { M->ActivateItem (miRingCount); if (OldRings < 2) { M->SetLongValue (miRingCount, 3); // Correct the value } } // Transfer current settings into the menu M->SetStringValue (miPhone, OldPhone); M->SetToggleValue (miCondition, OldRCond); M->SetLongValue (miRingCount, OldRings); // Disable the ring count if the current condition is not "delayed" if (OldRCond != rcDelayed) { M->GrayItem (miRingCount); } else { M->ActivateItem (miRingCount); if (OldRings < 2) { M->SetLongValue (miRingCount, 3); } } // Display a new status line and activate the menue PushStatusLine (siAbort | siAccept); M->Activate (); // Allow editing int Done = 0; while (!Done) { String Phone; unsigned RCond; unsigned Rings; // Get a choice from the user int Choice = M->GetChoice (); // Look what he wants... switch (Choice) { case miPhone: Phone = IstecBeautifyPhone (M->GetStringValue (miPhone)); M->SetStringValue (miPhone, Phone); if (Phone.NotEmpty () && M->GetToggleValue (miCondition) == rcNone) { // We have a phone number and no reroute, correct this M->SetToggleValue (miCondition, rcUnconditional); } break; case miCondition + rcNone: M->GrayItem (miRingCount); break; case miCondition + rcUnconditional: M->GrayItem (miRingCount); break; case miCondition + rcBusy: M->GrayItem (miRingCount); break; case miCondition + rcDelayed: M->ActivateItem (miRingCount); if (M->GetLongValue (miRingCount) < 2) { M->SetLongValue (miRingCount, 3); } break; case 0: // Retrieve the values from the menu and check them Phone = M->GetStringValue (miPhone); RCond = M->GetToggleValue (miCondition); if (RCond != rcDelayed) { Rings = 0; } else { Rings = M->GetLongValue (miRingCount); } if (M->GetAbortKey () == vkAbort) { // Abort - check if we have changes if (Phone != OldPhone || RCond != OldRCond || Rings != OldRings) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Check if the changed values are ok if (ExtRerouteOk (Phone, RCond, Rings)) { // Changes are ok, remember them and end the loop Config.SetReroute (Phone, RCond); Config.SetRerouteRings (Rings); Done = 1; } } break; } } // Pop the status line, delete the menue PopStatusLine (); delete M; } static void EditDevConfig (IstecDevConfig& Config) // Edit the given device configuration. { // Settings name for the window position static const String StgPosName = "EditDevConfig.ConfigMenue.Position"; // Menue constants const miDialCaps = 10; const miService = 20; const miReroute = 30; // Simple reroute, pre-2.00 const miChargePulse = 40; const miPIN = 50; const miTerminalMode = 60; const miKnockInt = 70; const miKnockExt = 80; const miKnockTFE = 90; const miExtReroute = 100; // Extended reroute, 2.00 and up const miKnockInt21 = 1000; const miKnockInt22 = 1010; const miKnockInt23 = 1020; const miKnockInt24 = 1030; const miKnockInt25 = 1040; const miKnockInt26 = 1050; const miKnockInt27 = 1060; const miKnockInt28 = 1070; const miKnockMSN0 = 1100; const miKnockMSN1 = 1110; const miKnockMSN2 = 1120; const miKnockMSN3 = 1130; const miKnockMSN4 = 1140; const miKnockMSN5 = 1150; const miKnockMSN6 = 1160; const miKnockMSN7 = 1170; const miKnockMSN8 = 1180; const miKnockMSN9 = 1190; const miKnockTFE1 = 1200; const miKnockTFE2 = 1210; const miKnockTFE3 = 1220; const miKnockTFE4 = 1230; // Save the configuration into a memory stream, remember the CRC u32 OldCRC = GetCRC (Config); MemoryStream SaveStream; SaveStream << Config; SaveStream.Seek (0); // Load the menue Menue* M; if (FirmwareVersion < 1.92) { M = (Menue*) LoadResource ("@ICDEVS.ConfigMenue-1.90"); } else if (FirmwareVersion < 1.93) { M = (Menue*) LoadResource ("@ICDEVS.ConfigMenue-1.92"); } else if (FirmwareVersion < 1.95) { M = (Menue*) LoadResource ("@ICDEVS.ConfigMenue-1.93"); } else { M = (Menue*) LoadResource ("@ICDEVS.ConfigMenue-2.00"); } // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, M->OuterBounds ().A); M->MoveAbs (Pos); // Set the menue header to show the device number M->SetHeader (FormatStr (LoadAppMsg (msDeviceHeader).GetStr (), Config.DevNum + 21)); // Insert the values into the menue M->SetToggleValue (miDialCaps, Config.DialCaps); M->SetToggleValue (miService, Config.Service); M->SetToggleValue (miChargePulse, Config.ChargePulse); M->SetStringValue (miPIN, Config.GetPIN ()); if (M->ItemWithID (miReroute) != 0) { M->SetStringValue (miReroute, Config.GetReroute ()); } if (M->ItemWithID (miExtReroute) != 0) { M->SetStringValue (miExtReroute, Config.GetReroute ()); } if (M->ItemWithID (miTerminalMode) != 0) { M->SetToggleValue (miTerminalMode, Config.TerminalMode); } if (M->ItemWithID (miKnockInt) != 0) { M->SetToggleValue (miKnockInt21, Config.GetIntKnock (knInt21)); M->SetToggleValue (miKnockInt22, Config.GetIntKnock (knInt22)); M->SetToggleValue (miKnockInt23, Config.GetIntKnock (knInt23)); M->SetToggleValue (miKnockInt24, Config.GetIntKnock (knInt24)); M->SetToggleValue (miKnockInt25, Config.GetIntKnock (knInt25)); M->SetToggleValue (miKnockInt26, Config.GetIntKnock (knInt26)); M->SetToggleValue (miKnockInt27, Config.GetIntKnock (knInt27)); M->SetToggleValue (miKnockInt28, Config.GetIntKnock (knInt28)); } if (M->ItemWithID (miKnockExt) != 0) { M->SetToggleValue (miKnockMSN0, Config.GetExtKnock (knMSN0)); M->SetToggleValue (miKnockMSN1, Config.GetExtKnock (knMSN1)); M->SetToggleValue (miKnockMSN2, Config.GetExtKnock (knMSN2)); M->SetToggleValue (miKnockMSN3, Config.GetExtKnock (knMSN3)); M->SetToggleValue (miKnockMSN4, Config.GetExtKnock (knMSN4)); M->SetToggleValue (miKnockMSN5, Config.GetExtKnock (knMSN5)); M->SetToggleValue (miKnockMSN6, Config.GetExtKnock (knMSN6)); M->SetToggleValue (miKnockMSN7, Config.GetExtKnock (knMSN7)); M->SetToggleValue (miKnockMSN8, Config.GetExtKnock (knMSN8)); M->SetToggleValue (miKnockMSN9, Config.GetExtKnock (knMSN9)); } if (M->ItemWithID (miKnockTFE) != 0) { M->SetToggleValue (miKnockTFE1, Config.GetExtKnock (knTFE1)); M->SetToggleValue (miKnockTFE2, Config.GetExtKnock (knTFE2)); M->SetToggleValue (miKnockTFE3, Config.GetExtKnock (knTFE3)); M->SetToggleValue (miKnockTFE4, Config.GetExtKnock (knTFE4)); } // Display a new status line and activate the menue PushStatusLine (siAbort | siAccept); M->Activate (); // Allow editing int Done = 0; String Num; while (!Done) { // Get a choice from the user int Choice = M->GetChoice (); // Look what he wants... switch (Choice) { case miDialCaps + dcKeine: case miDialCaps + dcInland: case miDialCaps + dcOrt: case miDialCaps + dcHalbamt: case miDialCaps + dcNichtamt: Config.DialCaps = Choice - miDialCaps; break; case miService + svFernsprechen: case miService + svFaxG3: case miService + svDatenModem: case miService + svDatexJModem: case miService + svAnrufbeantworter: case miService + svKombi: Config.Service = Choice - miService; break; case miReroute: Config.SetReroute (M->GetStringValue (miReroute)); M->SetStringValue (miReroute, Config.GetReroute ()); break; case miChargePulse+0: case miChargePulse+1: Config.ChargePulse = Choice - miChargePulse; break; case miPIN: Config.SetPIN (M->GetStringValue (miPIN)); break; case miTerminalMode: Config.TerminalMode = 0; break; case miTerminalMode+1: Config.TerminalMode = 1; break; case miExtReroute: Pos = M->ItemWithID (miExtReroute)->Pos (); M->Absolute (Pos); EditExtReroute (Pos, Config); M->SetStringValue (miExtReroute, Config.GetReroute ()); break; case miKnockInt21: Config.ClrIntKnock (knInt21); break; case miKnockInt21+1: Config.SetIntKnock (knInt21); break; case miKnockInt22: Config.ClrIntKnock (knInt22); break; case miKnockInt22+1: Config.SetIntKnock (knInt22); break; case miKnockInt23: Config.ClrIntKnock (knInt23); break; case miKnockInt23+1: Config.SetIntKnock (knInt23); break; case miKnockInt24: Config.ClrIntKnock (knInt24); break; case miKnockInt24+1: Config.SetIntKnock (knInt24); break; case miKnockInt25: Config.ClrIntKnock (knInt25); break; case miKnockInt25+1: Config.SetIntKnock (knInt25); break; case miKnockInt26: Config.ClrIntKnock (knInt26); break; case miKnockInt26+1: Config.SetIntKnock (knInt26); break; case miKnockInt27: Config.ClrIntKnock (knInt27); break; case miKnockInt27+1: Config.SetIntKnock (knInt27); break; case miKnockInt28: Config.ClrIntKnock (knInt28); break; case miKnockInt28+1: Config.SetIntKnock (knInt28); break; case miKnockMSN0: Config.ClrExtKnock (knMSN0); break; case miKnockMSN0+1: Config.SetExtKnock (knMSN0); break; case miKnockMSN1: Config.ClrExtKnock (knMSN1); break; case miKnockMSN1+1: Config.SetExtKnock (knMSN1); break; case miKnockMSN2: Config.ClrExtKnock (knMSN2); break; case miKnockMSN2+1: Config.SetExtKnock (knMSN2); break; case miKnockMSN3: Config.ClrExtKnock (knMSN3); break; case miKnockMSN3+1: Config.SetExtKnock (knMSN3); break; case miKnockMSN4: Config.ClrExtKnock (knMSN4); break; case miKnockMSN4+1: Config.SetExtKnock (knMSN4); break; case miKnockMSN5: Config.ClrExtKnock (knMSN5); break; case miKnockMSN5+1: Config.SetExtKnock (knMSN5); break; case miKnockMSN6: Config.ClrExtKnock (knMSN6); break; case miKnockMSN6+1: Config.SetExtKnock (knMSN6); break; case miKnockMSN7: Config.ClrExtKnock (knMSN7); break; case miKnockMSN7+1: Config.SetExtKnock (knMSN7); break; case miKnockMSN8: Config.ClrExtKnock (knMSN8); break; case miKnockMSN8+1: Config.SetExtKnock (knMSN8); break; case miKnockMSN9: Config.ClrExtKnock (knMSN9); break; case miKnockMSN9+1: Config.SetExtKnock (knMSN9); break; case miKnockTFE1: Config.ClrExtKnock (knTFE1); break; case miKnockTFE1+1: Config.SetExtKnock (knTFE1); break; case miKnockTFE2: Config.ClrExtKnock (knTFE2); break; case miKnockTFE2+1: Config.SetExtKnock (knTFE2); break; case miKnockTFE3: Config.ClrExtKnock (knTFE3); break; case miKnockTFE3+1: Config.SetExtKnock (knTFE3); break; case miKnockTFE4: Config.ClrExtKnock (knTFE4); break; case miKnockTFE4+1: Config.SetExtKnock (knTFE4); break; case 0: if (M->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (GetCRC (Config) != OldCRC) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes, reload from stream SaveStream >> Config; Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } break; } } // Save the current window position StgPutPoint (M->OuterBounds ().A, StgPosName); // Pop the status line, delete the menue PopStatusLine (); delete M; } void DeviceList (IstecConfig& Config, int& Changed) // List all devices and there settings, including the charges. Allow editing // the settings and charges. { static const String StgPosName = "DeviceList.DeviceListWindow.Position"; // Save the current config into a memory stream in case we want to cancel // changes. Calculate the CRC. u32 OldCRC = GetCRC (Config); MemoryStream SaveStream; SaveStream << Config; SaveStream.Seek (0); // Load the window Menue* Win = (Menue*) LoadResource ("@ICDEVS.DeviceListWindow"); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, Win->OuterBounds ().A); Win->MoveAbs (Pos); // Create a listbox inside the window Point Size; Size.X = Win->IXSize (); Size.Y = Win->IYSize () - 2; DevListBox* Box = new DevListBox (1, Size); Box->SetColl (&Config.DevColl); Win->AddItem (Box); Box->SetPos (0, 2); Box->Select (); Box->Draw (); Win->Activate (); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // Allow choosing an entry int Done = 0; while (!Done) { // Get keyboard input Key K = ::KbdGet (); // Let the box look for a useful key Box->HandleKey (K); // Look what's left int Selected; switch (K) { case kbEnter: Selected = Box->GetSelected (); if (Selected != -1) { EditDevConfig (*Config.DevColl [Selected]); Box->Draw (); } break; case vkAccept: // If we had changes, tell the caller if (GetCRC (Config) != OldCRC) { Changed = 1; } Done = 1; break; case vkResize: Win->MoveResize (); break; case vkAbort: if (GetCRC (Config) != OldCRC) { // We have changes - ask if we should discard them if (AskDiscardChanges () == 2) { // Discard the changes. To do that, reload the old // config data from the memory stream. SaveStream >> Config; Done = 1; } } else { Done = 1; } break; } } // Restore the status line PopStatusLine (); // Set a new collection for the listbox (otherwise the box would try to // delete the collection) Box->SetColl (NULL); // Save the current window position StgPutPoint (Win->OuterBounds ().A, StgPosName); // Delete the window delete Win; } estic-1.61.orig/estic/icdevs.h0100644000176100001440000000246107031424724015553 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDEVS.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICDEFS_H #define _ICDEFS_H #include "icconfig.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ void DeviceList (IstecConfig& Config, int& Changed); // List all devices and there settings, including the charges. Allow editing // the settings and charges. // End of ICDEVS.H #endif estic-1.61.orig/estic/icdiag.cc0100644000176100001440000005167307031424724015665 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDIAG.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "eventid.h" #include "delay.h" #include "strcvt.h" #include "coll.h" #include "datetime.h" #include "menue.h" #include "textitem.h" #include "listbox.h" #include "menuitem.h" #include "progutil.h" #include "settings.h" #include "winmgr.h" #include "icobjid.h" #include "icevents.h" #include "icintcon.h" #include "icmsg.h" #include "devstate.h" #include "icdlog.h" #include "icdiag.h" // Register the class LINK (MatrixWindow, ID_MatrixWindow); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msMatrixWindowTitle = MSGBASE_ICDIAG + 0; const u16 msMatrixWindowHeader = MSGBASE_ICDIAG + 1; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The name of the matrix window position in the settings file static const String MatrixWindowBounds = "MatrixWindow.Bounds"; // Width of the matrix window static const unsigned MatrixWindowWidth = 64; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; template class ListBox; #endif /*****************************************************************************/ /* class DevStateColl */ /*****************************************************************************/ class DevStateColl: public SortedCollection { protected: virtual int Compare (const unsigned char* Key1, const unsigned char* Key2); virtual const unsigned char* KeyOf (const DevStateInfo* Item); public: DevStateColl (); // Create a DevStateColl void DeleteDev (unsigned char Num); // Delete the device with the given numer. DevStateInfo* NewDev (unsigned char Num); // Create and insert a device with the given numer. DevStateInfo* GetDevStateInfo (unsigned char Num); // Return a pointer to the entry. Calls FAIL if the entry does not exist void SetState (unsigned char Dev, unsigned NewState); void ClrState (unsigned char Dev, unsigned NewState); // Set/reset the device state bits DevStateInfo* At (int Index); // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING void SetSchleife (unsigned Dev, int State); void SetAmt (unsigned Dev, int State, unsigned Amt); void SetInt (unsigned Dev, int State, unsigned Int); void SetTon (unsigned Dev, int State); void SetWTon (unsigned Dev, int State); void SetTFE (unsigned Dev, int State); void SetRuf (unsigned Dev, int State); // Set specific matrix states void AddDigit (unsigned Dev, char Digit); // Add a digit to the phone number if the device is in a state where a digit // is accepted (dialed) }; int DevStateColl::Compare (const unsigned char* Key1, const unsigned char* Key2) { if (*Key1 < *Key2) { return -1; } else if (*Key1 > *Key2) { return 1; } else { return 0; } } const unsigned char* DevStateColl::KeyOf (const DevStateInfo* Item) { return &Item->DevNum; } DevStateColl::DevStateColl (): SortedCollection (10, 10, 1) { // Insert 8 devices (more devices are added dynamically if they are // detected the first time) for (unsigned char Dev = 0; Dev < 8; Dev++) { NewDev (Dev); } } void DevStateColl::DeleteDev (unsigned char Num) // Delete the device with the given numer. { // Search for the device int Index; int Result = Search (&Num, Index); CHECK (Result != 0); // Delete the entry AtDelete (Index); } DevStateInfo* DevStateColl::NewDev (unsigned char Num) // Create and insert a device with the given numer. { // Create a new entry DevStateInfo* DI = new DevStateInfo (Num); // Insert the new entry Insert (DI); // And return it return DI; } DevStateInfo* DevStateColl::GetDevStateInfo (unsigned char Num) // Return a pointer to the entry. Creates an entry if none exists. { // Search for the entry int Index; if (Search (&Num, Index) == 0) { // No entry til now, create one return NewDev (Num); } else { // Found, return it return At (Index); } } void DevStateColl::SetState (unsigned char Dev, unsigned NewState) // Set the device state bits { GetDevStateInfo (Dev)->SetState (NewState); } void DevStateColl::ClrState (unsigned char Dev, unsigned NewState) // Reset the device state bits { GetDevStateInfo (Dev)->ClrState (NewState); } DevStateInfo* DevStateColl::At (int Index) // Return a pointer to the item at position Index. // OVERRIDE FOR DEBUGGING { // Check range if (Index < 0 || Index >= Count) { FAIL ("DevStateColl::At: Index out of bounds"); return NULL; } return SortedCollection::At (Index); } void DevStateColl::SetSchleife (unsigned Dev, int State) { GetDevStateInfo (Dev)->SetSchleife (State); } void DevStateColl::SetAmt (unsigned Dev, int State, unsigned Amt) { GetDevStateInfo (Dev)->SetAmt (State, Amt); } void DevStateColl::SetInt (unsigned Dev, int State, unsigned Int) { GetDevStateInfo (Dev)->SetInt (State, Int); } void DevStateColl::SetTon (unsigned Dev, int State) { GetDevStateInfo (Dev)->SetTon (State); } void DevStateColl::SetWTon (unsigned Dev, int State) { GetDevStateInfo (Dev)->SetWTon (State); } void DevStateColl::SetTFE (unsigned Dev, int State) { GetDevStateInfo (Dev)->SetTFE (State); } void DevStateColl::SetRuf (unsigned Dev, int State) { GetDevStateInfo (Dev)->SetRuf (State); } void DevStateColl::AddDigit (unsigned Dev, char Digit) // Add a digit to the phone number if the device is in a state where a digit // is accepted (dialed) { GetDevStateInfo (Dev)->AddDigit (Digit); } static DevStateColl DevState; /*****************************************************************************/ /* class MatrixListBox */ /*****************************************************************************/ class MatrixListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: MatrixListBox (i16 aID, const Point& aSize); // Create a matrix listbox MatrixListBox (StreamableInit); // Create an empty matrix listbox virtual ~MatrixListBox (); // Destroy a MatrixListBox virtual u16 StreamableID () const; // Return the streamable ID static Streamable* Build (); // Build an empty object }; // Register the class LINK (MatrixListBox, ID_MatrixListBox); MatrixListBox::MatrixListBox (i16 aID, const Point& aSize): ListBox ("", aID, aSize, atEditNormal, atEditBar, atEditNormal, NULL) { // Set the collection SetColl (&DevState); } inline MatrixListBox::MatrixListBox (StreamableInit): ListBox (Empty) // Create an empty matrix listbox { // Set the collection SetColl (&DevState); } MatrixListBox::~MatrixListBox () // Destroy a MatrixListBox { // Beware: Before deleting, reset the collection pointer of the listbox SetColl (NULL); } void MatrixListBox::Print (int Index, int X, int Y, u16 Attr) { // Get the line String S = Coll->At (Index)->MatrixLine; // Pad the line to length S.Pad (String::Right, Size.X); // Write out the string Owner->Write (X, Y, S, Attr); } u16 MatrixListBox::StreamableID () const // Return the streamable ID { return ID_MatrixListBox; } Streamable* MatrixListBox::Build () // Build an empty object { return new MatrixListBox (Empty); } /*****************************************************************************/ /* class MatrixWindow */ /*****************************************************************************/ void MatrixWindow::HandleKey (Key& K) // Key dispatcher used in Browse { // First call the derived function. ItemWindow::HandleKey (K); // Maybe the listbox has some work MatrixBox->HandleKey (K); } MatrixWindow::MatrixWindow (const Point& Pos, unsigned aDevCount): ItemWindow (Rect (Pos.X, Pos.Y, Pos.X+MatrixWindowWidth+2, Pos.Y+11), wfFramed | wfCanMove | wfCanResize | wfSaveVisible), MatrixBox (NULL), DevCount (aDevCount), ZoomSize (OBounds) { // Count of windows must be zero, otherwise this is an error CHECK (WindowCount == 0); // Lock window output Lock (); // If there is a stored window size in the settings file, resize the // window to the stored rectangle. Rect StoredBounds = StgGetRect (MatrixWindowBounds, OBounds); if (StoredBounds != OBounds) { Resize (StoredBounds); } // Set the window title SetHeader (LoadAppMsg (msMatrixWindowTitle)); // Create and insert the header line TextItem* HdrItem = new TextItem (LoadAppMsg (msMatrixWindowHeader), 100, atTextNormal, NULL); AddItem (HdrItem); HdrItem->SetWidth (IXSize ()); HdrItem->SetPos (0, 0); // Create a listbox inside the window Point Size (IXSize (), IYSize () - 1); MatrixBox = new MatrixListBox (1, Size); AddItem (MatrixBox); MatrixBox->SetPos (0, 1); MatrixBox->Draw (); // Redraw the window contents DrawInterior (); // Unlock the window, allowing output Unlock (); // Ok, we have the window now WindowCount++; // Tell the application that the window count has changed PostEvent (evMatrixWinChange, WindowCount); } inline MatrixWindow::MatrixWindow (StreamableInit): ItemWindow (Empty) { // One window more WindowCount++; // Tell the application that the window count has changed PostEvent (evMatrixWinChange, WindowCount); } MatrixWindow::~MatrixWindow () { // Store the current window position and size into the settings file StgPutRect (OBounds, MatrixWindowBounds); // Decrease the window count and invalidate the global pointer WindowCount--; // Tell the application that the window count has changed PostEvent (evMatrixWinChange, WindowCount); } void MatrixWindow::Store (Stream& S) const // Store the object into a stream { // Before storing, be shure to reset the pointer for the device state // collection MatrixBox->SetColl (NULL); // Now use the inherited store ItemWindow::Store (S); // Reset the collection pointer MatrixBox->SetColl (&DevState); // Store additional data S << DevCount << ZoomSize; } void MatrixWindow::Load (Stream& S) // Load the object from a stream { // Load the derived data ItemWindow::Load (S); // Load the device count S >> DevCount >> ZoomSize; // Get a pointer to the listbox MatrixBox = (MatrixListBox*) ForcedItemWithID (1); // Assign a pointer to the global collection MatrixBox->SetColl (&DevState); // The inherited Load function did not draw the contents of the listbox // since the listbox had no valid data collection at that time. Do the // redraw now. DrawMatrix (); } u16 MatrixWindow::StreamableID () const // Return the streamable ID { return ID_MatrixWindow; } Streamable* MatrixWindow::Build () // Build an empty object { return new MatrixWindow (Empty); } unsigned MatrixWindow::MinXSize () const // Return the minimum X size of the window. Override this to limit resizing. { return 7; // Device number + online flag } unsigned MatrixWindow::MinYSize () const // Return the minumim Y size of the window. Override this to limit resizing. { return 4; // Header and one device } void MatrixWindow::Resize (const Rect& NewBounds) // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). { // If we have already a matrix listbox, resize it to fit into the new // window if (MatrixBox) { MatrixBox->SetWidth (NewBounds.XSize () - 2); MatrixBox->SetHeight (NewBounds.YSize () - 3); } // Now do the actual resize ItemWindow::Resize (NewBounds); } void MatrixWindow::Zoom () // Zoom the window { // Get the desktop bounds Rect Desktop = Background->GetDesktop (); // Check if we must zoom in or out if (OBounds != Desktop) { // Remember the old size, then zoom out ZoomSize = OBounds; Resize (Desktop); } else { // Zoom in Resize (ZoomSize); } } void MatrixWindow::DrawMatrix () // Redraw the listbox after changes { MatrixBox->Draw (); } void MatrixWindow::HandleEvent (Event& E) // Handle incoming events { // Call the derived function ItemWindow::HandleEvent (E); if (E.Handled) { return; } // Switch on the type of event switch (E.What) { case evMatrixChange: // Redraw the complete matrix for now DrawMatrix (); break; } } /*****************************************************************************/ /* Static variables of class MatrixWindow */ /*****************************************************************************/ unsigned MatrixWindow::WindowCount = 0; /*****************************************************************************/ /* Helper functions */ /*****************************************************************************/ static char MapDigit (unsigned Digit) // Map a digit code into the corresponding character { // Remap the digit code to a real digit switch (Digit) { case 1: return '1'; case 2: return '2'; case 3: return '3'; case 4: return '4'; case 5: return '5'; case 6: return '6'; case 7: return '7'; case 8: return '8'; case 9: return '9'; case 10: return '0'; case 16: return 'R'; default: return '?'; } } /*****************************************************************************/ /* Matrix update functions */ /*****************************************************************************/ static void RedrawMatrixCol (unsigned Dev) { // Post an event PostEvent (evMatrixChange, (void*)DevState.GetDevStateInfo (Dev)); } static void WriteDialStatus (unsigned Dev, unsigned Digit) { // Remember the digit, but only if we don't have already a connection DevState.AddDigit (Dev, MapDigit (Digit)); // Update the matrix window RedrawMatrixCol (Dev); } static void SetMatrix (unsigned Col, unsigned Dev, int State) { // Check which matrix column to set switch (Col) { case 0: DevState.SetAmt (Dev, State, 1); break; case 1: DevState.SetAmt (Dev, State, 2); break; case 2: DevState.SetInt (Dev, State, 1); break; case 3: DevState.SetInt (Dev, State, 2); break; case 4: DevState.SetInt (Dev, State, 3); break; case 5: DevState.SetTon (Dev, State); break; case 6: DevState.SetWTon (Dev, State); break; case 7: DevState.SetTFE (Dev, State); break; default: WriteDebugLog (FormatStr ("Unknown matrix col: %d", Col)); break; } // Update the matrix column RedrawMatrixCol (Dev); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ static String MsgDesc (const char* S, unsigned Dev, unsigned State) { return FormatStr ("Device %d: %s %s", Dev+21, S, State? "on" : "off"); } static String DialDesc (const char* S, unsigned Dev, unsigned Digit) { return FormatStr ("Device %d: %s '%c'", Dev+21, S, MapDigit (Digit)); } static String MatrixDesc (unsigned Dev, unsigned Code, unsigned State) { // Map the code into a real action char* Action; switch (Code) { case 0: Action = "Line 1"; break; case 1: Action = "Line 2"; break; case 2: Action = "Int 1"; break; case 3: Action = "Int 2"; break; case 4: Action = "Int 3"; break; case 5: Action = "Tone"; break; case 6: Action = "Dial tone"; break; case 7: Action = "TFE"; break; default: Action = "Unknown matrix col"; break; } return FormatStr ("Device %d: %s %s", Dev+21, Action, State? "on" : "off"); } String DiagMsgDesc (const unsigned char* Msg) // Return a textual description of the given diagnostic message { switch (Msg [1]) { case 0x00: return "Enable diag mode"; case 0x01: return "Disable diag mode"; case 0x02: // connection matrix return MatrixDesc (Msg [3], Msg [2], Msg [4]); case 0x03: // call return MsgDesc ("Call", Msg [2], Msg [4]); case 0x04: // Schleifenzustand return MsgDesc ("Loop", Msg [2], Msg [4]); case 0x05: // Pulse dial return DialDesc ("Pulse dial", Msg [2], Msg [4]); case 0x06: // Tone dial return DialDesc ("Tone Dial", IntCon [Msg [2]], Msg [4]); case 0x07: // LED state return FormatStr ("LED state %s", Msg [4]? "on" : "off"); case 0x08: // Charges return ""; case 0x09: // TFE amplifier return ""; case 0x0A: // Door opener return ""; case 0x0D: // Switch return ""; default: // Unknown debug message! return "Unknown diagnostic message!"; } } void HandleDiagMsg (const unsigned char* Msg) // Handle a diagnostic message from the istec { // Check the event type String S; switch (Msg [1]) { case 0x02: // connection matrix SetMatrix (Msg [2], Msg [3], Msg [4]); break; case 0x03: // call DevState.SetRuf (Msg [2], Msg [4]); RedrawMatrixCol (Msg [2]); break; case 0x04: // Schleifenzustand DevState.SetSchleife (Msg [2], Msg [4]); RedrawMatrixCol (Msg [2]); break; case 0x05: // Pulse dial WriteDialStatus (Msg [2], Msg [4]); break; case 0x06: // Tone dial WriteDialStatus (IntCon [Msg [2]], Msg [4]); break; case 0x07: // LED state break; case 0x08: // Charges break; case 0x09: // TFE amplifier break; case 0x0A: // Door opener break; case 0x0D: // Switch break; default: // Unknown debug message! S = FormatStr ("%02x %02x %02x %02x %02x", Msg [1], Msg [2], Msg [3], Msg [4], Msg [5]); WriteDebugLog ("Warning: Got unknown diagnostic message: " + S); break; } } estic-1.61.orig/estic/icdiag.h0100644000176100001440000000614307031424725015520 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDIAG.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICDIAG_H #define _ICDIAG_H #include "itemwin.h" /*****************************************************************************/ /* class MatrixWindow */ /*****************************************************************************/ class MatrixWindow: public ItemWindow { class MatrixListBox* MatrixBox; // Direct pointer to listbox u16 DevCount; // Device count Rect ZoomSize; // Size for zooming static unsigned WindowCount; // Count of windows protected: virtual void HandleKey (Key& K); // Key dispatcher used in Browse public: MatrixWindow (const Point& Pos, unsigned aDevCount); // Create a matrix window MatrixWindow (StreamableInit); // Create an empty object virtual ~MatrixWindow (); // Destroy a matrix window virtual void Store (Stream&) const; // Store the object into a stream virtual void Load (Stream&); // Load the object from a stream virtual u16 StreamableID () const; // Return the streamable ID static Streamable* Build (); // Build an empty object virtual unsigned MinXSize () const; // Return the minimum X size of the window. Override this to limit resizing. virtual unsigned MinYSize () const; // Return the minumim Y size of the window. Override this to limit resizing. virtual void Resize (const Rect& NewBounds); // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). virtual void Zoom (); // Zoom the window void DrawMatrix (); // Redraw the listbox after changes virtual void HandleEvent (Event& E); // Handle incoming events }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ String DiagMsgDesc (const unsigned char* Msg); // Return a textual description of the given diagnostic message void HandleDiagMsg (const unsigned char* Msg); // Handle a diagnostic message from the istec // End of ICDIAG.H #endif estic-1.61.orig/estic/icdlog.cc0100644000176100001440000000514707031424725015702 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDLOG.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "errlog.h" #include "filepath.h" #include "icmsg.h" #include "icerror.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msOpenError = MSGBASE_ICDLOG + 0; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Append or overwrite? int AppendDebugLog = 0; // The logfile object static ErrLog* Logfile = 0; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void DoneDebugLog () // Close an open debug log { if (Logfile) { delete Logfile; Logfile = 0; } } void InitDebugLog (const String& Filename) // Initialize (open) the debug log. If the given name is empty, the call is // ignored. Notify the user in case of errors. { // Ignore an empty file name if (Filename.IsEmpty ()) { return; } // Create the logfile u16 Flags = AppendDebugLog? 0 : elTruncate; Logfile = new ErrLog (MakeAbsolute (Filename), Flags); // Check for errors if (Logfile->HasError ()) { // Show an error message IstecError (msOpenError); // Delete the logfile DoneDebugLog (); } } void WriteDebugLog (const String& Msg) // Log the given message if the debug log is open { if (Logfile) { Logfile->Write (Msg); } } estic-1.61.orig/estic/icdlog.h0100644000176100001440000000335407031424725015542 0ustar debacleusers/*****************************************************************************/ /* */ /* ICDLOG.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICDLOG_H #define _ICDLOG_H #include "str.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Append or overwrite? extern int AppendDebugLog; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void InitDebugLog (const String& Filename); // Initialize (open) the debug log. If the given name is empty, the call is // ignored. Notify the user in case of errors. void DoneDebugLog (); // Close an open debug log void WriteDebugLog (const String& Msg); // Log the given message if the debug log is open // End of ICDLOG.H #endif estic-1.61.orig/estic/icei.cc0100644000176100001440000000772107031424725015352 0ustar debacleusers/*****************************************************************************/ /* */ /* ICEI.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is an interface module to connect other software to ESTIC. All // important information regarding the Istec is routed through the event // handler below. Just fill in your code... #include "event.h" #include "str.h" #include "icevents.h" #include "devstate.h" #include "iccli.h" /*****************************************************************************/ /* class ExternalInterface */ /*****************************************************************************/ class ExternalInterface: public EventHandler { public: virtual void HandleEvent (Event& E); // Handle incoming events. }; void ExternalInterface::HandleEvent (Event& E) { // Switch on the type of event switch (E.What) { case evInit: // This event is posted if the initialization of ESTIC is // complete. All resources are already valid if this event // comes in. Add your own stuff if you have to. break; case evExit: // This event is posted from the applications constructor if // application is shutting down. All resources are still valid // when this event happens. break; case evAbort: // This event is posted in an emergency situation if spunk // detected an internal processing error. It is usually *not* // followed by an evExit event. // Beware: The application may be in an unstable state if this // event happens, so you cannot rely on anything. Place critical // cleanup code here but only if needed. break; case evIdle: // This event is posted if the application is idle. You cannot // rely on any specific calling frequency, this event may or // may not be posted. But if you have something, that must be // done in a regular manner, do it here... break; case evSecondChange: // This event may be posted if the application is idle and a // new second has begun. Used for clocks or other stuff. break; case evMinuteChange: // This event may be posted if the application is idle and a // new minute has begun. Used for clocks or other stuff. break; case evChargeUpdate: // This event is posted if something is written to the Charges // variable in module iccom. This does not mean that the charges // have really changed, but on the other side, the charges do // not change without posting this event. break; case evMatrixChange: // A device had a change in the connection matrix or the dialed // number. E.Info.P points to the DevStateInfo object that had // the change. break; case evCallLogMsg: // This event is posted after a call is complete. E.Info.O // contains a pointer to a string with the complete log message. // If you need more specific information, have a look at // evCallComplete. break; case evCallComplete: // This event is posted after an external call is complete. // E.Info.O is a pointer to a DevStateInfo object that contains // complete information about the call. break; case evIncomingCall: // Posted when the istec detects an incoming call and sends the // CLI message. E.Info.O is a pointer to a CLI object that // contains the calling partys number and more information. break; } } /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Declare a static ExternalInterface object to have the event handler called static ExternalInterface EI; estic-1.61.orig/estic/icerror.cc0100644000176100001440000000240407031424725016077 0ustar debacleusers/*****************************************************************************/ /* */ /* ICERROR.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "stdmsg.h" #include "progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ void IstecError (unsigned MsgNum) // Display an error message, the message is taken from the application message // base { ErrorMsg (LoadAppMsg (MsgNum)); } estic-1.61.orig/estic/icerror.h0100644000176100001440000000312507031424725015742 0ustar debacleusers/*****************************************************************************/ /* */ /* ICERROR.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICERROR_H #define _ICERROR_H #include "icmsg.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msErrorIntIgnored = MSGBASE_ICERROR + 0; // Internal error: ignored /*****************************************************************************/ /* Code */ /*****************************************************************************/ void IstecError (unsigned MsgNum); // Display an error message, the message is taken from the application message // base // End of ICERROR.H #endif estic-1.61.orig/estic/icevents.h0100644000176100001440000000502007031424725016111 0ustar debacleusers/*****************************************************************************/ /* */ /* ICEVENTS.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // ESTIC event codes #ifndef _ICEVENTS_H #define _ICEVENTS_H #include "eventid.h" /*****************************************************************************/ /* Event codes */ /*****************************************************************************/ // Charges have changed const unsigned evChargeUpdate = evUser + 1; // A matrix row has changed. Info.P is a pointer to the DevStateInfo entry const unsigned evMatrixChange = evUser + 2; // Log message for call. Info.O is a pointer to a string containing the message const unsigned evCallLogMsg = evUser + 3; // Call complete. Info.O is a pointer to a DevStateInfo object containing the // call data. const unsigned evCallComplete = evUser + 4; // Ring a phone. The U parameter is the device plus 256 times the duration // in seconds. const unsigned evForcedRing = evUser + 5; // Incoming call. Info.O points to a CLI object. const unsigned evIncomingCall = evUser + 6; // Log message for incoming call, Info.O points to a string containing the log // message const unsigned evIncomingLogMsg = evUser + 7; // CRON daemon has switched the active configuration. Info.U contains the new // DayNight setting const unsigned evDayNightChange = evUser + 8; // Changes for some windows. Info.U contains the window count const unsigned evMatrixWinChange = evUser + 10; const unsigned evCallWinChange = evUser + 11; const unsigned evChargeWinChange = evUser + 12; const unsigned evIMonWinChange = evUser + 13; const unsigned evCLIWinChange = evUser + 14; // End of ICEVENTS.H #endif estic-1.61.orig/estic/icfile.cc0100644000176100001440000000567707031424725015704 0ustar debacleusers/*****************************************************************************/ /* */ /* ICFILE.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Load/save configuration data to a file #include "stream.h" #include "syserror.h" #include "progutil.h" #include "icmsg.h" #include "icfile.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msInvalidVersion = MSGBASE_ICFILE + 0; const u16 msOpenError = MSGBASE_ICFILE + 1; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Change this if the data representation changes const u32 FileVersion = 160; /*****************************************************************************/ /* Code */ /*****************************************************************************/ String IstecSaveFile (const String& Filename, const IstecConfig& Config) // Save a configuration to a file. The function returns an error message or // the empty string if all is well. { // Open the stream FileStream S (Filename, "wb"); if (S.GetStatus () != stOk) { return LoadAppMsg (msOpenError) + GetSysErrorMsg (S.GetErrorInfo ()); } // Put version and config data into the file S << FileVersion << Config; // Success return ""; } String IstecLoadFile (const String& Filename, IstecConfig& Config) // Load a configuration from a file. The function returns an error message or // the empty string if all is well. { // Open the stream FileStream S (Filename, "rb"); if (S.GetStatus () != stOk) { return LoadAppMsg (msOpenError) + GetSysErrorMsg (S.GetErrorInfo ()); } // Read the version from the file u32 Version; S >> Version; if (Version != FileVersion) { return LoadAppMsg (msInvalidVersion); } // Load the config data S >> Config; // Success return ""; } estic-1.61.orig/estic/icfile.h0100644000176100001440000000310207031424725015523 0ustar debacleusers/*****************************************************************************/ /* */ /* ICFILE.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Load/save configuration data to a file #ifndef _ICFILE_H #define _ICFILE_H #include "str.h" #include "icconfig.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String IstecSaveFile (const String& Filename, const IstecConfig& Config); // Save a configuration to a file. The function returns an error message or // the empty string if all is well. String IstecLoadFile (const String& Filename, IstecConfig& Config); // Load a configuration from a file. The function returns an error message or // the empty string if all is well. // End of ICFILE.H #endif estic-1.61.orig/estic/icident.cc0100644000176100001440000000522607031424725016056 0ustar debacleusers/*****************************************************************************/ /* */ /* ICIDENT.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "progutil.h" #include "icmsg.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msISTECXXXX = MSGBASE_ICIDENT + 0; const u16 msISTEC1003 = MSGBASE_ICIDENT + 1; const u16 msISTEC1008 = MSGBASE_ICIDENT + 2; const u16 msISTEC1016 = MSGBASE_ICIDENT + 3; const u16 msISTEC1024 = MSGBASE_ICIDENT + 4; const u16 msISTEC2016 = MSGBASE_ICIDENT + 5; const u16 msISTEC2024 = MSGBASE_ICIDENT + 6; const u16 msISTEC2400 = MSGBASE_ICIDENT + 7; const u16 msISTEC2416 = MSGBASE_ICIDENT + 8; const u16 msISTEC2424 = MSGBASE_ICIDENT + 9; /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetIstecName (unsigned IstecType) // Get the name of the istec { // Assign the string number unsigned MsgNum; switch (IstecType) { case 1003: MsgNum = msISTEC1003; break; case 1008: MsgNum = msISTEC1008; break; case 1016: MsgNum = msISTEC1016; break; case 1024: MsgNum = msISTEC1024; break; case 2016: MsgNum = msISTEC2016; break; case 2024: MsgNum = msISTEC2024; break; case 2400: MsgNum = msISTEC2400; break; case 2416: MsgNum = msISTEC2416; break; case 2424: MsgNum = msISTEC2424; break; default: MsgNum = msISTECXXXX; break; } // Load and return the correct name return LoadAppMsg (MsgNum); } estic-1.61.orig/estic/icident.h0100644000176100001440000000230207031424725015710 0ustar debacleusers/*****************************************************************************/ /* */ /* ICIDENT.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICIDENT_H #define _ICIDENT_H /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetIstecName (unsigned IstecType); // Get the name of the istec // End of ICIDENT.H #endif estic-1.61.orig/estic/icintcon.cc0100644000176100001440000000264007031424725016242 0ustar debacleusers/*****************************************************************************/ /* */ /* ICINTCON.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The diag data for tone dial is somewhat weird: When using pulse dial, the // diag message from the istec contains the device number. When using tone // dial, the number of the internal connection is transmitted instead. To // show the device number in both cases, we hold the device that uses an // internal connection in the array below unsigned IntCon [3]; estic-1.61.orig/estic/icintcon.h0100644000176100001440000000276007031424725016107 0ustar debacleusers/*****************************************************************************/ /* */ /* ICINTCON.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICINTCON_H #define _ICINTCON_H /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The diag data for tone dial is somewhat weird: When using pulse dial, the // diag message from the istec contains the device number. When using tone // dial, the number of the internal connection is transmitted instead. To // show the device number in both cases, we hold the device that uses an // internal connection in the array below extern unsigned IntCon [3]; // End of ICINTCON.H #endif estic-1.61.orig/estic/icload.cc0100644000176100001440000002110607031424725015665 0ustar debacleusers/*****************************************************************************/ /* */ /* ICLOAD.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include "delay.h" #include "str.h" #include "filepath.h" #include "icconfig.h" #include "iccom.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ static String ComPortName = "COM2"; static IstecBaseConfig BaseConfig; static IstecDevConfig DevConfig; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void EvalCmd (int RetCode) // Evaluate the return code of an istec command function. If the return // code denotes an error, an error message is printed on stderr and the // program is terminated. { switch (RetCode) { case ieRecBufOverflow: // Receive buffer overflow fprintf (stderr, "Receive buffer overflow (internal icload error)\n"); exit (2); case ieRecBufUnderflow: // Receive buffer underflow fprintf (stderr, "Receive buffer underflow (internal icload error)\n"); exit (2); case ieInvalidReply: // Invalid reply fprintf (stderr, "Invalid reply from the ISTEC\n"); exit (2); case ieWrongDevice: // Wrong device number in reply fprintf (stderr, "Wrong device number in reply\n"); exit (2); case iePortNotOpen: // COM port not open fprintf (stderr, "Serial device is not open (internal icload error)\n"); exit (2); case ieTimeout: // Timeout fprintf (stderr, "Communication timeout\n"); exit (1); case ieDone: // ok break; default: fprintf (stderr, "EvalCmd: Unexpected return code\n"); exit (3); } } static void LoadFile (String Name) // Load the configuration from a file { // Add the default extension to the file name AddDefaultExtension (Name, ".ic"); // Open the file FILE* F = fopen (Name.GetStr (), "rb"); if (F == NULL) { fprintf (stderr, "Error opening %s\n", Name.GetStr ()); exit (1); } // Read the configuration fread (&BaseConfig, sizeof (BaseConfig), 1, F); fread (&DevConfig, sizeof (DevConfig), 1, F); // Close the file fclose (F); } static void ResetCharges () // Reset all charges { // Create an empty charges object IstecCharges Charges; // Send the istec command EvalCmd (IstecPutCharges (Charges)); } static int GetNewCharges () // Request and wait for an update of the charge info. Return a result code. { // Reset the flag ChargeUpdate = 0; // Send the command int Result = IstecRequestCharges (); if (Result == ieDone) { // Wait for the new charges unsigned I = 0; do { Delay (100); IstecPoll (); } while (++I < 40 && ChargeUpdate == 0); // Check for a timeout if (ChargeUpdate == 0) { // Timeout, pop up a message Result = ieTimeout; } else { Result = ieDone; } } return Result; } static int LoadConfig (IstecBaseConfig& BC, struct DevConfig* DC) // Load all config files and the charges from the istec { // Load the config stuff from the istec int Result = IstecGetConfig (BC, DC); // If we could get the configuration, read also the charges if (Result == ieDone) { Result = GetNewCharges (); } // Return the result return Result; } static void Usage () // Print usage information and exit { fprintf (stderr, "ICLOAD - Load ISTEC configuration\n" "(C) 1995 Ullrich von Bassewitz \n" "\n" "Usage: icload [options] [file]\n" "\n" "Options:\n" "\t-aADR Set port base address (DOS only)\n" "\t-c Print charges on stdout\n" "\t-iIRQ Set port IRQ (DOS only)\n" "\t-n Don't make new config permanent\n" "\t-pNAME Set name of serial device\n" "\t-r Reset charges\n"); exit (1); } int main (int argc, char* argv []) { // Command line options const char* ConfigFile = 0; int optPrintCharges = 0; int optResetCharges = 0; int optNotPermanent = 0; // Parse the command line int I = 1; while (I < argc) { char* Item = argv [I]; if (*Item == '-') { Item++; switch (*Item) { case 'a': // Set port address PortBase = atoi (++Item); break; case 'c': // Print charges optPrintCharges = 1; break; case 'i': // Set port irq PortIRQ = atoi (++Item); break; case 'n': // Don't make changes permanent optNotPermanent = 1; break; case 'p': // Set port name ComPortName = ++Item; break; case 'r': // Clear the charges optResetCharges = 1; break; default: // Print usage information and exit Usage (); break; } } else { // Configuration file name if (ConfigFile) { // Already got a filename fprintf (stderr, "Duplicate file name: %s\n", Item); exit (1); } else { ConfigFile = Item; } } // Next argument I++; } // Open the port if (OpenComPort (ComPortName) != 0) { // Port could not be opened fprintf (stderr, "Could not open serial port!\n"); exit (1); } // The com port is open. Make shure, it is closed on exit atexit (CloseComPort); // Com port could be opened, check for the istec EvalCmd (IstecReady ()); // Load the current configuration and charges from the istec IstecBaseConfig CurrentBaseConfig; IstecDevConfig CurrentDevConfig; EvalCmd (LoadConfig (CurrentBaseConfig, CurrentDevConfig)); // Ok, now: // // 1. If a config file is specified, send that file to the istec. // 2. If an output of the device charges is requested, do that. // 3. If the charges should be cleared, do that. // 4. If MakePermanent is not switched off, _and_ if a new config // file was sent to the istec, make the config permament. // // 1. if (ConfigFile != NULL) { // Load a config file into memory LoadFile (ConfigFile); // Send the stuff to the istec EvalCmd (IstecPutConfig (BaseConfig, DevConfig, CurrentBaseConfig.AB_InterfaceCount)); } // 2. // if (optPrintCharges) { for (unsigned I = 0; I < CurrentBaseConfig.AB_InterfaceCount; I++) { printf ("%d ", Charges [I]); } printf ("\n"); } // 3. if (optResetCharges) { ResetCharges (); } // 4. if (ConfigFile != 0 && optNotPermanent == 0) { EvalCmd (IstecMakePermanent ()); } // Close the com port CloseComPort (); // Success return 0; } estic-1.61.orig/estic/iclog.cc0100644000176100001440000001374207031426140015527 0ustar debacleusers/*****************************************************************************/ /* */ /* ICLOG.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "event.h" #include "strcvt.h" #include "datetime.h" #include "filepath.h" #include "icevents.h" #include "devstate.h" #include "iccli.h" #include "iclog.h" /*****************************************************************************/ /* class CallLogger */ /*****************************************************************************/ class CallLogger: public EventHandler { static String ExpandName (const String& Filename, const Time& T, unsigned Dev); // Expand the name to a real file name. static void LogOutgoing (const String& Filename, String Msg, const Time& T, unsigned Dev); // Log the message of the outgoing call to one file static void LogIncoming (const String& Filename, String Msg, const Time& T); // Log the message of an incoming call to one file public: virtual void HandleEvent (Event& E); // Handle incoming events }; String CallLogger::ExpandName (const String& Filename, const Time& T, unsigned Dev) // Expand the name to a real file name. { // Expand private escape sequences unsigned I = 0; unsigned Len = Filename.Len (); String S (Len); while (I < Len) { // Get the next character from the source char C = Filename [I++]; // Look after '%' only if another char follows if (C == '%' && I < Len) { C = Filename [I++]; switch (C) { case 'E': // %E - Insert extension number S += U32Str (Dev+21); break; default: S += '%'; S += C; break; } } else { // Just copy S += C; } } return MakeAbsolute (T.DateTimeStr (S)); } void CallLogger::LogOutgoing (const String& Filename, String Msg, const Time& T, unsigned Dev) // Log the message of the outgoing call to one file { // If the filename is empty, bail out early if (Filename.IsEmpty ()) { return; } // Expand the filename. String ExpandedName = ExpandName (Filename, T, Dev); // Open the file FILE* F = fopen (ExpandedName.GetStr (), "a+t"); if (F == NULL) { // Got an error - ignore it return; } // Convert the string to the local conventions Msg.OutputCvt (); // Write the message to the file fputs (Msg.GetStr (), F); fputc ('\n', F); // Close the file fclose (F); } void CallLogger::LogIncoming (const String& Filename, String Msg, const Time& T) // Log the message of an incoming call to one file { // If the filename is empty, bail out early if (Filename.IsEmpty ()) { return; } // Expand the filename. String ExpandedName = MakeAbsolute (T.DateTimeStr (Filename)); // Open the file FILE* F = fopen (ExpandedName.GetStr (), "a+t"); if (F == NULL) { // Got an error - ignore it return; } // Convert the string to the local conventions Msg.OutputCvt (); // Write the message to the file fputs (Msg.GetStr (), F); fputc ('\n', F); // Close the file fclose (F); } void CallLogger::HandleEvent (Event& E) // Handle incoming events { String Msg (80); DevStateInfo* DS; CLI* C; switch (E.What) { case evCallComplete: // Call is complete. E.Info.O is the DevStateInfo object DS = (DevStateInfo*) E.Info.O; // Check if we should log the call if (LogZeroCostCalls || DS->CallCharges > 0) { // Ok, get the log message and convert it to the output format Msg = DS->LogMsg (); Msg.OutputCvt (); // Log it in all three files LogOutgoing (OutgoingLog1, Msg, DS->CallStart, DS->DevNum); LogOutgoing (OutgoingLog2, Msg, DS->CallStart, DS->DevNum); LogOutgoing (OutgoingLog3, Msg, DS->CallStart, DS->DevNum); } break; case evIncomingCall: // Got an incoming call, E.Info.O is the CLI info object C = (CLI*) E.Info.O; // Build a message Msg = C->LogMsg (); // Log it to all three files LogIncoming (IncomingLog1, Msg, C->T); LogIncoming (IncomingLog2, Msg, C->T); LogIncoming (IncomingLog3, Msg, C->T); break; } } /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Names of the logfiles String OutgoingLog1 = "outgoing.log"; String OutgoingLog2 = ""; String OutgoingLog3 = ""; String IncomingLog1 = "incoming.log"; String IncomingLog2 = ""; String IncomingLog3 = ""; // If true, log calls with a chargecount of zero int LogZeroCostCalls = 1; // Price of a charge unit double PricePerUnit = 0.12; // A static copy of a CallLogger object static CallLogger CL; estic-1.61.orig/estic/iclog.h0100644000176100001440000000202407031424725015367 0ustar debacleusers/*****************************************************************************/ /* */ /* ICLOG.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICLOG_H #define _ICLOG_H #include "datetime.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Names of the logfiles extern String OutgoingLog1; extern String OutgoingLog2; extern String OutgoingLog3; extern String IncomingLog1; extern String IncomingLog2; extern String IncomingLog3; // If true, log calls with a chargecount of zero extern int LogZeroCostCalls; // Price of a charge unit extern double PricePerUnit; // End of ICLOG.H #endif estic-1.61.orig/estic/icmsg.h0100644000176100001440000000353507031424725015404 0ustar debacleusers/*****************************************************************************/ /* */ /* ICMSG.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICMSG_H #define _ICMSG_H #include "machine.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 MSGBASE_ISTEC = 0; const u16 MSGBASE_ICERROR = 200; const u16 MSGBASE_ICIDENT = 300; const u16 MSGBASE_ICDEVS = 400; const u16 MSGBASE_ICBASEED = 500; const u16 MSGBASE_ICDIAG = 600; const u16 MSGBASE_ICALIAS = 700; const u16 MSGBASE_ICIMON = 800; const u16 MSGBASE_ICDLOG = 900; const u16 MSGBASE_ICCWIN = 1100; const u16 MSGBASE_CHARGWIN = 1200; const u16 MSGBASE_ICCRON = 1300; const u16 MSGBASE_ICCLIWIN = 1400; const u16 MSGBASE_ICCTI = 1500; const u16 MSGBASE_ICFILE = 1600; const u16 MSGBASE_ICSHORT = 1700; // End of ICMSG.H #endif estic-1.61.orig/estic/icmsgwin.cc0100644000176100001440000001463007031424725016256 0ustar debacleusers/*****************************************************************************/ /* */ /* ICMSGWIN.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // A window that holds a header and an area for messages #include "coll.h" #include "textitem.h" #include "settings.h" #include "progutil.h" #include "icmsg.h" #include "icobjid.h" #include "icmsgwin.h" /*****************************************************************************/ /* class StringMsgColl */ /*****************************************************************************/ class StringMsgColl: public Collection { public: StringMsgColl (); // Create a StringMsgColl StringMsgColl (StreamableInit); // Create an empty StringMsgColl virtual u16 StreamableID () const; // return the object id static Streamable* Build (); // Return a new (empty) object virtual void Insert (String* S); // Insert a new string void Insert (const String& S); // Insert a new string }; // Register the class LINK (StringMsgColl, ID_StringMsgColl); StringMsgColl::StringMsgColl (): Collection (30, 0, 1) // Create a StringMsgColl { } StringMsgColl::StringMsgColl (StreamableInit): Collection (Empty) // Create an empty StringMsgColl { } u16 StringMsgColl::StreamableID () const // return the object id { return ID_StringMsgColl; } Streamable* StringMsgColl::Build () // Return a new (empty) object { return new StringMsgColl (Empty); } void StringMsgColl::Insert (String* S) // Insert a new string { if (Count == Limit) { // Collection is full, delete the first element AtDelete (0); } Collection::Insert (S); } void StringMsgColl::Insert (const String& S) // Insert a new string { Insert (new String (S)); } /*****************************************************************************/ /* class IstecMsgWindow */ /*****************************************************************************/ IstecMsgWindow::IstecMsgWindow (unsigned msWindowTitle, unsigned msWindowHeader1, unsigned msWindowHeader2, const String& aSizeName): ItemWindow (Rect (0, 1, 80, 16), wfFramed | wfCanMove | wfCanResize | wfSaveVisible), Messages (new StringMsgColl), ZoomSize (OBounds), SavedSizeName (aSizeName) // Construct an IstecMsgWindow { // Lock window output Lock (); // If there is a stored window size in the settings file, resize the // window to the stored rectangle. if (!SavedSizeName.IsEmpty ()) { Rect StoredBounds = StgGetRect (SavedSizeName, OBounds); if (StoredBounds != OBounds) { Resize (StoredBounds); } } // Set the header SetHeader (::LoadAppMsg (msWindowTitle)); // Create and insert the items for both header lines const String& Header1 = ::LoadAppMsg (msWindowHeader1); const String& Header2 = ::LoadAppMsg (msWindowHeader2); TextItem* H1 = new TextItem (Header1, 100, atTextNormal, NULL); TextItem* H2 = new TextItem (Header2, 101, atTextNormal, NULL); AddItem (H1); AddItem (H2); H1->SetWidth (Header1.Len ()); H2->SetWidth (Header2.Len ()); H1->SetPos (0, 0); H2->SetPos (0, 1); // Make an update of the window. DrawItems (); // Unlock the output Unlock (); } IstecMsgWindow::~IstecMsgWindow () // Destruct an IstecMsgWindow { // Store the current window position and size into the settings file if (!SavedSizeName.IsEmpty ()) { StgPutRect (OBounds, SavedSizeName); } // Delete the string collection delete Messages; } void IstecMsgWindow::Store (Stream& S) const { // Call the inherited Store ItemWindow::Store (S); // Store the string collection S.Put (Messages); // Store the rest of the stuff S << ZoomSize << SavedSizeName; } void IstecMsgWindow::Load (Stream& S) { // Call the inherited Load ItemWindow::Load (S); // Load the string collection Messages = (StringMsgColl*) S.Get (); // Load the rest of the stuff S >> ZoomSize >> SavedSizeName; } void IstecMsgWindow::DrawInterior () // Draw the window contents { // Lock window output Lock (); // Call the inherited function to draw item stuff ItemWindow::DrawInterior (); // Draw window specifics unsigned YSize = IYSize () - 2; unsigned Count = Messages->GetCount (); unsigned Index = Count > YSize? Count - YSize : 0; // Write out the lines int Y = 2; while (Index < Count) { // Watcom compiler bug: WCC needs an override here ItemWindow::Write (0, Y++, *Messages->At (Index++)); } // Set the cursor position to the next line SetCursorPos (Point (0, Y)); // Unlock the window, allow output Unlock (); } unsigned IstecMsgWindow::MinXSize () const // Return the minimum X size of the window. Override this to limit resizing. { return 10; } unsigned IstecMsgWindow::MinYSize () const // Return the minumim Y size of the window. Override this to limit resizing. { return 2 + 3; // One text line at least } void IstecMsgWindow::Zoom () // Zoom the window { // Get the desktop bounds Rect Desktop = Background->GetDesktop (); // Check if we must zoom in or out if (OBounds != Desktop) { // Remember the old size, then zoom out ZoomSize = OBounds; Resize (Desktop); } else { // Zoom in Resize (ZoomSize); } } void IstecMsgWindow::Write (const String& S) // Write a line to the window, advance the cursor { // Remember the new line Messages->Insert (S); // Calculate the line count and the position unsigned YSize = IYSize () - 2; unsigned XSize = IXSize (); unsigned Count = Messages->GetCount (); if (Count > YSize) { // Scroll - we have to rewrite all lines unsigned Index = Count - YSize; unsigned Y = 2; while (Index < Count) { String Line (XSize); Line = *Messages->At (Index++); Line.Pad (String::Right, XSize); ItemWindow::Write (0, Y++, Line); } } else { // Just one line - pad it to length String Line (XSize); Line = S; Line.Pad (String::Right, XSize); // Watcom compiler bug: WCC needs an override here ItemWindow::Write (0, 2 + Count - 1, Line); } } estic-1.61.orig/estic/icmsgwin.h0100644000176100001440000000370107031424725016115 0ustar debacleusers/*****************************************************************************/ /* */ /* ICMSGWIN.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // A window that holds a header and an area for messages #ifndef _ICMSGWIN_H #define _ICMSGWIN_H #include "itemwin.h" /*****************************************************************************/ /* class IstecMsgWindow */ /*****************************************************************************/ class IstecMsgWindow: public ItemWindow { class StringMsgColl* Messages; // List of messages Rect ZoomSize; // Small size when zooming String SavedSizeName; // Name of saved size in settings file public: IstecMsgWindow (StreamableInit); // Build constructor IstecMsgWindow (unsigned msWindowTitle, unsigned msWindowHeader1, unsigned msWindowHeader2, const String& aSizeName); // Construct an IstecMsgWindow virtual ~IstecMsgWindow (); // Destruct an IstecMsgWindow virtual void Store (Stream &) const; virtual void Load (Stream &); // Make the window persistent virtual void DrawInterior (); // Draw the window contents virtual unsigned MinXSize () const; // Return the minimum X size of the window. Override this to limit resizing. virtual unsigned MinYSize () const; // Return the minumim Y size of the window. Override this to limit resizing. virtual void Zoom (); // Zoom the window void Write (const String& S); // Write a line to the window, advance the cursor }; inline IstecMsgWindow::IstecMsgWindow (StreamableInit): ItemWindow (Empty) // Build constructor { } // End of ICMSGWIN.H #endif estic-1.61.orig/estic/icobjid.h0100644000176100001440000000243007031424725015676 0ustar debacleusers/*****************************************************************************/ /* */ /* ICOBJID.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICOBJID_H #define _ICOBJID_H #include "streamid.h" /*****************************************************************************/ /* Object ID's */ /*****************************************************************************/ const u16 ID_IMonWindow = ID_USER + 0; const u16 ID_MatrixWindow = ID_USER + 1; const u16 ID_MatrixListBox = ID_USER + 2; const u16 ID_CLIWindow = ID_USER + 3; const u16 ID_StringMsgColl = ID_USER + 4; const u16 ID_CallWindow = ID_USER + 5; const u16 ID_ChargeWindow = ID_USER + 6; const u16 ID_ChargeListbox = ID_USER + 7; const u16 ID_IstecBaseConfig = ID_USER + 8; const u16 ID_IstecDevConfig = ID_USER + 9; const u16 ID_IstecDevColl = ID_USER + 10; const u16 ID_IstecConfig = ID_USER + 11; const u16 ID_ShortNumberInfo = ID_USER + 12; // End of ICOBJID.H #endif estic-1.61.orig/estic/icshort.cc0100644000176100001440000006263707031426140016114 0ustar debacleusers/*****************************************************************************/ /* */ /* ICSHORT.CC */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Handle the short dial numbers #include "listbox.h" #include "crcstrm.h" #include "memstrm.h" #include "menue.h" #include "stdmenue.h" #include "settings.h" #include "syserror.h" #include "progutil.h" #include "icmsg.h" #include "icobjid.h" #include "icac.h" #include "iccti.h" #include "icconfig.h" #include "icalias.h" #include "icshort.h" // Register the classes LINK (ShortNumberInfo, ID_ShortNumberInfo); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msSigStandard = MSGBASE_ICSHORT + 0; const u16 msSigSignal1 = MSGBASE_ICSHORT + 1; const u16 msSigSignal2 = MSGBASE_ICSHORT + 2; const u16 msSigSignal3 = MSGBASE_ICSHORT + 3; const u16 msSigNone = MSGBASE_ICSHORT + 4; const u16 msEditHeader = MSGBASE_ICSHORT + 5; const u16 msOpenError = MSGBASE_ICSHORT + 6; const u16 msInvalidVersion = MSGBASE_ICSHORT + 7; const u16 msUnused = MSGBASE_ICSHORT + 8; const u16 msShortcut = MSGBASE_ICSHORT + 9; const u16 msAutoDial = MSGBASE_ICSHORT + 10; const u16 msLock = MSGBASE_ICSHORT + 11; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name that the window uses to store it's position/size in the settings file static const String ShortDialWindowBounds = "ShortDialWindow.Bounds"; // Version number of short numbers in a file const u32 FileVersion = 100; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class SortedCollection; template class Collection; template class ListBox; #endif /*****************************************************************************/ /* class ShortNumberInfo */ /*****************************************************************************/ ShortNumberInfo::ShortNumberInfo (unsigned aMemory): Memory (aMemory), Usage (usUnused), AutoDial (0), Devices (0), Signaling (siStandard), Locked (0) // Create a ShortNumberInfo { } void ShortNumberInfo::Load (Stream& S) // Load the object from a stream { S >> Memory >> Usage >> Number >> AutoDial >> Devices >> Signaling >> Locked; } void ShortNumberInfo::Store (Stream& S) const // Store the object into a stream { S << Memory << Usage << Number << AutoDial << Devices << Signaling << Locked; } u16 ShortNumberInfo::StreamableID () const // Return the stream ID { return ID_ShortNumberInfo; } Streamable* ShortNumberInfo::Build () // Return a new instance { return new ShortNumberInfo (Empty); } ShortNumberInfo::ShortNumberInfo (const IstecMsg& Msg) // Create a ShortNumberInfo from an istec message { Unpack (Msg); } ShortNumberInfo::ShortNumberInfo (StreamableInit): Number (Empty) // Build constructor { } void ShortNumberInfo::Unpack (const IstecMsg& Msg) // Unpack the contents of a message into the struct { // This *must* be a correct message PRECONDITION (Msg.IsCTIMsg () && (Msg.At (1) == CTI_QUERY || Msg.At (1) == CTI_ACK) && Msg.At (2) == CTI_LOAD_NUMBER); // Get the data from the message Memory = Msg.At (3); unsigned Len = (Msg.At (4) + 1) / 2; // Chars --> Bytes Number = FromBCD (&Msg.Data [5], Len, 0); AutoDial = Msg.At (5 + Len + 0); Devices = Msg.At (5 + Len + 1); Signaling = InSignal (Msg.At (5 + Len + 2)); Locked = Msg.At (5 + Len + 3); // Remove one leading dialprefix from the number, then beautify it if (Number.NotEmpty ()) { if (Number [0] == DialPrefix) { Number.Del (0, 1); if (Number.Len () > 2 && Number [0] == DialPrefix && Number [1] != DialPrefix) { // National number unsigned AreaCodeLen = IstecGetAreaCodeLen (Number); if (AreaCodeLen > 0) { Number.Ins (AreaCodeLen, '/'); } } } } // Ok, now determine the usage from the data if (Number.IsEmpty ()) { // Empty number, entry is unused Usage = usUnused; AutoDial = 0; Devices = 0; Signaling = siStandard; Locked = 0; } else if (AutoDial != 0) { // AutoDial is configured for some devices Usage = usAutoDial; } else if (Devices == 0) { // No devices configured, entry is unused Usage = usUnused; } else { // Valid devices, determine if shortcut or lock if (Locked) { Usage = usLock; } else { Usage = usShortcut; } } // End of message must be reached now CHECK (Msg.At (5 + Len + 4) == CTI_STOP); } void ShortNumberInfo::Pack (IstecMsg& Msg) const // Pack the data into a message ready for download to the istec { // Make a copy of the number with an dial prefix prepended and any non // digit chars removed. String Phone; if (Number.NotEmpty ()) { Phone = DialPrefix + Number; Phone.Remove ("+-/", rmAll); } // Stuff for converting the number to BCD unsigned char Buf [19]; unsigned NumBytes = (Phone.Len () + 1) / 2; unsigned I = 0; // Fill in data that is independent of the usage Buf [I++] = CTI_START; Buf [I++] = CTI_CONF; Buf [I++] = CTI_STORE_NUMBER; Buf [I++] = Memory; Buf [I++] = Phone.Len (); ToBCD (Phone.GetStr (), &Buf [I], NumBytes, 0); I += NumBytes; // The rest of the data depends on the usage switch (GetUsage ()) { case usUnused: Buf [I++] = 0; // AutoDial devices Buf [I++] = 0; // Devices Buf [I++] = OutSignal (GetSignaling ()); // Signal type Buf [I++] = 0; // Lock break; case usShortcut: Buf [I++] = 0; // AutoDial devices Buf [I++] = Devices; // Devices Buf [I++] = OutSignal (GetSignaling ()); // Signal type Buf [I++] = 0; // Lock break; case usAutoDial: Buf [I++] = AutoDial; // AutoDial devices Buf [I++] = 0; // Devices Buf [I++] = OutSignal (GetSignaling ()); // Signal type Buf [I++] = 0; // Lock break; case usLock: Buf [I++] = 0; // AutoDial devices Buf [I++] = Devices; // Devices Buf [I++] = OutSignal (GetSignaling ()); // Signal type Buf [I++] = 0xFF; // Lock break; default: FAIL ("ShortNumberInfo::Pack: Invalid usage type"); } // Fill in the rest of the data Buf [I++] = CTI_STOP; // Now put the stuff into the message Msg.NewData (I, Buf); } unsigned ShortNumberInfo::GetUsage () const // Get the usage info { if (Number.IsEmpty ()) { return usUnused; } else { return Usage; } } void ShortNumberInfo::SetNumber (const String& NewNumber) // Set a new number { Number = IstecBeautifyPhone (NewNumber); } unsigned ShortNumberInfo::GetSignaling () const // Return the signaling info { if (Number.IsEmpty ()) { return siStandard; } else { return Signaling; } } String ShortNumberInfo::GetAlias () const // Get the alias for the given number { return ::GetAlias (Number); } unsigned ShortNumberInfo::GetDeviceMap () const // Return a bitmap of devices that are valid for the current usage { // Determine from the usage which bitmap is valid unsigned Bitmap = 0; switch (GetUsage ()) { case usUnused: Bitmap = 0; break; case usShortcut: Bitmap = Devices; break; case usAutoDial: Bitmap = AutoDial; break; case usLock: Bitmap = Devices; break; default: FAIL ("ShortNumberInfo::GetDeviceMap: Unknown usage value"); } return Bitmap; } void ShortNumberInfo::SetDeviceMap (unsigned NewMap) // Set a new device map { switch (GetUsage ()) { case usUnused: /* Ignore it */ break; case usShortcut: Devices = NewMap; break; case usAutoDial: AutoDial = NewMap; break; case usLock: Devices = NewMap; break; default: FAIL ("ShortNumberInfo::SetDeviceMap: Unknown usage value"); } } String ShortNumberInfo::DeviceList () // Return a list of devices (e.g. "-2--567-") { const unsigned char Mask [8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; const char Dev [8] = { '1', '2', '3', '4', '5', '6', '7', '8' }; // Determine from the usage which bitmap is valid unsigned Bitmap = GetDeviceMap (); // Convert bitmap into a string String S (8); for (unsigned I = 0; I < 8; I++) { S += Bitmap & Mask [I]? Dev [I] : '-'; } return S; } const String& ShortNumberInfo::SignalName () // Return the name for a specific signaling type { unsigned MsgNum = 0; switch (Signaling) { case siStandard: MsgNum = msSigStandard; break; case siSignal1: MsgNum = msSigSignal1; break; case siSignal2: MsgNum = msSigSignal2; break; case siSignal3: MsgNum = msSigSignal3; break; case siNone: MsgNum = msSigNone; break; default: FAIL ("ShortNumberInfo::SignalName: Unknown signal type"); } return LoadAppMsg (MsgNum); } const String& ShortNumberInfo::UsageName () // Return the name for a usage { unsigned MsgNum = 0; switch (GetUsage ()) { case usUnused: MsgNum = msUnused; break; case usShortcut: MsgNum = msShortcut; break; case usAutoDial: MsgNum = msAutoDial; break; case usLock: MsgNum = msLock; break; default: FAIL ("ShortNumberInfo::UsageName: Unknown usage value"); } return LoadAppMsg (MsgNum); } /*****************************************************************************/ /* class ShortNumberColl */ /*****************************************************************************/ int ShortNumberColl::Compare (const u16* Key1, const u16* Key2) { if (*Key1 < *Key2) { return -1; } else if (*Key1 > *Key2) { return 1; } else { return 0; } } const u16* ShortNumberColl::KeyOf (const ShortNumberInfo* Item) // Helpers for managing sort order { return &Item->Memory; } ShortNumberColl::ShortNumberColl (): SortedCollection (100, 50, 1) { // Insert the default count of short numbers for (unsigned Memory = 1; Memory <= ShortNumberCount; Memory++) { Insert (new ShortNumberInfo (Memory)); } } ShortNumberColl::ShortNumberColl (StreamableInit): SortedCollection (Empty) { } ShortNumberInfo& ShortNumberColl::NewShortNumber (u16 aMemory) // Create and insert a new short number { // Create a new entry ShortNumberInfo* Info = new ShortNumberInfo (aMemory); // Insert the new entry... Insert (Info); // ... and return it return *Info; } ShortNumberInfo& ShortNumberColl::NewShortNumber (const IstecMsg& Msg) // Create and insert a new short number { // Create a new entry ShortNumberInfo* Info = new ShortNumberInfo (Msg); // Insert the new entry... Insert (Info); // ... and return it return *Info; } ShortNumberInfo& ShortNumberColl::GetShortNumber (u16 aMemory) // Get the entry in the specified memory. If it does not exist, it is created. { // Search for the index int Index; if (Search (&aMemory, Index) == 0) { // No entry til now, create one return NewShortNumber (aMemory); } else { // Found an entry, return it return *At (Index); } } /*****************************************************************************/ /* class ShortNumberListBox */ /*****************************************************************************/ class ShortNumberListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: ShortNumberListBox (i16 aID, const Point& aSize, WindowItem* NextItem = NULL); }; ShortNumberListBox::ShortNumberListBox (i16 aID, const Point& aSize, WindowItem* NextItem): ListBox ("", aID, aSize, atEditNormal, atEditBar, atEditHigh, NextItem) { } void ShortNumberListBox::Print (int Index, int X, int Y, u16 Attr) { // Get the entry ShortNumberInfo* Info = Coll->At (Index); // Create a string with the correct length String Line (Size.X); // Build the line. // Nr. Number______________ Alias___________ Verwendung_ Ger„te__ Signal__ Line = FormatStr (" %3u ", Info->GetMemory () + 300); Line.Add (Info->GetNumber (), 20).Add (" "); Line.Add (Info->GetAlias (), 16).Add (" "); Line.Add (Info->UsageName (), 11).Add (" "); Line.Add (Info->DeviceList (), 8).Add (" "); Line.Add (Info->SignalName (), 8).Add (" "); // Pad the line to fit into the window Line.Pad (String::Right, Size.X - 1); Line += ' '; // Print the name Owner->Write (X, Y, Line, Attr); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ // Item numbers for the short number edit menu const miNumber = 10; const miUsage = 20; const miSignaling = 30; const miDevice1 = 110; const miDevice2 = 120; const miDevice3 = 130; const miDevice4 = 140; const miDevice5 = 150; const miDevice6 = 160; const miDevice7 = 170; const miDevice8 = 180; static void SetValues (Menue* M, const ShortNumberInfo& Data) // Update the values in the menue from Data { const unsigned char DeviceItems [8] = { miDevice1, miDevice2, miDevice3, miDevice4, miDevice5, miDevice6, miDevice7, miDevice8 }; const unsigned char Mask [8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // Get the number. If it is empty, disable "Usage" and "Signaling" String Number = Data.GetNumber (); // Get the usage type. If it is "Unused", the device items must be // disabled unsigned Usage = Data.GetUsage (); // Set the data M->SetStringValue (miNumber, Number); M->SetToggleValue (miUsage, Usage); M->SetToggleValue (miSignaling, Data.GetSignaling ()); // Disable items if necessary if (Number.IsEmpty ()) { M->GrayItem (miUsage); M->GrayItem (miSignaling); } else { M->ActivateItem (miUsage); M->ActivateItem (miSignaling); } // Set the device map unsigned DeviceMap = Data.GetDeviceMap (); for (unsigned I = 0; I < sizeof (Mask) / sizeof (Mask [0]); I++) { M->SetToggleValue (DeviceItems [I], (DeviceMap & Mask [I]) != 0); if (Usage == usUnused) { M->GrayItem (DeviceItems [I]); } else { M->ActivateItem (DeviceItems [I]); } } } static void EditShortNumber (ShortNumberInfo& Data) // Edit short number data. { // Settings name for the window position static const String StgPosName = "EditShortNumber.EditMenue.Position"; // Save the current config into a memory stream in case we want to cancel // changes. Calculate the CRC. u32 OldCRC = GetCRC (Data); MemoryStream SaveStream; SaveStream << Data; SaveStream.Seek (0); // Load the window Menue* M = (Menue*) LoadResource ("@ICSHORT.ShortNumberEdit"); // Set the window header M->SetHeader (FormatStr (LoadAppMsg (msEditHeader).GetStr (), Data.GetMemory () + 300)); // If there is a stored window position, move the window to that position Point Pos = StgGetPoint (StgPosName, M->OuterBounds ().A); M->MoveAbs (Pos); // Transfer the data into the menu SetValues (M, Data); // Activate the menue M->Activate (); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // Allow editing int Done = 0; String Num; while (!Done) { // Get a choice from the user int Choice = M->GetChoice (); // Look what he wants... switch (Choice) { case miNumber: // Set the new number Data.SetNumber (M->GetStringValue (miNumber)); // Other data in the menue needs an update SetValues (M, Data); break; case miUsage + usUnused: case miUsage + usShortcut: case miUsage + usAutoDial: case miUsage + usLock: // Set the new usage Data.SetUsage (M->GetToggleValue (miUsage)); // Other data in the menue needs an update SetValues (M, Data); break; case miSignaling + siStandard: case miSignaling + siSignal1: case miSignaling + siSignal2: case miSignaling + siSignal3: case miSignaling + siNone: Data.SetSignaling (M->GetToggleValue (miSignaling)); break; case miDevice1: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x01); break; case miDevice1+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x01); break; case miDevice2: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x02); break; case miDevice2+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x02); break; case miDevice3: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x04); break; case miDevice3+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x04); break; case miDevice4: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x08); break; case miDevice4+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x08); break; case miDevice5: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x10); break; case miDevice5+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x10); break; case miDevice6: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x20); break; case miDevice6+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x20); break; case miDevice7: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x40); break; case miDevice7+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x40); break; case miDevice8: Data.SetDeviceMap (Data.GetDeviceMap () & ~0x80); break; case miDevice8+1: Data.SetDeviceMap (Data.GetDeviceMap () | 0x80); break; case 0: if (M->GetAbortKey () == vkAbort) { // Abort - ask if we have changes if (GetCRC (Data) != OldCRC) { // We have changes if (AskDiscardChanges () == 2) { // Discard changes, reload from stream SaveStream >> Data; Done = 1; } } else { // No changes Done = 1; } } else if (M->GetAbortKey () == vkAccept) { // Accept the changes Done = 1; } break; } } // Save the current window position StgPutPoint (M->OuterBounds ().A, StgPosName); // Pop the status line, delete the menue PopStatusLine (); delete M; } void ShortNumberList (ShortNumberColl& ShortNumbers, int& Changed) // List all short numbers. Allow editing. { // Save the current config into a memory stream in case we want to cancel // changes. Calculate the CRC. u32 OldCRC = GetCRC (ShortNumbers); MemoryStream SaveStream; SaveStream << ShortNumbers; SaveStream.Seek (0); // Load the window Menue* Win = (Menue*) LoadResource ("@ICSHORT.ShortNumberWindow"); // Make the window cover the whole desktop Win->Resize (Background->GetDesktop ()); // Create a listbox inside the window Point Size; Size.X = Win->IXSize (); Size.Y = Win->IYSize () - 2; ShortNumberListBox* Box = new ShortNumberListBox (1, Size); Box->SetColl (&ShortNumbers); Win->AddItem (Box); Box->SetPos (0, 2); Box->Select (); Box->Draw (); Win->Activate (); // New status line PushStatusLine (siAbort | siSelectKeys | siChange | siAccept); // Allow choosing an entry int Done = 0; while (!Done) { // Get keyboard input Key K = ::KbdGet (); // Let the box look for a useful key Box->HandleKey (K); // Look what's left int Selected; switch (K) { case kbEnter: Selected = Box->GetSelected (); if (Selected != -1) { EditShortNumber (*ShortNumbers [Selected]); Box->Draw (); } break; case vkAccept: // If we had changes, tell the caller if (GetCRC (ShortNumbers) != OldCRC) { Changed = 1; } Done = 1; break; case vkResize: Win->MoveResize (); break; case vkAbort: if (GetCRC (ShortNumbers) != OldCRC) { // We have changes - ask if we should discard them if (AskDiscardChanges () == 2) { // Discard the changes. To do that, reload the old // config data from the memory stream. SaveStream >> ShortNumbers; Done = 1; } } else { Done = 1; } break; } } // Restore the status line PopStatusLine (); // Set a new collection for the listbox (otherwise the box would try to // delete the collection) Box->SetColl (NULL); // Delete the window delete Win; } String FileSaveShort (const String& Filename, const ShortNumberColl& Numbers) // Save short numbers to a file. The function returns an error message or // the empty string if all is well. { // Open the stream FileStream S (Filename, "wb"); if (S.GetStatus () != stOk) { return LoadAppMsg (msOpenError) + GetSysErrorMsg (S.GetErrorInfo ()); } // Put version and config data into the file S << FileVersion << Numbers; // Success return ""; } String FileLoadShort (const String& Filename, ShortNumberColl& Numbers) // Load a configuration from a file. The function returns an error message or // the empty string if all is well. { // Open the stream FileStream S (Filename, "rb"); if (S.GetStatus () != stOk) { return LoadAppMsg (msOpenError) + GetSysErrorMsg (S.GetErrorInfo ()); } // Read the version from the file u32 Version; S >> Version; if (Version != FileVersion) { return LoadAppMsg (msInvalidVersion); } // Load the config data S >> Numbers; // Success return ""; } estic-1.61.orig/estic/icshort.h0100644000176100001440000001354707031424725015761 0ustar debacleusers/*****************************************************************************/ /* */ /* ICSHORT.H */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Handle the short dial numbers #ifndef _ICSHORT_H #define _ICSHORT_H #include "coll.h" #include "istecmsg.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Values for the "Usage" field in class ShortNumberInfo const unsigned usUnused = 0; const unsigned usShortcut = 1; const unsigned usAutoDial = 2; const unsigned usLock = 3; /*****************************************************************************/ /* class ShortNumberInfo */ /*****************************************************************************/ class ShortNumberInfo: public Streamable { friend class ShortNumberColl; u16 Memory; // Memory location of this number u16 Usage; // Usage String Number; // Stored number unsigned char AutoDial; // "Babyruf" unsigned char Devices; // Valid for which device? unsigned char Signaling; // Ring attribute unsigned char Locked; public: ShortNumberInfo (unsigned aMemory); // Create a ShortNumberInfo ShortNumberInfo (const IstecMsg& Msg); // Create a ShortNumberInfo from an istec message ShortNumberInfo (StreamableInit); // Build constructor virtual void Load (Stream& S); // Load the object from a stream virtual void Store (Stream& S) const; // Store the object into a stream virtual u16 StreamableID () const; // Return the stream ID static Streamable* Build (); // Return a new instance void Unpack (const IstecMsg& Msg); // Unpack the contents of a message into the struct void Pack (IstecMsg& Msg) const; // Pack the data into a message ready for download to the istec unsigned GetMemory () const; // Return the memory setting unsigned GetUsage () const; // Get the usage info void SetUsage (unsigned NewUsage); // Set the usage info const String& GetNumber () const; // Get the number info void SetNumber (const String& NewNumber); // Set a new number unsigned GetSignaling () const; // Return the signaling info void SetSignaling (unsigned NewSignaling); // Set the signaling info String GetAlias () const; // Get the alias for the given number unsigned GetDeviceMap () const; // Return a bitmap of devices that are valid for the current usage void SetDeviceMap (unsigned NewMap); // Set a new device map String DeviceList (); // Return a list of devices (e.g. "-2--567-") const String& SignalName (); // Return the name for a specific signaling type const String& UsageName (); // Return the name for a usage }; inline unsigned ShortNumberInfo::GetMemory () const // Return the memory setting { return Memory; } inline void ShortNumberInfo::SetUsage (unsigned NewUsage) // Set the usage info { Usage = NewUsage; } inline const String& ShortNumberInfo::GetNumber () const // Get the number info { return Number; } inline void ShortNumberInfo::SetSignaling (unsigned NewSignaling) // Set the signaling info { Signaling = NewSignaling; } /*****************************************************************************/ /* class ShortNumberColl */ /*****************************************************************************/ class ShortNumberColl: public SortedCollection { protected: virtual int Compare (const u16* Key1, const u16* Key2); virtual const u16* KeyOf (const ShortNumberInfo* Item); // Helpers for managing sort order public: ShortNumberColl (); // Construct a collection ShortNumberColl (StreamableInit); // Construct an empty collection ShortNumberInfo& NewShortNumber (u16 aMemory); // Create and insert a new short number ShortNumberInfo& NewShortNumber (const IstecMsg& Msg); // Create and insert a new short number ShortNumberInfo& GetShortNumber (u16 aMemory); // Get the entry in the specified memory. If it does not exist, it is created. }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void ShortNumberList (ShortNumberColl& ShortNumbers, int& Changed); // List all short numbers. Allow editing. String FileSaveShort (const String& Filename, const ShortNumberColl& Numbers); // Save short numbers to a file. The function returns an error message or // the empty string if all is well. String FileLoadShort (const String& Filename, ShortNumberColl& Numbers); // Load a configuration from a file. The function returns an error message or // the empty string if all is well. // End of ICSHORT.H #endif estic-1.61.orig/estic/icver.cc0100644000176100001440000000225507031424725015546 0ustar debacleusers/*****************************************************************************/ /* */ /* ICVER.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Version number of the ISTEC firmware. This is the default if no config is // loaded. double FirmwareVersion = 1.7; estic-1.61.orig/estic/icver.h0100644000176100001440000000235507031424726015412 0ustar debacleusers/*****************************************************************************/ /* */ /* ICVER.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ICVER_H #define _ICVER_H /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Version number of the ISTEC firmware. This is the default if no config is // loaded. extern double FirmwareVersion; // End of ICVER.H #endif estic-1.61.orig/estic/imon.cc0100644000176100001440000002672507031424726015411 0ustar debacleusers/*****************************************************************************/ /* */ /* IMON.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "chartype.h" #include "itemwin.h" #include "textitem.h" #include "strparse.h" #include "progutil.h" #include "stdmsg.h" #include "syserror.h" #include "settings.h" #include "winmgr.h" #include "icobjid.h" #include "icmsg.h" #include "icevents.h" #include "imon.h" // Register the classes LINK (IMonWindow, ID_IMonWindow); /*****************************************************************************/ /* Message Constants */ /*****************************************************************************/ const u16 msIMonWindowTitle = MSGBASE_ICIMON + 0; const u16 msIMonHeader1 = MSGBASE_ICIMON + 1; const u16 msIMonHeader2 = MSGBASE_ICIMON + 2; const u16 msIncoming = MSGBASE_ICIMON + 3; const u16 msOutgoing = MSGBASE_ICIMON + 4; const u16 msUsageNone = MSGBASE_ICIMON + 5; const u16 msUsageRaw = MSGBASE_ICIMON + 6; const u16 msUsageModem = MSGBASE_ICIMON + 7; const u16 msUsageNet = MSGBASE_ICIMON + 8; const u16 msUsageVoice = MSGBASE_ICIMON + 9; const u16 msUsageFax = MSGBASE_ICIMON + 10; const u16 msUsageUnknown = MSGBASE_ICIMON + 11; const u16 msNoInfoFile = MSGBASE_ICIMON + 12; const u16 msReadError = MSGBASE_ICIMON + 13; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name that the window uses to store it's position in the settings file static const String IMonPosition = "IMonWindow.Position"; // Define the ISDN stuff static const char InfoFileName [] = "/dev/isdninfo"; #ifdef CLEAN_IMON_SOURCE #include "/usr/src/isdn/include/isdn.h" #else // Define the ISDN stuff const unsigned ISDN_USAGE_NONE = 0; const unsigned ISDN_USAGE_RAW = 1; const unsigned ISDN_USAGE_MODEM = 2; const unsigned ISDN_USAGE_NET = 3; const unsigned ISDN_USAGE_VOICE = 4; const unsigned ISDN_USAGE_FAX = 5; const unsigned ISDN_USAGE_MASK = 127; const unsigned ISDN_USAGE_OUTGOING = 128; #endif // Count of IMonWindows unsigned IMonWindow::WindowCount = 0; /*****************************************************************************/ /* class IMonWindow */ /*****************************************************************************/ IMonWindow::IMonWindow (const Point& Pos): ItemWindow (Rect (Pos.X, Pos.Y, Pos.X+4, Pos.Y+3), wfFramed | wfCanMove | wfCanResize | wfSaveVisible), Status (0), F (NULL), ZoomSize (OBounds) // Construct an IMonWindow { // Lock window output Lock (); // Open the info file F = fopen (InfoFileName, "r"); if (F == NULL) { // We had an error opening the file. Do *not* return but construct // the window. The window will show but nothing more will happen. // This way it's more compatible with the window manager... ErrorMsg (FormatStr (LoadAppMsg (msNoInfoFile).GetStr (), InfoFileName)); Status = errno; } // Resize the window in X direction (Work() will resize the Y dir) const String& Header1 = LoadAppMsg (msIMonHeader1); const String& Header2 = LoadAppMsg (msIMonHeader2); Rect NewBounds = OBounds; NewBounds.B.X = NewBounds.A.X + Header1.Len () + 2; Resize (NewBounds); // If there is a stored window position in the settings file, move the // window to this position. As the window is invisible, this operation // is cheap and is performed in any case. MoveAbs (StgGetPoint (IMonPosition, OBounds.A)); // Set the header SetHeader (LoadAppMsg (msIMonWindowTitle)); // Create and insert the items for both header lines TextItem* H1 = new TextItem (Header1, 100, atTextNormal, NULL); TextItem* H2 = new TextItem (Header2, 101, atTextNormal, NULL); AddItem (H1); AddItem (H2); H1->SetWidth (Header1.Len ()); H2->SetWidth (Header2.Len ()); H1->SetPos (0, 0); H2->SetPos (0, 1); // Ok, we now have one window more WindowCount++; // Make a first update of the window. This will insert the needed // TextItems into the window an resize it according to the channels // available. Update (); // Unlock the output Unlock (); // Tell the application that the window count has changed PostEvent (evIMonWinChange, WindowCount); } IMonWindow::IMonWindow (StreamableInit): ItemWindow (Empty) { // One window more WindowCount++; // Tell the application that the window count has changed PostEvent (evIMonWinChange, WindowCount); } IMonWindow::~IMonWindow () // Destruct an IMonWindow { // Close the file if (F) { fclose (F); } // Write the current position to the settings file StgPutPoint (OBounds.A, IMonPosition); // One window less WindowCount--; // Tell the application that the window count has changed PostEvent (evIMonWinChange, WindowCount); } void IMonWindow::Store (Stream &S) const // Store the window in a stream { // Store the data from ItemWindow ItemWindow::Store (S); // Store additional data S << ZoomSize; } void IMonWindow::Load (Stream &S) // Load the window from a stream { // Load the parental data ItemWindow::Load (S); // Load additional data S >> ZoomSize; // We have to open the file again F = fopen (InfoFileName, "r"); if (F == NULL) { ErrorMsg (FormatStr (LoadAppMsg (msNoInfoFile).GetStr (), InfoFileName)); Status = errno; } else { Status = 0; } } u16 IMonWindow::StreamableID () const // Return the stream ID { return ID_IMonWindow; } Streamable* IMonWindow::Build () // Create an empty IMonWindow { return new IMonWindow (Empty); } unsigned IMonWindow::MinXSize () const // Return the minimum X size of the window. Override this to limit resizing. { return 20; } unsigned IMonWindow::MinYSize () const // Return the minumim Y size of the window. Override this to limit resizing. { return 6; // Two lines at least } void IMonWindow::Zoom () // Zoom the window { // Get the desktop bounds Rect Desktop = Background->GetDesktop (); // Check if we must zoom in or out if (OBounds != Desktop) { // Remember the old size, then zoom out ZoomSize = OBounds; Resize (Desktop); } else { // Zoom in Resize (ZoomSize); } } void IMonWindow::Update () // Update the window if information has changed { // Bail out if we had an error if (F == NULL || Status != 0) { return; } // Since isdn4linux 0.7beta, there will only be information available, // if something has changed. Use select() to make shure, we can read // from the device. // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // Set the file descriptor fd_set Desc; FD_ZERO (&Desc); FD_SET (fileno (F), &Desc); // Check input status, return if no data available int Res = select (fileno (F) + 1, &Desc, NULL, NULL, &Timeout); if (Res == 0) { // No info return; } else if (Res < 0) { // Some sort of error. Be shure to set the status before displaying an // error message Status = errno; ErrorMsg (GetSysErrorMsg (errno)); return; } // Read 6 lines from the file String Lines [li_count]; for (unsigned I = 0; I < li_count; I++) { char Line [512]; if (fgets (Line, sizeof (Line), F) == NULL) { // Error reading the file, be careful to set the status code before // showing the error message to avoid recursive calls if ((Status = errno) == 0) { // OOPS - no error. Use generic error code Status = -1; } // Display an error message ErrorMsg (FormatStr (LoadAppMsg (msReadError).GetStr (), InfoFileName)); return; } // Make a string and remove the trailing newline (if present) Lines [I] = &Line [7]; int Len = Lines [I].Len (); while (Len >= 0 && IsSpace (Lines [I] [Len-1])) { Len--; Lines [I].Trunc (Len); } } // Lock the output Lock (); // Set up a parser object for each line StringParser SP_ChMap (Lines [li_chmap], StringParser::SkipWS); StringParser SP_DrMap (Lines [li_drmap], StringParser::SkipWS); StringParser SP_Usage (Lines [li_usage], StringParser::SkipWS); StringParser SP_Phone (Lines [li_phone], StringParser::SkipWS); // Insert TextItems if some are missing, resize the window, write the // lines to the window unsigned Y = 2; // First free Y position unsigned ItemID = 1; // ID of first TextItem while (1) { // Get the infos i32 Driver; if (SP_DrMap.GetI32 (Driver) != 0) { // Error break; } i32 Channel; if (SP_ChMap.GetI32 (Channel) != 0) { // Error break; } u32 Usage; if (SP_Usage.GetU32 (Usage) != 0) { // Error break; } String Phone; if (SP_Phone.GetToken (Phone) != 0) { // Error break; } // This is the last entry if the driver number is -1 if (Driver < 0) { break; } // Get the service message unsigned MsgNum; switch (Usage & ISDN_USAGE_MASK) { case ISDN_USAGE_NONE: MsgNum = msUsageNone; break; case ISDN_USAGE_RAW: MsgNum = msUsageRaw; break; case ISDN_USAGE_NET: MsgNum = msUsageNet; break; case ISDN_USAGE_MODEM: MsgNum = msUsageModem; break; case ISDN_USAGE_VOICE: MsgNum = msUsageVoice; break; case ISDN_USAGE_FAX: MsgNum = msUsageFax; break; default: MsgNum = msUsageUnknown; break; } String Service = LoadAppMsg (MsgNum); Service.Pad (String::Right, 10); // Get the direction message, but beware: If the channel is unused, // there is no in/out message String InOut; if ((Usage & ISDN_USAGE_MASK) != ISDN_USAGE_NONE) { if (Usage & ISDN_USAGE_OUTGOING) { InOut = LoadAppMsg (msOutgoing); } else { InOut = LoadAppMsg (msIncoming); } } InOut.Pad (String::Center, 7); // Setup the line // This is the header: " Dr Ch Ein/Aus Dienst Nummer" String Line = FormatStr (" %2d %2d %s %s %s", Driver, Channel, InOut.GetStr (), Service.GetStr (), Phone.GetStr ()); // Check if the needed textitem is available. If yes, the window does // not need resizing TextItem* Item = (TextItem*) ItemWithID (ItemID); if (Item == NULL) { // Item does not exist - insert one Item = new TextItem (Line, ItemID, atTextNormal, NULL); AddItem (Item); // Adjust position an width Item->SetPos (0, Y); Item->SetWidth (IXSize ()); // Make shure, the window is large enough to show the item if (IYSize () <= Y) { // We need to resize the window Rect NewBounds = OBounds; NewBounds.B.Y = NewBounds.A.Y + Y + 3; Resize (NewBounds); } } else { // Window item exists, just set the item text Item->SetText (Line); } // Next line, next item Y++; ItemID++; } // Unlock the window. This will cause a window update Unlock (); } void IMonWindow::HandleEvent (Event& E) // Handle incoming events. Calls Update() if the application is idle { // Call the derived function ItemWindow::HandleEvent (E); if (E.Handled) { return; } // Check which event switch (E.What) { case evSecondChange: // Update the window Update (); break; } } estic-1.61.orig/estic/imon.h0100644000176100001440000000400407031424726015235 0ustar debacleusers/*****************************************************************************/ /* */ /* IMON.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module implements a simple isdn4linux line monitor #ifndef _ICIMON_H #define _ICIMON_H #include #include "itemwin.h" /*****************************************************************************/ /* class IMonWindow */ /*****************************************************************************/ class IMonWindow: public ItemWindow { private: // Types of lines read from isdninfo enum { li_idmap, li_chmap, li_drmap, li_usage, li_flags, li_phone, li_count }; int Status; // Status of the window static unsigned WindowCount; // Count of IMonWindows FILE* F; // /dev/isdninfo Rect ZoomSize; // Small window size for zooming public: IMonWindow (StreamableInit); // Build constructor IMonWindow (const Point& Pos); // Construct an IMonWindow virtual ~IMonWindow (); // Destruct an IMonWindow virtual void Store (Stream &) const; virtual void Load (Stream &); virtual u16 StreamableID () const; static Streamable* Build (); // Make the window persistent virtual unsigned MinXSize () const; // Return the minimum X size of the window. Override this to limit resizing. virtual unsigned MinYSize () const; // Return the minumim Y size of the window. Override this to limit resizing. virtual void Zoom (); // Zoom the window void Update (); // Update the window if information has changed void HandleEvent (Event& E); // Handle incoming events. Calls Update() if the application is idle }; // End of ICIMON.H #endif estic-1.61.orig/estic/istecmsg.cc0100644000176100001440000002504707031424726016261 0ustar debacleusers/*****************************************************************************/ /* */ /* ISTECMSG.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Defines a class that holds an istec message #include "check.h" #include "icver.h" #include "icdlog.h" #include "icdiag.h" #include "iccti.h" #include "istecmsg.h" /*****************************************************************************/ /* class IstecMsg */ /*****************************************************************************/ IstecMsg::IstecMsg (unsigned MsgSize, const unsigned char* Buf): ErrCode (0), Data (0) // Create a message { NewData (MsgSize, Buf); } IstecMsg::~IstecMsg () { delete [] Data; } void IstecMsg::NewData (unsigned MsgSize, const unsigned char* Buf) // Replace the current data by the new stuff. If Buf is not 0, the // contents of Buf are copied to the message. { // Delete the old stuff delete [] Data; // Use the new message size Size = MsgSize; // Check the parameters if (MsgSize > 0) { Data = new unsigned char [MsgSize]; if (Buf) { // We got data, copy it memmove (Data, Buf, MsgSize); } } else { Data = 0; } } String IstecMsg::AsciiData () const { return ::AsciiData (Data, Size); } int IstecMsg::IsDiagMsg () const // Return true if the message is a diagnostic message { // Unnecessary override for gcc return ::IsDiagMsg (Data, Size); } int IstecMsg::IsCLIMsg () const // Return true if the message is a calling line identification message { // Unnecessary override for gcc return ::IsCLIMsg (Data, Size); } int IstecMsg::IsCTIMsg () const // Return true if the message is a CTI message { // Unnecessary override for gcc return ::IsCTIMsg (Data, Size); } int IstecMsg::IsChargeInfo () const // Return true if the message is a charge info message { // Unnecessary override for gcc return ::IsChargeInfo (Data, Size); } unsigned char& IstecMsg::At (unsigned Index) // Access the Data member bounds checked. { PRECONDITION (Index < Size); return Data [Index]; } const unsigned char& IstecMsg::At (unsigned Index) const // Access the Data member bounds checked. { PRECONDITION (Index < Size); return Data [Index]; } /*****************************************************************************/ /* Other Istec Message related stuff */ /*****************************************************************************/ String IstecMsgDesc (const unsigned char* Data) // Return a string describing the Istec message. This is for debug purposes // only, the string is hardcoded, not loaded from the resource. { PRECONDITION (Data != 0); switch (Data [0]) { case 'C': return "Calling line identification"; case 0x02: return "Are you there?"; case 0x05: return "Write charge data"; case 0x06: return "Request charge data"; case 0x07: return "Write device configuration"; case 0x08: return "Request device configuration"; case 0x09: return "Write base configuration"; case 0x0a: return "Request base configuration"; case 0x0c: return "End configuration"; case 0x11: return "End configuration (ACK)"; case 0x12: return "Hi! Nice to meet you!"; case 0x13: return "Error reply (NACK)"; case 0x15: return "Charge data"; case 0x16: return "Device configuration data"; case 0x17: return "Base configuration data"; case 0x18: return "Write device configuration acknowledged"; case CTI_START: return "CTI message"; case 0xdd: return "Diagnostic message"; default: return "Unknown message"; } } String AsciiData (const unsigned char* Data, unsigned Size) // Create an ascii string with the hex representation of the message data { // Check the programmer :-) PRECONDITION (Data != NULL && Size > 0); String S (Size * 3); // Create the string for (unsigned I = 0; I < Size; I++) { S += FormatStr ("%02X ", Data [I]); } // Add a short description of the message if VerboseDebugLog is enabled if (IsDiagMsg (Data, Size)) { S += DiagMsgDesc (Data); } else if (IsCTIMsg (Data, Size)) { S += CTIMsgDesc (Data, Size); } else { S += IstecMsgDesc (Data); } // Return the result return S; } int IsDiagMsg (const unsigned char* Data, unsigned Size) // Return true if the given message is a diagnostic message { PRECONDITION (Data != NULL); return Size == 6 && Data [0] == 0xdd; } int IsCLIMsg (const unsigned char* Data, unsigned Size) // Return true if the message is a calling line identification message { // At least "CLImn\x0c\x0d" if (Size < 7 || Data [0] != 'C' || Data [1] != 'L' || Data [2] != 'I') { return 0; } else { return 1; } } int IsCTIMsg (const unsigned char* Data, unsigned Size) // Return true if the message is a CTI message { // The shortest possible message is CTI_START/CTI_GROUP/CTI_OP/CTI_STOP return (Size >= 4 && Data [0] == CTI_START); } int IsChargeInfo (const unsigned char* Data, unsigned Size) // Return true if the message contains the ISTEC charges { if (Data [0] != 0x15) { // No charge info return 0; } if (FirmwareVersion < 2.00) { return (Size == 129); } else { return (Size == 17); } } unsigned SendMsgSize (const unsigned char* Data, unsigned BufSize) // The function returns the real size of the given message to send. Since // the messages given to this function are created by the programmer (that // is me - hi!), a non determinable message size is a programming error. // Note: BufSize is the size of the message buffer, the real message that // is sent maybe smaller than this value. { unsigned Version; // Check the given parameter PRECONDITION (Data != NULL && BufSize > 0); switch (Data [0]) { case 0x02: case 0x06: case 0x08: case 0x0a: case 0x0c: return 1; case 0x05: if (FirmwareVersion < 2.00) { return 1 + 64 * sizeof (u16); } else { return 1 + 8 * sizeof (u16); } case 0x07: if (FirmwareVersion < 1.93) { return 18; } else if (FirmwareVersion < 1.95) { return 22; } else if (FirmwareVersion < 2.00) { return 23; } else { return 27; } case 0x09: // This is ugly, but I cannot help: Use the firmware version // from the message instead of the saved one, since we may // not know about the version when receiving this message. // To be shure not to access non-existing message members, // check the length first. CHECK (BufSize >= 94); Version = unsigned (Data [4]) * 100 + unsigned (Data [5]); if (Version < 193) { return 94; } else if (Version < 200) { return 107; } else { return 117; } case CTI_START: // A CTI message - use the real size return BufSize; case 0xdd: return 6; default: FAIL ("SendMsgSize: Trying to create invalid message!"); return 0; } } unsigned RecMsgSize (unsigned char* Data, unsigned Size) // Calculate the size of a message. First byte is opcode. { // Check the given parameter PRECONDITION (Data != NULL && Size > 0); switch (Data [0]) { case 'C': // A CLI message, return the actual size return Size; case 0x11: case 0x12: return 1; case 0x13: WriteDebugLog ("Got error reply: " + AsciiData (Data, Size)); return 2; case 0x15: if (FirmwareVersion < 2.00) { return 129; } else { return 17; } case 0x16: if (FirmwareVersion < 1.93) { return 18; } else if (FirmwareVersion < 1.95) { return 22; } else if (FirmwareVersion < 2.00) { return 23; } else { return 27; } case 0x17: // This is ugly, but I cannot help: Use the firmware version // from the message instead of the saved one, since we may // not know about the version when receiving this message. // To be shure not to access non-existing message members, // check the length first. if (Size != 94 && Size != 107 && Size != 117) { WriteDebugLog ("Error: Invalid message length: " + AsciiData (Data, Size)); return Size; } else { // Get the version unsigned Version = unsigned (Data [4]) * 100 + unsigned (Data [5]); if (Version < 193) { return 94; } else if (Version < 200) { return 107; } else { return 117; } } case 0x18: return 2; case CTI_START: // A CTI message - use the real size return Size; case 0xdd: return 6; default: WriteDebugLog ("Warning: Cannot determine message length: " + AsciiData (Data, Size)); return Size; } } estic-1.61.orig/estic/istecmsg.h0100644000176100001440000001002507031424726016111 0ustar debacleusers/*****************************************************************************/ /* */ /* ISTECMSG.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Defines a class that holds an istec message #ifndef _ISTECMSG_H #define _ISTECMSG_H #include "str.h" /*****************************************************************************/ /* class IstecMsg */ /*****************************************************************************/ class IstecMsg { int ErrCode; public: unsigned Size; unsigned char* Data; IstecMsg (unsigned MsgSize, const unsigned char* Buf = 0); // Create a message ~IstecMsg (); // Free the data area void NewData (unsigned MsgSize, const unsigned char* Buf = 0); // Replace the current data by the new stuff. If Buf is not 0, the // contents of Buf are copied to the message. String AsciiData () const; // Return the message converted to a string int IsDiagMsg () const; // Return true if the message is a diagnostic message int IsCLIMsg () const; // Return true if the message is a calling line identification message int IsCTIMsg () const; // Return true if the message is a CTI message int IsChargeInfo () const; // Return true if the message is a charge info message void SetError (int Code); // Set the error code int GetError () const; // Get the error code unsigned char& At (unsigned Index); // Access the Data member bounds checked. const unsigned char& At (unsigned Index) const; // Access the Data member bounds checked. }; inline void IstecMsg::SetError (int Code) // Set the error code { ErrCode = Code; } inline int IstecMsg::GetError () const // Get the error code { return ErrCode; } /*****************************************************************************/ /* Other Istec Message related stuff */ /*****************************************************************************/ String IstecMsgDesc (const unsigned char* Data); // Return a string describing the Istec message. This is for debug purposes // only, the string is hardcoded, not loaded from the resource. String AsciiData (const unsigned char* Data, unsigned Size); // Create an ascii string with the hex representation of the message data int IsDiagMsg (const unsigned char* Data, unsigned Size); // Return true if the given message is a diagnostic message int IsCLIMsg (const unsigned char* Data, unsigned Size); // Return true if the message is a calling line identification message int IsCTIMsg (const unsigned char* Data, unsigned Size); // Return true if the message is a CTI message int IsChargeInfo (const unsigned char* Data, unsigned Size); // Return true if the message contains the ISTEC charges unsigned SendMsgSize (const unsigned char* Data, unsigned BufSize); // The function returns the real size of the given message to send. Since // the messages given to this function are created by the programmer (that // is me - hi!), a non determinable message size is a programming error. // Note: BufSize is the size of the message buffer, the real message that // is sent maybe smaller than this value. unsigned RecMsgSize (unsigned char* Data, unsigned Size); // Calculate the size of a message. First byte is opcode. // End of ISTECMSG.H #endif estic-1.61.orig/estic/make/0040755000176100001440000000000007061535301015037 5ustar debacleusersestic-1.61.orig/estic/make/freebsd-x.mak0100644000176100001440000000452007031424730017406 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for FreeBSD / X Window System * # * * # * (C) 1995-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk CFLAGS = -DFREEBSD -g -Wall -I$(INCDIR) -x c++ -L /usr/X11R6/lib -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icprefix.o \ icshort.o \ icver.o \ istecmsg.o # ------------------------------------------------------------------------------ # all: xestic xestic: $(LIB) $(OBJS) $(CC) -o xestic $(OBJS) $(LIB) -ltermcap -lg++ -lX11 # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DFREEBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile make/freebsd-x.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg make/*.mak alias.dat bin-dist: estic icload strip -rm -f estic.zip $(ZIP) -9 estic.zip estic estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # clean up clean: -rm -f *.bak *~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/estic/make/freebsd.mak0100644000176100001440000000443007031424730017141 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for FreeBSD * # * * # * (C) 1995-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk CFLAGS = -DFREEBSD -g -Wall -I$(INCDIR) -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icprefix.o \ icshort.o \ icver.o \ istecmsg.o # ------------------------------------------------------------------------------ # all: estic estic: $(LIB) $(OBJS) $(CC) -o estic $(OBJS) $(LIB) -ltermcap -lg++ # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DFREEBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile freebsd.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg *.mak alias.dat bin-dist: estic icload strip -rm -f estic.zip $(ZIP) -9 estic.zip estic estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # clean up clean: -rm -f *.bak *~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/estic/make/linux-x.mak0100644000176100001440000000466307031424730017143 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for Linux / X Window System * # * * # * (C) 1995-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk # Flags for the GNU C compiler CFLAGS = -DLINUX -g -O2 -Wall -I$(INCDIR) -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icshort.o \ icver.o \ imon.o \ istecmsg.o ACOBJ = ../areacode/areacode.o # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: xestic include .depend else all: depend endif xestic: $(LIB) $(OBJS) $(CC) -o xestic $(OBJS) $(ACOBJ) $(LIB) -lg++ /usr/X11/lib/libX11.a # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DLINUX -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile linux.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg *.mak alias.dat bin-dist: estic icload strip -rm -f estic.zip $(ZIP) -9 estic.zip estic estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # clean up clean: -rm *.bak *~ zap: clean -rm *.o -rm .depend estic-1.61.orig/estic/make/linux.mak0100644000176100001440000000474007031424730016672 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for Linux * # * * # * (C) 1995-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk # Flags for the GNU C compiler CFLAGS = -DLINUX -g -O2 -Wall -I$(INCDIR) -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icshort.o \ icver.o \ imon.o \ istecmsg.o ACOBJ = ../areacode/areacode.o # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: estic include .depend else all: depend endif estic: $(LIB) $(OBJS) $(CC) -o estic $(OBJS) $(ACOBJ) $(LIB) -lncurses -lg++ # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DLINUX -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile linux.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg *.mak alias.dat bin-dist: estic icload strip -rm -f estic.zip $(ZIP) -9 estic.zip estic estic.res estic.doc estic.chg estic.ini alias.dat convert: dos2iso -f *.cc *.h *.doc *.dat estic.ini estic.chg make/*.mak # ------------------------------------------------------------------------------ # clean up clean: -rm *.bak *~ zap: clean -rm *.o -rm .depend estic-1.61.orig/estic/make/netbsd-x.mak0100644000176100001440000000475107031424730017261 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for NetBSD / X Window System * # * * # * (C) 1995-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk # Both configurations of CFLAGS will probably work since FreeBSD has a # smart linker... #CFLAGS = -DNETBSD -g -Wall -I$(INCDIR) -x c++ -L /usr/X11/lib CFLAGS = -DNETBSD -I$(INCDIR) -x c++ -L /usr/X11/lib -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icprefix.o \ icshort.o \ icver.o \ istecmsg.o # ------------------------------------------------------------------------------ # all: xestic xestic: $(LIB) $(OBJS) $(CC) -o xestic $(OBJS) $(LIB) -L/usr/local/lib -lncurses /usr/X11/lib/libX11.a # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DNETBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile make/netbsd-x.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg make/*.mak alias.dat bin-dist: estic icload strip -rm -f estic.zip $(ZIP) -9 estic.zip estic estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # clean up clean: -rm -f *.bak *~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/estic/make/solaris-x.mak0100644000176100001440000000545307031426143017456 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for Solaris-SPARC / X Window System * # * * # * (C) 1995-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # * Portierung Sparc Solaris 2.5 * # * * # * Martin Helmling * # * Lindenhofstr. 78 * # * 68163 Mannheim * # * email mh@guug.de oder mh@octogon.de * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ LIB = ../spunk/spunk.a INCDIR = ../spunk # Both configurations of CFLAGS will probably work since FreeBSD has a # smart linker... #CFLAGS = -DSOLARIS -g -O2 -Wall -I$(INCDIR) -pipe -x c++ -L /usr/openwin/lib CFLAGS = -DSOLARIS -g -O2 -Wall -I$(INCDIR) -pipe -x c++ -L /usr/openwin/lib -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icshort.o \ icver.o \ istecmsg.o ACOBJ = ../areacode/areacode.o # ------------------------------------------------------------------------------ # all: xestic xestic: $(LIB) $(OBJS) $(CC) -o xestic $(OBJS) $(ACOBJ) $(LIB) -lg++ -L/usr/openwin/lib -lX11 #-lm -lsocket -lnsl -lgen # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DSOLARIS -MM *.cc > .depend # ------------------------------------------------------------------------------ # Create a ZIP file strip: strip estic zip: -rm -f estic.zip -rm -f *~ cp Makefile make/solaris-x.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg *.mak alias.dat bin-dist: estic strip -rm -f estic.zip $(ZIP) -9 estic.zip xestic estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # clean up clean: -rm -f *.bak *~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/estic/make/svr40-x.mak0100644000176100001440000000424007031424730016751 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for SVR4 / X Window System * # * * # * (C) 1995-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld CC = gcc LIB = ../spunk/spunk.a INCDIR = ../spunk # Flags for the GNU C compiler CFLAGS = -DSVR4 -O2 -Wall -I$(INCDIR) -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icshort.o \ icver.o \ imon.o \ istecmsg.o ACOBJ = ../areacode/areacode.o # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: xestic include .depend else all: depend endif xestic: $(LIB) $(OBJS) $(CC) -o xestic $(OBJS) $(ACOBJ) $(LIB) -lg++ -lc -lX11 -lnsl -lsocket -L /usr/ucblib -lucb # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DSVR4 -MM *.cc > .depend # ------------------------------------------------------------------------------ # Strin the executable strip: strip xestic # ------------------------------------------------------------------------------ # clean up clean: -rm *.bak *~ zap: clean -rm *.o -rm .depend estic-1.61.orig/estic/make/svr40.mak0100644000176100001440000000420507031424730016505 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile for SVR4 * # * * # * (C) 1995-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld CC = gcc LIB = ../spunk/spunk.a INCDIR = ../spunk # Flags for the GNU C compiler CFLAGS = -DSVR4 -O2 -Wall -I$(INCDIR) -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES # ------------------------------------------------------------------------------ # Implicit rules .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All OBJ files OBJS = callwin.o \ chargwin.o \ cliwin.o \ devstate.o \ estic.o \ icac.o \ icalias.o \ icbaseed.o \ iccli.o \ icconfig.o \ iccom.o \ iccprint.o \ iccron.o \ iccti.o \ icdevs.o \ icdiag.o \ icdlog.o \ icei.o \ icerror.o \ icfile.o \ icident.o \ icintcon.o \ iclog.o \ icmsgwin.o \ icshort.o \ icver.o \ imon.o \ istecmsg.o ACOBJ = ../areacode/areacode.o # ------------------------------------------------------------------------------ # ifeq (.depend,$(wildcard .depend)) all: estic include .depend else all: depend endif estic: $(LIB) $(OBJS) $(CC) -o estic $(OBJS) $(ACOBJ) $(LIB) -ltermcap -lg++ -lc -L /usr/ucblib -lucb # ------------------------------------------------------------------------------ # Create a dependency file depend dep: @echo "Creating dependency information" $(CC) -I$(INCDIR) -DSVR4 -MM *.cc > .depend # ------------------------------------------------------------------------------ # Strip the executable strip: strip estic # ------------------------------------------------------------------------------ # clean up clean: -rm *.bak *~ zap: clean -rm *.o -rm .depend estic-1.61.orig/estic/make/watcom.mak0100644000176100001440000001256007031424730017024 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Generelle Einstellungen .AUTODEPEND .SUFFIXES .ASM .C .CC .CPP .SWAP # ------------------------------------------------------------------------------ # Allgemeine Definitionen # Names of executables AS = TASM AR = WLIB LD = WLINK !if $d(__OS2__) ZIP = zip MV = c:\os2\4os2\4os2 /C MOVE /Q !else ZIP = pkzip MV = mv !endif !if !$d(TARGET) !if $d(__OS2__) TARGET = OS2 !else TARGET = DOS !endif !endif LIBDIR= ..\spunk INCDIR= ..\spunk # target specific macros. !if $(TARGET)==OS2 # --------------------- OS2 --------------------- SYSTEM = os2v2 CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !elif $(TARGET)==DOS32 # -------------------- DOS4G -------------------- SYSTEM = dos4g CC = WPP386 CCCFG = -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==DOS # --------------------- DOS --------------------- SYSTEM = dos CC = WPP # Optimize for size when running under plain DOS, but use 286 code. Don't # include ANY debugging code to make as many programs runable under plain DOS # as possible. CCCFG = -bt=$(TARGET) -d$(TARGET) -dSPUNK_NODEBUG -i=$(INCDIR) -d1 -oailmns -s -zp2 -zc -2 -fp2 -ml -zq -w2 -ze -zt255 !elif $(TARGET)==NETWARE # --------------------- NETWARE ------------------- SYSTEM = netware CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==NT # --------------------- NT ---------------------- SYSTEM = nt CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !else !error !endif LIB = $(LIBDIR)\$(TARGET)\SPUNK.LIB # ------------------------------------------------------------------------------ # Implicit rules .c.obj: $(CC) $(CCCFG) $< .cc.obj: $(CC) $(CCCFG) $< # -------------------------------------------------------------------- all: exe exe: istec os2: $(MAKE) -DTARGET=OS2 nt: $(MAKE) -DTARGET=NT dos32: $(MAKE) -DTARGET=DOS32 dos: $(MAKE) -DTARGET=DOS istec: estic.exe # -------------------------------------------------------------------- # ESTIC estic.exe: callwin.obj \ chargwin.obj \ cliwin.obj \ devstate.obj \ estic.obj \ icac.obj \ icalias.obj \ icbaseed.obj \ iccli.obj \ icconfig.obj \ iccom.obj \ iccprint.obj \ iccron.obj \ iccti.obj \ icdevs.obj \ icdiag.obj \ icdlog.obj \ icei.obj \ icerror.obj \ icfile.obj \ icident.obj \ icintcon.obj \ iclog.obj \ icmsgwin.obj \ icshort.obj \ icver.obj \ istecmsg.obj @copy makefile make\watcom.mak > nul $(LD) system $(SYSTEM) @&&| DEBUG all NAME estic.exe OPTION DOSSEG OPTION STACK=32K FILE callwin.obj FILE chargwin.obj FILE cliwin.obj FILE devstate.obj FILE estic.obj FILE icac.obj FILE icalias.obj FILE icbaseed.obj FILE iccli.obj FILE icconfig.obj FILE iccom.obj FILE iccprint.obj FILE iccron.obj FILE iccti.obj FILE icdevs.obj FILE icdiag.obj FILE icdlog.obj FILE icei.obj FILE icerror.obj FILE icfile.obj FILE icident.obj FILE icintcon.obj FILE iclog.obj FILE icmsgwin.obj FILE icshort.obj FILE icver.obj FILE istecmsg.obj FILE ..\areacode\areacode.obj LIBRARY $(LIB) | # ------------------------------------------------------------------------------ # ZIP File erzeugen zip: -del estic.zip -del *.bak copy makefile make\watcom.mak $(ZIP) -9 estic.zip *.cc *.h estic.res estic.ini *.doc *.chg make\*.mak alias.dat strip: -65535 wstrip estic.exe -65535 wstrip icload.exe bin-dist: exe strip -del estic.zip $(ZIP) -9 estic.zip estic.exe icload.exe estic.res estic.doc estic.chg estic.ini alias.dat # ------------------------------------------------------------------------------ # Zeilenzahl linecount: -wc -l *.cc *. # ------------------------------------------------------------------------------ # Aufr umen clean: -del *.bak zap: clean -del *.obj -del *.mbr -del *.dbr estic-1.61.orig/estic/samples/0040755000176100001440000000000007061535301015566 5ustar debacleusersestic-1.61.orig/estic/samples/alias.dat0100644000176100001440000000167207031424730017354 0ustar debacleusers; Beispiel für ein ESTIC Aliasfile. Zeilen mit einem ';' an der ersten ; Stelle sind Kommentare. Leere Zeilen werden ignoriert. Alle anderen Zeilen ; enthalten als erstes die Nummer, für die ein Alias definiert werden soll ; dann den String, durch den die Nummer ersetzt werden soll. ; Die Nummer kann (der besseren Lesbarkeit halber) Sonderzeichen, jedoch ; keine Leerzeichen (Tabs usw.) enthalten. 0711121212, 0711/121212, ; 0711-121212 oder +49-711-121212 sind Beispiele für zulässige Nummern. ; ; Achtung: Ein Alias für ein interes Gerät (21-xx) sollte maximal 12, ; ein Alias für ein externes maximal 16 Zeichen lang sein, alles was länger ; ist wird von ESTIC abgeschnitten, weil es sonst nicht in eine Zeile im ; Logfile passt. ; ; 123456789012 21 "Büro" 22 "Fax, Büro" 23 "Schlafzimmer" 24 "Wohnzimmer" 25 "Kinderzimmer" 26 "Küche" 27 "Handy" 28 "Anrufb." ; 1234567890123456 01188 "Telefon-Auskunft" 06231/123456 "H. Kohl, privat" estic-1.61.orig/estic/samples/cron.dat0100644000176100001440000001101607031424730017215 0ustar debacleusers; ; Beispiel Cron Datei ; ; Jede Zeile ist entweder leer, ein Kommentar, oder wie folgt aufgebaut: ; ; Minuten Stunden Tag Monat Wochentag Kommando [Argumente] ; ; Die Wertebereiche für die einzelnen Felder sind: ; ; Minute 0..59 ; Stunde 0..59 ; Tag 1..31 ; Monat 1..12 ; Wochentag 0..6 (0 = Sonntag) ; ; Das Kommando wird dann ausgeführt, wenn die aktuelle Zeit der Zeit ; entspricht, die in den ersten 5 Felder angegeben ist. Dabei handelt es ; sich um eine UND Verknüpfung, d.h. wenn Tag=13 und Wochentag=Freitag, ; dann wird das Kommando an jedem Freitag den 13. ausgeführt. ; ; Die Angabe in den ersten 5 Feldern beschränkt sich nicht nur auf einzelne ; Werte, sondern auch auf mehrere Werte, oder Bereiche. Alle folgenden ; Angaben sind korrekte Angaben für das Minutenfeld, für die anderen Felder ; gilt adäquates: ; ; 13 Ausführen wenn Minute = 13 ; 13,15 Ausführen wenn Minute = 13 oder 15 ; 13-15 Ausführen wenn Minute = 13, 14 oder 15 ; 5-20/5 Ausführen wenn Minute = 5, 10, 15 oder 20 ; ; Weiterhin ist für ein Feld die Angabe '*' möglich, mit der Bedeutung ; "jede volle ...". ; ; Folgende Kommandos werden unterstützt: ; ; PrintCharges # Speichert die aktuelle Gebühren ; ClearCharges # Setzt die Gebühren zurück ; LoadConfig # Lädt neue Einstellungen in die Istec ; SwitchConfig # Tag/Nachtumschaltung der FW >= 2.0 ; Ring # Läßt den Apparat für Sekunden klingeln ; ; kann - äquivalent zum Dateinamen für das Gebühren-Logfile - ; mit Abkürzungen für Zeitangaben erweitert werden: ; ; %% für das Zeichen '%' ; %a Wochentag, kurz ; %A Wochentag, lang ; %b Monat, kurz ; %B Monat, lang ; %c Zeit+Datum ; %d Tag des Monats (01-31) ; %H Stunde (00-23) ; %I Stunde (00-12) ; %j Tag des Jahres (001-366) ; %m Monat (01-12) ; %M Minute (00-59) ; %p AM oder PM ; %S Sekunde (00-59) ; %U Kalenderwoche, Sonntag erster Wochentag (00-53) ; %w Nummer des Wochentags (Sonntag = 0) ; %W Kalenderwoche, Montag erster Wochentag (00-53) ; %x Datum ; %X Zeit ; %y Jahr, zweistellig (00-99) ; %Y Jahr, vierstellig ; ; Achtung: Alle Bezeichner (für Monat, Tag usw.) sind englisch! ; ; ; Noch ein paar vollständige Beispielangaben (das ';' zu Beginn der Zeile fehlt ; natürlich bei einer "echten" Angabe). ; Apparat 21 morgens um 8 Uhr eine Minute klingeln lassen ;0 8 * * * Ring 21 60 ; Apparat 21 an Wochentagen um 8 Uhr eine Minute klingeln lassen ;0 8 * * 1-5 Ring 21 60 ; Am Monatsende die Gebühren speichern und rücksetzen. Die Kommandos werden ; in genau der Reihenfolge ausgeführt, in der sie in der Datei vorkommen d.h. ; die beiden folgenden Zeilen speichern erst die Gebühren und setzen sie dann ; zurück. ;0 0 1 * * PrintCharges charges.dat ;0 0 1 * * ClearCharges ; Wochentags, abends um 18 Uhr eine neue Konfiguration für die Nacht einlesen ;0 18 * * 1-5 LoadConfig nacht.ic ; Werktags morgens um 7 Uhr die Konfiguration wieder auf "Tag" stellen ;0 7 * * 1-5 LoadConfig tag.ic ; Beispiele für den ab der Firmware 2.0 verfügbaren Befehl zur Tag-/ ; Nachtumschaltung. ACHTUNG: Der Befehl ist nicht ganz unproblematisch. ; ; * Zum einen kann nicht die gesamte Konfiguration umgeschaltet werden (die ; Dienstekennung ist ein Beispiel für ein Datum, das anscheinend nur ; einmal vorhanden ist). ; * Zum zweiten führt die Verwendung dieses Befehls normalerweise dazu, daß ; die von ESTIC geladene Konfiguration nicht mehr mit derjenigen ; übereinstimmt, die tatsächlich aktiv ist. Das ist von der Bedienung her ; etwas veerwirrend, ist aber bei LoadConfig genauso. ; * Drittens darf der Befehl nicht zusammen mit LoadConfig verwendet werden, ; da die Istec nach LoadConfig das EEPROM sperrt für einige Zeit sperrt, ; und der SwitchConfig Befehl mit einem Fehler terminiert. Zwischen den ; beiden Befehlen sollte zumindest eine Minute liegen. ; * Und zuletzt ist anzumerken, daß der Befehl fehlerhaft implementiert ist. ; Meine Istec hat nach diesem Befehl sporadisch mehrfache Bestätigungen ; über die erfolgte Umschaltung zurückgeschickt, zum Teil kam direkt ; eine Bestätigung, und dann 20-30 Sekunden später nochmal eine, die ESTIC ; nicht erwartet, und die deshalb später zu einem Folgefehler führt. ; ; Für alle trotzdem mutigen, hier die versprochenen Beispiele. Sie setzen ; voraus, daß die beiden Konfigurationen in der Istec sinnvoll belegt sind. ; Wochentags, abends um 18 Uhr auf "Nacht" umschalten ;0 18 * * 1-5 SwitchConfig nacht ; Werktags morgens um 7 Uhr die Konfiguration wieder auf "Tag" stellen ;0 7 * * 1-5 SwitchConfig tag estic-1.61.orig/estic/samples/estic.ini0100644000176100001440000003150407031424730017376 0ustar debacleusers; ; Beispiel eines INI Files für ESTIC <-- das ist im übrigen ein Kommentar ; ; Diese Datei muss UNBEDINGT vor dem ersten Start von ESTIC angepasst werden! ; ; ------------------------- ESTIC Grundeinstellungen ------------------------ [ESTIC] ; Das File in dem ESTIC seine Einstellungen speichert. Dazu gehören ; sämtliche(!) Fenster, Positionen, Größen und ähnliches. Unter den *nix ; Derivaten kann der Namen die Tilde als Ersatz für das Home-Verzeichnis ; beinhalten (ein guter Name wäre z.B. "~/.esticrc"). ; Bei Problemen kann diese Datei ohne weiteres gelöscht werden, da sie ; keine für ESTIC "lebenswichtigen" Daten enthält. ; Die Defaulteinstellung ist "estic.rc", d.h. die Datei wird im aktuellen ; Verzeichnis angelegt. Ist der Name leer (""), dann wird nichts gespeichert. SettingsFile = "estic.rc" ; ----------------------------- Schnittstelle ------------------------------- [Port] ; Der Port- bzw. Device-Name PortName = "COM2" ; Nur für DOS, wird ignoriert für Linux & OS/2. Der Wert 0 benutzt die ; Standard-Adresse für den oben angegebenen Port. Hex-Werte können in der Form ; $3F8 oder 0x3F8 eingegeben werden ;PortBase = 0 ; Nur für DOS: Wertebereich: 0x08-0x0F oder 0x70-0x77, oder 0. Der Wert 0 ; benutzt den Standard-IRQ für diesen Port. Hex-Werte können in der Form ; $70 oder 0x70 eingegeben werden ; ACHTUNG, nicht verwechseln: IRQ9 == INT 0x71 etc. !!!! ;PortIRQ = 0 ; -------------------------------- Ausdruck --------------------------------- [Printing] ; String der als Kopfzeile verwendet wird Headline = "" ; Währung. Wird derzeit von ESTIC nicht verwendet, da bei einer Änderung nicht ; nur die Währung, sondern auch das Format umgestellt werden muss ($20 vs. 20DM) ; Falls der Ausdruck jemals Einheiten verwenden sollte, wird vermutlich die ; sowieso bekannte landesspezifische Einheit verwendet. ;Currency = "DM" ; DM/Einheit, default ist 12 Pf ;PricePerUnit = 0.12 ; -------------------------------- Windows -------------------------------- [Windows] ; Bildschirm-Modus (nur für DOS & OS/2). Default ist die Verwendung des ; aktuell eingestellten Modus. ; ; Folgende Modi sind verfügbar: ; ; 0 40x25, B/W DOS, OS/2 ; 1 40x25, Farbe DOS, OS/2 ; 2 80x25, B/W DOS, OS/2 ; 3 80x25, Farbe DOS, OS/2 ; 257 80x30, Farbe, nur VGA DOS, OS/2 ; 258 80x34, Farbe, nur VGA DOS, OS/2 ; 259 80x43, Farbe, nur VGA DOS, OS/2 ; 260 80x50, Farbe, nur VGA DOS, OS/2 ; 261 80x60, Farbe, nur VGA DOS, OS/2 ; 262 94x25, Farbe, nur VGA DOS ; 263 94x30, Farbe, nur VGA DOS ; 264 94x34, Farbe, nur VGA DOS ; 265 94x43, Farbe, nur VGA DOS ; 266 94x50, Farbe, nur VGA DOS ; 267 94x60, Farbe, nur VGA DOS ; 298 100x40, nur ET4000 DOS ; 512 "ask" - aktuellen Modus verwenden (default) VideoMode = 258 ; Soll in der rechten oberen Ecke Zeit/Datum permanent angezeigt werden? ; Mögliche Werte: ; None (keine Anzeige) ; Minutes (Stunden/Minuten) ; Seconds (auch Sekunden) ; Default ist Minutes ;ShowDateTime = Minutes ; Soll direkt beim Start das Fenster mit den Informationen über die Istec ; (Software-Version usw.) angezeigt werden? ; Default ist yes ;ShowInfoOnStartup = yes ; -------------------------------- AreaCode ------------------------------- [AreaCode] ; ESTIC verwendet die areacode Datenbank um Infos über Vorwahlen zu erhalten. ; Bisher sind in der Datenbank die Vorwahlen für Deutschland und die Schweiz ; enthalten. Neue Datenfiles gibt es von ftp://ftp.musoftware.com/pub/areacode/. ; Die Verwendung von areacode ermöglicht diverse Features, die sonst nicht ; möglich wären, z.B. die Prüfung auf gültige Nummern bei den Kurzwahlen oder ; Aliasen. ; Areacode ist im übrigen als (C++ kompatibler C-) Quelltext erhältlich und ; darf frei verwendet werden, auch für kommerzielle Anwendungen. ; Name und Pfad zum areacode Datenfile? Die Linux-Installationroutine kopiert ; es normalerweise als "areacodes" nach /usr/lib, wenn es dort nicht ist, ist ; der folgende Pfad zu setzen. Die Verwendung von /usr/lib/areacodes hat den ; Vorteil, dass die Zusammenarbeit mit anderen Programmen problemloser ist ; (isdnlog erwartet das File auch dort). Alle anderen (DOS usw.) erwarten ; die Datei im aktuellen Verzeichnis als "areacode.dat" ; Wenn der Pfad leer ist, dann wird der Default verwendet (areacode.dat im ; aktuellen Verzeichnis). ;AreaCodeFile = "areacode.dat" ; Internationale Vorwahl des eigenen Landes ohne "Verkehrsausscheidungsziffern". ; Der Default ist der in der Istec gespeicherte Landescode. Dieser wird dann ; verwendet, wenn die folgende Angabe leer ist. Der Landescode sollte immer ; gesetzt werden, auch wenn er - bei angeschlossener Istec - streng genommen ; nicht notwendig ist. Er hat dann Gültigkeit, wenn keine Istec gefunden wird, ; oder wenn die Istec Firmware (noch) keine Landescodes unterstützt (1.93 oder ; kleiner). ;CountryCode = "49" ; Vorwahl ohne "Verkehrsausscheidungsziffer". Wird verwendet um lokale Nummern ; in der Datenbank suchen zu können. ;AreaCode = "711" ; Die "Verkehrssuscheidungsziffer" an und für sich. Default ist "0" ;DialPrefix = "0" ; ------------------------------- Call-Logs ------------------------------- [Call-Logs] ; Namen der Logfiles in die ESTIC ausgehende und eingehende Gespräche loggt. ; Die angegebenen Namen sollten einen Pfad enthalten und können u.a. ; Steuercodes für strftime enthalten. Durch die Wahl des Namens kann z.B. ; ein Tages-, Wochen- oder Monatslog erzeugt werden: Wenn der Name z.B. so ; gewählt ist, dass er sich jeden Tag ändert, dann entsteht ein Tageslog. ; Die Namen sind nur Vorschläge - speziell unter Linux und OS/2 bietet es ; sich an, längere Namen zu verwenden. ; ; Verwendet werden können: ; ; %% für das Zeichen '%' ; %a Wochentag, kurz ; %A Wochentag, lang ; %b Monat, kurz ; %B Monat, lang ; %c Zeit+Datum (nicht zweckmässig) ; %d Tag des Monats (01-31) ; %E Apparat, von dem das Gespräch ausging (21-28) NUR AUSGEHEND!! ; %H Stunde (00-23) ; %I Stunde (00-12) ; %j Tag des Jahres (001-366) ; %m Monat (01-12) ; %M Minute (00-59) ; %p AM oder PM ; %S Sekunde (00-59) ; %U Kalenderwoche, Sonntag erster Wochentag (00-53) ; %w Nummer des Wochentags (Sonntag = 0) ; %W Kalenderwoche, Montag erster Wochentag (00-53) ; %x Datum ; %X Zeit ; %y Jahr, zweistellig (00-99) ; %Y Jahr, vierstellig ; ; Achtung: Alle Bezeichner (für Monat, Tag usw.) sind englisch! ; ; Default ist für OutgoingLog1 die Datei "outgoing.log" im aktuellen ; Verzeichnis, für die beiden anderen der Leerstring (d.h. kein Logging). ; Für den Eintrag in das Logfile ist die Startzeit maßgeblich, d.h. die ; Zeit zu der das Gespräch begonnen wurde. ; ; An ein Logfile wird prinzipiell immer angehängt wenn die Datei existiert, ; ansonsten wird sie erzeugt. Ergibt sich aus den angegebenen Pattern ; mehrfach derselbe Name, so wird in dieses File auch mehrfach geloggt. ; ;OutgoingLog1 = "%d-%m-%y.log" ; Ergibt 01-08-95.log ;OutgoingLog1 = "%d-%m-%y.out" ; Ergibt 01-08-95.out ;OutgoingLog2 = "KW%W-%y.log" ; Ergibt KW43-95.log ;OutgoingLog2 = "%b-%y.%E" ; Ergibt Feb-95.21 ;OutgoingLog3 = "%m-%Y.log" ; Ergibt 12-1995.log OutgoingLog1 = "O-%b-%y.log" ; Ergibt O-Feb-95.log IncomingLog1 = "I-%m-%Y.log" ; Ergibt I-Feb-95.log ; Angabe, ob Gespräche mit 0 Einheiten (z.B. wenn nicht abgehoben wurde) ; geloggt werden. LogZeroCostCalls = yes ; Wie viele Stellen sollen am hinteren Ende der Nummer ausge-X-t werden? ; Default ist 0. ; ACHTUNG: Bei Werten > 0 können keine Aliase mehr aufgelöst werden, da ; die Nummer im Aliasfile nicht mehr gefunden wird! ;XDigits = 3 ; --------------------------------- Aliase -------------------------------- [Alias] ; Hier können Aliase für die einzelnen Anschlüsse vergeben werden. Diese ; tauchen dann in den Logfiles neben den Nummern auf. ; ; Für das Eintragen der Aliase gibt es zwei verschiedene Möglichkeiten. ; ; * Direktes Eintragen hier im .ini File. Das ist nur für die eigenen Geräte ; möglich (d.h. die Nummern 21..XX), alle anderen Nummern werden ignoriert. ; * Ein separates Alias-File. Dort können sowohl Aliase für die eigenen ; Geräte als auch für ausgehende Nummern aufgenommen werden. ; ; Die Unterscheidung erfolgt anhand der Variable "AliasFile". Ist hier ein ; Name angegeben, dann werden nur die Aliase aus dieser Datei verwendet. ; Ist kein Name für die Alias-Datei angegeben, dann wird versucht, die ; Aliase für die eigenen Geräte aus der ini Datei zu lesen. ; Die folgenden Einträge werden ignoriert, weil weiter unten eine Alias-Datei ; angegeben ist. Es soll nur die Syntax gezeigt werden. ;21 = "Büro" ;22 = "Martin" ;23 = "Fax, Büro" ;24 = "Philip" ;25 = "Wohnzimmer" ;28 = "Anrufb." ; Ein Aliasfile, das Namen für bestimmte Rufnummern enthält. AliasFile = "alias.dat" ; Wenn AutoReadAliases auf on gesetzt ist, dann wird nach jedem Gespräch die ; oben angegebene Alias-Datei neu eingelesen. Da das nur dann notwendig ist, ; wenn sich das Aliasfile öfters ändert, ist der Default off, d.h. einlesen ; nur auf explizite Anforderung in ESTIC. Der Schalter hat keine Wirkung, ; wenn kein Aliasfile definiert ist. AutoReadAliases = no ; on/off/yes/no/1/0 möglich ; ---------------------------------- Cron --------------------------------- [Cron] ; Wird eine Cron-Datei verwendet? Wenn ja, Namen hier angeben (Default ist ; der Leerstring). Eine Beispieldatei mit Erklärungen findet sich unter dem ; Namen cron.dat ;CronFile = "cron.dat" ; ------------------------------- Debugging ------------------------------- [Debug] ; Zeit in ms, die nach dem Gespräch gewartet wird, bevor die Gebühren ; abgefragt werden. Falls nach Gesprächen manchmal (oder immer) 0 Einheiten ; geloggt werden, obwohl eine Verbindung zustande kam, diesen Wert vorsichtig ; erhöhen. WaitAfterCall = 700 ; Festlegen ob nach dem Absenden eine kurze oder eine lange Pause gemacht ; werden soll. Default ist 'on'. ShortWaitAfterMsg = on ; Logfile für's Debugging, default ist der Leerstring ;DebugLog = "debug.log" ; Soll ein existierendes Debug-Log beim Start von ESTIC überschrieben werden, ; oder sollen neue Daten angehängt werden? Default ist überschreiben (no) ;AppendDebugLog = no ; Die folgenden Einstellungen sind Firmware spezifisch. Da sie eigentlich nicht ; geändert werden müssen (außer vielleicht zu Testzwecken) befinden sie sich ; im Abschnitt "Debug" und nicht im Abschnitt "Firmware". ;ConfigVersionHigh = 2 ;ConfigVersionLow = 0 ; -------------------------------- Firmware ------------------------------- [Firmware] ; Die unterschiedlichen Versionen der Istec Firmware unterstützen ; unterschiedliche Features. Bei angeschlossener Istec erkennt ESTIC selber, ; welche Version der Firmware verwendet wird. Sollen Konfiguratonsdateien ; erstellt werden, ohne daß eine Istec angeschlossen ist, dann kann ESTIC ; nicht erkennen, welche Firmware-Version vorhanden ist und stellt u.U. ; bestimmte Einstellungen nicht zur Wahl. Mit der Variable FirmwareVersion ; kann angegeben werden, welche Version ESTIC bei nicht angeschlossener ; annehmen soll. Der Default ist Firmware Version 1.70. ; Nochmal: Das hat nur eine Bedeutung, wenn _keine_ Istec angeschlossen ist. ;FirmwareVersion = 1.93 ; Umschiffung eines Bugs in alten Istec Firmware-Versionen: Versionen bis hin ; zur Version 1.93 schalten selbsttätig irgendwann den Diagnose-Modus ab, den ; ESTIC zur Darstellung der Verbindungsmatrix und der Gesprächserfassung ; benötigt. Soll der Diagnose-Modus in regelmäßigen Abständen von ESTIC ; eingeschaltet werden? Mögliche Werte sind ON, OFF und AUTO, Default ist ; AUTO (d.h. ON, wenn Firmware <= 1.93). DiagModeUpdate = auto ; Ab der Firmware-Version 2.0 vom November 1996 kann die Istec eingehende ; Anrufe melden. Das geht aber nur dann, wenn der Diagnosemodus nicht ; eingeschaltet ist. Das bedeutet, dass es nicht gleichzeitig möglich ist, ; die Verbindungsmatrix/Logging ausgehender Rufe zu haben, und eine Anzeige/ ; Logging eingehender Rufe. Ich habe mit den Entwicklern gesprochen und mir ; wurde zugesagt, dass diese Beschraenkung entfernt wird - das ist aber ; offensichtlich nicht geschehen. Wenn Emmerich sich doch noch entschliessen ; sollte, beides gleichzeitig zu ermoeglichen, dann kann das Abschalten des ; Diagnose-Modus beim Öffnen des Fensters für eingehende Anrufe hier ; unterbunden werden. ; Default ist "yes", d.h. der Diagnosemodus wird beim Öffnen des Fensters ; ab- und beim Schliessen wieder angeschaltet. ;CLINoDiagMode = yes estic-1.61.orig/spunk/0040755000176100001440000000000007061535305014157 5ustar debacleusersestic-1.61.orig/spunk/doc/0040755000176100001440000000000007061535304014723 5ustar debacleusersestic-1.61.orig/spunk/doc/hier.doc0100644000176100001440000000550707031424711016341 0ustar debacleusersNote: Objects marked with * are template classes Point Rect EventHandler Object --+-- Stream --+-- NullStream ----- CRCStream | | | +-- FileStream ----- TextFileStream | | | +-- MemoryStream | +-- StreamableClass | +-- Streamable --+-- Container | | | +-- ResourceIndex | | | +-- _Collection ----- *Collection --+-- *SortedCollection --+-- StringCollection | | | | | | | +-- MsgCollection | | | | | | | +-- ResourceCollection | | | | | | | +-- StreamableClasses | | | | | | | +-- KeyMapper | | | | | +-- Palette | | | +-- *MemPool | | | +-- StringPool | | | +-- String ----- Message | | | +-- Window --+-- StatusLine ----- BottomStatusLine | | | | | +-- ItemWindow --+-- GenericMenue --+-- Menue | | | | | | | | | +-- MenueBar ----- TopMenueBar | | | | | | | +-- FileViewer | | | | | +-- RootWindow | | | +-- WindowItem --+-- MenueItem --+-- SubMenueItem ----- MenueBarItem | | | | | | | +-- MenueLine | | | | | | | +-- EditMenueItem --+-- LongItem | | | | | | | +-- HexItem | | | | | | | +-- StringItem | | | | | | | +-- ToggleItem --+-- OffOnItem | | | | | | | | | +-- NoYesItem | | | | | | | +-- FloatItem | | | | | | | +-- TimeItem | | | | | | | +-- DateItem | | | | | | | +-- RStringItem | | | | | | | | | | | +-- EditLine --+-- FloatEdit | | | | | | | +-- LongEdit ----- HexEdit | | | | | | | +-- TextEdit | | | | | | | +-- TimeEdit | | | | | | | +-- DateEdit | | | | | | | +-- PasswordEdit | | | | | | | +-- FileEdit | | | | | | | | +-- ListBox | | | | | +-- TextItem | | | | | +-- *Stack | | | +-- BitSet | | | +-- CharSet | | | +-- *CircularBuffer | | | +-- TimeDiff | | | +-- Time | | | +-- FileSelector | | +-- _ListNode ----- *ListNode | +-- Screen | +-- Keyboard | +-- Thread ----- Program | +-- IniFile | +-- ResourceFile ----- ProgramSettings | +-- Event estic-1.61.orig/spunk/doc/spunk.doc0100644000176100001440000010026607031424711016550 0ustar debacleusers SPUNK Version 1.10, February '96 A portable C++ class library for creating text mode applications (C) 1992-96 Ullrich von Bassewitz Abstract -------- SPUNK is a C++ class library that supports writing text mode applications that are portable between different operating systems that are popular on the IBM PC. This is not a complete documentation but merely an overview. It should enable you to know, what is possible with SPUNK, and where to you have to search for more information in the source. Contents -------- 1 Overview 1.1 ....... Some critic at the beginning 1.2 ....... Data types 1.3 ....... Error handling 1.4 ....... Portability 1.4.1 ............... Overview 1.4.2 ............... Concrete steps 1.5 ....... Persistent objects 1.6 ....... Resources 1.6.1 ............... Naming conventions 1.6.2 ............... National language versions of resources 1.6.3 ............... The resource editor ResEd 1.7 ....... General purpose objects 1.7.1 ............... class Point 1.7.2 ............... class Rect 1.7.3 ............... class String 1.7.4 ............... class Container 1.7.5 ............... class MemPool 1.7.6 ............... class StringPool 1.7.7 ............... class Stack 1.7.8 ............... class FIFO 1.7.9 ............... class BitSet 1.7.10 ............... class CharSet 1.7.11 ............... class ListNode 1.7.12 ............... class Collection 1.7.13 ............... class SortedCollection 2 Windows and menues 2.1 ....... Window coordinates 2.2 ....... Window colors 2.3 ....... Window states 2.4 ....... ItemWindows - windows that contain items 2.5 ....... Menues 2.5.1 ............... Menu items 2.5.2 ............... Edit items 3 Creating an application 3.1 ....... class Program 3.2 ....... The program resource 3.3 ....... Environment variables 3.3.1 ............... The SPUNK_LANGUAGE setting 3.3.2 ............... The SPUNK_COUNTRY setting 3.3.3 ............... The SPUNK_COLOR setting (Linux/FreeBSD) 3.3.4 ............... The SPUNK_CP437 setting (Linux/FreeBSD) 3.3.5 ............... The SPUNK_CTYPE setting (Linux/FreeBSD) 3.3.6 ............... The SPUNK_XINVERTMONO setting (X windows) 3.3.7 ............... The SPUNK_XFONT setting (X windows) 3.4 ....... Signal handling 3.5 ....... Useful hints 1 Overview ---------- SPUNK is a C++ library that allows the creation of text mode programs that compile under 16- and 32-bit DOS, Linux, FreeBSD and OS/2. Apart from that, SPUNK implements * many other useful classes such as Strings, Collections, Stacks FIFOs etc. * persistent objects. A resource file class allows storing those objects in files and loading them by name at runtime. This allows easy support of different languages and interactive development of menues and windows. Many of the ideas in this library came from discussions with a friend of mine, Michael Peschel, and from another (non portable) text mode library written in Turbo-Pascal we wrote together some time ago. 1.1 Some critic at the beginning -------------------------------- I would like to point out, that SPUNK is not perfect, not even (and this is important) in my own eyes. If I had to do it again, I would change many things. Some of them have "historic" reasons, for example: * The string class is not compliant to the ANSI string class definition. At the time, I started to write the SPUNK library there has been no ANSI string class. Because of the nature of persistent objects, I will probably not change the string class of the library. * I did not use C++ exceptions for error handling, because most compilers, that were available at that time, had no support for exceptions. On the other side, I made decisions, that were simply wrong (or just not as good as they could have been). One of those wrong decisions, I regret most, is the event handling. Event handling in the library is clearly not what you would expect from an object orientated library. The current event handling (which relies on the application polling the keyboard) hinders extensions like mouse support and modeless switching between windows. But since the library is intended to be the last text mode interface, I will write in my life, many of those things will not change. Maybe I'm able to learn from my mistakes when writing other libraries or applications. 1.2 Data types -------------- I avoided introducing many new data types using typedef. New data types are a constant source of confusion, and because C compilers have a very lax type checking, usage of those data types is not enforced by the compiler. Source code is difficult to read when using those data types (ULONG, APIRET, HPIPE etc.), because you have to know, what each type represents. Even in the OS/2 programmers manual, there are many examples, where the result of a API function is stored in a variable of type ULONG, but the correct type should be an APIRET (which is an ULONG). This shows that many programmers (even those, who should know better) do not remember all those different types. Having so many artificial types, that no one remembers them all, does not help anyone. A few very important data types are the ones that are defined in machine.h (because they are machine dependent). Those data types are used, whenever you need an integer of a predefined size. Use "u32" instead of "unsigned int", because the first one will work, even under DOS, the second will not. Apart from that, I used the plain C data types whenever possible. There is no new boolean type and there are no typedefs for pointers to objects. 1.3 Error handling ------------------ All SPUNK functions do intensive parameter checking in functions. All conditions, where invalid parameters are given, or unexpected error codes are returned are handled as fatal errors by the library. Checking for fatal errors and handling those situations is done via a set of macros in check.h. Each of those macro calls the function Check, which in turn calls another function via a function pointer if the check failed. On startup, the function vector points to a routine that simply prints an error message containing the place of the error and aborts the program. You get such an error message if a SPUNK program could not find it's resource file: Internal error: Error loading resource file hexed.res, \ file program.cc, line 147 When the application object has initialized the window system and keyboard handler, it replaces this function by one, that pops up a window describing the error. After confirmation of the error by the user, the program is aborted. Because all those errors are fatal errors, there is no way to save any user data or do cleanups on exit. The philosophy behind this is, that if the SPUNK library detects massive coding errors in your application, there is a great possibility that continuing would result in a desaster. If you plan to replace the error handling function, you will usually leave the function pointer untouched, but override the virtual function Program::AppError (which is the one that is called after all that macro/function pointer replacement hassle). After returning from this function, the virtual function Program::Cleanup is called and the program is aborted. If you decide to replace the error vector yourself, be shure, not to return to the calling function! Most macros are used to check for invalid parameters or other non-recoverable conditions, so returning would would not be good. 1.4 Portability --------------- SPUNK is not portable to every computer system under the sun. You will probably have very few problems, porting SPUNK to an intel based PC system, but trying to port SPUNK to - for example - the Mac might become a nightmare. 1.4.1 Overview -------------- Most modules that are operating system dependent, are in one of the *src directories. Those modules are: delay.cc Wait for a given time. filesys.cc File system functions that are os dependent kbd.cc The keyboard handler nlsinit.cc Initialization for the national language system. screen.cc The screen handler sercom.cc This is a module for doing communication via the serial lines. The distinction between os dependent modules and os independent ones is not extremely consequent. There are some other modules that contain one or two #ifdef's, mostly to select different system include files, but also, to do some additional os dependent stuff (limiting memory consumption under DOS for example). Whenever writing data to streams (see the discussion of persistent objects below), one of the portable data types mentioned above is used (this rule has one exception: floating point types. After many discussions, I decided, that the IEEE formats of the intel coprocessor are portable enough, so floating point numbers are stored as binary values. This is no problem as long as you don't try a Mac port :-) This means, that resources are portable between the supported operating systems. If your DOS application stores a window in a file, your Linux, FreeBSD or OS/2 application is able to load and display this window. Note: If you create your own persistent objects, you are yourself responsible for the data, you write to the stream. For example: enum { red, green, blue } Color; ... S << Color; is _not_ portable, because the size of an enum differs from compiler to compiler. Use a cast to and from a data type with a constant size when storing and loading enums. 1.4.2 Concrete steps -------------------- [Missing] 1.5 Persistent objects ---------------------- Many of the objects implemented by SPUNK are persistent. This means, that there lifetime may exceed the lifetime of the program. Persistent objects are heavily used throughout the library. They are the framework for the complete resource management (see below). Knowledge of two classes is needed to understand, how persistent objects work: First, there is a stream class, that can hold a stream of persistent objects. Second there is an anchestor class for all persistent objects: class Streamable. If you create persistent objects yourself, they have to be derived from class Streamable (or a descendant of class Streamable). In addition, you have to override/provide one or more of the following functions: virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); Plus an additional "build constructor", that takes an argument of type StreamableInit and initializes an empty instance. Load and Store write and read the instance data to/from the stream given as an argument. You may call the Load and Store functions of the anchestor to handle his data. StreamableID must return a unique 16 bit number, that identifies your object. Please use ID's above or equal to ID_USER (defined in streamid.h) for your own applications as values below ID_USER are reserved for use in the SPUNK library. Build simply returns a new instance created by the use of the build constructor. This probably sounds very complicated, but in reality is easy, because three of the functions mentioned above are "one line functions" that are essentially the same for every object. Let's try an example. Assume you have a class Msg that is derived from class String (which in turn is derived from class Streamable), that adds an u16 to the object data (the message number). A simplified implementation of the class interface might look like this: class Msg : public String { private: u16 MsgNum; public: // The build constructor: Msg (StreamableInit); // A "normal" constructor Msg (u16 Num, const char* S); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); }; And this is the implementation of the functions defined above: inline Msg::Msg (StreamableInit): String (Empty) { } void Msg::Load (Stream& S) { String::Load (S); // Handle data of class String S >> MsgNum; // Handle instance data } void Msg::Store (Stream& S) const { String::Store (S); // Handle data of class String S << MsgNum; // Handle instance data } u16 Msg::StreamableID () const { return ID_Msg; // Defined elsewhere, just a number } Streamable* Msg::Build () { return new Msg (Empty); // Return an empty object } As you can see, most functions needed for making an object persistent are very simple, especially the build constructor is usually empty, StreamableID and Build are one-liners. One (last) thing: You have to add a line like LINK (Msg, ID_Msg); to the top of your .cc file. This will register the streamable class at the stream manager whenever this module is linked in by your application. If you get an error message "ID 6789 not registered" when trying to load a resource, you forgot the above statement. The other side of persistent objects is a class of type Stream. Usually you don't have to deal with objects of types Stream (apart from creating and destroying them). Streams are something, you can write objects (or just data) to or read from. A very popular descendant of class Stream is class FileStream that implements a Stream using a disk file (I know that the word stream is somewhat overstressed, especially in the unix world, but I cannot change that). But this is not the only purpose, you can use streams for. Assume, you have created an object containing program options, that are stored on disk and that can be edited by the user of your application. After finished editing, you may want to know, if the user has actually changed anything, so you can ask him, if he wants to store the new data or discard the changes. One possibility is to check each and every member variable against the old value, that has been saved before the editing. This is a clumsy and complicated, approach especially if your object has many data members. For a better solution another descendant of class Stream is used: class CRCStream. A CRCStream is derived from a special stream class, that simply discards all data written to it. Class CRCStream "enhances" this behavior by calculating a crc checksum over the data written. So you may do the following: // Before editing: CRCStream CS1; CS1 << MyObj; u32 OldCRC = CS1.GetCRC (); // After editing: CRCStream CS2; CS2 << MyObj; int HasChanges = CS2GetCRC () != OldCRC; This may be further simplified by using the global function GetCRC which creates a new CRCStream, writes the object to it and returns the CRC of the object data. See crcstrm.h for more details. One of the most asked questions regarding streams is the following: What is the difference between using Load/Store, the operators <> and using Put and Get on a stream? When should you use one and when the other(s)? The solution is simple: Using Load and Store is the same as using the operators << and >>. If you have a look into strmable.h, you will notice, that the operators << and >> are implemented using Load and Store, both being virtual functions that are usually overriden by your own persistent objects. Load and Store write and read object data to and from the stream, but they don't provide a way for object identification. So, to load object data from a Stream using Load, you have to create an empty object yourself and you have to make shure, that the data beginning at the current stream position is data belonging to the object just created. Put and Get do more: Get identifies the object at the current stream position, creates an empty object of that type on the heap, loads the instance data to this object and returns the object just created. Put writes out the identification data needed by Get, together with the instance data of the object. 1.6 Resources ------------- Imagine to have something like a stockkeeping for persistent objects. If you had this, you could say to the stock-keeper "Please give me a copy of the window called 'About-Window', a german version would be fine". Persistent objects stored in such a manner are called resources. When your application starts, the constructor of the Program object will search for the resource file for your application. This resource file is usually created by copying the library resource file "baseres.res" to your application resource file, and then adding the resources needed by your application. The resource file contains many different types of objects, for example: * Menues and windows. * Messages. * Other data like character translation tables. 1.6.1 Naming conventions ------------------------ I have developed the following rules for the names of resources. However, you are free to use your own rules as the library does not enforce any naming conventions (apart from the names of the language specific resources, see below for details). - Resources may have any name (you can even use spaces inside the name) - The name is preceeded by the name of the module that uses the resource in capital letters. - The module name is separated from the resource name by a dot. - Application resources add a @ in front of the module name. This way, application resources are grouped together in the resource directory before the library resources. Example 1, editor window for the password module, generic version: PASSWORD.EditWindow Dito, german version (see below) 001.PASSWORD.EditWindow Example 2, application resource, generic version: @HEXOPT.EditWindow Dito, german version (see below): 001.@HEXOPT.EditWindow 1.6.2 National language versions of resources --------------------------------------------- Support of different languages consists in many situations in just loading another menu or message. The Program::LoadResource function supports this by automatically choosing the correct resource according to the current language. This works as follows: Every language is assigned a number. If you load a resource by name, the function mentioned above will first add the number before the resource name and try to find this resource. If the resource is found, it is loaded. If not, the generic version without a preceeded language number is tried. As a last ressort, the english version (language #2) is tried. Let's look at the following example. Your code contains the statement // Load the edit window Menue* Win = (Menue*) LoadResource ("@HEXOPT.EditWindow"); If the current language is set to german (1), Program::LoadResource will search for 001.@HEXOPT.EditWindow If it does not find this resource, it will try @HEXOPT.EditWindow If this fails, it will try the english version 002.@HEXOPT.EditWindow So multiple languages are easily supported by providing different resources. If you decide to add another language, you don't have to change your source code, adding new resource will usually by enough. 1.6.3 The resource editor ResEd ------------------------------- To simplify the usage of resource files, there is a resource editor called ResEd. With ResEd you can... * create menues and windows and add them to the resource file. * delete resources you don't need any longer. * merge resource files. The resources in the resource file that are merged overwrite already existing resources. This is useful if you want to update your application specific resource from a new base resource file (containing the library resources). * add data files. ResEd will create a container object that contains your data and write this container object to the resource file. * create and edit message bases containing the messages used by your application. Messages can also be read from a text file. * print resources to a file or to the printer. Beware: ResEd is a developers tool, not an end user application. Because of that, it has some rough edges. It is not a typical SPUNK application - in many places ResEd is a hack (yes, I have to admit that :-) 1.7 General purpose objects --------------------------- SPUNK contains many general purpose objects that are useful, even if you are not using any windows. This does not mean, that those objects are completely independent from the rest of the library! All classes mentioned below use the SPUNK error handling and (maybe) other SPUNK classes to implement functionality. 1.7.1 class Point ----------------- This class (it is actually a struct) is defined in rect.h. A Point consists of a X/Y pair of coordinates. There are some funtions to work with objects of class Point, for example comparing two Points or writing instances of class Point to a stream. 1.7.2 class Rect ---------------- A Rect consists of two Points, one describing the upper left, the other the lower right corner of a rectangle. There are many utility functions, for example to calculate the union or intersection of two rectangles. Instances of class Rect are persistent and can be written to a stream. Class Rect is defined in rect.h 1.7.3 class String ------------------ Class String is defined in str.h. Have a look at the header file for a description of all member and friend functions. Strings are very intensively used throughout the SPUNK library. A direct descendant of class String, is used to store Strings by numbers in resource files. The class String is not compatible to the class String of the new standard C++ library. This is because my class String is much older than the standard. 1.7.4 class Container --------------------- Objects of class Container do nothing more but hold data. They are used to put an "object envelope" around some data, to handle it in an object oriented fashion. Containers are persistent, so you can use instances of class Container to store data in streams using the usual Stream::Put and Stream::Get methods. 1.7.5 class MemPool ------------------- This is a template class that is used to create a memory pool for identical objects. The memory pool may grow but not shrink. This is ideal if you need to gather data and throw it away completely after use. Class MemPool is a base class of class StringPool. The latter has been used for the identifier table of a compiler I wrote. 1.7.6 class StringPool ---------------------- Class StringPool is derived from class MemPool. It implements a pool for strings of varying size that can be accessed by name or by index. It has been used as an identifier table for a compiler. 1.7.7 class Stack ----------------- This is a template class that implements a stack ob objects. 1.7.8 class FIFO ---------------- This is a template class that implements an object queue. 1.7.9 class BitSet ------------------ Class BitSet can hold a set of numbers, internally implemented by a set of bits. You can check if a number is a member of the set and do many other operations on this set. The numbers must not start from zero, you can give other values for the upper and lower bounds on creation. 1.7.10 class CharSet -------------------- Because of speed considerations this bitset class has not been derived from class BitSet. It is a class that can hold a set of characters (values 0..255). 1.7.11 class ListNode --------------------- This is a template class that is used to build double linked circular lists. There are many places in the library, where objects of class ListNode are used: ItemWindows for example hold a linked list of the items contained in the windows in such a list. ListNode objects are not persistent for themselves, but have some support for writing persistent items to a stream. See listnode.h for implementation details. 1.7.12 class Collection ----------------------- Class Collection is a template class. Collections are best thought of as dynamically allocated arrays. Collections contain pointers to objects (preferably of the same type). Depending on the initialization, Collections will dynamically grow if you add more objects. You can iterate through every member of a Collection, add and delete members and more. Collections are streamable (persistent). See coll.h for more details. 1.7.13 class SortedCollection ----------------------------- Class SortedCollection is a descendant of class Collection. Members of class SortedCollection are stored in a sorted fashion. The sort is done by a key, that you have to provide. Searching a member in a SortedCollection is much faster, because the sort allows a binary search to be used. 2 Windows and menues -------------------- A window as it is implemented in the window module is a rectangular area on the screen. A window may have a frame and it may be in different states. There are many functions to work with windows, you can write text to a window (even to an invisible window), you can move and resize the window, change the window palette etc. 2.1 Window coordinates ---------------------- 2.2 Window colors ----------------- Window colors are not given as absolute screen colors but as indices into a window palette. There are 9 predefined palettes, but your program may add more. Every palette must exist in a color and in a monochrome version. Palettes are managed by an object of class Palette that is created on startup. A window holds just the number of the palette it uses. As every color is not a real color but an index into the current palette, changing the palette number changes all colors of the window. There are some rules used throughout the library for using the different palettes. There are special palettes for error and system error windows. Menues use the gray palette, editor windows are blue, notification windows are cyan and so on. 2.3 Window states ----------------- 2.4 ItemWindows - windows that contain items -------------------------------------------- An ItemWindow is a window that contains some other objects that are displayed inside the window. 2.5 Menues ---------- 2.5.1 Menu items ---------------- 2.5.2 Edit items ---------------- 3 Creating an application ------------------------- Creating an application with SPUNK is easy. Have a look into the files skel.h and skel.cc - they contain a complete program skeleton. All you have to do is to add functionality. 3.1 class Program ----------------- All programs have an application object that is derived from class Program. Things do not happen in functions called from main, but in the context of this application object and its member functions. Usually your function main looks like this: int main (int argc, char** argv) { MyProgramObj MyApp (argc, argv); return MyApp.Run (); } A pointer to the (one and only) program object is stored in the global variable App. This allows accessing member functions of your program object from other places. The constructor of class Program will take the argument list and explode any wildcard arguments when run under DOS or OS/2. After that, you may access the argument list via the member variables ArgCount and ArgVec from anywhere in your program. 3.2 The program resource ------------------------ The constructor of class Program will search for the program resource and open it. There has to be a program resource, because many functions in the library try to access this resource. The resources needed by the library are contained in a file named baseres.res. When you start developing your program, create your resource file by copying this base resource to your program resource, then add your own resources to this file. There are many utility functions that access the resource file. Most functions are functions of class Program, but have a counterpart in a global function to make accessing this functions easy. There is, for example, a function Program::LoadResource and a global function LoadResource. Note: One of the functions to access the resource is somewhat dangerous. To load a message, do not call LoadMsg! This will try to find the message in the message base called PROGRAM.Messages. Use LoadAppMsg instead to load your application messages. LoadAppMsg loads the messages from a message base that has the name of your program preceeded with '@' and ".Messages" added (eg. @HEXED.Messages). The Language specific version of this message base is searched first (as described above). 3.3 Environment variables ------------------------- The SPUNK library in general uses some environment variables to change the inner workings of spunk to the environment, in which the application is running. Some other settings are used under the Unix like operating systems. 3.3.1 The SPUNK_LANGUAGE setting -------------------------------- 3.3.2 The SPUNK_COUNTRY setting ------------------------------- 3.3.3 The SPUNK_COLOR setting (Linux & FreeBSD only) ---------------------------------------------------- Use the environment variable SPUNK_COLOR to force the Linux screen module to use (ANSI compatible) color strings or not. The default is to use colors on the console (which is automagically detected by the screen module). This setting is useful if you are connected via a DOS or OS/2 terminal program that supports colors. Use on of "yes", "on", "1" to force the use of color "no", "off", "0" to disable colors Case is ignored when looking at the values of environment strings. Beware: Using SPUNK_COLOR=yes in an XTerm window won't look very good for two reasons. First, XTerm has a very strange default color mapping. But second (and this is even worse), XTerm does not support enough colors (16 are needed, 8 supported). I have heard of an XTerm clone that supports ANSI colors, but I have not tested this. Use the X backend when running spunk apps under X if possible. 3.3.4 The SPUNK_CP437 setting (Linux & FreeBSD only) ---------------------------------------------------- Use the environment variable SPUNK_CP437 to tell the Linux screen module that your terminal supports the IBM codepage 437. Given this setting, the screen module will not translate from the internal used character set and will use the IBM linedrawing characters which will make framed windows look much nicer. Default is to use this setting on the console (after switching the console character set to codepage 437). This setting is useful if you are connected via a DOS or OS/2 terminal program that supports the IBM codepage 437. Use on of "yes", "on", "1" to force the use of the codepage 437 "no", "off", "0" to disable the use of codepage 437 Case is ignored when looking at the values of environment strings. 3.3.5 The SPUNK_CTYPE setting (Linux/FreeBSD) --------------------------------------------- Since the possible values of LC_CTYPE differ widely from operating system to operating system (and also between the different versions of one operating system), SPUNK_CTYPE is the last resort if you cannot change the value of LC_CTYPE for some reason. The setting for SPUNK_CTYPE overrides the one from LC_CTYPE. There is currently only one possible value: ISO-8859-1 Use the ISO-8859-1 character set Case is ignored when evaluating the string. 3.3.6 The SPUNK_XINVERTMONO setting (X windows) ----------------------------------------------- 3.3.7 The SPUNK_XFONT setting (X windows) ----------------------------------------- The X backend tries to use a font named VGA for it's display. This font comes with dosemu under Linux and is a fixed size font that has the VGA (CP 437) character set. If you don't have this font (Linux usually has it, FreeBSD has it not), you may use any other fixed size font. Just set SPUNK_XFONT to the name of the font, you want to use. If the name of the font starts with "vga" (any case), spunk assumes that the codepage 437 is available. If it does not start with "vga", spunk assumes an ascii font. If you are using an ISO-8859-1 font, don't forget to set LC_CTYPE or SPUNK_CTYPE so that spunk will use the correct character set. Usage of the vga font is strongly encouraged since this will look much better than using one of the ISO8859-1 fonts. 3.4 Signal handling ------------------- The application object by default catches all important signals and reroutes them to virtual functions that may be overridden by derived objects. Each of those signal handling functions returns an int that says if the signal has been handled by the function. If the function returns zero (meaning, the signal has not been handled), the signal is re-raised without reinstalling the signal handler, so that the default action occurs. So you don't have to use the signal() function to catch any signals, this is done for you by the application. Just define your own virtual signal handling function, which is automatically activated when a signal is caught. 3.5 Useful hints ---------------- estic-1.61.orig/spunk/.cvsignore0100644000176100001440000000007107031424676016157 0ustar debacleusersos2 dos dos32 netware nt makefile Makefile .depend resed estic-1.61.orig/spunk/baseres.res0100644000176100001440000017050007031424676016323 0ustar debacleusersAnna@ń´ģ6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpfpapdp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pDtaptpepipepnp p p p p p p p p p p p p p p p p p p pVteprpzpepipcphpnpipspspep p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6D Dateien`6V/ Verzeichnisse2N1Name( 3ž`6é˙˙Pfadb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp p p p p p pBpepnpuptpzpeprpnpapmpep p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprptp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KBenutzer-ID Benutzername Passwort LevelPH6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pItDp p p p p p p p p p p p p p p                       p³p³p pBpepnpuptpzpeprp-pNtapmpep p p                                 p³p³p pPtapspspwpoprptp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStipcphpeprphpepiptpsp-pEpbpepnpep p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/I  Benutzer-ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N 1 Benutzer-Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPasswort "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSicherheits-Ebene0*)/ PH6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprptp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp— ˙˙ Passwort:  PH6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ Benutzer-ID: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōHilfe bernehmen Abbruch Ende Weiter ˇndern Drucken Grafik  Einfgen L”schen Auswahl Best„tigen Bewegen Login Logout Ende Zoom  Schliessen ™ffnen Gr”įe  Speichern  ~~ Auswahl  ~ÄŁ~ Auswahl  ~ Bild-~ Bl„ttern  ~~ Bewegen  ~Ctrl+~ Gr”įe Sind Sie sicher?dWirklich Ende?eˇnderungen verwerfen?fˇnderungen sichern?g @Ja @Neinh @Nein @Jai Fehler Č Information É Systemfehler Ź Best„tigen ŅAbbruch Ó Ignorieren Ō Wiederholen ÕEnde ÖEinen Moment bitte...×Ungltige Eingabe,Zu viele Nachkommastellen-"Wert ist zu klein (Minimum ist %g).!Wert ist zu groį (Maximum ist %g)/#Wert ist zu klein (Minimum ist %ld)0"Wert ist zu groį (Maximum ist %ld)1Leereingabe ist unzul„ssig2Keine Datei-Erweiterung erlaubt3Aus AnNein Ja‘Wert ist zu groįōWert ist zu kleinõFehlerhafte Eingabeö2%s: Sektion %s, %s nicht gefunden oder fehlerhaft.X*Fehler beim ™ffnen der Passwort-Datei^(%s)¼)Fehler beim Lesen der Passwort-Datei^(%s)½1Fehler beim Schreiben auf die Passwort-Datei^(%s)¾)Es muį eine Benutzer-ID angegeben werden!æ)Es muį ein Benutzername angegeben werden!Ą%Es muį ein Passwort angegeben werden!Į-Ein Benutzer mit dieser ID existiert bereits!Ā/Ungltige Benutzer-ID oder ungltiges Passwort!ĆSonntag Montag!Dienstag"Mittwoch# Donnerstag$Freitag%Samstag&So'Mo(Di)Mi*Do+Fr,Sa-Januar.Februar/M„rz0April1Mai2Juni3Juli4August5 September6Oktober7November8Dezember9Jan:Feb;M„r<Apr=Mai>Jun?Jul@AugASepBOktCNovDDezEKeine Hilfe verfgbar„ Keine Hilfe fr dieses Stichwort… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+Bild-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Bild-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Bild-™Alt+Ende Alt+Bild- Alt+Einfg¢Alt+Entf£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-EndeEsc-PgDn Esc-Einfg¢Esc-Entf£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Verzeichnis 5 Fehler %d: %süKein Fehler (OOPS!)żDatei oder Pfad nicht gefundenžNicht genug Speicher˙Zugriff verweigert Zu viele offene Files 9Nicht gengend Speicherplatz auf dem angesprochenen Ger„t %Tempor„rer Fehler - nochmal versuchen Ger„t/Datei ist in Benutzung Datei ist zu groį I/O Fehler Datei ist ein Verzeichnis Datei ist kein Verzeichnis Zu viele Links 'Operation nur mit Block Devices m”glich &Operation nur mit Char Devices m”glich Device existiert nicht 4Operation ist nur fr den Besitzer der Datei m”glich Broken Pipe Dateisystem ist readonly +Seek kann nicht auf Pipes ausgefhrt werden Prozess existiert nicht Ausfhrbare Datei ist busy Name ist zu lang Keine Locks verfgbar Verzeichnis ist nicht leer Datei nicht gefunden Pfad nicht gefunden Laufwerk ist ungltig 0Aktuelles Verzeichnis kann nicht gel”scht werden Datei existiert bereits Unbekannter Fehler (%d) "Es sind zu viele Fenster ge”ffnet!Ä 6P > = Fensterliste  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pFpepnpsptpeprplpipsptpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpaptphp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pFtiplpepsp p p p p p p p p p p p p p p p p p p p p pDtiprpepcptpoprpipepsp p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6F!Files`6D  Directories2N1Name( 3ž`6é˙˙Pathb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp p p p p p p p p p pUpspeprp pNpapmpep p p p p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprpdp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KUser ID User Name Password LevelPH6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pItDp p p p p p p p p p p p p p p p p p p                       p³p³p pUpspeprp pNtapmpep p p p p p p                                 p³p³p pPtapspspwpoprpdp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStepcpuprpiptpyp pLpepvpeplp p p p p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/IUser ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N1 User Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPassword "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSecurity Level0*)/ PH6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  PH6P :9 ŲŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp” ˙˙User ID:  ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōHelpAccept Abort End Proceed Change Print  Graphics Insert Delete Select Confirm Move Login Logout Exit Zoom Close Open Resize Save  ~~ Select  ~ÄŁ~ Select  ~ PgDn PgUp~ Browse  ~~ Move  ~Ctrl-~ Resize Are you shure?d Really quit?eDiscard changes?f Save changes?g@Yes @Noh@No @Yesi Error Č Information É Fatal Error ŹConfirm ŅAbort ÓIgnore ŌRetry ÕEnd ÖOne moment please...× Invalid input,Too many trailing digits-"Value is too small (minimum is %g)."Value is too large (maximum is %g)/#Value is too small (minimum is %ld)0#Value is too large (maximum is %ld)1Input cannot be empty2No filename extension allowed3Off On NoYes‘Value is too largeōValue is too smallõ Invalid inputö,%s: Section %s, key %s not found or invalid.X$Error opening the password file^(%s)¼$Error reading the password file^(%s)½'Error writing to the password file^(%s)¾The user id cannot be empty!æThe user name cannot be empty!ĄAn empty password is invalid!Į'A user with this ID does already exist!Ā$Invalid user id or invalid password!ĆSunday Monday!Tuesday" Wednesday#Thursday$Friday%Saturday&Sun'Mon(Tue)Wed*Thu+Fri,Sat-January.February/March0April1May2June3July4August5 September6October7November8December9Jan:Feb;Mar<Apr=May>Jun?Jul@AugASepBOctCNovDDecENo help available„No help on this topic… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+PgUp™Alt+EndAlt+PgDnAlt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Error %d: %süNo error (OOPS!)żFile or path not foundžNot enough memory˙ Access denied Too many open files No space left on device Try again Device or file is busy File is too large I/O error File is a directory File is no directory Too many links Block device required Char device required Device does not exist !You are not the owner of the file Broken pipe File system is readonly Cannot seek on pipes Process does not exist Text file is busy Name is too long No locks available Directory is not empty File not found Path not found Drive is invalid Cannot remove current directory File exists Unknown error (%d) There are too many windows open!Ä 6P > = Window list  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pWpipnpdpopwp plpipsptp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙š ōHelp Overnemen  Afbreken Einde Verder  Veranderen  Afdrukken Grafiek  Invoegen  Verwijderen Keuze Bevestigen Bewegen Login Logout Einde Zoom Sluiten Openen Grootte Opslaan  ~~ Keuze  ~ÄŁ~ Keuze  ~ Beeld-~ bladeren  ~~ Bewegen  ~Ctrl+~ Groote  Bent U zeker?dEcht verlaten?eWijzigingen ongedaan maken?fVeranderinge schrijven?g@Ja @Neeh@Nee @Jai Fout Č Informatie É Systeemfout Ź Bevestigen Ņ Ophouden ÓNegeren Ō Herhalen ÕEinde ÖEven wachten a.u.b...×Ongeldige invoer,Te veel cijfers na de Komma-"Waarde is te klein (Minimum is %g)."Waarde is te groot (Maximum is %g)/#Waarde is te klein (Minimum is %ld)0#Waarde is te groot (Maximum is %ld)1Lege invoer is niet toegelaten2Geen Bestand ending toegelaten3UitAanNeeJaa‘Waarde is te grootōWaarde is te klijnõ Foute invoerö(%s: Sektie %s, %s niet gevonden of fout.X5Fout bij het openen van het wachtwoorden-bestand^(%s)¼4Fout bij het lezen van het wachtwoorden-bestand^(%s)½8Fout bij het schrijven van het wachtwoorden-bestand^(%s)¾"De User-ID moet aangegeven worden!æ#De Usernaam moet aangegeven worden!Ą&Een wachtwoord moet aangegeven worden!Į Een User met deze ID bestaat al!Ā*Ongeldige User-ID of ongeldige wachtwoord!ĆZondag Maandag!Dinsdag"Woensdag# Donderdag$Vrijdag%Zaterdag&So'Ma(Di)Wo*Do+Fr,Za-Januari.Februari/Maart0April1Mei2Juni3Juli4Augustus5 September6Oktober7November8December9Jan:Feb;Maa<Apr=Mai>Jun?Jul@AugASepBOktCNovDDecEGeen Hulp beschikbaar„Geen Hulp voor dit Steekword… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpatieCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+Pg-v Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pg-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+Pg-™Alt+EndAlt+Pg-Alt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+EscAlt+spacetoutsCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Fout %d: %süGeen fout (OOPS!)żBestand of pad niet gevondenžTe weinig geheugen˙Ingreep geweigerd Te veel geopende bestanden ,Te weinig ruimte op het angesproken apparaat &Tijdelijke fout - Probeer het nog eens Apparaat/Bestand is in gebruik Bestand te groot I/O Fout Bestand is een directory Bestand is geen directory Te veel links *Operatie alleen mogelijk met block devices )Operatie alleen mogelijk met char devices Device bestaat niet <Operatie is alleen voor de eigenaar van dit bestand mogelijk Broken Pipe Bestandsysteem is alleen-lezen (Seek kan niet op Pipes uitgevoerd worden Proces bestaat niet !Uitvourbare bestand is in gebruik Naam is te lang Geen lockings beschikbaar Directory is niet leeg Bestand niet gevonden Path niet gevonden Schijf is onjuist ,Huidige directory kan niet verwijderd worden Bestand bestaat al Onbekende fout (%d) Te veel vensters geopend!Ä 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  PH6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p zIpDp puptpepnptpep:p z z z z                       z³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ ID utente: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōGuida Accetta Annulla Termina  Continua  Modifica Stampa Grafica  Inserisci  Cancella Seleziona Conferma Muovi Login Logout Termina Zoom Chiudi Apri  Dimensione Salva  ~~ Seleziona  ~ÄŁ~ Seleziona  ~ Pag-~ sfoglia  ~~ Muovi  ~Ctrl+~ Dimensione E' proprio sicuro?dProprio terminare?eAnnullare modifiche?fSalvare modifiche?g@S¨ @Noh@No @S¨i Errore Č Informazione É Errore di sistema Ź Conferma ŅAnnulla ÓIgnora ŌRipeti ÕFine Ö Un momento...×Valore non valido,Troppi zero dopo la virgola-$Valore troppo piccolo (al minimo %g).$Valore troppo grande (al massimo %g)/%Valore troppo piccolo (al minimo %ld)0%Valore troppo grande (al massimo %ld)1Ci vuole qualcosa!2Estensione file non ammessa3Off OnNoS¨‘Valore troppo grandeōValore troppo piccoloõValore sbagliatoö+%s: sezione %s, %s non trovata o sbagliata.X/Errore di apertura del file delle password (%s)¼.Errore di lettura del file delle password (%s)½0Errore di scrittura del file delle password (%s)¾Ci vuole un ID utente!æCi vuole un nome utente!ĄCi vuole una password!Į#Un utente con questo ID esiste gi…!Ā ID utente o password non validi!ĆDomenica Luned¨!Marted¨" Mercoled¨#Gioved¨$Venerd¨%Sabato&Do'Lu(Ma)Me*Gi+Ve,Sa-Gennaio.Febbraio/Marzo0Aprile1Maggio2Giugno3Luglio4Agosto5 Settembre6Ottobre7Novembre8Dicembre9Gen:Feb;Mar<Apr=Mag>Giu?Lug@AgoASetBOttCNovDDicEGuida non disponibile„.Guida non disponibile per questa parola chiave… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+Pag-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pag-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Pag-™Alt+Fine Alt+Pag-Alt+Ins¢Alt+Canc£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-FineEsc-PgDnEsc-Ins¢Esc-Canc£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Byte 4 Directory 5 Errore %d: %süNessun errore (OOPS!)żFile o path non trovatižMemoria insufficiente˙Accesso negato Troppi files aperti ,Memoria insufficiente sul device indirizzato Errore temporaneo - riprovare Device/file in uso File troppo grande Errore di I/O Il file una directory Il file non una directory Troppi links /L'operazione possibile solo con block devices .L'operazione possibile solo con char devices Device non esistente :L'operazione possibile solo per il proprietario del file Broken Pipe $Il file di sistema e' a sola lettura %Seek non pu• essere eseguito su pipes Processo non esistente File eseguibile impegnato Nome troppo lungo Nessun lock disponibile La directory non vuota File non trovato Path non trovato Drive non valido .La directory attuale non pu• essere cancellata Il file esiste gi… Errore sconosciuto (%d) Sono aperte troppe finestre!Ä 6P > = Lista finestre  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pLpipsptpap pfpipnpepsptprpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,./:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° .,-:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAA¸€EEEIIIA¸E’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨ˇ†‘‘“”•–—™›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° BEF.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙!"#$%&˙()*+,˙./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU›¯˛AIOUNN¦§Ø©Ŗ«¬­®Æ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüż˙˙° F ,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° ˛.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° L..,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° Fr'...,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙ČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚ¨ŪÜŻŽßąįāćä<=>?@ABCDEFGHIJ !"#$%&'()KLMNOPQ RST4U3 VWX6Y oZp–\ ]—_`abcdefghi™›klmn¯qrstuvw˛xyz{|}~ ¢£¤¦§Ø©€‚Ŗ«…¬­®Æ°†±²³´µ¶·ø¹ŗ‰»¼½¾ˇæ¸ĄĮĀ“”° ,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° SEK.,-.;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° DM.,.:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° mk ,..;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° >< ^ >< ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ° »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±> #include "check.h" #include "stream.h" #include "bitset.h" #include "streamid.h" // Register the class LINK (BitSet, ID_BitSet); /*****************************************************************************/ /* class BitSet */ /*****************************************************************************/ BitSet::BitSet (int BitCount, int FirstIndex) : Count (BitCount), First (FirstIndex), Last (FirstIndex + BitCount - 1), Bytes ((BitCount + 7) / 8) { // Get memory BitBucket = new unsigned char [Bytes]; // Clear memory Clear (); } BitSet::BitSet (const BitSet& Set) { // Copy Members Count = Set.Count; First = Set.First; Last = Set.Last; Bytes = Set.Bytes; // Get memory BitBucket = new unsigned char [Bytes]; // Copy BitBucket memcpy (BitBucket, Set.BitBucket, Bytes); } BitSet::~BitSet () // Destructor { delete [] BitBucket; } u16 BitSet::StreamableID () const { return ID_BitSet; } void BitSet::Store (Stream& S) const { S << Count << First << Last << Bytes; S.Write (BitBucket, Bytes); } void BitSet::Load (Stream& S) { S >> Count >> First >> Last >> Bytes; BitBucket = new unsigned char [Bytes]; S.Read (BitBucket, Bytes); } BitSet& BitSet::operator = (const BitSet& Set) // Assignment operator { if (this != &Set) { // Beware of Set = Set; Count = Set.Count; Bytes = Set.Bytes; First = Set.First; Last = Set.Last; delete BitBucket; BitBucket = new unsigned char [Bytes]; memcpy (BitBucket, Set.BitBucket, Bytes); } return *this; } BitSet& BitSet::operator += (int Bit) { // Range-Check PRECONDITION ((Bit >= First) && (Bit <= Last)); Bit -= First; BitBucket [Bit / 8] |= (unsigned char) (0x01 << (Bit % 8)); return *this; } BitSet& BitSet::operator += (const BitSet& Set) { unsigned char* P1 = BitBucket; unsigned char* P2 = Set.BitBucket; for (unsigned I = 0; I < Bytes; I++, P1++, P2++) { *P1 |= *P2; } return *this; } BitSet& BitSet::operator -= (int Bit) { // Range-Check PRECONDITION ((Bit >= First) && (Bit <= Last)); Bit -= First; BitBucket [Bit / 8] &= (unsigned char) ~(0x01 << (Bit % 8)); return *this; } BitSet& BitSet::operator -= (const BitSet& Set) { unsigned char* P1 = BitBucket; unsigned char* P2 = Set.BitBucket; for (unsigned I = 0; I < Bytes; I++, P1++, P2++) { *P1 &= ~(*P2); } return *this; } BitSet operator ~ (const BitSet& Set) { BitSet NewSet (Set); return NewSet.Reverse (); } BitSet operator + (const BitSet& Set, int Bit) { return (BitSet (Set) += Bit); } BitSet operator + (const BitSet& Set1, const BitSet& Set2) { return (BitSet (Set1) += Set2); } BitSet operator - (const BitSet& Set, int Bit) { return (BitSet (Set) -= Bit); } BitSet operator - (const BitSet& Set1, const BitSet& Set2) { return (BitSet (Set1) -= Set2); } int BitSet::operator [] (int Bit) const { // check range PRECONDITION ((Bit >= First) && (Bit <= Last)); Bit -= First; return (*(BitBucket + (Bit / 8)) >> (Bit % 8)) & 0x0001; } int operator == (const BitSet& Set1, const BitSet& Set2) { // Must have same margins if ((Set1.Count != Set2.Count) || (Set1.First != Set2.First) || (Set1.Last != Set2.Last)) { return 0; } // compare BitBuckets return (memcmp (Set1.BitBucket, Set2.BitBucket, Set1.Bytes) == 0); } int operator != (const BitSet& Set1, const BitSet& Set2) { // Must have same margins if ((Set1.Count != Set2.Count) || (Set1.First != Set2.First) || (Set1.Last != Set2.Last)) { return 1; } // compare BitBuckets return (memcmp (Set1.BitBucket, Set2.BitBucket, Set1.Bytes) != 0); } int BitSet::IsEmpty () // returns 1 if the set is empty, 0 otherwise { unsigned I; unsigned char* P; for (I = 0, P = BitBucket; I < Bytes; I++, P++) { if (*P) { // not empty return 0; } } // is empty return 1; } BitSet& BitSet::Clear () // Resets all bits { memset (BitBucket, 0, Bytes); return *this; } BitSet& BitSet::SetAll () // Set all bits. Note: Don't set the bits inside the range covered // by bytes * 8 but outside First-Last { // Set all but the last byte if (Bytes > 1) { memset (BitBucket, 0xFF, Bytes - 1); } // Last byte (maybe no full byte) BitBucket [Bytes-1] = (unsigned char) (0xFF >> (7 - ((Count - 1) % 8))); // Return a reference return *this; } BitSet& BitSet::Reverse () // Reverse each and every bit { // Reverse all but the last byte for (unsigned I = 0; I < Bytes-1; I++) { BitBucket [I] ^= 0xFF; } // Reverse the last byte (maybe no full byte) BitBucket [Bytes-1] ^= (0xFF >> (7 - ((Count - 1) % 8))); // Return a reference return *this; } int BitSet::Traverse (int Forward, int (*F) (int, void*), void* Data) const // Traverse through all bits that are set { i32 I; int Bit; if (Forward) { for (I = First, Bit = 0; I <= Last; I++, Bit++) { if ((*(BitBucket + (Bit / 8)) >> (Bit % 8)) & 0x0001) { if (F (I, Data) != 0) { return I; } } } } else { for (I = Last, Bit = Count - 1; I >= First; I--, Bit--) { if ((*(BitBucket + (Bit / 8)) >> (Bit % 8)) & 0x0001) { if (F (I, Data) != 0) { return I; } } } } // Not found return Last + 1; } estic-1.61.orig/spunk/bitset.h0100644000176100001440000000554007031424676015630 0ustar debacleusers/*****************************************************************************/ /* */ /* BITSET.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _BITSET_H #define _BITSET_H #include "machine.h" #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* class BitSet */ /*****************************************************************************/ class BitSet : public Streamable { private: unsigned char* BitBucket; i32 Count; i32 First; i32 Last; u32 Bytes; // Redundant, for speedup public: BitSet (int BitCount, int FirstIndex = 0); BitSet (const BitSet& Set); BitSet (StreamableInit X); ~BitSet (); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Traverse through all bits that are set int Traverse (int Forward, int (*F) (int, void*), void* = NULL) const; // New member functions (operators) BitSet& operator = (const BitSet& Set); // Assignment BitSet& operator += (int Bit); BitSet& operator += (const BitSet& Set); BitSet& operator -= (int Bit); BitSet& operator -= (const BitSet & Set); int operator [] (int Bit) const; // Friend operators friend BitSet operator ~ (const BitSet& Set); friend BitSet operator + (const BitSet& Set, int Bit); friend BitSet operator + (const BitSet& Set1, const BitSet& Set2); friend BitSet operator - (const BitSet& Set, int Bit); friend BitSet operator - (const BitSet& Set1, const BitSet& Set2); friend int operator == (const BitSet& Set1, const BitSet& Set2); friend int operator != (const BitSet& Set1, const BitSet& Set2); // New member functions int IsEmpty (); // Return true if the bitset is empty (all bits zero), return false // otherwise BitSet& Clear (); // Set all bits to zero BitSet& SetAll (); // Set all bits to one's BitSet& Reverse (); // Reverse each and every bit i32 Low () const; // Return the low border of the bit numbers i32 High () const; // Return the high border of the bit numbers }; inline BitSet::BitSet (StreamableInit) { } inline Streamable* BitSet::Build () { return new BitSet (Empty); } inline i32 BitSet::Low () const // Return the low border of the bit numbers { return First; } inline i32 BitSet::High () const // Return the high border of the bit numbers { return Last; } // End of BITSET.H #endif estic-1.61.orig/spunk/charset.cc0100644000176100001440000001206307031424676016123 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARSET.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "streamid.h" #include "stream.h" #include "charset.h" // Register class CharSet LINK (CharSet, ID_CharSet); /*****************************************************************************/ /* class CharSet */ /*****************************************************************************/ CharSet::CharSet (const char* Set) // Construct a charset from a string (include all characters that are // in the string) { // Clear the buffer Clear (); // Add all characters from the string *this += Set; } CharSet::CharSet (const String& Set) // Construct a charset from a string (include all characters that are // in the string) { // Clear the buffer Clear (); // Add all characters from the string *this += Set; } void CharSet::Load (Stream& S) { S.Read (Buf, sizeof (Buf)); } void CharSet::Store (Stream& S) const { S.Write (Buf, sizeof (Buf)); } u16 CharSet::StreamableID () const { return ID_CharSet; } Streamable* CharSet::Build () { return new CharSet (Empty); } // Traverse through all bits that are set int CharSet::Traverse (int Forward, int (*F) (char, void*), void* Data) const { unsigned I; if (Forward) { I = 0; do { if ((Buf [I / 8] >> (I % 8)) & 0x01) { if (F (I, Data) != 0) { return I; } } I++; } while (I < 256); } else { I = 256; do { I--; if ((Buf [I / 8] >> (I % 8)) & 0x01) { if (F (I, Data) != 0) { return I; } } } while (I > 0); } // Not found return -1; } CharSet& CharSet::operator = (const CharSet& Set) { if (this != &Set) { memcpy (Buf, Set.Buf, sizeof (Buf)); } return *this; } CharSet& CharSet::operator = (const char* Set) { // Clear the set Clear (); // Add all characters from the string return *this += Set; } CharSet& CharSet::operator = (const String& Set) { return *this = Set.GetStr (); } CharSet& CharSet::operator += (const CharSet& Set) { for (unsigned I = 0; I < sizeof (Buf); I++) { Buf [I] |= Set.Buf [I]; } return *this; } CharSet& CharSet::operator += (const char* Set) { // Add all characters from the string char C; while ((C = *Set++) != '\0') { *this += C; } return *this; } CharSet& CharSet::operator += (const String& Set) { return *this += Set.GetStr (); } CharSet& CharSet::operator -= (const CharSet& Set) { for (unsigned I = 0; I < sizeof (Buf); I++) { Buf [I] &= ~Set.Buf [I]; } return *this; } CharSet& CharSet::operator -= (const char* Set) { // Sub all characters from the string char C; while ((C = *Set++) != '\0') { *this -= C; } return *this; } CharSet& CharSet::operator -= (const String& Set) { return *this -= Set.GetStr (); } CharSet operator ~ (const CharSet& Set) { CharSet NewSet = Set; return NewSet.Reverse (); } CharSet operator + (const CharSet& Set, char C) { CharSet NewSet = Set; return (NewSet += C); } CharSet operator + (const CharSet& Set1, const CharSet& Set2) { CharSet NewSet = Set1; return (NewSet += Set2); } CharSet operator - (const CharSet& Set, char C) { CharSet NewSet = Set; return (NewSet -= C); } CharSet operator - (const CharSet& Set1, const CharSet& Set2) { CharSet NewSet = Set1; return (NewSet -= Set2); } int CharSet::IsEmpty () // Return true if the charset is empty, return false otherwise { for (unsigned I = 0; I < sizeof (Buf); I++) { if (Buf [I] != 0) { // Not empty return 0; } } // Empty return 1; } CharSet& CharSet::AddRange (char C1, char C2) // Adds a complete range of characters to the character set { unsigned U1 = (unsigned)(unsigned char)C1; unsigned U2 = (unsigned)(unsigned char)C2; while (U1 <= U2) { *this += (char) U1; U1++; } return *this; } CharSet& CharSet::Reverse () // Reverse the set { for (unsigned I = 0; I < sizeof (Buf); I++) { Buf [I] ^= 0xFF; } return *this; } estic-1.61.orig/spunk/charset.h0100644000176100001440000001060007031424677015761 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARSET.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _CHARSET_H #define _CHARSET_H #include #include "strmable.h" // Forwards class String; /*****************************************************************************/ /* class CharSet */ /*****************************************************************************/ class CharSet: public Streamable { protected: unsigned char Buf [32]; // Buffer for 256 bits public: CharSet (); // Construct a CharSet object. The set is initially empty CharSet (StreamableInit); // Construct an empty CharSet object CharSet (const CharSet&); // Construct a charset from another one CharSet (const char* Set); // Construct a charset from a string (include all characters that are // in the string) CharSet (const String& Set); // Construct a charset from a string (include all characters that are // in the string) // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Traverse through all bits that are set int Traverse (int Forward, int (*F) (char, void*), void* = NULL) const; // Operators CharSet& operator = (const char* Set); CharSet& operator = (const String& Set); CharSet& operator = (const CharSet& Set); inline CharSet& operator += (char C); CharSet& operator += (const char* Set); CharSet& operator += (const String& Set); CharSet& operator += (const CharSet& Set); inline CharSet& operator -= (char C); CharSet& operator -= (const char* Set); CharSet& operator -= (const String& Set); CharSet& operator -= (const CharSet& Set); inline int operator [] (char C) const; // Friend operators friend CharSet operator ~ (const CharSet& Set); friend CharSet operator + (const CharSet& Set, char C); friend CharSet operator + (const CharSet& Set1, const CharSet& Set2); friend CharSet operator - (const CharSet& Set, char C); friend CharSet operator - (const CharSet& Set1, const CharSet& Set2); friend inline int operator == (const CharSet& Set1, const CharSet& Set2); friend inline int operator != (const CharSet& Set1, const CharSet& Set2); // New member functions int IsEmpty (); // Return true if the charset is empty, return false otherwise CharSet& Clear (); // Exclude all possible chars CharSet& SetAll (); // Include all possible chars CharSet& AddRange (char C1, char C2); // Adds a complete range of characters to the character set CharSet& Reverse (); // Reverse the set }; inline CharSet::CharSet () // Construct a CharSet object. The set is initially empty { memset (Buf, 0, sizeof (Buf)); } inline CharSet::CharSet (StreamableInit) // construct an empty CharSet object { } inline CharSet::CharSet (const CharSet& Set) // Construct a charset from another one { memcpy (Buf, Set.Buf, sizeof (Buf)); } inline CharSet& CharSet::operator += (char C) { register unsigned X = (unsigned)(unsigned char)C; Buf [X / 8] |= 0x01 << (X % 8); return *this; } inline CharSet& CharSet::operator -= (char C) { register unsigned X = (unsigned)(unsigned char)C; Buf [X / 8] &= ~(0x01 << (X % 8)); return *this; } inline int CharSet::operator [] (char C) const { register unsigned X = (unsigned)(unsigned char)C; return (Buf [X / 8] >> (X % 8)) & 0x0001; } inline int operator == (const CharSet& Set1, const CharSet& Set2) { return (memcmp (Set1.Buf, Set2.Buf, sizeof (Set1.Buf)) == 0); } inline int operator != (const CharSet& Set1, const CharSet& Set2) { return (memcmp (Set1.Buf, Set2.Buf, sizeof (Set1.Buf)) != 0); } inline CharSet& CharSet::Clear () // Exclude all possible chars { memset (Buf, 0, sizeof (Buf)); return *this; } inline CharSet& CharSet::SetAll () // Include all possible chars { memset (Buf, 0xFF, sizeof (Buf)); return *this; } // End of CHARSET.H #endif estic-1.61.orig/spunk/charstrm.cc0100644000176100001440000000732307031424677016321 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARSTRM.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module defines a special family of streams. A CharacterStream is // different from a Stream in that it is not possible to do things like // Seek and Truncate. Instead, they have timeouts for read and write. // Usually a CharacterStream works on something like a serial device, a // network connection and such. #include "charstrm.h" /*****************************************************************************/ /* class CharacterStream */ /*****************************************************************************/ u32 CharacterStream::GetPos () // Get the current value of the stream pointer { FAIL ("CharacterStream::Truncate: Operation not allowed on this Stream type"); return 0; } u32 CharacterStream::GetSize () // Return the size of the stream in bytes { FAIL ("CharacterStream::Truncate: Operation not allowed on this Stream type"); return 0; } void CharacterStream::Seek (unsigned long /* Pos */) // Set the stream pointer to the specified position { FAIL ("CharacterStream::Truncate: Operation not allowed on this Stream type"); } void CharacterStream::SeekToEnd () // Set the stream pointer to the end of the stream { FAIL ("CharacterStream::Truncate: Operation not allowed on this Stream type"); } void CharacterStream::Truncate () // Truncate the stream at the current position { FAIL ("CharacterStream::Truncate: Operation not allowed on this Stream type"); } void CharacterStream::SetReadTimeout (double T) // Set the read timeout for the stream. // A value of zero means no timeout (error if data not immidiately // available) a value less than zero means "indefinite wait". // Beware: The implementation of the timeout is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. { ReadTimeout = T; } void CharacterStream::SetWriteTimeout (double T) // Set the write timeout for the stream. // A value of zero means no timeout (error if data cannot be written // immidiately) a value less than zero means "indefinite wait". // Beware: The implementation of the timeouts is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. { WriteTimeout = T; } size_t CharacterStream::ReadCount () const // Return the amount of bytes that can be read without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be read without // blocking and 0 otherwise. { ABSTRACT (); return 0; } size_t CharacterStream::WriteCount () const // Return the amount of bytes that can be written without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be written without // blocking and 0 otherwise. { ABSTRACT (); return 0; } estic-1.61.orig/spunk/charstrm.h0100644000176100001440000000751707031424677016170 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARSTRM.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module defines a special family of streams. A CharacterStream is // different from a Stream in that it is not possible to do things like // Seek and Truncate. Instead, they have timeouts for read and write. // Usually a CharacterStream works on something like a serial device, a // network connection and such. #ifndef _CHARSTRM_H #define _CHARSTRM_H #include #include "stream.h" /*****************************************************************************/ /* class CharacterStream */ /*****************************************************************************/ class CharacterStream: public Stream { protected: double ReadTimeout, WriteTimeout; // The timeouts - see the functions SetReadTimeout/SetWriteTimeout for an // explanation. public: virtual u32 GetPos (); // Get the current value of the stream pointer virtual u32 GetSize (); // Return the size of the stream in bytes virtual void Seek (unsigned long Pos); // Set the stream pointer to the specified position virtual void SeekToEnd (); // Set the stream pointer to the end of the stream virtual void Truncate (); // Truncate the stream at the current position virtual void SetReadTimeout (double T); // Set the read timeout for the stream. // A value of zero means no timeout (error if data not immidiately // available) a value less than zero means "indefinite wait". // Beware: The implementation of the timeout is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. virtual void SetWriteTimeout (double T); // Set the write timeout for the stream. // A value of zero means no timeout (error if data cannot be written // immidiately) a value less than zero means "indefinite wait". // Beware: The implementation of the timeouts is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. double GetReadTimeout () const; // Return the read timeout double GetWriteTimeout () const; // Return the write timeout virtual size_t ReadCount () const; // Return the amount of bytes that can be read without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be read without // blocking and 0 otherwise. virtual size_t WriteCount () const; // Return the amount of bytes that can be written without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be written without // blocking and 0 otherwise. }; inline double CharacterStream::GetReadTimeout () const // Return the read timeout { return ReadTimeout; } inline double CharacterStream::GetWriteTimeout () const // Return the write timeout { return WriteTimeout; } // End of CHARSTRM.H #endif estic-1.61.orig/spunk/chartype.cc0100644000176100001440000000343407031424677016314 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARTYPE.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "check.h" #include "charset.h" #include "chartype.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // This is character set that contains all whitespace chars (as defined by // IsSpace (c) != 0). The current definition assumes ASCII. This is not a // problem but must be changed when porting to non-ASCII systems (probably // by a #define). Beware: '\0' is classified _not_ as space to make coding // easier. extern const CharSet WhiteSpace ("\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17" "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" " "); /*****************************************************************************/ /* Other code */ /*****************************************************************************/ unsigned DigitValue (int C) // Calculate the numeric value for the given digit (e.g. '9' --> 9). Valid // input are digits and the characters A-Z and a-z. For other input, FAIL // is called. { // Make shure we have valid input PRECONDITION (IsAlNum (C)); // Convert the character if (C <= '9') { return C - '0'; } else if (C <= 'Z') { return C - 'A' + 10; } else { return C - 'a' + 10; } } estic-1.61.orig/spunk/chartype.h0100644000176100001440000000453707031424677016163 0ustar debacleusers/*****************************************************************************/ /* */ /* CHARTYPE.H */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _CHARTYPE_H #define _CHARTYPE_H #include /*****************************************************************************/ /* Data */ /*****************************************************************************/ // This is character set that contains all whitespace chars (as defined by // IsSpace (c) != 0). The current definition assumes ASCII. This is not a // problem but must be changed when porting to non-ASCII systems (probably // by a #define). Beware: '\0' is classified _not_ as space to make coding // easier. extern const class CharSet WhiteSpace; /*****************************************************************************/ /* Character classification functions */ /*****************************************************************************/ inline int IsAlpha (int C) { return isascii (C) && isalpha (C); } inline int IsAlNum (int C) { return isascii (C) && isalnum (C); } inline int IsAscii (int C) { return isascii (C); } inline int IsCntrl (int C) { return isascii (C) && iscntrl (C); } inline int IsDigit (int C) { return isascii (C) && isdigit (C); } inline int IsGraph (int C) { return isascii (C) && isgraph (C); } inline int IsPrint (int C) { return isascii (C) && isprint (C); } inline int IsPunct (int C) { return isascii (C) && ispunct (C); } inline int IsSpace (int C) { return isascii (C) && isspace (C); } inline int IsXDigit (int C) { return isascii (C) && isxdigit (C); } /*****************************************************************************/ /* Other code */ /*****************************************************************************/ unsigned DigitValue (int C); // Calculate the numeric value for the given digit (e.g. '9' --> 9). Valid // input are digits and the characters A-Z and a-z. For other input, FAIL // is called. // End of CHARTYPE.H #endif estic-1.61.orig/spunk/check.cc0100644000176100001440000000461607031424677015555 0ustar debacleusers/*****************************************************************************/ /* */ /* CHECK.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include /*****************************************************************************/ /* Data */ /*****************************************************************************/ const char* _MsgInternalError = "Internal error: "; const char* _MsgAbstractCall = "Call to abstract method"; const char* _MsgPrecondition = "Precondition violated: "; const char* _MsgCheckFailed = "Check failed: "; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void _CheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line); // The fail vector #ifdef __GNUC__ volatile #endif void (*CheckFailed) (const char*, const char* Cond, int Code, const char* File, int Line) = _CheckFailed; static void _CheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line) { fprintf (stderr, "%s%s", Msg, Cond); if (Code) { fprintf (stderr, " (= %d), file ", Code); } else { fprintf (stderr, ", file "); } fprintf (stderr, "%s, line %d\n", File, Line); exit (3); } void Check (const char* Msg, const char* Cond, int Code, const char* File, int Line) { if (Code != 0) { CheckFailed (Msg, Cond, Code, File, Line); } } estic-1.61.orig/spunk/check.h0100644000176100001440000000567007031424677015420 0ustar debacleusers/*****************************************************************************/ /* */ /* CHECK.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _CHECK_H #define _CHECK_H /*****************************************************************************/ /* Data */ /*****************************************************************************/ extern const char* _MsgInternalError; // "Internal error: " extern const char* _MsgAbstractCall; // "Call to abstract method" extern const char* _MsgPrecondition; // "Precondition violated: " extern const char* _MsgCheckFailed; // "Check failed: " extern #ifdef __GNUC__ volatile #endif void (*CheckFailed) (const char* Msg, const char* Cond, int Code, const char* File, int Line); // Function pointer that is called from Check if the condition code is true. /*****************************************************************************/ /* Code */ /*****************************************************************************/ extern void Check (const char* Msg, const char* Cond, int Code, const char* File, int Line); // This function is called from all check macros (see below). It checks, wether // the given Code is true (!= 0). If so, it calls the CheckFailed vector with // the given strings. If not, it simply returns. #define FAIL(s) CheckFailed (_MsgInternalError, s, 0, __FILE__, __LINE__) // Fail macro. Is used if something evil happens, calls CheckFailed directly. #define ABSTRACT() FAIL(_MsgAbstractCall) // Short for FAIL. Is used in abstract class member functions. #ifdef SPUNK_NODEBUG #define PRECONDITION(c) #define CHECK(c) #define ZCHECK(c) #else // These macros are usually defined!!! #define PRECONDITION(c) Check (_MsgPrecondition, \ #c, !(c), __FILE__, __LINE__) #define CHECK(c) Check (_MsgCheckFailed, \ #c, !(c), __FILE__, __LINE__) #define ZCHECK(c) Check (_MsgCheckFailed, \ #c, c, __FILE__, __LINE__) #endif // End of CHECK.H #endif estic-1.61.orig/spunk/circbuf.h0100644000176100001440000001425707031424677015761 0ustar debacleusers/*****************************************************************************/ /* */ /* CIRCBUF.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Some comments on the rewrite (12/96): // // * The size of the circular buffer is now a template argument. This gives // somewhat better access times. // // * The counter got removed. This has two implications: // // 1. The buffer cannot hold Size items since there is an ambiguitiy // when In and Out are equal (this would mean "buffer empty" or // "buffer full" if the buffer could hold Size items). // 2. Get and Put may be called from different threads (class // CircularBuffer is thread-safe now). This is true as long as no // other functions are called (Load/Store, or even PutInFront are // *not* thread-safe). // // * As Get() needs to copy the returned object twice, one should // probably put pointers into an CircularBuffer object if the objects // are bigger than just a few bytes in size. // #ifndef _CIRCBUF_H #define _CIRCBUF_H #include "machine.h" #include "check.h" #include "object.h" #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* class CircularBuffer */ /*****************************************************************************/ template class CircularBuffer : public Streamable { protected: T Data [Size]; unsigned In; unsigned Out; protected: virtual void PutItem (Stream& S, T Item) const; virtual T GetItem (Stream& S); public: CircularBuffer (); // Construct a CircularBuffer object CircularBuffer (StreamableInit); // Build constructor // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; static Streamable* Build (); unsigned GetCount () const; // Return the count of items in the buffer int IsEmpty () const; // Return true if the buffer is empty int NotEmpty () const; // Return true if the buffer is not empty int IsFull () const; // Return true if the buffer is full void Put (const T& Item, int IgnoreOverflow = 1); // Put something into the buffer void PutInFront (const T& Item, int IgnoreOverflow = 1); // Put something as first item into the buffer T Get (); // Get an item from the buffer const T& Peek () const; // Peek at the first item in the buffer }; template CircularBuffer::CircularBuffer () : In (0), Out (0) { // Check parameters PRECONDITION (Size > 0); } template inline CircularBuffer::CircularBuffer (StreamableInit) { } template void CircularBuffer::Load (Stream& S) { u16 Count; S >> Count; // Reset the in/out pointers In = Out = 0; // Now read the items while (Count--) { Data [In] = GetItem (S); In = (In + 1) % Size; } } template void CircularBuffer::Store (Stream& S) const { // Store data u16 Count = GetCount (); S << Count; // Store the items unsigned O = Out; while (Count--) { PutItem (S, Data [O]); O = (O + 1) % Size; } } template T CircularBuffer::GetItem (Stream&) { ABSTRACT (); return *((T*) NULL); } template void CircularBuffer::PutItem (Stream&, T) const { ABSTRACT (); } template inline Streamable* CircularBuffer::Build () { return new CircularBuffer (Empty); } template inline unsigned CircularBuffer::GetCount () const // Return the count of items in the buffer { int Count = int (In) - int (Out); if (Count < 0) { return Count + Size; } else { return Count; } } template inline int CircularBuffer::IsEmpty () const { return (GetCount () == 0); } template inline int CircularBuffer::NotEmpty () const // Return true if the buffer is not empty { return (GetCount () != 0); } template inline int CircularBuffer::IsFull () const { return (GetCount () == Size-1); } template void CircularBuffer::Put (const T& Item, int IgnoreOverflow) { if (IsFull ()) { if (IgnoreOverflow) { return; } else { FAIL ("CircularBuffer::Put: Overflow"); } } Data [In] = Item; In = (In + 1) % Size; } template void CircularBuffer::PutInFront (const T& Item, int IgnoreOverflow) { if (IsFull ()) { if (IgnoreOverflow) { return; } else { FAIL ("CircularBuffer::PutInFront: Overflow"); } } if (Out == 0) { Out = Size - 1; } else { Out--; } Data [Out] = Item; } template T CircularBuffer::Get () { // There must be at least one element PRECONDITION (NotEmpty ()); T X = Data [Out]; Out = (Out + 1) % Size; return X; } template const T & CircularBuffer::Peek () const { // There must be at least one element PRECONDITION (NotEmpty ()); return Data [Out]; } // End of CIRCBUF.H #endif estic-1.61.orig/spunk/coll.cc0100644000176100001440000001747007031424677015433 0ustar debacleusers/*****************************************************************************/ /* */ /* COLL.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "machine.h" #include "check.h" #include "object.h" #include "stream.h" #include "coll.h" // Pointer to error routine void (*CollectionError) (int) = NULL; /*****************************************************************************/ /* class _Collection */ /*****************************************************************************/ // This is a base class for the template class Collection that has full // functionality but uses void pointers instead of typed pointers. The // implementation of class Collection consists merely of inline functions // calling the derived member functions and casting when necessary. This will // hopefully help to decrease program size. _Collection::_Collection (StreamableInit): Items (0) { } _Collection::_Collection (int aLimit, int aDelta, int aShouldDelete): ShouldDelete (aShouldDelete) { // check parameters if (aLimit < 0 || aDelta < 0 || (aLimit + aDelta) == 0 || aLimit > MaxCollectionSize || aDelta > MaxCollectionSize) { FAIL ("_Collection::_Collection: Overflow error"); return; } // get values - one of is != 0 Limit = aLimit ? aLimit : aDelta; Delta = aDelta; Count = 0; // allocate memory Items = AllocItemSpace (Limit); } _Collection::~_Collection () { // Release allocated memory but do not try to call DeleteAll (this calls // FreeItem, but _Collection::FreeItem will call ABSTRACT) FreeItemSpace (Items); } void* _Collection::At (int Index) { // Check range if (Index < 0 || Index >= Count) { FAIL ("_Collection::At: Index out of bounds"); return NULL; } return Items [Index]; } const void* _Collection::At (int Index) const { // Check range if (Index < 0 || Index >= Count) { FAIL ("_Collection::At: Index out of bounds"); return NULL; } return Items [Index]; } void _Collection::AtDelete (int Index) { // Check range if (Index < 0 || Index >= Count) { FAIL ("_Collection::AtDelete: Index out of bounds"); return; } // Free entry if necessary if (ShouldDelete) { FreeItem (Items [Index]); } // Delete entry Count--; memmove (Items + Index, Items + Index + 1, (Count - Index) * sizeof (void*)); } void _Collection::AtInsert (int Index, void* Item) { // Check range, Index may be one more than the index of the last element if (Index < 0 || Index > Count) { FAIL ("_Collection::AtInsert: Index out of bounds"); return; } // Check if the collection must grow if (Count == Limit) { // Increase size, check if possible if (Delta == 0 || (Limit + Delta) > MaxCollectionSize) { // Cannot grow FAIL ("_Collection::AtInsert: Overflow error"); return; } // Change the size SetLimit (Limit + Delta); } // We can insert the element. If the item is not inserted at the end // of the collection, we must create a "hole" if (Count != Index) { memmove (Items + Index + 1, Items + Index, (Count - Index) * sizeof (void*)); } Count++; // store the new item Items [Index] = Item; } void _Collection::AtReplace (int Index, void* Item) { // check range if (Index < 0 || Index >= Count) { FAIL ("_Collection::AtReplace: Index out of bounds"); return; } // Free item if necessary if (ShouldDelete) { FreeItem (Items [Index]); } // Store item Items [Index] = Item; } void _Collection::Delete (void* Item) { int Index = IndexOf (Item); if (Index != -1) { if (ShouldDelete) { FreeItem (Items [Index]); } Items [Index] = NULL; } } void _Collection::DeleteAll () { if (ShouldDelete) { while (Count) { FreeItem (Items [--Count]); } } else { Count = 0; } } void* _Collection::Traverse (int Forward, int (*Func) (void*, void*), void* UserData) { int I; void** P; if (Forward) { for (I = 0, P = Items; I < Count; I++, P++) { if (Func (*P, UserData) != 0) { // stop and return current return *P; } } } else { for (I = Count-1, P = Items + I; I >= 0; I--, P--) { if (Func (*P, UserData) != 0) { // stop and return current return *P; } } } // Not found return NULL; } void _Collection::FreeItem (void*) { ABSTRACT (); } void* _Collection::GetItem (Stream& S) { // Assume it's some sort of object return S.Get (); } void** _Collection::AllocItemSpace (int ItemCount) // Allocate item space { return new void* [ItemCount]; } void _Collection::FreeItemSpace (void** Space) // Deallocate item space { delete [] Space; } int _Collection::IndexOf (const void* Item) { int C; void** I; // generic collection "features" a linear search for (C = 0, I = Items; C < Count; C++, I++) { if (*I == Item) { return C; } } // Not found return -1; } void _Collection::Insert (void* Item) { // Default is to add the item at the end AtInsert (Count, Item); } void _Collection::Pack () { int I, J; for (I = 0; I < Count; I++) { // Try to find a NULL pointer if (Items [I] == NULL) { // Count the number of NULL pointers in a row J = I+1; while (J < Count && Items [J] == NULL) { J++; } // Delete those NULL pointers memmove (Items + I, Items + J, (Count - J) * sizeof (void*)); // Update Count Count -= J - I; } } } void _Collection::PutItem (Stream& S, void* Item) const { // Assume it's a streamable object S.Put ((Streamable*) Item); } void _Collection::SetLimit (int aLimit) { // Limit the new limit if (aLimit < Count) { aLimit = Count; } else if (aLimit > MaxCollectionSize) { aLimit = MaxCollectionSize; } // allocate memory void** P = AllocItemSpace (aLimit); // Copy old data into new array memcpy (P, Items, Count * sizeof (void*)); // Release old memory FreeItemSpace (Items); // Remember new array and limit Items = P; Limit = aLimit; } void _Collection::Load (Stream& S) { // The build constructor sets Items to 0. So, if Items is *not* 0 now, // someone is calling Load (or operator <<) with existing data. Do the // best we can to imitate builtin data types in this case and delete the // existing stuff before reloading. if (Items) { // Delete all items, then delete the item space DeleteAll (); FreeItemSpace (Items); } // Read correct size u32 aCount, aDelta, aLimit; u16 aShouldDelete; S >> aCount; S >> aDelta; Delta = aDelta; S >> aLimit; Limit = aLimit; S >> aShouldDelete; ShouldDelete = aShouldDelete; // allocate memory Items = AllocItemSpace (Limit); // Read items. Do not insert them directly but use Insert. This causes // nearly no spead penalty on collections and only little on // SortedCollections, but does a re-sort if the sort order of a // SortedColl has changed (String ordering according to national // conventions for example). Count = 0; while (aCount--) { Insert (GetItem (S)); } } void _Collection::Store (Stream& S) const { // Write correct size u32 aCount = (u32) Count; u32 aDelta = (u32) Delta; u32 aLimit = (u32) Limit; u16 aShouldDelete = (u16) ShouldDelete; // Write data S << aCount << aDelta << aLimit << aShouldDelete; // Write items for (int I = 0; I < Count; I++) { PutItem (S, Items [I]); } } estic-1.61.orig/spunk/coll.h0100644000176100001440000003146407031424677015274 0ustar debacleusers/*****************************************************************************/ /* */ /* COLL.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _COLL_H #define _COLL_H #include #include #include "check.h" #include "object.h" #include "strmable.h" #include "stream.h" static const coIndexError = 1; // Index out of range static const coOverflowError = 2; // Collection overflow // max number of elements in a collection #ifdef DOS static const int MaxCollectionSize = 0x4000; #else // real limit is memory, so use any value big enough static const int MaxCollectionSize = 0x400000L; #endif // Pointer to error routine extern void (*CollectionError) (int); // Forwards for classes class Stream; class Streamable; /*****************************************************************************/ /* class _Collection */ /*****************************************************************************/ // This is a base class for the template class Collection that has full // functionality but uses void pointers instead of typed pointers. The // implementation of class Collection consists merely of inline functions // calling the derived member functions and casting when necessary. This will // hopefully help to decrease program size. class _Collection : public Streamable { protected: void** Items; // Pointer to Items int Count; // Item count int Limit; // Upper limit for Count int Delta; // increase when growing public: int ShouldDelete; // If true, items are owned by the collection protected: virtual void FreeItem (void* Item); virtual void PutItem (Stream& S, void* Item) const; virtual void* GetItem (Stream& S); // Allocate and deallocate item space virtual void** AllocItemSpace (int ItemCount); virtual void FreeItemSpace (void** Space); public: _Collection (int aLimit, int aDelta, int aShouldDelete = 0); _Collection (StreamableInit); virtual ~_Collection (); // derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; // New members void* At (int Index); const void* At (int Index) const; void AtDelete (int Index); void AtInsert (int Index, void* Item); void AtReplace (int Index, void* Item); void Delete (void* Item); void DeleteAll (); int GetCount () const; void* Traverse (int Forward, int (*Func) (void*, void*), void* UserData = NULL); int IndexOf (const void* Item); void Insert (void* Item); int IsEmpty (); void Pack (); void SetLimit (int aLimit); }; inline int _Collection::GetCount () const { // This is not a virtual function - calling is direct and not via the // virtual table pointer. So we can check safely this against NULL to // allow empty collections stored as NULL pointers return this ? Count : 0; } inline int _Collection::IsEmpty () { return (GetCount () == 0); } /*****************************************************************************/ /* template class Collection */ /*****************************************************************************/ template class Collection : public _Collection { protected: virtual void FreeItem (void* Item); public: Collection (int aLimit, int aDelta, int aSouldDelete = 0); Collection (StreamableInit); virtual ~Collection (); // derived from class Streamable virtual void Load (Stream&); static Streamable* Build (); virtual T* At (int Index); // Return a pointer to the item at position Index. virtual const T* At (int Index) const; // Return a pointer to the item at position Index. virtual void AtInsert (int Index, T* Item); // Insert an item at the given position. virtual void AtReplace (int Index, T* Item); // Replace the item at the given position by a new one. If ShouldDelete // is true, FreeItem is also called for the replaced item. virtual void Delete (T* Item); // Delete a specific item. The entry is replaced by a NULL pointer, if // ShouldDelete is true, FreeItem is called in addition to that. virtual T* Traverse (int Forward, int (*Func) (T*, void*), void* UserData = NULL); // Traverse through the collection, calling Func for every item, giving // a pointer to the item and a user supplied pointer as parameters. If // Func returns a value other than zero, traversing stops. virtual int IndexOf (const T* Item); // Return the index of the given item in the collection. virtual void Insert (T* Item); // Insert an item into the collection T* operator [] (int Index); const T* operator [] (int Index) const; // Synonym for At (Index) }; template inline Collection::Collection (StreamableInit): _Collection (Empty) { } template inline Collection::Collection (int aLimit, int aDelta, int aShouldDelete): _Collection (aLimit, aDelta, aShouldDelete) { } template Collection::~Collection () { // Delete all items here because ~_Collection will not do that (it can't, // because _Collection::FreeItem is non functionable). DeleteAll (); } template inline T* Collection::At (int Index) { return (T*) _Collection::At (Index); } template inline const T* Collection::At (int Index) const { return (T*) _Collection::At (Index); } template inline void Collection::AtInsert (int Index, T* Item) { _Collection::AtInsert (Index, (void*) Item); } template inline void Collection::AtReplace (int Index, T* Item) { _Collection::AtReplace (Index, (void*) Item); } template inline void Collection::Delete (T* Item) { _Collection::Delete ((void*) Item); } template inline T* Collection::Traverse (int Forward, int (*Func) (T*, void*), void* UserData) { typedef int (*UntypedFunc) (void*, void*); return (T*) _Collection::Traverse (Forward, (UntypedFunc) Func, UserData); } template void Collection::FreeItem (void* Item) { delete (T*) Item; } template inline int Collection::IndexOf (const T* Item) { return _Collection::IndexOf ((void*) Item); } template inline void Collection::Insert (T* Item) { _Collection::Insert ((void*) Item); } template void Collection::Load (Stream& S) // Load the collection from a stream. This function will *not* call // _Collection::Load since _Collection::Insert is not virtual. { // The build constructor sets Items to 0. So, if Items is *not* 0 now, // someone is calling Load (or operator <<) with existing data. Do the // best we can to imitate builtin data types in this case and delete the // existing stuff before reloading. if (Items) { // Delete all items, then delete the item space DeleteAll (); FreeItemSpace (Items); } // Read correct size u32 aCount, aDelta, aLimit; u16 aShouldDelete; S >> aCount; S >> aDelta; Delta = aDelta; S >> aLimit; Limit = aLimit; S >> aShouldDelete; ShouldDelete = aShouldDelete; // allocate memory Items = AllocItemSpace (Limit); // Read items. Do not insert them directly but use Insert. This causes // nearly no spead penalty on collections and only little on // SortedCollections, but does a re-sort if the sort order of a // SortedColl has changed (String ordering according to national // conventions for example). Count = 0; while (aCount--) { Insert ((T*) GetItem (S)); } } template Streamable* Collection::Build () { return new Collection (Empty); } template inline T* Collection::operator [] (int Index) { return At (Index); } template inline const T* Collection::operator [] (int Index) const { return At (Index); } /*****************************************************************************/ /* template class SortedCollection */ /*****************************************************************************/ template class SortedCollection : public Collection { public: i16 Duplicates; // Duplicates allowed yes/no protected: virtual int Compare (const U* Key1, const U* Key2); // Compare the keys of two items in the collection virtual const U* KeyOf (const T* Item); // Return the key of a given item public: SortedCollection (int aLimit, int aDelta, int aShouldDelete = 0); // Constructor SortedCollection (StreamableInit); // Build constructor // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; static Streamable* Build (); virtual int IndexOf (const T* Item); virtual void Insert (T* Item); virtual int Search (const U* Key, int& Index); T* Find (const U* Key); // Find the item with the given key. If duplicates are allowed, this // function will return the first item with this key (and is therefor // almost useless - use search instead). If no matching key is found, // the function returns NULL. }; template inline SortedCollection::SortedCollection (StreamableInit X) : Collection (X) { } template inline SortedCollection::SortedCollection (int aLimit, int aDelta, int aShouldDelete) : Collection (aLimit, aDelta, aShouldDelete), Duplicates (0) { } template void SortedCollection::Load (Stream& S) { Collection::Load (S); S >> Duplicates; } template void SortedCollection::Store (Stream& S) const { Collection::Store (S); S << Duplicates; } template Streamable* SortedCollection::Build () { return new SortedCollection (Empty); } template int SortedCollection::Compare (const U*, const U*) { ABSTRACT (); return 0; } template int SortedCollection::IndexOf (const T* Item) { int Index; const U* Key = KeyOf (Item); T* Item2; // Search entry if (Search (Key, Index) == 0) { // Item not found return -1; } // If not duplicates allowed, we've found the item. if (!Duplicates) { return Index; } // Duplicates allowed. Do a linear search. // (Hint: Search returns the first of all entrys with the same key) Item2 = (T*) Items [Index]; do { if (Item2 == Item) { // That's it ! return Index; } // Get next Item2 = (T*) Items [++Index]; } while (Index < Count && Compare (Key, KeyOf (Item2)) == 0); // Item not found return -1; } template void SortedCollection::Insert (T* Item) // Inserts an item into a sorted collection. If Duplicates is != 0, the // item is placed in front of all other items with the same key. { int Index; // Search for the element if (Search (KeyOf (Item), Index) != 0) { // An Item with this key exists. Are duplicates allowed? if (!Duplicates) { // No duplicates, nothing to do return; } } // Index points to the correct position, insert item AtInsert (Index, Item); } template int SortedCollection::Search (const U* Key, int& Index) { // do a binary search int First = 0; int Last = Count - 1; int Current; int Result; int S = 0; while (First <= Last) { // Set current to mid of range Current = (Last + First) / 2; // Do a compare Result = Compare (KeyOf ((T*) Items [Current]), Key); if (Result < 0) { First = Current + 1; } else { Last = Current - 1; if (Result == 0) { // Found. If no Duplicates are allowed, end the search. // Otherwise repeat the procedure until the first of all // items with the same key is found. S = 1; // function result if (!Duplicates) { // Set condition to terminate loop First = Current; } } } } Index = First; return S; } template const U* SortedCollection::KeyOf (const T* Item) { // Return the item itself return (U*) Item; } template T* SortedCollection::Find (const U* Key) // Find the item with the given key. If duplicates are allowed, this // function will return the first item with this key (and is therefor // almost useless - use search instead). If no matching key is found, // the function returns NULL. { int I; if (Search (Key, I) != 0) { // We found the key, I is the index return At (I); } else { // We did not find the key return 0; } } // End of COLL.H #endif estic-1.61.orig/spunk/cont.cc0100644000176100001440000001232107031424677015433 0ustar debacleusers/*****************************************************************************/ /* */ /* CONT.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include "streamid.h" #include "cont.h" // Register class Container LINK(Container, ID_Container); /*****************************************************************************/ /* class Container */ /*****************************************************************************/ Container::Container (const Container& C) { if (C.Data == NULL) { // Other container is empty Data = NULL; Size = 0; } else { // Second container is not empty Size = C.Size; Data = new char [Size]; memcpy (Data, C.Data, Size); } } Container::~Container () { FreeData (); } void Container::Load (Stream& S) { // Get Size of Data S >> Size; // Maybe, size is 0 if (Size == 0) { Data = NULL; } else { Data = new char [Size]; S.Read (Data, Size); } } void Container::Store (Stream& S) const { S << Size; S.Write (Data, Size); } u16 Container::StreamableID () const { return ID_Container; } Streamable* Container::Build () { return new Container (Empty); } void Container::FreeData () { delete [] Data; Data = NULL; Size = 0L; } void* Container::GetData () // Don't inline this function - it's needed in this module for correct linking { return Data; } const void* Container::GetData () const // Don't inline this function - it's needed in this module for correct linking { return Data; } void* Container::RetrieveData () // Return the current data and empty the container. After this call, // the calling function is responsible for managing/deleting the data. { void* D = Data; Data = NULL; Size = 0; return D; } void Container::PutData (void* DataPtr, u32 DataSize) { // Free old data FreeData (); // Get control of new data Data = DataPtr; Size = DataSize; } Container& Container::CopyFrom (void* DataPtr, u32 DataSize) // Free the current data, create a new data block, copy given data { // If compiled under DOS: Check for maximum block size #ifdef DOS CHECK (DataSize < 0xFFF0L); #endif // Free the current data FreeData (); // Create a new data block and copy the given data Data = memcpy (new unsigned char [DataSize], DataPtr, DataSize); // Remember the size Size = DataSize; // Return a reference to this return *this; } int Container::StoreData (const String& Filename) const { FILE* F; // If compiled under DOS: Honor the maximum data size for fwrite #ifdef DOS CHECK (Size < 0xFFF0L); #endif // Create a new file for writing if ((F = fopen (Filename.GetStr (), "wb")) == NULL) { // Cannot open file return 0; } // Write the container data to the file fwrite (Data, (size_t) Size, 1, F); // Close the file, return success fclose (F); return 1; } int Container::LoadData (const String& Filename) { FILE* F; u32 FileSize; // Get the size of the file struct stat StatBuf; if (stat (Filename.GetStr (), &StatBuf) != 0) { // No file return 0; } FileSize = StatBuf.st_size; // When running under DOS, check for enough memory as new is not // able to handle requests > 0xFFF0 bytes. #ifdef DOS if (FileSize > 0xFFF0) { // File is too big. return 0; } #endif // Try to open the file for reading if ((F = fopen (Filename.GetStr (), "rb")) == NULL) { // Error return 0; } // Now as chances are good to access the file, we drop any old data // and allocate memory for the new data FreeData (); if (FileSize > 0) { Size = (u32) FileSize; Data = new char [FileSize]; // Now read in the file data (void) fread (Data, (size_t) Size, 1, F); } // Close the file, ignore errors (don't know how to handle them) fclose (F); // Return success return 1; } Container& Container::operator = (const Container &rhs) { // Beware of C = C if (&rhs != this) { // Free current data FreeData (); // Get data from right hand side if (rhs.Data == NULL) { Data = NULL; Size = 0; } else { Size = rhs.Size; Data = new char [Size]; memcpy (Data, rhs.Data, Size); } } return *this; } estic-1.61.orig/spunk/cont.h0100644000176100001440000000567307031424677015311 0ustar debacleusers/*****************************************************************************/ /* */ /* CONT.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _CONT_H #define _CONT_H #include #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* class Container */ /*****************************************************************************/ class Container : public Streamable { private: void* Data; // Pointer to data u32 Size; // Size of data protected: Container (StreamableInit X); // Build constructor public: Container (); Container (const Container&); virtual ~Container (); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Build constructor void FreeData (); // Free the data. Set the data pointer to NULL and size to zero. void* GetData (); // Return a pointer to the data const void* GetData () const; // Return a const pointer to the data void* RetrieveData (); // Return the current data and empty the container. After this call, // the calling function is responsible for managing/deleting the data. u32 DataSize () const; // Return the data size void PutData (void* DataPtr, u32 DataSize); // Free the current data and store the new data in the container. Container& CopyFrom (void* DataPtr, u32 DataSize); // Free the current data, create a new data block, copy given data int StoreData (const String& Filename) const; // Store the current data in the given file. Return 1 on success, 0 on // failure. int LoadData (const String& Filename); // Delete the current data, read new data from a file. The function // returns 1 on success, 0 on failure. Container& operator = (const Container& C); // Assignment operator for containers }; inline Container::Container (StreamableInit) { } inline Container::Container () : Data (NULL), Size (0) { } inline u32 Container::DataSize () const { return Size; } // End of CONT.H #endif estic-1.61.orig/spunk/copying.txt0100644000176100001440000000175507031424677016403 0ustar debacleusers SPUNK LIBRARY (C) Copyright 1992-1996 Ullrich von Bassewitz COPYING CONDITIONS This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution estic-1.61.orig/spunk/cpucvt.cc0100644000176100001440000000425107031424677015777 0ustar debacleusers/*****************************************************************************/ /* */ /* CPUCVT.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file contains code to convert to and from little endian data types // into the native format. #include "cpucvt.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ #ifdef CPU_BIG_ENDIAN void ToLittleEndian (i16& X) { X = ((X << 8) & 0xFF00) | ((X >> 8) & 0x00FF); } void ToLittleEndian (i32& X) { X = ((X >> 24) & 0x000000FF) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) | ((X << 24) & 0xFF000000); } void ToLittleEndian (u16& X) { X = ((X << 8) & 0xFF00) | ((X >> 8) & 0x00FF); } void ToLittleEndian (u32& X) { X = ((X >> 24) & 0x000000FF) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) | ((X << 24) & 0xFF000000); } void ToLittleEndian (_double& X) { // Swap the longs u32 Tmp = X.I [0]; X.I [0] = X.I [1]; X.I [1] = Tmp; // Swap the bytes inside the longs ToLittleEndian (X.I [0]); ToLittleEndian (X.I [1]); } void FromLittleEndian (i16& X) { X = ((X << 8) & 0xFF00) | ((X >> 8) & 0x00FF); } void FromLittleEndian (i32& X) { X = ((X >> 24) & 0x000000FF) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) | ((X << 24) & 0xFF000000); } void FromLittleEndian (u16& X) { X = ((X << 8) & 0xFF00) | ((X >> 8) & 0x00FF); } void FromLittleEndian (u32& X) { X = ((X >> 24) & 0x000000FF) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) | ((X << 24) & 0xFF000000); } void FromLittleEndian (_double& X) { // Swap the longs u32 Tmp = X.I [0]; X.I [0] = X.I [1]; X.I [1] = Tmp; // Swap the bytes inside the longs FromLittleEndian (X.I [0]); FromLittleEndian (X.I [1]); } #endif estic-1.61.orig/spunk/cpucvt.h0100644000176100001440000000457507031424677015652 0ustar debacleusers/*****************************************************************************/ /* */ /* CPUCVT.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file contains code to convert to and from little endian data types // into the native format. #ifndef __CPUCVT_H #define __CPUCVT_H #include "machine.h" /*****************************************************************************/ /* Types */ /*****************************************************************************/ union _double { double F; u32 I [2]; }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ #ifdef CPU_LITTLE_ENDIAN // We already have little endian format, inline no-op functions inline void ToLittleEndian (i16&) { } inline void ToLittleEndian (i32&) { } inline void ToLittleEndian (u16&) { } inline void ToLittleEndian (u32&) { } inline void ToLittleEndian (_double&) { } inline void FromLittleEndian (i16&) { } inline void FromLittleEndian (i32&) { } inline void FromLittleEndian (u16&) { } inline void FromLittleEndian (u32&) { } inline void FromLittleEndian (_double&) { } #else // We have to convert void ToLittleEndian (i16& X); void ToLittleEndian (i32& X); void ToLittleEndian (u16& X); void ToLittleEndian (u32& X); void ToLittleEndian (_double& X); void FromLittleEndian (i16& X); void FromLittleEndian (i32& X); void FromLittleEndian (u16& X); void FromLittleEndian (u32& X); void FromLittleEndian (_double& X); #endif // End of CPUCVT.H #endif estic-1.61.orig/spunk/crc.h0100644000176100001440000000411707031424677015105 0ustar debacleusers/*****************************************************************************/ /* */ /* CRC.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // The functions declared in this header file are contained in more than one // .cc file. This is because rather large tables are used and with more than // one object file, the linker is able to sort out the needed ones. #ifndef _CRC_H #define _CRC_H #include #include "machine.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ u16 CRC_CCITT (u16 StartCRC, const void* Buf, size_t BufSize); // Calculate the crc over the data in the buffer using the CCITT polynomial // x^16 + x^12 + x^5 + 1 void CRC_CCITT (char B, u16& CRC); // One byte version of the above u16 CRC_16 (u16 StartCRC, const void* Buf, size_t BufSize); // Calculate the crc over the data in the buffer using the polynomial // x^16 + x^15 + x^2 + 1 void CRC_16 (char B, u16& CRC); // One byte version of the above u32 CRC_32 (u32 StartCRC, const void* Buf, size_t BufSize); // Calculate the crc over the data in the buffer using the polynomial // x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. void CRC_32 (char B, u32& CRC); // One byte version of the above // End of CRC.H #endif estic-1.61.orig/spunk/crc16.cc0100644000176100001440000000776507031424677015426 0ustar debacleusers/*****************************************************************************/ /* */ /* CRC16.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Table for CRC-16 (x^16 + x^15 + x^2 + 1) // Bits are shifted LSB --> MSB static const u16 CRC_16_Tab [256] = { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ u16 CRC_16 (u16 StartCRC, const void* Buf, size_t BufSize) { // Cast the pointer const unsigned char* P = (const unsigned char*) Buf; // CRC calculation while (BufSize--) { StartCRC = (StartCRC >> 8) ^ CRC_16_Tab [(StartCRC ^ *P) & 0xFF]; P++; } // Return the result return StartCRC; } void CRC_16 (char B, u16& CRC) { CRC = (CRC >> 8) ^ CRC_16_Tab [(CRC ^ B) & 0xFF]; } estic-1.61.orig/spunk/crc32.cc0100644000176100001440000001214107031424677015404 0ustar debacleusers/*****************************************************************************/ /* */ /* CRC32.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Table for CRC-32 (the polynomial is // x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1). // Bits are shifted LSB --> MSB static const u32 CRC_32_Tab [256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 CRC_32 (u32 StartCRC, const void* Buf, size_t BufSize) { // Cast the pointer const unsigned char* P = (const unsigned char*) Buf; // CRC calculation while (BufSize--) { StartCRC = (StartCRC >> 8) ^ CRC_32_Tab [(StartCRC ^ *P) & 0xFF]; P++; } // Return the result return StartCRC; } void CRC_32 (char B, u32& CRC) { CRC = (CRC >> 8) ^ CRC_32_Tab [(CRC ^ B) & 0xFF]; } estic-1.61.orig/spunk/crcccitt.cc0100644000176100001440000000707507031424677016300 0ustar debacleusers/*****************************************************************************/ /* */ /* CRCCCITT.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" #include "check.h" // // Table for CCITT-CRC (x^16 + x^12 + x^5 + 1) // Bits are shifted MSB --> LSB // static const u16 CRC_CCITT_Tab [256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; u16 CRC_CCITT (u16 StartCRC, const void* Buf, size_t BufSize) { // Cast the pointer const unsigned char* P = (const unsigned char*) Buf; // CRC calculation while (BufSize--) { StartCRC = (StartCRC << 8) ^ CRC_CCITT_Tab [(StartCRC >> 8) ^ *P]; P++; } // Return the result return StartCRC; } void CRC_CCITT (char B, u16& CRC) { CRC = (u16) (CRC << 8) ^ CRC_CCITT_Tab [(CRC >> 8) ^ B]; } estic-1.61.orig/spunk/crcstrm.cc0100644000176100001440000000316007031424677016146 0ustar debacleusers/*****************************************************************************/ /* */ /* CRCSTRM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "strmable.h" #include "crcstrm.h" /*****************************************************************************/ /* class CRCStream */ /*****************************************************************************/ void CRCStream::Write (const void *Buf, size_t Count) { CRC = CRC_32 (CRC, Buf, Count); } /*****************************************************************************/ /* Outside the classes */ /*****************************************************************************/ u32 GetCRC (const Streamable* O) { CRCStream S; S << *O; return S.GetCRC (); } u32 GetCRC (const Streamable& O) { CRCStream S; S << O; return S.GetCRC (); } estic-1.61.orig/spunk/crcstrm.h0100644000176100001440000000356607031424677016022 0ustar debacleusers/*****************************************************************************/ /* */ /* CRCSTRM.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _CRCSTRM_H #define _CRCSTRM_H #include "crc.h" #include "nullstrm.h" /*****************************************************************************/ /* class CRCStream */ /*****************************************************************************/ class CRCStream : public NullStream { protected: u32 CRC; public: CRCStream (); // Derived from class NullStream virtual void Write (const void *Buf, size_t Count); // New functions u32 GetCRC () const; }; inline CRCStream::CRCStream () : NullStream (), CRC (0) { } inline u32 CRCStream::GetCRC () const { return CRC; } /*****************************************************************************/ /* Outside the classes */ /*****************************************************************************/ u32 GetCRC (const Streamable*); u32 GetCRC (const Streamable&); // Return a CRC value for the instance data // End of CRCSTRM.H #endif estic-1.61.orig/spunk/datetime.cc0100644000176100001440000003337407031424677016277 0ustar debacleusers/*****************************************************************************/ /* */ /* DATETIME.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "msgid.h" #include "national.h" #include "streamid.h" #include "progutil.h" #include "datetime.h" /*****************************************************************************/ /* message constants */ /*****************************************************************************/ const u16 msLongNameOfDayBase = MSGBASE_DATETIME + 0; const u16 msShortNameOfDayBase = MSGBASE_DATETIME + 7; const u16 msLongNameOfMonthBase = MSGBASE_DATETIME + 14; const u16 msShortNameOfMonthBase = MSGBASE_DATETIME + 26; /*****************************************************************************/ /* Number days per month */ /*****************************************************************************/ static unsigned LeapYearTab [12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static unsigned NormYearTab [12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /*****************************************************************************/ /* utilities */ /*****************************************************************************/ String LongNameOfDay (WeekDay aDay) { return LoadMsg (u16 (msLongNameOfDayBase + aDay)); } String ShortNameOfDay (WeekDay aDay) { return LoadMsg (u16 (msShortNameOfDayBase + aDay)); } String LongNameOfMonth (unsigned aMonth) { CHECK ((aMonth >= 1) && (aMonth <= 12)); return LoadMsg (u16 (msLongNameOfMonthBase + aMonth - 1)); } String ShortNameOfMonth (unsigned aMonth) { CHECK ((aMonth >= 1) && (aMonth <= 12)); return LoadMsg (u16 (msShortNameOfMonthBase + aMonth - 1)); } int IsLeapYear (unsigned aYear) { return ((aYear % 4) == 0) && ((aYear % 100) != 0) ? 1 : 0; } int IsLeapYear (const Time& aTime) { return IsLeapYear (aTime.GetYear()); } unsigned DaysOfYear (unsigned aYear) { return IsLeapYear (aYear) ? 366 : 365; } unsigned DaysOfYear (const Time& aTime) { return DaysOfYear (aTime.GetYear ()); } unsigned DaysOfMonth (unsigned aMonth, unsigned aYear) { CHECK ((aMonth >= 1) && (aMonth <= 12)); return IsLeapYear (aYear) ? LeapYearTab [aMonth-1] : NormYearTab [aMonth-1]; } unsigned DaysOfMonth (const Time& aTime) { return DaysOfMonth (aTime.GetMonth (), aTime.GetYear ()); } /*****************************************************************************/ /* class TimeDiff */ /*****************************************************************************/ void TimeDiff::Load (Stream& S) { S >> Diff; } void TimeDiff::Store (Stream& S) const { S << Diff; } u16 TimeDiff::StreamableID () const { return ID_TimeDiff; } Streamable* TimeDiff::Build () { return new TimeDiff (Empty); } /*****************************************************************************/ /* class Time */ /*****************************************************************************/ Time::Time (tm& TM) { T = mktime (&TM); } Time::Time (unsigned Year, unsigned Month, unsigned Day, unsigned Hour, unsigned Min, unsigned Sec) { // Check the given parameters PRECONDITION (Year >= 1970 && Year <= 2030); PRECONDITION (Month > 0 && Month <= 12); PRECONDITION (Day > 0 && Day <= 31); PRECONDITION (Hour < 24 && Min < 60 && Sec < 60); // Assign the values struct tm TM; TM.tm_sec = Sec; TM.tm_min = Min; TM.tm_hour = Hour; TM.tm_mday = Day; TM.tm_mon = Month - 1; TM.tm_year = Year - 1900; // Do the conversion T = mktime (&TM); } void Time::Load (Stream &S) { S >> T; } void Time::Store (Stream &S) const { S << T; } u16 Time::StreamableID () const { return ID_Time; } Streamable* Time::Build () { return new Time (Empty); } String Time::DateStr () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Setup for conversion int Month = TM->tm_mon + 1; int Year = TM->tm_year + 1900; int Day = TM->tm_mday; // Set up string according to local date format switch (NLSData.Date) { case 0: return FormatStr ("%02d%c%02d%c%04d", Month, NLSData.DateSep, Day, NLSData.DateSep, Year); case 1: return FormatStr ("%02d%c%02d%c%04d", Day, NLSData.DateSep, Month, NLSData.DateSep, Year); case 2: return FormatStr ("%04d%c%02d%c%02d", Year, NLSData.DateSep, Month, NLSData.DateSep, Day); default: FAIL ("Unknown value for NLSData.Date"); } // Never reached return String (); } String Time::TimeStr (int Seconds) const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Set up string according to local time format int PM = 0; switch (NLSData.Time) { case 0: // am/pm if (TM->tm_hour >= 12) { TM->tm_hour -= 12; PM = 1; } if (Seconds) { // Include seconds in string return FormatStr ("%02d%c%02d%c%02d %s", TM->tm_hour, NLSData.TimeSep, TM->tm_min, NLSData.TimeSep, TM->tm_sec, PM ? "pm" : "am"); } else { // No seconds return FormatStr ("%02d%c%02d %s", TM->tm_hour, NLSData.TimeSep, TM->tm_min, PM ? "pm" : "am"); } case 1: if (Seconds) { // Include seconds return FormatStr ("%02d%c%02d%c%02d", TM->tm_hour, NLSData.TimeSep, TM->tm_min, NLSData.TimeSep, TM->tm_sec); } else { // String without seconds return FormatStr ("%02d%c%02d", TM->tm_hour, NLSData.TimeSep, TM->tm_min); } default: FAIL ("Unknown value for NLSData.Time"); } // Never reached return String (); } String Time::DateTimeStr (int Seconds) const { return DateStr () + ' ' + TimeStr (Seconds); } String Time::DateTimeStr (const String& Fmt) const { char Buf [512]; // Convert to string time_t Val = (time_t) T; size_t Result = strftime (Buf, sizeof (Buf), Fmt.GetStr (), localtime (&Val)); CHECK (Result != 0); // return the result return String (Buf); } void Time::SetYear (unsigned Year) { // Check the given parameter PRECONDITION (Year >= 1970 && Year <= 2030); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for year TM->tm_year = Year - 1900; // Convert back to time_t T = mktime (TM); } void Time::SetMonth (unsigned Month) { // Check the given parameter PRECONDITION (Month > 0 && Month <= 12); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for month TM->tm_mon = Month - 1; // Convert back to time_t T = mktime (TM); } void Time::SetDay (unsigned Day) { // Check the given parameter PRECONDITION (Day > 0 && Day <= 31); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for day TM->tm_mday = Day; // Convert back to time_t T = mktime (TM); } void Time::SetHour (unsigned Hour) { // Check the given parameter PRECONDITION (Hour < 24); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for hour TM->tm_hour = Hour; // Convert back to time_t T = mktime (TM); } void Time::SetMin (unsigned Min) { // Check the given parameter PRECONDITION (Min < 60); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for minute TM->tm_min = Min; // Convert back to time_t T = mktime (TM); } void Time::SetSec (unsigned Sec) { // Check the given parameter PRECONDITION (Sec < 60); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new value for second TM->tm_sec = Sec; // Convert back to time_t T = mktime (TM); } void Time::SetTime (unsigned Hour, unsigned Min, unsigned Sec) { // Check the given parameters PRECONDITION (Hour < 24 && Min < 60 && Sec < 60); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new values TM->tm_hour = Hour; TM->tm_min = Min; TM->tm_sec = Sec; // Convert back to time_t T = mktime (TM); } void Time::SetTime (unsigned SecondOfDay) { // Check the given parameters PRECONDITION (SecondOfDay <= 23*3600 + 59*60 + 59); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new values TM->tm_sec = SecondOfDay % 60; SecondOfDay /= 60; TM->tm_min = SecondOfDay % 60; SecondOfDay /= 60; TM->tm_hour = SecondOfDay; // Convert back to time_t T = mktime (TM); } void Time::SetDate (unsigned Year, unsigned Month, unsigned Day) { // Check the given parameters PRECONDITION (Year >= 1970 && Year <= 2030); PRECONDITION (Month >= 1 && Month <= 12); PRECONDITION (Day >= 1 && Day <= 31); // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Assign new values TM->tm_year = Year - 1900; TM->tm_mon = Month - 1; TM->tm_mday = Day; // Convert back to time_t T = mktime (TM); } unsigned Time::GetYear () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return year return TM->tm_year + 1900; } unsigned Time::GetMonth () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return month return TM->tm_mon + 1; } unsigned Time::GetDay () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return day return TM->tm_mday; } unsigned Time::GetHour () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return hour return TM->tm_hour; } unsigned Time::GetMin () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return minute return TM->tm_min; } unsigned Time::GetSec () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Return second return TM->tm_sec; } void Time::GetTime (unsigned& Hour, unsigned& Min, unsigned& Sec) const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Set return values Hour = TM->tm_hour; Min = TM->tm_min; Sec = TM->tm_sec; } u32 Time::GetTime () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Calculate and return time in seconds return u32 (TM->tm_hour) * 3600 + u32 (TM->tm_min) * 60 + TM->tm_sec; } void Time::GetDate (unsigned& Year, unsigned& Month, unsigned& Day) const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Set return values Year = TM->tm_year + 1900; Month = TM->tm_mon + 1; Day = TM->tm_mday; } void Time::GetDateTime (unsigned& Year, unsigned& Month, unsigned& Day, unsigned& WeekDay, unsigned& Hour, unsigned& Min, unsigned& Sec) const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // Set return values Year = TM->tm_year + 1900; Month = TM->tm_mon + 1; Day = TM->tm_mday; WeekDay = TM->tm_wday; Hour = TM->tm_hour; Min = TM->tm_min; Sec = TM->tm_sec; } WeekDay Time::GetDayOfWeek () const { // Convert time to tm structure time_t Val = (time_t) T; struct tm* TM = localtime (&Val); // return value return WeekDay (TM->tm_wday); } estic-1.61.orig/spunk/datetime.h0100644000176100001440000002031007031424677016123 0ustar debacleusers/*****************************************************************************/ /* */ /* DATETIME.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _DATETIME_H #define _DATETIME_H #include #include #include "stream.h" // Forwards class TimeDiff; class Time; /*****************************************************************************/ /* Utilities */ /*****************************************************************************/ // Beware: The following must match the values in struct tm.tm_wday! enum WeekDay { Son, Mon, Tue, Mid, Thu, Fri, Sat }; // Name of days and months String LongNameOfDay (WeekDay aDay); String ShortNameOfDay (WeekDay aDay); String LongNameOfMonth (unsigned aMonth); String ShortNameOfMonth (unsigned aMonth); int IsLeapYear (unsigned aYear); int IsLeapYear (const Time& aTime); unsigned DaysOfYear (unsigned aYear); unsigned DaysOfYear (const Time& aTime); unsigned DaysOfMonth (unsigned aMonth, unsigned aYear); unsigned DaysOfMonth (const Time& aTime); /*****************************************************************************/ /* class TimeDiff */ /*****************************************************************************/ class TimeDiff: public Streamable { friend class Time; protected: double Diff; TimeDiff (StreamableInit); // Build constructor public: TimeDiff (double = 0); // Constructor TimeDiff (const TimeDiff&); // Copy constructor // Derived from class Streamable virtual void Load (Stream& S); virtual void Store (Stream& S) const; virtual u16 StreamableID () const; static Streamable* Build (); TimeDiff& operator = (const TimeDiff& rhs); // Assignment operator u32 GetSec (); // Get time diff in seconds // This functions are also declared as friends of class Time! friend inline Time operator - (const Time& lhs, const TimeDiff& rhs); friend inline Time operator + (const Time& lhs, const TimeDiff& rhs); }; inline TimeDiff::TimeDiff (StreamableInit) { } inline TimeDiff::TimeDiff (double Val) : Diff (Val) { } inline TimeDiff::TimeDiff (const TimeDiff& X): Diff (X.Diff) { } inline TimeDiff& TimeDiff::operator = (const TimeDiff& rhs) { Diff = rhs.Diff; return *this; } inline u32 TimeDiff::GetSec () // Get time diff in seconds { return (u32) Diff; } /*****************************************************************************/ /* class Time */ /*****************************************************************************/ class Time: public Streamable { protected: double T; public: Time (); Time (time_t Val); Time (tm& TM); Time (unsigned Year, unsigned Month, unsigned Day, unsigned Hour = 0, unsigned Min = 0, unsigned Sec = 0); Time (const Time&); Time (StreamableInit X); // Derived from class Streamable virtual void Load (Stream& S); virtual void Store (Stream& S) const; virtual u16 StreamableID () const; static Streamable* Build (); // Setting variables void SetYear (unsigned Year); void SetMonth (unsigned Month); void SetDay (unsigned Day); void SetHour (unsigned Hour); void SetMin (unsigned Min); void SetSec (unsigned Sec); void SetTime (unsigned Hour, unsigned Min, unsigned Sec); void SetTime (unsigned SecondOfDay); void SetDate (unsigned Year, unsigned Month, unsigned Day); // Getting variables unsigned GetYear () const; unsigned GetMonth () const; unsigned GetDay () const; unsigned GetHour () const; unsigned GetMin () const; unsigned GetSec () const; void GetTime (unsigned& Hour, unsigned& Min, unsigned& Sec) const; u32 GetTime () const; void GetDate (unsigned& Year, unsigned& Month, unsigned& Day) const; void GetDateTime (unsigned& Year, unsigned& Month, unsigned& Day, unsigned& WeekDay, unsigned& Hour, unsigned& Min, unsigned& Sec) const; WeekDay GetDayOfWeek () const; // Conversion routines String DateStr () const; String TimeStr (int Seconds = 1) const; String DateTimeStr (int Seconds = 1) const; String DateTimeStr (const String& Fmt) const; // Name of days and months String LongNameOfDay () const; String ShortNameOfDay () const; String LongNameOfMonth () const; String ShortNameOfMonth () const; int IsLeapYear () const; unsigned DaysOfYear () const; unsigned DaysOfMonth () const; // Time& operator = (const Time& rhs); Time& operator -= (const TimeDiff& rhs); Time& operator += (const TimeDiff& rhs); // friend inline TimeDiff operator - (const Time& lhs, const Time& rhs); friend inline Time operator - (const Time& lhs, const TimeDiff& rhs); friend inline Time operator + (const Time& lhs, const TimeDiff& rhs); friend inline int operator == (const Time& lhs, const Time& rhs); friend inline int operator != (const Time& lhs, const Time& rhs); friend inline int operator > (const Time& lhs, const Time& rhs); friend inline int operator < (const Time& lhs, const Time& rhs); friend inline int operator >= (const Time& lhs, const Time& rhs); friend inline int operator <= (const Time& lhs, const Time& rhs); }; inline Time::Time (StreamableInit) { } inline Time::Time () : T (time (NULL)) { } inline Time::Time (time_t Val) : T (Val) { } inline Time::Time (const Time& X) : T (X.T) { } inline String Time::LongNameOfDay () const { return ::LongNameOfDay (GetDayOfWeek ()); }; inline String Time::ShortNameOfDay () const { return ::ShortNameOfDay (GetDayOfWeek ()); }; inline String Time::LongNameOfMonth () const { return ::LongNameOfMonth (GetMonth()); } inline String Time::ShortNameOfMonth () const { return ::ShortNameOfMonth (GetMonth()); } inline int Time::IsLeapYear () const { return ::IsLeapYear (GetYear ()); } inline unsigned Time::DaysOfYear () const { return ::DaysOfYear (GetYear ()); } inline unsigned Time::DaysOfMonth () const { return ::DaysOfMonth (GetMonth (), GetYear ()); } inline Time& Time::operator = (const Time& rhs) { T = rhs.T; return *this; } inline Time& Time::operator -= (const TimeDiff& rhs) { T -= rhs.Diff; return *this; } inline Time& Time::operator += (const TimeDiff& rhs) { T += rhs.Diff; return *this; } inline TimeDiff operator - (const Time& lhs, const Time& rhs) { return TimeDiff (lhs.T - rhs.T); } inline Time operator - (const Time& lhs, const TimeDiff& rhs) { return Time ((time_t) (lhs.T - rhs.Diff)); } inline Time operator + (const Time& lhs, const TimeDiff& rhs) { return Time ((time_t) (lhs.T + rhs.Diff)); } inline int operator == (const Time& lhs, const Time& rhs) { return fabs (lhs.T - rhs.T) < 1; } inline int operator != (const Time& lhs, const Time& rhs) { return fabs (lhs.T - rhs.T) >= 1; } inline int operator > (const Time& lhs, const Time& rhs) { return (lhs.T - rhs.T) >= 1; } inline int operator < (const Time& lhs, const Time& rhs) { return (lhs.T - rhs.T) <= -1; } inline int operator >= (const Time& lhs, const Time& rhs) { return (lhs.T - rhs.T) > -1; } inline int operator <= (const Time& lhs, const Time& rhs) { return (lhs.T - rhs.T) < 1; } inline Time Now () // Return the current time { return Time (time (NULL)); } // End of DATETIME.H #endif estic-1.61.orig/spunk/delay.h0100644000176100001440000000317507031424700015422 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System dependent function for waiting some time. #ifndef __DELAY_H #define __DELAY_H #include "machine.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 Delay (u32 ms); // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // The function returns the real time passed or just ms. // End of DELAY.H #endif estic-1.61.orig/spunk/environ.cc0100644000176100001440000000753207031424700016143 0ustar debacleusers/*****************************************************************************/ /* */ /* ENVIRON.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "str.h" #include "strparse.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetEnvVar (const char* Var) // Retrieve an environment var. The result is empty if the string does not // exist. { return String (getenv (Var)); } String GetEnvVar (const String& Var) // Retrieve an environment var. The result is empty if the string does not // exist. { return String (getenv (Var.GetStr ())); } i32 GetEnvVal (const char* Var, const String& ValStr) // Read the environment variable Var and compare the value with values stored // in ValStr. ValStr looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // Case is ignored when comparing the value. The first value stored in ValStr // is the default, it is returned if Var does not exist or is invalid. // The function calls FAIL if the given ValStr is invalid. // Don't forget the trailing '|' ! { // Get the environment value String Val = GetEnvVar (Var); // Match the keyword ignoring case return MatchKeyword (Val.ToUpper (), ToUpper (ValStr)); } i32 GetEnvVal (const String& Var, const String& ValStr) // Read the environment variable Var and compare the value with values stored // in ValStr. ValStr looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // Case is ignored when comparing the value. The first value stored in ValStr // is the default, it is returned if Var does not exist or is invalid. // The function calls FAIL if the given ValStr is invalid. Don't forget the // trailing '|' ! { // BC complains over a (nonexistant) ambiguity here, so do explicit // casting here... return GetEnvVal (Var.GetStr (), String (ValStr)); } i32 GetEnvNum (const char* Var, i32 Default) // Read the environment variable Var and treat the value as a number string. // Return the converted number or Default if the variable does not exist or // contains an invalid value. { // Get the value String Val = GetEnvVar (Var); // Try to convert it to a number StringParser SP (Val); i32 Value; if (SP.GetI32 (Value) == 0) { // Done return Value; } else { // Error return Default; } } i32 GetEnvNum (const String& Var, i32 Default) // Read the environment variable Var and treat the value as a number string. // Return the converted number or Default if the variable does not exist or // contains an invalid value. { return GetEnvNum (Var.GetStr (), Default); } int GetEnvBool (const char* Var, int Default) // Read the environment variable and treat it as a boolean value. Accepted // values are "on" "off" "yes" "no" "1" "0". Default is returned if the // variable does not exist or the value is invalid. { if (Default) { return GetEnvVal (Var, String ("1^YES|0^NO|1^ON|0^OFF|1^1|0^0|")); } else { return GetEnvVal (Var, String ("0^NO|1^YES|0^OFF|1^ON|0^0|1^1|")); } } int GetEnvBool (const String& Var, int Default) // Read the environment variable and treat it as a boolean value. Accepted // values are "on" "off" "yes" "no" "1" "0". Default is returned if the // variable does not exist or the value is invalid. Case of the value is // ignored by this function. { return GetEnvBool (Var.GetStr (), Default); } estic-1.61.orig/spunk/environ.h0100644000176100001440000000572707031424700016011 0ustar debacleusers/*****************************************************************************/ /* */ /* ENVIRON.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ENVIRON_H #define _ENVIRON_H #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetEnvVar (const char* Var); // Retrieve an environment var. The result is empty if the string does not // exist. String GetEnvVar (const String& Var); // Retrieve an environment var. The result is empty if the string does not // exist. i32 GetEnvVal (const char* Var, const String& ValStr); // Read the environment variable Var and compare the value with values stored // in ValStr. ValStr looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // Case is ignored when comparing the value. The first value stored in ValStr // is the default, it is returned if Var does not exist or is invalid. // The function calls FAIL if the given ValStr is invalid. Don't forget the // trailing '|' ! i32 GetEnvVal (const String& Var, const String& ValStr); // Read the environment variable Var and compare the value with values stored // in ValStr. ValStr looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // Case is ignored when comparing the value. The first value stored in ValStr // is the default, it is returned if Var does not exist or is invalid. // The function calls FAIL if the given ValStr is invalid. Don't forget the // trailing '|' ! i32 GetEnvNum (const char* Var, i32 Default = 0); // Read the environment variable Var and treat the value as a number string. // Return the converted number or Default if the variable does not exist or // contains an invalid value. i32 GetEnvNum (const String& Var, i32 Default = 0); // Read the environment variable Var and treat the value as a number string. // Return the converted number or Default if the variable does not exist or // contains an invalid value. int GetEnvBool (const char* Var, int Default = 1); // Read the environment variable and treat it as a boolean value. Accepted // values are "on" "off" "yes" "no" "1" "0". Default is returned if the // variable does not exist or the value is invalid. int GetEnvBool (const String& Var, int Default = 1); // Read the environment variable and treat it as a boolean value. Accepted // values are "on" "off" "yes" "no" "1" "0". Default is returned if the // variable does not exist or the value is invalid. Case of the value is // ignored by this function. // End of ENVIRON.H #endif estic-1.61.orig/spunk/errlog.cc0100644000176100001440000000615207031424700015752 0ustar debacleusers/*****************************************************************************/ /* */ /* ERRLOG.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include "errlog.h" /*****************************************************************************/ /* class ErrLog */ /*****************************************************************************/ ErrLog::ErrLog (const String& Filename, u16 aFlags) : Flags (u16 (aFlags & elCritical)), Name (Filename) { // If the elTruncate flag is set, remove the file without evaluating // the error code (the file may not exist). if (aFlags & elTruncate) { (void) remove (Name.GetStr ()); } // Try to open the log file, setting the error bit Open (); // If the file is critical close it again if (Flags & elCritical) { Close (); } } ErrLog::~ErrLog () { Close (); } void ErrLog::Open () // Open the file { if (HasError ()) { return; } if ((Flags & elOpen) == 0) { // Open the file F = fopen (Name.GetStr (), "at"); if (F == NULL) { // Remember error condition Flags |= elFileError; } else { // Set buffering mode to line buffered setvbuf (F, NULL, _IOLBF, BUFSIZ); // Mark file as open Flags |= elOpen; } } } void ErrLog::Close () // Close the log file { if (HasError ()) { return; } if (Flags & elOpen) { if (fclose (F) != 0) { Flags |= elFileError; return; } Flags &= ~elOpen; } } void ErrLog::Write (const String& Msg) // Write a message to the file { // Open the file if needed if (Flags & elCritical) { Open (); } // Bail out if the file cannot be accessed if (Flags & elFileError) { return; } // Create the complete message and write it to the file String S (CompleteMsg (Msg)); fputs (S.GetStr (), F); // If the log file is critical, close the file if (Flags & elCritical) { Close (); } } String ErrLog::CompleteMsg (const String& Msg) // Build a complete message line from the given partial message { time_t timer = time (NULL); char Buf [30]; strcpy (Buf, asctime (localtime (&timer))); Buf [24] = '\0'; return FormatStr ("[%s] ", Buf) + Msg + '\n'; } estic-1.61.orig/spunk/errlog.h0100644000176100001440000000451007031424700015610 0ustar debacleusers/*****************************************************************************/ /* */ /* ERRLOG.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ERRLOG_H #define _ERRLOG_H #include #include "str.h" /*****************************************************************************/ /* Constants */ /*****************************************************************************/ const u16 elCritical = 0x0001; // Critical, open close for each message const u16 elTruncate = 0x0002; // Truncate on first open const u16 elOpen = 0x0010; // File is open const u16 elFileError = 0x0100; // Cannot access file /*****************************************************************************/ /* class ErrLog */ /*****************************************************************************/ class ErrLog : public Object { private: FILE* F; u16 Flags; String Name; virtual void Open (); virtual void Close (); public: ErrLog (const String& Filename, u16 aFlags = elCritical); ~ErrLog (); void Write (const String& Msg); // Write a message to the file int HasError (); // Return a value != 0 if there have been file errors virtual String CompleteMsg (const String& Msg); // Build a complete message line from the given partial message }; inline int ErrLog::HasError () // Return a value != 0 if there have been file errors { return (Flags & elFileError); } // End of ERRLOG.H #endif estic-1.61.orig/spunk/event.cc0100644000176100001440000000756707031424700015614 0ustar debacleusers/*****************************************************************************/ /* */ /* EVENT.CC */ /* */ /* (C) 1996-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "event.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class CircularBuffer; template class ListNode; #endif /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The root of the event handler list. Don't try to replace this by a // listnode item, it simplifies the code but unfortunately does not work! ListNode* EventHandler::EventHandlerList; /*****************************************************************************/ /* class Event */ /*****************************************************************************/ Event::Event (unsigned aWhat): What (aWhat), Handled (0) { // Clear the object pointer since the destructor will try to delete it Info.O = 0; } Event::Event (unsigned aWhat, unsigned long InfoData): What (aWhat), Handled (0) { Info.O = 0; Info.U = InfoData; } Event::Event (unsigned aWhat, void* InfoData): What (aWhat), Handled (0) { Info.O = 0; Info.P = InfoData; } Event::Event (unsigned aWhat, Object* InfoData): What (aWhat), Handled (0) { Info.O = InfoData; } Event::~Event () { delete Info.O; } /*****************************************************************************/ /* class EventHandler */ /*****************************************************************************/ EventHandler::EventHandler (): EventHandlerNode (this) // Establish the event handler { // Insert this handler into the list of handlers if (EventHandlerList) { EventHandlerNode.InsertAfter (EventHandlerList); } else { EventHandlerList = &EventHandlerNode; } } EventHandler::~EventHandler () // Delete the event handler { // Unlink the node, but be shure to correct the list pointer if (EventHandlerList == &EventHandlerNode) { // The list pointer points to this node if (EventHandlerNode.IsEmpty ()) { // The list is empty EventHandlerList = NULL; } else { EventHandlerList = EventHandlerNode.Next (); // Unlink is done by the destructor } } } void EventHandler::HandleEvent (Event& /*E*/) // Handle an incoming event. Default is to do nothing. { } /*****************************************************************************/ /* class EventFuncHandler */ /*****************************************************************************/ // This is an EventHandler object that reroutes events to a user supplied // function, enabling temporary rerouting of events. void EventFuncHandler::HandleEvent (Event& E) // Handle an incoming event. Default is to do nothing. { // Call one of the user supplied functions if (HandlerFunc1 != 0) { HandlerFunc1 (E); } else if (HandlerFunc2 != 0) { HandlerFunc2 (E, UserData); } } EventFuncHandler::EventFuncHandler (void (*HandlerFunc) (Event&)): HandlerFunc1 (HandlerFunc), HandlerFunc2 (0), UserData (0) // Establish the event handler { } EventFuncHandler::EventFuncHandler (void (*HandlerFunc) (Event&, void*), void* Data): HandlerFunc1 (0), HandlerFunc2 (HandlerFunc), UserData (Data) // Establish the event handler { } estic-1.61.orig/spunk/event.h0100644000176100001440000000565607031424700015453 0ustar debacleusers/*****************************************************************************/ /* */ /* EVENT.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _EVENT_H #define _EVENT_H #include "machine.h" #include "object.h" #include "circbuf.h" #include "listnode.h" /*****************************************************************************/ /* class Event */ /*****************************************************************************/ class Event: public Object { public: unsigned What; // Which event is it? struct { // Additional event info unsigned long U; double F; void* P; // Destructor will *not* free P Object* O; // Destrcutor *will* free O } Info; int Handled; // True if event is handled public: Event (unsigned aWhat); Event (unsigned aWhat, unsigned long InfoData); Event (unsigned aWhat, void* InfoData); Event (unsigned aWhat, Object* InfoData); virtual ~Event (); }; /*****************************************************************************/ /* class EventQueue */ /*****************************************************************************/ class EventQueue: public CircularBuffer { }; /*****************************************************************************/ /* class EventHandler */ /*****************************************************************************/ class EventHandler { friend class Program; // Must be a friend to deliver events private: static ListNode* EventHandlerList; ListNode EventHandlerNode; public: EventHandler (); // Establish the event handler virtual ~EventHandler (); // Delete the event handler virtual void HandleEvent (Event& E); // Handle an incoming event. Default is to do nothing. }; /*****************************************************************************/ /* class EventFuncHandler */ /*****************************************************************************/ // This is an EventHandler object that reroutes events to a user supplied // function, enabling temporary rerouting of events. class EventFuncHandler: private EventHandler { private: void (*HandlerFunc1) (Event&); void (*HandlerFunc2) (Event&, void*); void* UserData; virtual void HandleEvent (Event& E); // Handle an incoming event. Default is to do nothing. public: EventFuncHandler (void (*HandlerFunc) (Event&)); // Establish the event handler EventFuncHandler (void (*HandlerFunc) (Event&, void*), void* Data); // Establish the event handler }; // End of EVENT.H #endif estic-1.61.orig/spunk/eventid.h0100644000176100001440000000403507031424700015756 0ustar debacleusers/*****************************************************************************/ /* */ /* EVENTID.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Definitions for the event codes used inside the spunk library. For // applications use event codes starting from evUser. #ifndef _EVENTID_H #define _EVENTID_H /*****************************************************************************/ /* Event codes */ /*****************************************************************************/ // Program startup and end const unsigned evInit = 1; // This event *may* be posted // by the application // constructor if init is // complete. const unsigned evExit = 2; // This event *may* be posted // by the programs destructor // when the program ends // without an error const unsigned evAbort = 3; // The program aborts because // of an error. // Idle function const unsigned evIdle = 5; // The program is idle const unsigned evSecondChange = 6; // Posted every second if the // application is idle const unsigned evMinuteChange = 7; // Posted every minute if the // application is idle // Screen size const unsigned evScreenSizeChange = 8; // Change of the screen size // Window manager const unsigned evWinMgrNoWindows = 10; // No more open windows const unsigned evWinMgrFirstOpen = 11; // One open window const unsigned evWinMgrLastClose = 12; // Max count - 1 reached const unsigned evWinMgrMaxWindows = 13; // Max count of windows reached // Main menu const unsigned evDisableCommand = 20; // Disable a main menu command const unsigned evEnableCommand = 21; // Enable a main menu command // User defined events const unsigned evUser = 10000; // End of EVENTID.H #endif estic-1.61.orig/spunk/filecoll.cc0100644000176100001440000002440507031424700016252 0ustar debacleusers/*****************************************************************************/ /* */ /* FILECOLL.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module produces warnings about unreachable code under DOS and OS/2. // You can safely ignore this warnings. #include #ifdef __WATCOMC__ # include #else # include # include #endif #include "streamid.h" #include "filesys.h" #include "filepath.h" #include "filecoll.h" // Register the classes LINK (FileInfo, ID_FileInfo); LINK (FileInfoColl, ID_FileInfoColl); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class FileInfo */ /*****************************************************************************/ void FileInfo::Init () // Initialize - is called from the constructors { // Try to stat the file struct stat Buf; if (stat (Name.GetStr (), &Buf) != 0) { Error = errno; return; } // Reset the error code and transfer the information to the object Error = 0; Dev = Buf.st_dev; Inode = Buf.st_ino; Mode = Buf.st_mode; LinkCount = Buf.st_nlink; UID = Buf.st_uid; GID = Buf.st_gid; RDev = Buf.st_rdev; Size = Buf.st_size; ATime = Buf.st_atime; MTime = Buf.st_mtime; CTime = Buf.st_ctime; } FileInfo::FileInfo (const FileInfo& FI): Name (FI.Name), Error (FI.Error), Dev (FI.Dev), Inode (FI.Inode), Mode (FI.Mode), LinkCount (FI.LinkCount), UID (FI.UID), GID (FI.GID), RDev (FI.RDev), Size (FI.Size), ATime (FI.ATime), MTime (FI.MTime), CTime (FI.CTime) { } FileInfo& FileInfo::operator = (const FileInfo& rhs) // Assignment operator { // Beware! Ignore FI = FI if (&rhs != this) { Name = rhs.Name; Error = rhs.Error; Dev = rhs.Dev; Inode = rhs.Inode; Mode = rhs.Mode; LinkCount = rhs.LinkCount; UID = rhs.UID; GID = rhs.GID; RDev = rhs.RDev; Size = rhs.Size; ATime = rhs.ATime; MTime = rhs.MTime; CTime = rhs.CTime; } return *this; } void FileInfo::Load (Stream& S) { S >> Name >> Error >> Dev >> Inode >> Mode >> LinkCount >> UID >> GID >> RDev >> Size >> ATime >> MTime >> CTime; } void FileInfo::Store (Stream& S) const { S << Name << Error << Dev << Inode << Mode << LinkCount << UID << GID << RDev << Size << ATime << MTime << CTime; } u16 FileInfo::StreamableID () const { return ID_FileInfo; } Streamable* FileInfo::Build () { return new FileInfo (Empty); } String FileInfo::PermStr () const // Create a file permission string from the mode { char S [11]; // Calling this function with errors is invalid PRECONDITION (Error == 0); // Set file type if (S_ISREG (Mode)) { S [0] = '-'; } else if (S_ISDIR (Mode)) { S [0] = 'd'; #ifdef UNIXLIKE_OS } else if (S_ISLNK (Mode)) { S [0] = 'l'; } else if (S_ISFIFO (Mode)) { S [0] = 'f'; } else if (S_ISSOCK (Mode)) { S [0] = 's'; } else if (S_ISBLK (Mode)) { S [0] = 'b'; #endif } else if (S_ISCHR (Mode)) { S [0] = 'c'; } S [1] = (Mode & S_IRUSR) ? 'r' : '-'; S [2] = (Mode & S_IWUSR) ? 'w' : '-'; S [3] = (Mode & S_ISUID) ? 's' : (Mode & S_IXUSR) ? 'x' : '-'; S [4] = (Mode & S_IRGRP) ? 'r' : '-'; S [5] = (Mode & S_IWGRP) ? 'w' : '-'; S [6] = (Mode & S_ISGID) ? 's' : (Mode & S_IXGRP) ? 'x' : '-'; S [7] = (Mode & S_IROTH) ? 'r' : '-'; S [8] = (Mode & S_IWOTH) ? 'w' : '-'; S [9] = (Mode & S_ISVTX) ? 't' : (Mode & S_IXOTH) ? 'x' : '-'; S [10] = '\0'; // return the result return String (S); } /*****************************************************************************/ /* class FileInfoColl */ /*****************************************************************************/ int FileInfoColl::ReadFiles (String Dir, const String& FileSpec, unsigned ModeAnd, unsigned ModeXor) // Create a collection of files in the given directory. Files not matching // FileSpec are not inserted. The mode of all files found are xor'ed with // ModeXor, than and'ed with ModeAnd. If the result is zero, the file is // not inserted into the collection. This is a convienient way to choose // files by mode. { // Delete the old contents of the collection DeleteAll (); // If the directory is empty, use the current dir if (Dir.IsEmpty ()) { Dir = GetCurrentDir (); } // Delete a trailing path separator DelPathSep (Dir); // Remember if the file system, the directory resides on, preserves the // case of the names int PreservesCase = FileSysPreservesCase (Dir); // Open the directory stream DIR* D; #if (defined (DOS) && (__BCPLUSPLUS__==0x310)) || (defined (DOS32) && defined (__GO32__)) // BC++ 3.1 for DOS and djgpp both have a buggy declaration for opendir(): // the parameter is not declared as const. I'll assume that the function // will not change the name and cast away the constness (*sigh*) if ((D = opendir ((char*) Dir.GetStr ())) == NULL) { #else if ((D = opendir (Dir.GetStr ())) == NULL) { #endif // Invalid directory return errno; } // Ok, work with Dir is done, add the path separator again AddPathSep (Dir); // Read one name after the other int ErrorCode = 0; dirent* Entry; while ((Entry = readdir (D)) != NULL) { if (Match (Entry->d_name, FileSpec) != 0) { // File name matches the given filespec FileInfo* FI = new FileInfo (Dir + Entry->d_name); if (FI->Error != 0) { // An error occured ErrorCode = FI->Error; delete FI; } else if (((FI->Mode ^ ModeXor) & ModeAnd) == 0) { // We are not interested in this file delete FI; } else { // Ok, we want that file. If the file system does not preserve // the case of names, convert the file name to lower case if (!PreservesCase) { FI->Name.ToLower (); } Insert (FI); } } } // Close the directory stream closedir (D); // return the error code return ErrorCode; } int FileInfoColl::ReadFiles (String Dir) // Create a collection of files in the given directory inserting all of the // files in this directory regardless of mode and filetype. { // Delete the old contents of the collection DeleteAll (); // If the directory is empty, use the current dir if (Dir.IsEmpty ()) { Dir = GetCurrentDir (); } // Make the given directory clean and absolute Dir = CleanPath (Dir); // Delete a trailing path separator DelPathSep (Dir); // Remember if the file system, the directory resides on, preserves the // case of the names int PreservesCase = FileSysPreservesCase (Dir); // Open the directory stream DIR* D; #if (defined (DOS) && (__BCPLUSPLUS__==0x310)) || (defined (DOS32) && defined (__GO32__)) // BC++ 3.1 for DOS and djgpp both have a buggy declaration for opendir(): // the parameter is not declared as const. I'll assume that the function // will not change the name and cast away the constness (*sigh*) if ((D = opendir ((char*) Dir.GetStr ())) == NULL) { #else if ((D = opendir (Dir.GetStr ())) == NULL) { #endif // Invalid directory return errno; } #if defined (DOSLIKE_OS) // Check and remember if we are in the root and first level dirs. This // will be needed for tweaking DOS & OS/2 later. int RootLevel = Dir.Len () == 3; // Since Dir is clean, this is ok String Root, N; FSplit (Dir, Root, N); int SecondLevel = Root.Len () == 3 && N.Len () > 0; #endif // Ok, work with Dir is done, add the path separator again AddPathSep (Dir); // Read one name after the other int ErrorCode = 0; dirent* Entry; while ((Entry = readdir (D)) != NULL) { #if defined (DOSLIKE_OS) // On OS/2 systems, the root directory of HPFS drives contains a ".." // directory that points back to the root directory. Calling stat // with such a name fails. So check for this before creating a new // FileInfo entry. // Another problem under DOS & OS/2 are the entries ".." in second // level directories. Calling stat with an argument of "C:\X\.." // will fail, but "C:\" (which is the correct name) is ok, since it // is handled in a special way by the stat function (so one can say // that this is a stat bug, stat should do also a special handling // on names like C:\X\..). To enable the special handling by stat, // use the name of the root directory in this case, but do not // forget to set the correct name. FileInfo* FI; if (strcmp (Entry->d_name, "..") == 0) { if (RootLevel) { // This is really the root dir, ignore the ".." entry continue; } if (SecondLevel) { FI = new FileInfo (Root); FI->Name = ".."; // Use the correct name! } else { // Not a special directory FI = new FileInfo (Dir + Entry->d_name); } } else { // Normal file, stat it FI = new FileInfo (Dir + Entry->d_name); } #else // This is the way to do it under a _real_ operating system FileInfo* FI = new FileInfo (Dir + Entry->d_name); #endif // If the file has no error, insert it if (FI->Error != 0) { // An error occured ErrorCode = FI->Error; delete FI; } else { // Ok, we want that file. If the file system does not preserve // the case of names, convert the file name to lower case if (!PreservesCase) { FI->Name.ToLower (); } Insert (FI); } } // Close the directory stream closedir (D); // return the error code return ErrorCode; } int FileInfoColl::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } const String* FileInfoColl::KeyOf (const FileInfo* Item) { return &Item->Name; } u16 FileInfoColl::StreamableID () const { return ID_FileInfoColl; } estic-1.61.orig/spunk/filecoll.h0100644000176100001440000001114207031424700016106 0ustar debacleusers/*****************************************************************************/ /* */ /* FILECOLL.H */ /* */ /* (C) 1995,97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _FILECOLL_H #define _FILECOLL_H #include "statdef.h" #include "coll.h" #include "strmable.h" #include "str.h" /*****************************************************************************/ /* class FileInfo */ /*****************************************************************************/ class FileInfo: public Streamable { private: void Init (); // Initialize - is called from the constructors public: String Name; // Name of the file u16 Error; // Error code after init u16 Dev; // Device the file resides on u16 Inode; u16 Mode; // File mode u16 LinkCount; u16 UID; // user id of owner u16 GID; // group id of owner u16 RDev; u32 Size; // file size in bytes u32 ATime; // last access time u32 MTime; // last modify time u32 CTime; // creation time public: FileInfo (const char* Pathname); FileInfo (const String& Pathname); FileInfo (const FileInfo& FI); FileInfo (StreamableInit); // Construct a FileInfo object // Member functions derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); String PermStr () const; // Create a file permission string from the mode FileInfo& operator = (const FileInfo& rhs); // Assignment operator int IsFifo () const; // Return true if the file is a FIFO special file int IsChr () const; // Return true if the file is a character special file int IsBlk () const; // Return true if the file is a block special file int IsDir () const; // Return true if the file is a directory int IsReg () const; // Return true if the file is a regular file }; inline FileInfo::FileInfo (const String& Pathname): Name (Pathname) { Init (); } inline FileInfo::FileInfo (const char* Pathname): Name (Pathname) { Init (); } inline FileInfo::FileInfo (StreamableInit): Name (Empty) { } inline int FileInfo::IsFifo () const // Return true if the file is a FIFO special file { return (Error == 0 && S_ISFIFO (Mode)); } inline int FileInfo::IsChr () const // Return true if the file is a character special file { return (Error == 0 && S_ISCHR (Mode)); } inline int FileInfo::IsBlk () const // Return true if the file is a block special file { return (Error == 0 && S_ISBLK (Mode)); } inline int FileInfo::IsDir () const // Return true if the file is a directory { return (Error == 0 && S_ISDIR (Mode)); } inline int FileInfo::IsReg () const // Return true if the file is a regular file { return (Error == 0 && S_ISREG (Mode)); } /*****************************************************************************/ /* class FileInfoColl */ /*****************************************************************************/ class FileInfoColl: public SortedCollection { protected: virtual int Compare (const String* Key1, const String* Key2); virtual const String* KeyOf (const FileInfo* Item); public: FileInfoColl (int aLimit = 100, int aDelta = 50); // Constructor, create an empty collection FileInfoColl (StreamableInit); // Build constructor // Derived from class Streamable virtual u16 StreamableID () const; int ReadFiles (String Dir, const String& FileSpec, unsigned ModeAnd, unsigned ModeXor); // Create a collection of files in the given directory. Files not matching // FileSpec are not inserted. The mode of all files found are xor'ed with // ModeXor, than and'ed with ModeAnd. If the result is zero, the file is // not inserted into the collection. This is a convienient way to choose // files by mode. int ReadFiles (String Dir); // Create a collection of files in the given directory inserting all of the // files in this directory regardless of mode and filetype. }; inline FileInfoColl::FileInfoColl (int aLimit, int aDelta): SortedCollection (aLimit, aDelta, 1) { } inline FileInfoColl::FileInfoColl (StreamableInit): SortedCollection (Empty) { } // End of FILECOLL.H #endif estic-1.61.orig/spunk/filepath.cc0100644000176100001440000003513107031424700016253 0ustar debacleusers/*****************************************************************************/ /* */ /* FILEPATH.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifdef DOSLIKE_OS # include # include # include # include #else # include #endif #include "check.h" #include "filesys.h" #include "filecoll.h" #include "filepath.h" #include "environ.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ void AddPathSep (String& Path) // Add a trailing path separator if the given path does not end in one { if (Path.Len () > 0 && Path [Path.Len () - 1] != FileSysPathSep) { Path += FileSysPathSep; } } void DelPathSep (String& Path) // Delete a trailing path separator if the last char of path is one { // Get the path length unsigned Len = Path.Len (); // Check if there is a trailing path sep if (Len > 0 && Path [Len - 1] == FileSysPathSep) { // Beware! // * A single path separator means the root directory // * A root dir may also contain a drive or volume spec if (Len == 1) { // Just a root dir spec return; } #if defined(FILESYS_HAS_DRIVES) if (Len == 3 && Path [1] == ':') { // A root dir of a drive return; } #endif // Ok, we have a real path with a trailing separator Path.Trunc (Len - 1); } } void AddDefaultExtension (String& PathName, const String& DefExt) // Add the extension DefExt to PathName if PathName has no extension { // Split up the name String Dir, Name, Ext; FSplit (PathName, Dir, Name, Ext); // Check if there is already an extension if (Ext.IsEmpty ()) { // No extension present - add the default extension PathName += DefExt; } } void ForceExtension (String& PathName, const String& Ext) // Force the file name in PathName to have the extension Ext { // Split the name into its components String Path; String Name; String OldExt; FSplit (PathName, Path, Name, OldExt); // Now reassemble the name using the new extension PathName = Path + Name + Ext; } void FSplit (const String& Pathname, String& Path, String& Name) // Split a complete path in its components. Name and extension aren't separated { // Beware: On systems that support disk drives, "d:lib" is a valid name // that should be splited into "d:" and "lib" // Get the position of the rightmost separator char int SepPos = Pathname.ScanL (FileSysPathSep); #if defined(FILESYS_HAS_DRIVES) int ColonPos = Pathname.ScanL (':'); SepPos = SepPos > ColonPos ? SepPos : ColonPos; #endif // Check if we had a separator if (SepPos == -1) { // No separator, no path Path.Clear (); Name = Pathname; } else { // Extract path Path = Pathname.Cut (0, SepPos+1); Name = Pathname.Cut (SepPos+1, Pathname.Len () - SepPos - 1); } } void FSplit (const String& Pathname, String& Path, String& Name, String& Ext) // Split a complete path in its components { // Beware: On systems that support disk drives, "d:lalle.faz" is a valid // name that should be splited into "d:", "lalle" and ".faz" // Get the position of the rightmost separator char int SepPos = Pathname.ScanL (FileSysPathSep); #if defined(FILESYS_HAS_DRIVES) int ColonPos = Pathname.ScanL (':'); SepPos = SepPos > ColonPos ? SepPos : ColonPos; #endif // Check if we had a separator if (SepPos == -1) { // No separator, no path Path.Clear (); // Extract extension int DotPos = Pathname.ScanL ('.'); if (DotPos == -1) { // No extension Ext.Clear (); Name = Pathname; } else { Name = Pathname.Cut (0, DotPos); Ext = Pathname.Cut (DotPos, Pathname.Len () - DotPos); } } else { // Extract path Path = Pathname.Cut (0, SepPos+1); // Extract extension int DotPos = Pathname.ScanL ('.'); if (DotPos == -1 || DotPos < SepPos) { // No extension Ext.Clear (); Name = Pathname.Cut (SepPos+1, Pathname.Len () - SepPos - 1); } else { // Extension exists Name = Pathname.Cut (SepPos+1, DotPos - SepPos - 1); Ext = Pathname.Cut (DotPos, Pathname.Len () - DotPos); } } } int FExists (const String& Filename, int AccessMode) // Check if the file exists and confirms to the given access mode { return (access (Filename.GetStr (), AccessMode) == 0); } String FSearch (String List, const String& File, int AccessMode) // Searches a list of different directories in LIST for the file FILE. // The directories are separated by ListSep (defined in machine.h). If // FILE is found in one of those directories, the complete, absolute(!) // path to the file is returned. Othwerwise, an empty string is returned. { // Search loop while (!List.IsEmpty ()) { String Dir; // Extract the first directory from the list int P = List.Pos (FileSysListSep); if (P == -1) { // There is only one element left Dir = List; List.Clear (); // List is empty now } else { // More than one element left Dir = List.Cut (0, P); List.Del (0, P+1); } // Check if we have got an empty directory (nothing to do in this case) if (Dir.IsEmpty ()) { continue; } // Make the path clean, add a path separator #ifdef NETWARE AddPathSep (Dir); #else Dir = CleanPath (Dir); #endif // Check if the file exists if (FExists (Dir + File, AccessMode)) { // Found ! return Dir; } } // not found return String (); } String ShortPath (String S, unsigned Len) // Try to shorten the filepath in S by replacing one or more subdirectories // by "...". This is done until the path fits into the given length Len. // If such an abreviation is not possible, S is returned - so check the length // of the result before using the returned string. { static const char ReplaceStr [] = "..."; static const unsigned ReplaceLen = 3; // Length of ReplaceStr if (S.Len () <= Len) { // The length is already ok return S; } int I = S.Pos (FileSysPathSep); if (I == -1) { // There is no subdirectory to replace return S; } int J = I; I++; // position after the path separator do { // Skip the path separator J++; // Search for the next one while (J < S.Len () && S [J] != FileSysPathSep) { J++; } if (J >= S.Len ()) { // No path separator found return S; } // Repeat until the new length is ok } while (S.Len () - unsigned (J - I) + ReplaceLen > Len); // Ok, delete the substring and replace by the dot sequence S.Del (I, J - I); S.Ins (I, ReplaceStr); // Return the result return S; } String TempName () // Return a name for a temporary file (this function uses tmpnam) { return String (tmpnam (NULL)); } char GetCurrentDrive () // Return the current drive as a letter { #if !defined(FILESYS_HAS_DRIVES) // Cannot be called if the file system does not support drives FAIL ("GetCurrentDrive called on a system without drives"); return '\0'; #else int Drive = FileSysGetDrive (); if (FileSysIgnoresCase (Drive)) { return Drive - 1 + 'A'; } else { return Drive - 1 + 'a'; } #endif } String GetCurrentDir () // Return the current directory including the current drive if the file system // supports drives. The returned string includes a trailing path separator! { // Use the file system function return FileSysCurrentDir (); } int FHasWildcards (const String& Pathname) // Return 1 if the given path contains one of the wildcard characters '*', '?', // '[]' or '{}', return zero otherwise. { return Pathname.Pos ('*') >= 0 || Pathname.Pos ('?') >= 0 || Pathname.Pos ('[') >= 0 || Pathname.Pos (']') >= 0 || Pathname.Pos ('{') >= 0 || Pathname.Pos ('}') >= 0; } int FIsAbsolute (const String& Path) // Return true if the given path is an absolute path { // An empty path cannot be absolute if (Path.IsEmpty ()) { return 0; } // If the file system supports drives, there may be a leading // drive specifier #if defined(FILESYS_HAS_DRIVES) if (Path.Len () > 2 && Path [1] == ':') { // look behind the drive specifier return Path [2] == FileSysPathSep; } else { // Look at the first character of the path name return Path [0] == FileSysPathSep; } #else // If the file system does not support drives, allow the // tilde as a representation for the home directory if (Path [0] == '~') { // Assume that the home directory is absolute, no further checking return 1; } else { // Look at the first character of the path name return Path [0] == FileSysPathSep; } #endif } #if defined(FILESYS_HAS_DRIVES) int FHasDriveSpec (const String& Path) // Return 1 if the given path has a drive specification, return 0 otherwise { return Path.Len () >= 2 && Path [1] == ':'; } #else int FHasDriveSpec (const String& /* Path */) // Return 1 if the given path has a drive specification, return 0 otherwise { return 0; } #endif int CreatePath (const String& /*Dir*/) // Dir is assumed to be a complete directory without a file name. A trailing // path separator in Dir is ignored. The function tries to create the given // directory (including all parent directories) if they don't exist. // The return value is a system error code, it is zero if no error occured. { return 1; // ## } u32 FSize (const String& Name) // Return the size of the given file. On error -1 converted to u32 is returned { // Stat the file FileInfo FI (Name); if (FI.Error != 0 || FI.IsReg () == 0) { // Error or file is not a regular file return (u32) -1; } else { return FI.Size; } } String CleanPath (String Path) // Assume Path is a directory (no file!). Make the path absolute including // a drive if needed and delete "." and ".." parts and add a trailing // path separator. { // Check if path is empty if (Path.IsEmpty ()) { // This one is easy... return GetCurrentDir (); } // Make the path absolute (remember: Path is not empty!) #if defined(FILESYS_HAS_DRIVES) // Add a drivespec if needed if (!FHasDriveSpec (Path)) { // Drive is missing char Drive [3]; Drive [0] = GetCurrentDrive (); Drive [1] = ':'; Drive [2] = '\0'; Path.Ins (0, Drive); } // Make the path absolute if needed (remember: The drive is already added) if (!FIsAbsolute (Path)) { // Path is not absolute int Drive = Path [0] >= 'a' ? Path [0] - 'a' + 1 : Path [0] - 'A' + 1; if (Path.Len () == 2) { // Just a drive. Add the working directory for this drive Path += FileSysCurrentDir (0, Drive); } else { Path = Path.Cut (0, 2) + FileSysCurrentDir (0, Drive) + Path.Cut (2, Path.Len () - 2); } } #else if (Path [0] != FileSysPathSep) { // Support a tilde as a replacement for the home directory of the // user. This is a unix convention, it is implicitly assumed that // operating systems that do not support drives are unix alikes. if (Path [0] == '~') { // Expand the tilde Path.Del (0, 1); Path.Ins (0, GetEnvVar ("HOME")); } else { // No tilde, the path is relativ to the current directory Path = GetCurrentDir () + Path; } } #endif // Add a path separator AddPathSep (Path); // Path is now absolute, remove "." and ".." sequences char F [5]; // Check for "/./" F [0] = FileSysPathSep; F [1] = '.'; F [2] = FileSysPathSep; F [3] = '\0'; int Pos = Path.Pos (F); while (Pos != -1) { Path.Del (Pos, 2); Pos = Path.Pos (F); } // Check for "/../" F [2] = '.'; F [3] = FileSysPathSep; F [4] = '\0'; Pos = Path.Pos (F); while (Pos != -1) { // Find the previous path element int I = Pos - 1; while (I >= 0 && Path [I] != FileSysPathSep) { I--; } // Delete it if (I < 0) { // Absolute path begins with "/../", just delete it Path.Del (Pos, 3); } else { // Delete "/../" and preceeding dir Path.Del (I, Pos - I + 3); } // Check for next occurance Pos = Path.Pos (F); } // Ok, path is clean return Path; } String MakeAbsolute (const String& Pathname) // Assume Pathname is the name of a file with or without a relative or // absolute path. Make Pathname contain the absolute name of the file. { // Split the given name into path and filename String Path, Name; FSplit (Pathname, Path, Name); // Now clean up the path and reassemble Pathname return CleanPath (Path) + Name; } int FMatch (String Source, String Pattern) // Use String::Match to check if Source is matched by Pattern. This function // is different from String::Match in that it ignores case on systems where // case is ignored in file names. So use this function for matching file // names instead of the function from module str. { if (FileSysIgnoresCase ()) { // File system ignores case. Use the upper case equivalent of both // strings for the match. Source.ToUpper (); Pattern.ToUpper (); } return Match (Source, Pattern); } estic-1.61.orig/spunk/filepath.h0100644000176100001440000001176207031424700016121 0ustar debacleusers/*****************************************************************************/ /* */ /* FILEPATH.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _FILEPATH_H #define _FILEPATH_H #if defined (DOS) || defined (DOS32) || defined (OS2) # include #else # include #endif #include "statdef.h" #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ void AddPathSep (String& Path); // Add a trailing path separator if the given path does not end in one void DelPathSep (String& Path); // Delete a trailing path separator if the last char of path is one void AddDefaultExtension (String& PathName, const String& DefExt); // Add the extension DefExt to PathName if PathName has no extension void ForceExtension (String& PathName, const String& Ext); // Force the file name in PathName to have the extension Ext void FSplit (const String& Pathname, String& Path, String& Name); // Split a complete path in its components. Name and extension aren't separated void FSplit (const String& Pathname, String& Path, String& Name, String& Ext); // Split a complete path in its components int FExists (const String& Filename, int AccessMode = F_OK); // Check if the file exists and confirms to the given access mode String FSearch (String List, const String& File, int AccessMode = F_OK); // Searches a list of different directories in LIST for the file FILE. // The directories are separated by ListSep (defined in machine.h). If // FILE is found in one of those directories, the complete, absolute(!) // path to the file is returned. Othwerwise, an empty string is returned. String ShortPath (String S, unsigned Len); // Try to shorten the filepath in S by replacing one or more subdirectories // by "...". This is done until the path fits into the given length Len. // If such an abreviation is not possible, S is returned - so check the length // of the result before using the returned string. String TempName (); // Return a name for a temporary file (this function uses tmpnam) char GetCurrentDrive (); // Return the current drive as a letter String GetCurrentDir (); // Return the current directory including the current drive if the file system // supports drives. The returned string includes a trailing path separator! int FHasWildcards (const String& Pathname); // Return 1 if the given path contains one of the wildcard characters '*', '?' // or '[]', return zero otherwise. int FMatch (const String& Source, const String& Pattern); // Match the string in Source against Pattern. Pattern may contain the // wildcards '*', '?', '[abcd]' '[ab-d]', '[!abcd]', '[!ab-d]' // The function returns a value of zero if Source does not match Pattern, // otherwise a non zero value is returned. // If Pattern contains an invalid wildcard pattern (e.g. 'A[x'), the function // returns zero. int FIsAbsolute (const String& Path); // Return true if the given path is an absolute path int FHasDriveSpec (const String& Path); // Return 1 if the given path has a drive specification, return 0 otherwise int CreatePath (const String& Dir); // Dir is assumed to be a complete directory without a file name. A trailing // path separator in Dir is ignored. The function tries to create the given // directory (including all parent directories) if they don't exist. // The return value is a system error code, it is zero if no error occured. String CleanPath (String Path); // Assume Path is a directory (no file!). Make the path absolute including // a drive if needed and delete "." and ".." parts and add a trailing // path separator. String MakeAbsolute (const String& Pathname); // Assume Pathname is the name of a file with or without a relative or // absolute path. Make Pathname contain the absolute name of the file. u32 FSize (const String& Name); // Return the size of the given file. On error -1 converted to u32 is returned int FMatch (String Source, String Pattern); // Use String::Match to check if Source is matched by Pattern. This function // is different from String::Match in that it ignores case on systems where // case is ignored in file names. So use this function for matching file // names instead of the function from module str. // End of FILEPATH.H #endif estic-1.61.orig/spunk/filesel.cc0100644000176100001440000007463407031424700016115 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESEL.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "msgid.h" #include "chartype.h" #include "palette.h" #include "filesys.h" #include "filepath.h" #include "filecoll.h" #include "listbox.h" #include "strcvt.h" #include "menuedit.h" #include "stdmsg.h" #include "progutil.h" #include "thread.h" #include "settings.h" #include "filesel.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msBytes = MSGBASE_FILESEL + 0; const u16 msDirectory = MSGBASE_FILESEL + 1; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Name of the settings resource for the window position static const String FSelPosName = "FileSelector.FileSelectorWindow.Position"; /*****************************************************************************/ /* */ /*****************************************************************************/ // // |<-------- 24 -------->| |<--------- 24 ------->| // |<----------------- 42 ----------------->| // |<--------------------- 50 --------------------->| // |<------------------------ 56 ------------------------>| // ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Open file ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ // ³ ³ // 1 ³ Path c:\usr\uz\c\lib\ ³ // 2 ³ Name °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ³ // ³ ³ // 4 ³ Files Directories ³ // 5 ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ - // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ 1 // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ 0 // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ | // 14 ³ °°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°° ³ - // ³ ³ // 16 ³ Info ³ // 17 ³ °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ³ // ³ °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° ³ // ³ ³ // ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ // /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListBox; #endif /*****************************************************************************/ /* class FileListBox */ /*****************************************************************************/ class FileListBox: public ListBox { protected: String SearchText; int Found; virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: FileListBox (i16 aID, const Point& Size, WindowItem* NextItem = NULL); // Construct a FileListBox virtual void HandleKey (Key& K); // Override ListBox::HandleKey and implement a search function for files. }; FileListBox::FileListBox (i16 aID, const Point& Size, WindowItem* NextItem): ListBox ("", aID, Size, atEditNormal, atEditBar, atEditHigh, NextItem), Found (1) { } void FileListBox::Print (int Index, int X, int Y, u16 Attr) // Display one of the listbox entries { // Get the entry FileInfo* FI = Coll->At (Index); // Get the name and pad it to size String Line = ' ' + FI->Name; if (FI->IsDir ()) { Line += FileSysPathSep; } Line.Pad (String::Right, Size.X); // Print the line Owner->Write (X, Y, Line, Attr); } void FileListBox::HandleKey (Key& K) // Override ListBox::HandleKey and implement a search function for files. { if (IsPlainKey (K) && !IsCntrl (K)) { if (Found == 1 && SearchText.Len () < 255) { // This key is ours! Add it to the search string SearchText += NLSUpCase (K); // Search for a name, beginning with SearchText. We cannot do a // binary search here, because we ignore case. So do a linear // search, even if it is ineffective. unsigned Count = Coll->GetCount (); unsigned I = 0; while (I < Count) { String S = Coll->At (I)->Name; S.Trunc (SearchText.Len ()); S.ToUpper (); if (S == SearchText) { break; } I++; } if (I < Count) { // We found it! Set the selected item SetSelected (I); } else { // We did not find the string. Remember that Found = 0; } } // In any case, mark the key as handled K = kbNoKey; } else { // Call the derived function and reset the searcher ListBox::HandleKey (K); SearchText.Clear (); Found = 1; } } /*****************************************************************************/ /* File selector constants */ /*****************************************************************************/ const i16 miName = 1; const i16 miFiles = 3; const i16 miDirectories = 4; const i16 miFileBox = 5; const i16 miDirBox = 6; const i16 miPathLine = 10; const i16 miInfoLine1 = 11; const i16 miInfoLine2 = 12; /*****************************************************************************/ /* class FileSelector */ /*****************************************************************************/ FileSelector::FileSelector (const String& Header, const String& aDefExt, u32 aOptions): DirColl (new FileInfoColl), FileColl (new FileInfoColl), DefExt (aDefExt), Options (aOptions), Path (GetCurrentDir ()), NameSpec ("*") { // Insert a leading dot into DefExt if one is missing and add DefExt to // the default name spec if DefExt is not empty if (!DefExt.IsEmpty ()) { if (DefExt [0] != '.') { DefExt.Ins (0, '.'); } NameSpec += DefExt; } // Load the window from the file Win = (Menue*) LoadResource ("FILESEL.FileSelectorWindow"); // If there is a stored window position and the flag fsIgnoreStoredPos is // not set, move the window to that position if ((Options & fsIgnoreStoredPos) == 0) { Point Pos = StgGetPoint (FSelPosName, Win->OuterBounds ().A); Win->MoveAbs (Pos); } // Set the header Win->SetHeader (Header); // Get pointers to the text items PathLine = (TextItem*) Win->ItemWithID (miPathLine); InfoLine1 = (TextItem*) Win->ItemWithID (miInfoLine1); InfoLine2 = (TextItem*) Win->ItemWithID (miInfoLine2); // Create and place the listboxes FileBox = new FileListBox (miFileBox, Point (24, 10), NULL); Win->AddItem (FileBox); FileBox->SetPos (2, 5); DirBox = new FileListBox (miDirBox, Point (24, 10), NULL); Win->AddItem (DirBox); DirBox->SetPos (28, 5); // Set the listbox collections FileBox->SetColl (FileColl); DirBox->SetColl (DirColl); // Deactivate the list boxes because they are controlled by the label // items FileBox->Deactivate (); DirBox->Deactivate (); // Redraw the window interior Win->DrawInterior (); } FileSelector::~FileSelector () // Delete the file selector { // Save the current window position StgPutPoint (Win->OuterBounds ().A, FSelPosName); // Delete the window. This will delete the listboxes including both // collections delete Win; } void FileSelector::SetDefExt (const String& NewExt) // Set the default extension { // Remember the new extension DefExt = NewExt; if (HasDefExt ()) { // Add a leading dot if one is missing if (DefExt [0] != '.') { DefExt.Ins (0, '.'); } // If the current name spec is '*', assume that the constructor has // set this and change it if (NameSpec == "*") { NameSpec = '*' + DefExt; } } } void FileSelector::ReadFiles () // Read the files according to name spec { String Dir, Name; // This can last some time Window* WaitWin = PleaseWaitWindow (); // Display the path in the window, from where the files are read PathLine->SetText (ShortPath (Path, 42)); // Clear the old file and dir collections FileColl->DeleteAll (); DirColl->DeleteAll (); // Read in a complete list of all files. FileInfoColl* AllFiles = new FileInfoColl; int ErrorCode = AllFiles->ReadFiles (Path); if (ErrorCode != 0) { // An error occured but AllFiles is valid (but maybe empty). Display // an error message and continue. SysErrorMsg (ErrorCode); } // Now sort the files: If the file matches the file mask and the modes, // insert it into the file collection. If the file is a directory, insert // it into the directory collection. Drop all other files. // To avoid copying, set the SouldDelete member of AllFiles to 0, and // delete retrieve _all_ entries from AllFiles. AllFiles->ShouldDelete = 0; i32 Count = AllFiles->GetCount (); while (--Count >= 0) { // Get the next entry FileInfo* FI = AllFiles->At (Count); // Is it a directory? if (FI->IsDir ()) { // Drop the path part of the name FSplit (FI->Name, Dir, Name); FI->Name = Name; // Ignore the current (".") directory if (FI->Name != ".") { // Insert it into DirColl DirColl->Insert (FI); } else { // Current dir - trash it delete FI; } // Is it a regular file with matching modes? } else if (FI->IsReg () && ((FI->Mode ^ ModeXor) & ModeAnd) != 0) { // Regular file with matching mode, check name FSplit (FI->Name, Dir, Name); if (FMatch (Name, NameSpec)) { // Drop the path part of the name FI->Name = Name; FileColl->Insert (FI); } else { // We do not want this file, delete it delete FI; } } else { // Unknown stuff, delete it delete FI; } } // Delete the (now empty) list of all files delete AllFiles; // Reset and redraw the listboxes FileBox->Reset (); FileBox->Draw (); DirBox->Reset (); DirBox->Draw (); // Clear the info rectangle ClearInfo (); // Delete the "please wait" window delete WaitWin; } Key FileSelector::BrowseBox (FileListBox* Box) // Allow browsing the a listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. { // Select the box and make it active Win->SelectNewItem (Box); // Get the current selection of the box. If the selection is valid, print // information on this file/dir, else clear the info rectangle ShowInfo (Box->GetSelection ()); // Remember the selected entry int LastSel = Box->GetSelected (); int NewSel; // Endless loop waiting for input... while (1) { // Get a key Key K = KbdGet (); // Handle listbox keys Box->HandleKey (K); // Look if something is left switch (K) { case kbNoKey: // Box has handled the key. Check if an update of the info // area is needed NewSel = Box->GetSelected (); if (NewSel != LastSel) { LastSel = NewSel; ShowInfo (Box->GetSelection ()); } break; case vkAbort: return vkAbort; case vkResize: // Resize request Win->MoveResize (); break; case kbTab: case kbShiftTab: // Handle tab and reverse tab like reserved keys return K; case kbEnter: case vkAccept: // Got a selection return kbNoKey; default: if (K != Box->GetAccelKey () && KeyIsRegistered (K)) { return K; } break; } } } Key FileSelector::BrowseFileBox () // Allow browsing the file listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. { // Get a pointer to the corresponding label and select it WindowItem* Label = Win->ForcedItemWithID (miFiles); // Select the label Label->Select (); // Allow browsing Key K = BrowseBox (FileBox); // Deselect the label Label->Deselect (); // Return the result return K; } Key FileSelector::BrowseDirBox () // Allow browsing the dir listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. { // Get a pointer to the corresponding label and select it WindowItem* Label = Win->ForcedItemWithID (miDirectories); // Select the label Label->Select (); // Allow browsing Key K = BrowseBox (DirBox); // Deselect the label Label->Deselect (); // Return the result return K; } String FileSelector::FileTimeStr (const FileInfo* FI) // Return the date/time of the file as a string for display in the info box { Time T (FI->MTime); String S = T.DateTimeStr (); S.Pad (String::Right, 19); return S; } void FileSelector::ClearInfo () // Clear the info rectangle { // Lock the window Win->Lock (); // Clear the info lines InfoLine1->SetText (EmptyString); InfoLine2->SetText (EmptyString); // Unlock the window, allow screen output Win->Unlock (); } void FileSelector::ShowFileInfo (const FileInfo* FI) // Show information about a file { // Lock the window Win->Lock (); // Display the complete name in the first line, make shure, the string // is not longer than the info area String Line1 = ' ' + ShortPath (Path + FI->Name, InfoLine1->GetWidth () - 2); InfoLine1->SetText (Line1); // Build a string like "drwxrwxrwx 123456789 Bytes 12.12.1995 13:24:25" String Line2 (InfoLine2->GetWidth ()); Line2 = ' '; Line2 += FI->PermStr (); String Size = U32Str (FI->Size); // gcc 2.5.8 workaround Size.Pad (String::Left, 11); Line2 += Size; Line2 += LoadMsg (msBytes); Line2 += FileTimeStr (FI); // Write out the second line InfoLine2->SetText (Line2); // Unlock the window, allow screen output Win->Unlock (); } void FileSelector::ShowDirInfo (const FileInfo* FI) // Show information about a directory { // Lock the window Win->Lock (); // Display the complete name in the first line, make shure, the string // is not longer than the info area String Line1 = ' ' + ShortPath (Path + FI->Name, InfoLine1->GetWidth () - 2); InfoLine1->SetText (Line1); // Build a string like "drwxrwxrwx Directory 12.12.1995 13:24:25" String Line2 (InfoLine2->GetWidth ()); Line2 = ' '; Line2 += FI->PermStr (); Line2 += LoadMsg (msDirectory); Line2 += FileTimeStr (FI); // Write out the second line InfoLine2->SetText (Line2); // Unlock the window, allow screen output Win->Unlock (); } void FileSelector::ShowSpecialInfo (const FileInfo* FI) // Show information about a special file { // Lock the window Win->Lock (); // Display the complete name in the first line, make shure, the string // is not longer than the info area String Line1 = ' ' + ShortPath (Path + FI->Name, InfoLine1->GetWidth () - 2); InfoLine1->SetText (Line1); // Build a string like "drwxrwxrwx 123456789 Bytes 12.12.1995 13:24:25" String Line2 (InfoLine2->GetWidth ()); Line2 = ' '; Line2 += FI->PermStr (); String Size = U32Str (FI->Size); // gcc 2.5.8 workaround Size.Pad (String::Left, 11); Line2 += Size; Line2 += LoadMsg (msBytes); Line2 += FileTimeStr (FI); // Write[Aut the second line InfoLine2->SetText (Line2); // Unlock the window, allow screen output Win->Unlock (); } void FileSelector::ShowInfo (const FileInfo* FI) // Calls one of ShowFileInfo/ShowDirInfo/ShowSpecialInfo { // Distribute to one of the virtual functions if (FI == NULL) { // Invalid file info, clear the info area ClearInfo (); } else if (FI->IsReg ()) { // Regular file ShowFileInfo (FI); } else if (FI->IsDir ()) { // Directory ShowDirInfo (FI); } else { // Special file ShowSpecialInfo (FI); } } int FileSelector::EditNameSpec () // Allow editing the name spec and return: // // 0 on abort // 1 if the value has been accepted but not changed // 2 if NameSpec/Path has a new value now and this value contains // wildcard chars or is not a directory // 3 if the name exists as a file (selection) // { // Get a pointer to the edit field FileEdit* FE = (FileEdit*) Win->ForcedItemWithID (miName); // Select the edit field Win->SelectNewItem (FE); // Allow editing the filespec int Abort; FE->Edit (Abort); // Set FileSpec and return the correct result if (Abort) { return 0; } else { String NewSpec = FE->GetValue (); if (NameSpec == NewSpec) { // Nothing has changed return 1; } // There are some possibilities now: // * If the name part of the new spec contains wildcard // characters, the dir part must be a directory. // * If the name part does not contain wildcards, assume it is // a directory, if it ends in a path separator char. // * If the name does not contain wildcards, it may also be a // directory. Try to stat the file to check that. // * If the user input ends in a path separator, the FSplit // function returns an empty name part, so the complete // input is automatically handled as a directory. // * If the name part does not contain wildcards is not a // directory and does not exist as a file, but a default // extension exists, check if the name with the default // extension added exists as a file. If yes, assume this as // the selected file. // Split the input into a directory and a name part. String Dir, Name; FSplit (NewSpec, Dir, Name); // If the name part is empty, use the last spec used if (Name.IsEmpty ()) { Name = NameSpec; } // Assume that the name is non existant or contains wildcards int RetVal = 2; // If the name part contains wildcards, the dir part must be a // directory if (FHasWildcards (Name)) { // Use the given Dir if it's not empty if (!Dir.IsEmpty ()) { // value entered contains a directory NewDir (Dir); } } else { // Name does not contain wildcards. Add the dir from the new spec // to the current path. if (!Dir.IsEmpty ()) { NewDir (Dir); } // Stat the file FileInfo FI (Path + Name); if (FI.Error != 0) { // File/Dir does not exist. If the fsFileMustExist flag is // not set, add an eventual default extension and accept // the input as new selection. if ((Options & fsFileMustExist) == 0) { AddDefaultExtension (Name, DefExt); RetVal = 3; } else { // The file must exist, but does not. If the name has no // extension but a default extension exists, check if the // name with the default extension added exists as a file. // If yes return this as the selected file. if (HasDefExt ()) { String D, N, E; FSplit (Path + Name, D, N, E); if (E.IsEmpty ()) { // Has no extension! Check if there is a file with // this name FileInfo FO (Path + Name + DefExt); if (FO.Error != 0) { // Not found SysErrorMsg (FO.Error); } else { // Beware: The resulting name may not be the // name of a file! if (FO.IsReg ()) { // Set up the new name Name += DefExt; // Found a selection RetVal = 3; } else { // Print the original error message from // above SysErrorMsg (FI.Error); } } } else { SysErrorMsg (FI.Error); } } else { SysErrorMsg (FI.Error); } } } else { // The file exists, but it may be a directory. Check that. if (FI.IsDir ()) { // The given name is a directory. Handle that. NewDir (Name); Name = NameSpec; // Last spec used } else if (FI.IsReg ()) { // The given name exists as a file. RetVal = 3; } } } // Remember the new name spec NameSpec = Name; // Set the new value for the edit field FE->SetValue (NameSpec); // Return the result return RetVal; } } void FileSelector::NewDir (String DirPath) // Add DirPath to the path { if (FIsAbsolute (DirPath)) { // Absolute path, replace Path Path = CleanPath (DirPath); } else { // The path is relative but maybe it has a drive spec... if (FHasDriveSpec (DirPath)) { // DirPath contains a drive spec - make it absolute Path = CleanPath (DirPath); } else { // Relative path without drive spec, add DirPath to the current path Path = CleanPath (Path + DirPath); } } } String FileSelector::GetChoice (const String& aFileSpec, u16 aModeAnd, u16 aModeXor) // Pop up the window and allow selecting a file. aModeAnd and aModeXor are // valid only for files, not for directories. The function will return the // file choosen or an empty string if the user aborted the dialog with esc. { // If there is a new filespec given, split and store it if (!aFileSpec.IsEmpty ()) { // Filespec given split it in name and directory FSplit (aFileSpec, Path, NameSpec); Path = CleanPath (Path); } // Store the modes and read the files ModeAnd = aModeAnd; ModeXor = aModeXor; ReadFiles (); // Get a pointer to the edit line FileEdit* NameEdit = (FileEdit*) Win->ForcedItemWithID (miName); // Set the flags for the file editline NameEdit->SetFileFlags (ffPathOk | ffWildcardsOk | ffExtensionOk); // Set the current value for the file edit line NameEdit->SetValue (NameSpec); // Register the window keys Win->RegisterItemKeys (); // Remember the old state and make the window active unsigned OldState = Win->GetState (); Win->Activate (); // Show a new status line PushStatusLine (HasHelp () ? siHelp | siAbort : siAbort); // Select the name as active item Win->SelectNewItem (miName); WindowItem* ActiveItem = NameEdit; String Result; int Sel; Key K; int Done = 0; while (!Done) { switch (ActiveItem->GetID ()) { case miName: switch (EditNameSpec ()) { case 0: // Abort Done = 1; break; case 1: // No change. If there are files, edit the filebox, // else edit the dirbox if (FileBox->GetCount () > 0) { ActiveItem = FileBox; } else if (DirBox->GetCount () > 0) { ActiveItem = DirBox; } break; case 2: // New file spec, read new files ReadFiles (); // If there are files, edit the filebox, else edit the // dirbox if (FileBox->GetCount () > 0) { ActiveItem = FileBox; } else if (DirBox->GetCount () > 0) { ActiveItem = DirBox; } break; case 3: // Selection Result = Path + NameSpec; Done = 1; break; } break; case miFileBox: K = BrowseFileBox (); switch (K) { case kbNoKey: // Got a selection Sel = FileBox->GetSelected (); if (Sel != -1) { Result = Path + FileColl->At (Sel) -> Name; Done = 1; } break; case vkAbort: Done = 1; break; default: KbdPut (K); break; } break; case miDirBox: K = BrowseDirBox (); switch (K) { case kbNoKey: // Got a selection Sel = DirBox->GetSelected (); if (Sel != -1) { // Change the directory NewDir (DirColl->At (Sel) -> Name); // Read in the files ReadFiles (); // If the dir box is empty but the file box is not, // change the active item to the file box if (DirBox->GetCount () == 0) { if (FileBox->GetCount () > 0) { ActiveItem = FileBox; } else { ActiveItem = NameEdit; } } } break; case vkAbort: Done = 1; break; default: KbdPut (K); break; } break; } // Check for any keys if (CurThread () -> KbdKeyAvail ()) { // There is a key - get it Key K = KbdGet (); // Handle the key, drop it if unknown if (K == Win->GetAccelKey (miName)) { ActiveItem = NameEdit; } else if (K == Win->GetAccelKey (miFiles)) { ActiveItem = FileBox; } else if (K == Win->GetAccelKey (miDirectories)) { ActiveItem = DirBox; } else if (K == kbTab) { if (ActiveItem == DirBox) { ActiveItem = FileBox; } else if (ActiveItem == FileBox) { ActiveItem = DirBox; } } else if (K == kbShiftTab) { if (ActiveItem == DirBox) { ActiveItem = FileBox; } else if (ActiveItem == FileBox) { ActiveItem = DirBox; } } else if (KeyIsRegistered (K)) { KbdPut (K); Done = 1; } } } // Restore the old status line PopStatusLine (); // Unregister the menue keys Win->UnregisterItemKeys (); // Restore the window state Win->SetState (OldState); // Free the list of files/directories FileColl->DeleteAll (); DirColl->DeleteAll (); // Return the selected file return Result; } estic-1.61.orig/spunk/filesel.h0100644000176100001440000001250507031424700015744 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESEL.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _FILESEL_H #define _FILESEL_H #include "str.h" #include "filecoll.h" #include "textitem.h" #include "menue.h" /*****************************************************************************/ /* Constants */ /*****************************************************************************/ const u32 fsFileMayNotExist = 0x00000000; const u32 fsFileMustExist = 0x00000001; const u32 fsIgnoreStoredPos = 0x00010000; // Ignore settings position /*****************************************************************************/ /* class FileSelector */ /*****************************************************************************/ // Forwards class FileInfoColl; class FileListBox; class FileSelector: public Streamable { protected: String HelpKey; // Help keyword class Menue* Win; // The visible part of the selector class FileInfoColl* DirColl; // Directories class FileInfoColl* FileColl; // Files class FileListBox* DirBox; // Directory listbox class FileListBox* FileBox; // Filename listbox String DefExt; // Default extension u32 Options; // File selector options String Path; // Absolute directory String NameSpec; // Last namespec used u16 ModeAnd; // Files to show u16 ModeXor; // Files not to show TextItem* PathLine; // path line TextItem* InfoLine1; // info line #1 TextItem* InfoLine2; // info line #2 int HasDefExt () const; // Return true if the selector has a default extension String FileTimeStr (const FileInfo* FI); // Return the date/time of the file as a string for display in the info box void ReadFiles (); // Read the files according to name spec Key BrowseBox (FileListBox* Box); // Allow browsing the a listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. Key BrowseDirBox (); // Allow browsing the dir listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. Key BrowseFileBox (); // Allow browsing the file listbox. If an entry is selected, return kbNoKey. // On abort or hotkey, return the key. int EditNameSpec (); // Allow editing the name spec and return: // // 0 on abort // 1 if the value has been accepted but not changed // 2 if NameSpec/Path has a new value now and this value contains // wildcard chars or is not a directory // 3 if the name exists as a file (selection) // void NewDir (String DirPath); // Add DirPath to the path void ClearInfo (); // Clear the info rectangle virtual void ShowFileInfo (const FileInfo* FI); // Show information about a file virtual void ShowDirInfo (const FileInfo* FI); // Show information about a directory virtual void ShowSpecialInfo (const FileInfo* FI); // Show information about a special file void ShowInfo (const FileInfo* FI); // Calls one of ShowFileInfo/ShowDirInfo/ShowSpecialInfo public: FileSelector (const String& Header, const String& aDefExt = "", u32 aOptions = fsFileMustExist); // Create a file selector with the given header virtual ~FileSelector (); // Delete the file selector String GetChoice (const String& aFileSpec = "", u16 aModeAnd = S_IFREG, u16 aModeXor = 0); // Pop up the window and allow selecting a file. aModeAnd and aModeXor are // valid only for files, not for directories. The function will return the // file choosen or an empty string if the user aborted the dialog with esc. // If aFileSpec is empty, the last spec is used (this defaults to "*" and // the current directory after init. void SetHelpKey (const String& NewKey); // Set the help keyword const String& GetHelpKey () const; // Return the current help keyword int HasHelp () const; // Return true if the viewer has a valid help key void SetDefExt (const String& NewExt); // Set the default extension void SetOptions (u32 NewOption); // Set new file selector options void ResetOptions (u32 NewOption); // Reset some file selector options }; inline int FileSelector::HasDefExt () const // Return true if the selector has a default extension { return DefExt.Len () > 0; } inline void FileSelector::SetHelpKey (const String& NewKey) // Set the help keyword { HelpKey = NewKey; } inline const String& FileSelector::GetHelpKey () const // Return the current help keyword { return HelpKey; } inline int FileSelector::HasHelp () const // Return true if the selector has a valid help key { return HelpKey.Len () > 0; } inline void FileSelector::SetOptions (u32 NewOption) // Set new file selector options { Options |= NewOption; } inline void FileSelector::ResetOptions (u32 NewOption) // Reset some file selector options { Options &= ~NewOption; } // End of FILESEL.H #endif estic-1.61.orig/spunk/filesys.h0100644000176100001440000001275207031424700016003 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // #ifndef __FILESYS_H #define __FILESYS_H #include "str.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ // The following constants describe features of the file system. To avoid // compiler warnings (regarding dead code) the constants are not declared as // static but as extern. This will result in somewhat larger code because // in some places code is included that is never executed, but as there are // only a few places, I thought it would be safer to get rid of the compiler // warnings than to minimize code size. extern const char FileSysPathSep; // Path separator extern const char FileSysListSep; // Path list separator extern const FileSysMaxPath; // Maximum path length extern const FileSysMaxDir; // Maximum directory length extern const FileSysMaxName; // Maximum file name length extern const FileSysMaxExt; // Maximum extension length (including the dot) /*****************************************************************************/ /* struct FileSysInfo */ /*****************************************************************************/ struct FileSysInfo { char fsName [80]; // Name of the file system // char fsValidChars [32]; // Bitset, 1 == valid file name char unsigned fsMaxPath; // Maximum length of a path unsigned fsMaxDir; // Maximum length of a directory unsigned fsMaxName; // Maximum length of a file name unsigned fsMaxExt; // Maximum length of a extension (including the dot) char fsCurDir [256]; // Current directory int fsPreservesCase; // 1 if filesys preserves case int fsIgnoresCase; // 1 if filesys ignores case }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ int FileSysGetDrive (); // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! int FileSysSetDrive (unsigned Drive); // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! int FileSysExtractDrive (const String& Path); // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). void FileSysGetInfo (FileSysInfo& Info, int Drive = 0); // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. inline void FileSysGetInfo (FileSysInfo& Info, const String& Path) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { FileSysGetInfo (Info, FileSysExtractDrive (Path)); } int FileSysPreservesCase (int Drive = 0); // Return 1 if the file system on the given drive preserves the case in // filenames inline int FileSysPreservesCase (const String& Path) // Return 1 if the file system on the given drive preserves the case in // filenames { return FileSysPreservesCase (FileSysExtractDrive (Path)); } int FileSysIgnoresCase (int Drive = 0); // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). inline int FileSysIgnoresCase (const String& Path) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { return FileSysIgnoresCase (FileSysExtractDrive (Path)); } int FileSysValidChar (const char C); // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. int FileSysValidName (const String& Path); // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! #ifdef FILESYS_HAS_DRIVES String FileSysCurrentDir (int IncludeDrive = 1, int Drive = 0); #else String FileSysCurrentDir (int IncludeDrive = 0, int Drive = 0); #endif // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. // End of FILESYS.H #endif estic-1.61.orig/spunk/frame.cc0100644000176100001440000000323707031424700015553 0ustar debacleusers/*****************************************************************************/ /* */ /* FRAME.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // /*****************************************************************************/ /* Definition of the frame characters */ /*****************************************************************************/ // These are some predefined arrays with characters that are used in window // frames, horizontal lines and more // Codepage 850 (works also for CP 437) unsigned char CP850_InactiveFrame [12] = { 0xda, 0xbf, 0xc0, 0xd9, 0xc4, 0xb3, 0xc3, 0xb4, 0xc2, 0xc1, 0xc5, 0x00 // Ś æ Ą Ł Ä ³ Ć ´ Ā Į Å }; unsigned char CP850_ActiveFrame [12] = { 0xc9, 0xbb, 0xc8, 0xbc, 0xcd, 0xba, 0xcc, 0xb9, 0xcb, 0xca, 0xca, 0x00 }; // KOI-8r according to Michael A. Rodiono (marod@piglet.cnit.nsk.su) unsigned char KOI8r_InactiveFrame [12] = { 130, 131, 132, 133, 128, 129, 134, 135, 136, 137, 129, 0 }; unsigned char KOI8r_ActiveFrame [12] = { 165, 168, 171, 174, 000, 000, 177, 181, 184, 187, 190, 0 }; // No linedrawing support unsigned char SimpleFrame [12] = "++++-|+++++"; // This are the variables that are used to access the arrays above. They are // initialized to the CP 437 specific frame arrays unsigned char* InactiveFrame = CP850_InactiveFrame; unsigned char* ActiveFrame = CP850_ActiveFrame; estic-1.61.orig/spunk/fviewer.cc0100644000176100001440000002316107031424700016126 0ustar debacleusers/*****************************************************************************/ /* */ /* FVIEWER.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "streamid.h" #include "fviewer.h" #include "progutil.h" // Register the classes LINK (FileViewer, ID_FileViewer); /*****************************************************************************/ /* class FileViewer */ /*****************************************************************************/ FileViewer::FileViewer (const String& Name, const Rect& Bounds, u16 aState, u16 aPalette, u16 Number) : ItemWindow (Bounds, aState, aPalette, Number), F (new TextFileStream (Name)), FirstLine (0), MarkedLine (InvalidLine), HOffset (0), HDelta (10), HLimit (1000) { SetHeader (String (" ") + Name + ' '); Init (); } FileViewer::FileViewer (TextFileStream* S, const Rect& Bounds, u16 aState, u16 aPalette, u16 Number): ItemWindow (Bounds, aState, aPalette, Number), F (S), FirstLine (0), HOffset (0), HDelta (10), HLimit (1000) { Init (); } FileViewer::FileViewer (StreamableInit): ItemWindow (Empty) // Build constructor { } void FileViewer::Init () // Caled from the constructors { // Set the zoom size ZoomSize = OBounds; if (OBounds == Background->GetDesktop ()) { // We already have max size, choose a random smaller size ZoomSize.Grow (-3, -3); } // Draw the window contents DrawInterior (); } FileViewer::~FileViewer () { // Delete the text file stream delete F; } void FileViewer::Store (Stream& S) const // Store the object into a stream { // Call the derived function writing out the Window stuff ItemWindow::Store (S); // Write out the FileViewer stuff S << FirstLine << MarkedLine << HOffset << HDelta << HLimit << HelpKey << ZoomSize; // Write out the name of the displayed file S << F->GetName (); } void FileViewer::Load (Stream& S) // Load the object from a stream { // Call the derived function to load the Window stuff ItemWindow::Load (S); // Load the FileViewer stuff S >> FirstLine >> MarkedLine >> HOffset >> HDelta >> HLimit >> HelpKey >> ZoomSize; // Read the name of the displayed file String Name (Empty); S >> Name; // Reopen the file F = new TextFileStream (Name); // If the file is valid, validate FirstLine if (F->GetStatus () == stOk) { if (FirstLine + IYSize () > F->LineCount ()) { // File has changed, FirstLine is invalid FirstLine = 0; } } // If the file is valid, draw the window interior DrawInterior (); } u16 FileViewer::StreamableID () const // Return the stream ID of the object { return ID_FileViewer; } Streamable* FileViewer::Build () // Return a new, empty object { return new FileViewer (Empty); } void FileViewer::PgUp () { if (FirstLine != 0) { if (FirstLine > IYSize () - 1) { FirstLine -= IYSize () - 1; } else { FirstLine = 0; } DrawInterior (); } } void FileViewer::PgDn () { if (!AtEnd ()) { // Scroll window contents up FirstLine += IYSize () - 1; if (FirstLine > F->LineCount () - IYSize ()) { FirstLine = F->LineCount () - IYSize (); } DrawInterior (); } } void FileViewer::Down () { if (!AtEnd ()) { // Don't do screen output Lock (); // Scroll window contents up FirstLine++; ScrollUp (); // Seek to the current starting line in the stream F->LineSeek (FirstLine + MaxY ()); // Display line at the bottom of the window DrawLine (MaxY ()); // Update the screen Unlock (); } } void FileViewer::Up () { if (!AtStart ()) { // Don't do screen output Lock (); // Scroll window contents down FirstLine--; ScrollDown (); // Seek to the current starting line in the stream F->LineSeek (FirstLine); // Display line at the top of the window DrawLine (0); // Update the screen Unlock (); } } void FileViewer::Left () { if (HOffset > 0) { if (HOffset > HDelta) { HOffset -= HDelta; } else { HOffset = 0; } DrawInterior (); } } void FileViewer::Right () { if (HOffset < HLimit) { if ((HOffset += HDelta) > HLimit) { HOffset = HLimit; } DrawInterior (); } } void FileViewer::ToTop () { if (FirstLine != 0) { FirstLine = 0; DrawInterior (); } } void FileViewer::Home () { if (HOffset != 0 || FirstLine != 0) { HOffset = 0; FirstLine = 0; DrawInterior (); } } void FileViewer::ToBot () { if (!AtEnd ()) { FirstLine = F->LineCount () - IYSize (); DrawInterior (); } } void FileViewer::End () { if (HOffset != 0 || (!AtEnd ())) { FirstLine = F->LineCount () - IYSize (); HOffset = 0; DrawInterior (); } } void FileViewer::CenterLine (unsigned Line) // Center the given line in the viewer (if possible) { // Set the first line according to the given line if (Line < IYSize () / 2) { FirstLine = 0; } else { FirstLine = Line - IYSize () / 2; } DrawInterior (); } void FileViewer::CenterAndMarkLine (unsigned Line) // Center (if possible) and mark the given line { MarkedLine = Line; CenterLine (Line); } int FileViewer::LineIsVisible (unsigned Line) // Returns 1 if the given line is visible in the window, 0 otherwise { return (Line >= FirstLine && Line <= FirstLine + IYSize ()); } void FileViewer::ShowLine (unsigned Line) // Show the line in the window if it is not already visible { if (!LineIsVisible (Line)) { CenterLine (Line); } } void FileViewer::HandleKey (Key& K) { switch (K) { case vkUp: Up (); K = kbNoKey; break; case vkDown: Down (); K = kbNoKey; break; case vkLeft: Left (); K = kbNoKey; break; case vkRight: Right (); K = kbNoKey; break; case vkPgUp: PgUp (); K = kbNoKey; break; case vkPgDn: PgDn (); K = kbNoKey; break; case vkEnd: End (); K = kbNoKey; break; case vkCtrlPgDn: ToBot (); K = kbNoKey; break; case vkHome: Home (); K = kbNoKey; break; case vkCtrlPgUp: ToTop (); K = kbNoKey; break; default: ItemWindow::HandleKey (K); break; } } void FileViewer::DrawLine (int Y, int Single) // Draw one line at position Y. The line is read from the current position in // the file { unsigned XSize = IBounds.XSize (); // Read the line from the file String Line = F->GetLine ().Cut (HOffset, XSize); // Convert the line to the internally used character set Line.InputCvt (); // Determine the line attribute int Attr; if (MarkedLine != InvalidLine && Y == (int) (MarkedLine - FirstLine)) { // Marked line, use invers attribute, write complete line Attr = atTextInvers; Single = 1; } else { // Some other line Attr = atTextNormal; } // Pad the line to the window width if needed if (Single) { // Only one line, no ClrScr(), pad to line length Line.Pad (String::Right, XSize); } // Draw the line Write (0, Y, Line, Attr); } void FileViewer::DrawInterior () // Redraw the window interior { // Lock screen output Lock (); // Clear the screen Clear (); // Check the file status, don't do anything if the status is not ok if (F->GetStatus () == stOk) { // Seek to the current starting line in the stream F->LineSeek (FirstLine); // Now display all lines in the window u32 Cur = FirstLine; int LinesToDisplay = (int) (F->LineCount () - Cur); if (LinesToDisplay > (int) IYSize ()) { LinesToDisplay = IYSize (); } for (int Y = 0; Y < LinesToDisplay; Y++) { // Draw the line DrawLine (Y, 0); } } // Unlock the window, allow output Unlock (); } u32 FileViewer::GetStatusFlags () // Returns the flags that are used to build the status line in Browse { u32 Flags = ItemWindow::GetStatusFlags () | siCursPgKeys_Move; if (HasHelp ()) { Flags |= siHelp; } return Flags; } void FileViewer::Zoom () // Zoom the window { // Get the desktop bounds Rect Desktop = Background->GetDesktop (); // Check if we must zoom in or out if (OBounds != Desktop) { // Remember the old size, then zoom out ZoomSize = OBounds; Resize (Desktop); } else { // Zoom in Resize (ZoomSize); } } estic-1.61.orig/spunk/fviewer.h0100644000176100001440000001171707031424700015774 0ustar debacleusers/*****************************************************************************/ /* */ /* FVIEWER.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __FVIEWER_H #define __FVIEWER_H #include "textstrm.h" #include "keydef.h" #include "itemwin.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ const u32 InvalidLine = 0xFFFFFFFF; // An invalid line /*****************************************************************************/ /* class FileViewer */ /*****************************************************************************/ class FileViewer: public ItemWindow { private: virtual void DrawLine (int Y, int Single = 1); // Draw one line at position Y. The line is read from the current // position in the file int AtStart (); // Return true if the first displayed line is at start of file int AtEnd (); // Return true if the last displayed line is at the end of the file void Init (); // Called from the constructors protected: TextFileStream* F; // u32 FirstLine; // First line in window u32 MarkedLine; // Marked line in window i16 HOffset; // horizontal line offset i16 HDelta; // Amount of chars to skip horizontal i16 HLimit; // Limit for HOffset String HelpKey; // help keyword Rect ZoomSize; // Small size for zooming virtual u32 GetStatusFlags (); // Returns the flags that are used to build the status line in Browse public: FileViewer (const String& Name, const Rect& Bounds, u16 aState = wfFramed, u16 aPalette = paGray, u16 Number = 0); FileViewer (TextFileStream* S, const Rect& Bounds, u16 aState = wfFramed, u16 aPalette = paGray, u16 Number = 0); FileViewer (StreamableInit); // Build constructor virtual ~FileViewer (); // Destroy a fileviewer virtual void Store (Stream&) const; // Store the object into a stream virtual void Load (Stream&); // Load the object from a stream virtual u16 StreamableID () const; // Return the stream ID of the object static Streamable* Build (); // Return a new, empty object virtual void DrawInterior (); // Redraw the window interior void SetHelpKey (const String& NewKey); // Set the help keyword const String& GetHelpKey () const; // Return the current help keyword int HasHelp () const; // Return true if the viewer has a valid help key // Key handling functions (they are public, because it can be useful // to call for example End () before browsing) virtual void PgUp (); virtual void PgDn (); virtual void Down (); virtual void Up (); virtual void Left (); virtual void Right (); virtual void Home (); virtual void End (); virtual void ToTop (); virtual void ToBot (); virtual void CenterLine (unsigned Line); // Center the given line in the viewer (if possible) void CenterAndMarkLine (unsigned Line); // Center (if possible) and mark the given line void ShowLine (unsigned Line); // Show the line in the window if it is not already visible virtual int LineIsVisible (unsigned Line); // Returns 1 if the given line is visible in the window, 0 otherwise virtual void HandleKey (Key& K); // Key dispatcher used in Browse int GetStatus () const; // Get the status of the used stream int GetErrorInfo () const; // Get the error info of the used stream const String& GetName () const; // Get the file name of the text file virtual void Zoom (); // Zoom the window }; inline int FileViewer::AtStart () // Return true if the first displayed line is at start of file { return (FirstLine == 0); } inline int FileViewer::AtEnd () // Return true if the last displayed line is at the end of the file { return (FirstLine + IYSize () >= F->LineCount ()); } inline int FileViewer::GetStatus () const // Get the status of the used stream { return F->GetStatus (); } inline int FileViewer::GetErrorInfo () const // Get the error info of the used stream { return F->GetErrorInfo (); } inline const String& FileViewer::GetName () const // Get the file name of the text file { return F->GetName (); } inline void FileViewer::SetHelpKey (const String& NewKey) // Set the help keyword { HelpKey = NewKey; } inline const String& FileViewer::GetHelpKey () const // Return the current help keyword { return HelpKey; } inline int FileViewer::HasHelp () const // Return true if the viewer has a valid help key { return HelpKey.Len () > 0; } // End of FVIEWER.H #endif estic-1.61.orig/spunk/header.blk0100644000176100001440000000066607031424700016077 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // estic-1.61.orig/spunk/inifile.cc0100644000176100001440000003723107031424700016101 0ustar debacleusers/*****************************************************************************/ /* */ /* INIFILE.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "inifile.h" #include "msgid.h" #include "strparse.h" #include "progutil.h" #include "coll.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msKeyNotFound = MSGBASE_INIFILE + 0; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class SectionOfs */ /*****************************************************************************/ class SectionOfs: public Object { friend class SectionColl; private: String Section; // Name of the section u32 Line; // Line after section header public: SectionOfs (const String& SectionName, u32 LineNum); }; SectionOfs::SectionOfs (const String& SectionName, u32 LineNum): Section (SectionName), Line (LineNum) { } /*****************************************************************************/ /* class SectionColl */ /*****************************************************************************/ class SectionColl: public SortedCollection { protected: // Derived from class SortedCollection virtual int Compare (const String* Key1, const String* Key2); virtual const String* KeyOf (const SectionOfs* Item); public: SectionColl (); i32 GetSection (const String& SectionName); // Search for the section, return -1 if not found, Line otherwise }; SectionColl::SectionColl (): SortedCollection (50, 10) { ShouldDelete = 1; } int SectionColl::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } const String* SectionColl::KeyOf (const SectionOfs* Item) { return &Item->Section; } i32 SectionColl::GetSection (const String& SectionName) // Search for the section, return -1 if not found, Line otherwise { int Index; if (Search (&SectionName, Index) == 0) { // Not found return -1; } else { return At (Index)->Line; } } /*****************************************************************************/ /* class IniFile */ /*****************************************************************************/ IniFile::IniFile (const String& Name, int InputTranslate): S (new TextFileStream (Name)), Filename (Name), Sections (new SectionColl), Translate (InputTranslate) // Open the stream in read-only mode. A non existant file is considered // an error. { SetupIndex (); } IniFile::~IniFile () // Delete the TextFileStream { delete Sections; delete S; } void IniFile::SetupIndex () // Fill all sections into the index collection. { // Seek to the start of the file S->LineSeek (0); // search for the section start points u32 LineNum = 0; while (LineNum < S->LineCount ()) { // Read the next line String Line = S->GetLine (); LineNum++; // Skip empty lines and lines, not beginning with '[' if (Line.IsEmpty () || Line [0] != '[') { continue; } // Ok, a line with a section name is found, delete the '[' Line.Del (0, 1); // Search for the end marker int Pos = Line.Pos (']'); if (Pos == -1) { // Ill-formed line, skip it continue; } // Ok, we have a valid entry. Extract the section name and uppercase it Line.Trunc (Pos); Line.ToUpper (); // Insert the section together with the starting line into the line coll Sections->Insert (new SectionOfs (Line, LineNum)); } } void IniFile::DelComment (String& S) // Delete a trailing comment from the string S { int Pos = S.Pos (';'); if (Pos != -1) { S.Del (Pos, S.Len () - Pos); } } i32 IniFile::FindSection (String Section) // Seek to the line after the section header. Return the current line number // or -1 if the section was not found { // Search for the section entry in the index i32 LineNum = Sections->GetSection (Section.ToUpper ()); if (LineNum >= 0) { // Found the section, seek to the position S->LineSeek (LineNum); } return LineNum; } String IniFile::FindKey (String Key, u32 CurLine) // Find the line with the given key. The search ends when end of file is // reached or when a new section begins. The complete line containing // the key is returned, or, if the key is not found, an empty string. { // The search is not case sensitive Key.ToUpper (); // Search for the key while (CurLine < S->LineCount ()) { // Read a line String Line (S->GetLine ()); CurLine++; // If the Line is empty or has a comment leader, skip it if (Line.IsEmpty () || Line [0] == ';') { continue; } // If the line is a section marker, end the search if (Line [0] == '[') { break; } // Otherwise extract the Key part of the line int Pos = Line.Pos ('='); if (Pos == -1) { // Ill formed line, skip it continue; } // Extract the first part of the line, uppercase it and delete blanks String KeyPart (Line.Cut (0, Pos)); Pos--; while (Pos >= 0 && Line [Pos] == ' ') { Pos--; } KeyPart.Trunc (Pos+1); KeyPart.ToUpper (); // Now check if the keys match if (KeyPart == Key) { // Found it return Line; } } // Key not found return String (""); } void IniFile::Fail (const String& Section, const String& Key) // Called from GetString/GetInt when the section/key is not found. Ends // the program via FAIL { FAIL (FormatStr (LoadMsg (msKeyNotFound).GetStr (), Filename.GetStr (), Section.GetStr (), Key.GetStr ()).GetStr ()); } int IniFile::KeyExists (const String& Section, const String& Key) // returns 1 if the given key exists, 0 otherwise { // Search for the section i32 CurLine = FindSection (Section); if (CurLine == -1) { // Section not found return 0; } return (!FindKey (Key, CurLine).IsEmpty ()); } int IniFile::KeyExists (const char* Section, const char* Key) // returns 1 if the given key exists, 0 otherwise { return KeyExists (String (Section), String (Key)); } String IniFile::ReadLine (const String& Section, const String& Key) // return the Line or an empty string if the section/key does not exist { // Search for the section i32 CurLine = FindSection (Section); if (CurLine == -1) { // Section not found return ""; } // Now search for the key String Line (FindKey (Key, CurLine)); if (Line.IsEmpty ()) { // Key not found return ""; } // Extract the data part and return it int Pos = Line.Pos ('='); Line.Del (0, Pos+1); return Line; } i32 IniFile::ReadInt (const String& Section, const String& Key, i32 Default) // return the int or Default if the section/key doesn't exist { // Read the line String S (ReadLine (Section, Key)); if (S.IsEmpty ()) { // Key not found return Default; } // Allow comments DelComment (S); // Convert the value StringParser P (S); P.SetFlags (StringParser::SkipWS | StringParser::PascalHex | StringParser::CHex); i32 Val; if (P.GetI32 (Val) != 0) { // Parsing error, return default return Default; } else { // Ok, return the value return Val; } } i32 IniFile::ReadInt (const char* Section, const char* Key, i32 Default) // return the int or Default if the section/key doesn't exist { return ReadInt (String (Section), String (Key), Default); } double IniFile::ReadFloat (const String& Section, const String& Key, double Default) // Return a double or default if section/key doesn't exist { // Read the key as a string String S (ReadLine (Section, Key)); if (S.IsEmpty ()) { // Key not found return Default; } // Allow comments DelComment (S); StringParser P (S, StringParser::SkipWS | StringParser::AllowDP); double Val; if (P.GetFloat (Val) != 0) { // Parsing error, return default return Default; } else { // Ok, return the value return Val; } } double IniFile::ReadFloat (const char* Section, const char* Key, double Default) // Return a double or default if section/key doesn't exist { return ReadFloat (String (Section), String (Key), Default); } String IniFile::ReadString (const String& Section, const String& Key, const String& Default) // return the String or default if the section/key does not exist { // Read the data part of the line String Line = ReadLine (Section, Key); if (Line.IsEmpty ()) { // Key not found or empty return Default; } // Extract the string int Pos = Line.ScanR ('"'); if (Pos == -1) { return ""; } Line.Del (0, Pos+1); Pos = Line.ScanL ('"'); if (Pos == -1) { return ""; } Line.Trunc (Pos); // If Translate is set, translate the string from the external into the // internal representation if (Translate) { Line.InputCvt (); } // Return the string return Line; } String IniFile::ReadString (const char* Section, const char* Key, const String& Default) // return the String or default if the section/key does not exist { return ReadString (String (Section), String (Key), Default); } i32 IniFile::ReadKeyword (const String& Section, const String& Key, const String& Keywords) // Read a key value from the file and match it against a list of keywords // using MatchKeyword from module string. The number associated with the // matched keyword, or the default is returned. Beware: Case is ignored! { // Read the line String S = ReadLine (Section, Key); // Allow comments DelComment (S); // Delete whitespace from the value S.Remove (WhiteSpace, rmLeading | rmTrailing); // Convert the value return MatchKeyword (S.ToUpper (), Keywords); } i32 IniFile::ReadKeyword (const char* Section, const char* Key, const String& Keywords) // Read a key value from the file and match it against a list of keywords // using MatchKeyword from module string. The number associated with the // matched keyword, or the default is returned. Beware: Case is ignored! { return ReadKeyword (String (Section), String (Key), Keywords); } int IniFile::ReadBool (const String& Section, const String& Key, int Default) // Return a boolean or default if the section/key does not exist { if (Default) { return ReadKeyword (Section, Key, "1^YES|0^NO|1^ON|0^OFF|1^1|0^0|"); } else { return ReadKeyword (Section, Key, "0^NO|1^YES|0^OFF|1^ON|0^0|1^1|"); } } int IniFile::ReadBool (const char* Section, const char* Key, int Default) // Return a boolean or default if the section/key does not exist { return ReadBool (String (Section), String (Key), Default); } String IniFile::GetLine (const String& Section, const String& Key) // Same as ReadLine, but the Section/Key must exist. If it does not, // the program is aborted via Fail { // Search for the section i32 CurLine = FindSection (Section); if (CurLine == -1) { // Section not found Fail (Section, Key); } // Now search for the key String Line (FindKey (Key, CurLine)); if (Line.IsEmpty ()) { // Key not found Fail (Section, Key); } // Extract data part and return it int Pos = Line.Pos ('='); Line.Del (0, Pos+1); return Line; } i32 IniFile::GetInt (const String& Section, const String& Key) // Same as ReadInt, but the Section/Key must exist. If it does not, // the program is aborted via Fail { // Read the key as a string String S (GetLine (Section, Key)); if (S.IsEmpty ()) { // Key not found Fail (Section, Key); } // Allow comments DelComment (S); // Convert the value StringParser P (S); P.SetFlags (StringParser::SkipWS | StringParser::PascalHex | StringParser::CHex); i32 Val; if (P.GetI32 (Val) != 0) { // Parsing error, abort program Fail (Section, Key); } // Ok, return the value return Val; } i32 IniFile::GetInt (const char* Section, const char* Key) // Same as ReadInt, but the Section/Key must exist. If it does not, // the program is aborted via Fail { return GetInt (String (Section), String (Key)); } double IniFile::GetFloat (const String& Section, const String& Key) // Same as ReadFloat, but the Section/Key must exist. If it does not, // the program is aborted via FAIL { // Read the key as a string String S (GetLine (Section, Key)); if (S.IsEmpty ()) { // Key not found Fail (Section, Key); } // Allow comments DelComment (S); StringParser P (S, StringParser::SkipWS | StringParser::AllowDP); double Val; if (P.GetFloat (Val) != 0) { // Parsing error, abort program Fail (Section, Key); } // Ok, return the value return Val; } double IniFile::GetFloat (const char* Section, const char* Key) // Same as ReadFloat, but the Section/Key must exist. If it does not, // the program is aborted via FAIL { return GetFloat (String (Section), String (Key)); } String IniFile::GetString (const String& Section, const String& Key) // Same as ReadString, but the Section/Key must exist. If it does not, // the program is aborted via Fail { // Now search for the key String Line = GetLine (Section, Key); if (Line.IsEmpty ()) { // Key not found Fail (Section, Key); } // Extract the string and return it int Pos = Line.ScanR ('"'); if (Pos == -1) { Fail (Section, Key); } Line.Del (0, Pos+1); Pos = Line.ScanL ('"'); if (Pos == -1) { Fail (Section, Key); } Line.Trunc (Pos); // If Translate is set, translate the string from the external into the // internal representation if (Translate) { Line.InputCvt (); } // Return the result return Line; } String IniFile::GetString (const char* Section, const char* Key) // Same as ReadString, but the Section/Key must exist. If it does not, // the program is aborted via Fail { return GetString (String (Section), String (Key)); } i32 IniFile::GetKeyword (const String& Section, const String& Key, const String& Keywords) { // Read the line String S = ReadLine (Section, Key); if (S.IsEmpty ()) { // Key not found Fail (Section, Key); } // Allow comments DelComment (S); // Delete whitespace from the value S.Remove (WhiteSpace, rmLeading | rmTrailing); // Convert the value return MatchKeyword (S.ToUpper (), Keywords); } i32 IniFile::GetKeyword (const char* Section, const char* Key, const String& Keywords) // Same as ReadKeyword, but the Section/Key must exist. If it does not, // the program is aborted via FAIL { return GetKeyword (String (Section), String (Key), Keywords); } int IniFile::GetBool (const String& Section, const String& Key, int Default) // Same as ReadBool, but the Section/Key must exist. If it does not, // the program is aborted via FAIL { if (Default) { return GetKeyword (Section, Key, "1^YES|0^NO|1^ON|0^OFF|1^1|0^0|"); } else { return GetKeyword (Section, Key, "0^NO|1^YES|0^OFF|1^ON|0^0|1^1|"); } } int IniFile::GetBool (const char* Section, const char* Key, int Default) // Same as ReadBool, but the Section/Key must exist. If it does not, // the program is aborted via FAIL { return GetBool (String (Section), String (Key), Default); } estic-1.61.orig/spunk/inifile.h0100644000176100001440000001274107031424701015743 0ustar debacleusers/*****************************************************************************/ /* */ /* INIFILE.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __INIFILE_H #define __INIFILE_H #include "textstrm.h" /*****************************************************************************/ /* class IniFile */ /*****************************************************************************/ // Forward to an implementation class class SectionColl; class IniFile: public Object { protected: TextFileStream* S; String Filename; // Name of the ini file class SectionColl* Sections; // Collection with section offsets int Translate; // Translate input strings if true void SetupIndex (); // Fill all sections into the index collection. void DelComment (String& S); // Delete a trailing comment from the string S i32 FindSection (String Section); // Seek to the line after the section header. Return the current line number // or -1 if the section was not found String FindKey (String Key, u32 CurLine); // Find the line with the given key. The search ends when end of file is // reached or when a new section begins. The complete line containing // the key is returned, or, if the key is not found, an empty string. String ReadLine (const String& Section, const String& Key); // return the Line or an empty string if the section/key does not exist String GetLine (const String& Section, const String& Key); // Same as ReadLine, but the Section/Key must exist. If it does not, // the program is aborted via Fail void Fail (const String& Section, const String& Key); // Called from GetString/GetInt when the section/key is not found. Ends // the program via FAIL public: IniFile (const String& Name, int InputTranslate = 1); // Open the stream in read-only mode. A non existant file is considered // as an error. If InputTranslate is set to 1, read strings(!) are // translated from the external to the internal used character set. virtual ~IniFile (); // Delete the TextFileStream int KeyExists (const String& Section, const String& Key); int KeyExists (const char* Section, const char* Key); // returns 1 if the given key exists, 0 otherwise i32 ReadInt (const String& Section, const String& Key, i32 Default); i32 ReadInt (const char* Section, const char* Key, i32 Default); // return the int or Default if the section/key doesn't exist double ReadFloat (const String& Section, const String& Key, double Default); double ReadFloat (const char* Section, const char* Key, double Default); // Return a double or default if section/key doesn't exist String ReadString (const String& Section, const String& Key, const String& Default); String ReadString (const char* Section, const char* Key, const String& Default); // return the String or default if the section/key does not exist i32 ReadKeyword (const String& Section, const String& Key, const String& Keywords); i32 ReadKeyword (const char* Section, const char* Key, const String& Keywords); // Read a key value from the file and match it against a list of keywords // using MatchKeyword from module string. The number associated with the // matched keyword, or the default is returned. Beware: Case is ignored! int ReadBool (const String& Section, const String& Key, int Default); int ReadBool (const char* Section, const char* Key, int Default); // Return a boolean or default if the section/key does not exist i32 GetInt (const String& Section, const String& Key); i32 GetInt (const char* Section, const char* Key); // Same as ReadInt, but the Section/Key must exist. If it does not, // the program is aborted via FAIL double GetFloat (const String& Section, const String& Key); double GetFloat (const char* Section, const char* Key); // Same as ReadFloat, but the Section/Key must exist. If it does not, // the program is aborted via FAIL String GetString (const String& Section, const String& Key); String GetString (const char* Section, const char* Key); // Same as ReadString, but the Section/Key must exist. If it does not, // the program is aborted via FAIL i32 GetKeyword (const String& Section, const String& Key, const String& Keywords); i32 GetKeyword (const char* Section, const char* Key, const String& Keywords); // Same as ReadKeyword, but the Section/Key must exist. If it does not, // the program is aborted via FAIL. Note: The function will not detect if // section and key are valid but the key value is not. int GetBool (const String& Section, const String& Key, int Default); int GetBool (const char* Section, const char* Key, int Default); // Same as ReadBool, but the Section/Key must exist. If it does not, // the program is aborted via FAIL int GetStatus () const; // Get the stream status int GetErrorInfo () const; // Get the stream error info }; inline int IniFile::GetStatus () const // Get the stream status { return S->GetStatus (); } inline int IniFile::GetErrorInfo () const // Get the stream error info { return S->GetErrorInfo (); } // End of INIFILE.H #endif estic-1.61.orig/spunk/itemlbl.cc0100644000176100001440000000602407031424701016107 0ustar debacleusers/*****************************************************************************/ /* */ /* ITEMLBL.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Class ItemLabel is a special window item that acts as a label for another // window item. #include "streamid.h" #include "itemlbl.h" // Register class ItemLabel LINK (ItemLabel, ID_ItemLabel); /*****************************************************************************/ /* class ItemLabel */ /*****************************************************************************/ ItemLabel::ItemLabel (const String& aItemText, i16 aID, i16 aCtrlID, WindowItem* NextItem): WindowItem (aItemText, aID, NextItem), CtrlID (aCtrlID) { } void ItemLabel::Store (Stream& S) const { WindowItem::Store (S); S << CtrlID; } void ItemLabel::Load (Stream& S) { WindowItem::Load (S); S >> CtrlID; } u16 ItemLabel::StreamableID () const { return ID_ItemLabel; } Streamable* ItemLabel::Build () { return new ItemLabel (Empty); } WindowItem* ItemLabel::GetCtrlItem () // Return a pointer to the controlled item or NULL { if (CtrlID != 0) { return GetRootWindow () -> ItemWithID (CtrlID); } else { return NULL; } } void ItemLabel::Gray () { // Gray the label WindowItem::Gray (); // If there is a valid controlled item, gray that one, too WindowItem* Item = GetCtrlItem (); if (Item) { Item->Gray (); } } void ItemLabel::Select () { // Select the label WindowItem::Select (); // If there is a valid controlled item, select that one, too WindowItem* Item = GetCtrlItem (); if (Item) { Item->Select (); } } void ItemLabel::Deselect () { // Deselect the label WindowItem::Deselect (); // If there is a valid controlled item, deselect that one, too WindowItem* Item = GetCtrlItem (); if (Item) { Item->Deselect (); } } i16 ItemLabel::Choose () // Choose an entry { // Item must be active PRECONDITION (IsActive ()); // Use the controlled item WindowItem* Item = GetCtrlItem (); if (Item) { Item->Activate (); CtrlChoice = Item->Choose (); Item->Deactivate (); return CtrlChoice ? ID : 0; } else { CtrlChoice = 0; return ID; } } estic-1.61.orig/spunk/make/0040755000176100001440000000000007061535304015073 5ustar debacleusersestic-1.61.orig/spunk/make/borland.mak0100644000176100001440000001726707031424714017217 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for Borland-C (DOS & OS/2) * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Zwehrenbuehlstrasse 33 * # * D-72070 Tuebingen * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # BEWARE: This makefile is no longer up to date!!! # ------------------------------------------------------------------------------ # Generelle Einstellungen .AUTODEPEND .SUFFIXES .ASM .C .CC .CPP .SWAP # ------------------------------------------------------------------------------ # Allgemeine Definitionen # Names of executables CC = BCC AS = TASM AR = TLIB LD = TLINK !if $d(__OS2__) ZIP = zip !else ZIP = pkzip !endif !if !$d(TARGET) !if $d(__OS2__) TARGET = OS2 !else TARGET = DOS !endif !endif !if !$d(LIBDIR) LIBDIR = $(TARGET) !endif LIB = $(TARGET)\spunk.lib .PRECIOUS $(LIB) !if $d(INCDIR) INCDIR = . !endif !if !$d(CCCFG) CCCFG = BCC$(TARGET).CFG !endif # ------------------------------------------------------------------------------ # Implicit rules .c.obj: $(CC) +$(CCCFG) -I$(INCDIR) -n$(TARGET) -c {$< } .cc.obj: $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c {$< } .asm.obj: $(AS) -Mx $*.asm,$*.obj .path.obj = $(TARGET) # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.obj \ charset.obj \ charstrm.obj \ chartype.obj \ check.obj \ coll.obj \ cont.obj \ cpucvt.obj \ crc16.obj \ crc32.obj \ crcccitt.obj \ crcstrm.obj \ datetime.obj \ environ.obj \ errlog.obj \ event.obj \ filecoll.obj \ filepath.obj \ filesel.obj \ filesys.obj \ frame.obj \ fviewer.obj \ inifile.obj \ itemlbl.obj \ itemwin.obj \ kbd.obj \ keydef.obj \ keymap.obj \ listnode.obj \ memstrm.obj \ menue.obj \ menuedit.obj \ menuitem.obj \ msg.obj \ msgcoll.obj \ national.obj \ nlsinit.obj \ nullstrm.obj \ object.obj \ palette.obj \ password.obj \ program.obj \ progutil.obj \ rect.obj \ rescoll.obj \ resource.obj \ rng.obj \ screen.obj \ sercom.obj \ serstrm.obj \ splitmsg.obj \ statline.obj \ stdmenue.obj \ stdmsg.obj \ str.obj \ strbox.obj \ strcoll.obj \ strcvt.obj \ stream.obj \ strmable.obj \ strparse.obj \ strpool.obj \ syserror.obj \ textstrm.obj \ thread.obj \ winattr.obj \ window.obj \ winmgr.obj \ winsize.obj # # Additional target specific modules # !if $(TARGET)==DOS XOBJS = _sercom.obj !endif .PRECIOUS $(OBJS:.obj=.cc) $(XOBJS:.obj=.asm) $(LIB) # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.obj \ resedit.obj \ resfile.obj \ resitem.obj \ resprint.obj \ resutil.obj \ reswin.obj # ------------------------------------------------------------------------------ # Make the needed directories libdir: @- if not exist $(LIBDIR) mkdir $(LIBDIR) # ------------------------------------------------------------------------------ # Resource editor $(TARGET)\resed.exe: $(LIB) $(RESEDITOBJS) $(CC) +$(CCCFG) -l-yx -eresed.exe @&&| $(TARGET)\resed.obj $(TARGET)\resedit.obj $(TARGET)\resfile.obj $(TARGET)\resitem.obj $(TARGET)\resprint.obj $(TARGET)\resutil.obj $(TARGET)\reswin.obj $(LIB) | # ------------------------------------------------------------------------------ # File-Transfer program filetran: $(TARGET)\filetran.exe $(TARGET)\filetran.exe: lib filetran.obj $(CC) +$(CCCFG) -l-yx -efiletran.exe @&&| $(TARGET)\filetran.obj $(LIB) | # ------------------------------------------------------------------------------ # Library lib: $(LIB) !if $(TARGET)==OS2 $(LIB): $(OBJS) $(XOBJS) @echo Creating librarian job file -@if exist lib.job del /Q lib.job &@echo +-$? ^& >> lib.job @echo *dummy >> lib.job $(AR) /P64 $(LIB) @lib.job -@del /Q lib.job !else $(LIB): $(OBJS) $(XOBJS) @echo Creating librarian job file -@if exist lib.job del /Q lib.job &@echo +-$? & >> lib.job @echo *dummy >> lib.job $(AR) /P64 $(LIB) @lib.job -@del /Q lib.job !endif # ------------------------------------------------------------------------------ # OS specific modules filesys.obj: $(TARGET)SRC\filesys.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** kbd.obj: $(TARGET)SRC\kbd.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** nlsinit.obj: $(TARGET)SRC\nlsinit.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** screen.obj: $(TARGET)SRC\screen.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** sercom.obj: $(TARGET)SRC\sercom.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** _sercom.obj: $(TARGET)SRC\_sercom.asm $(AS) -m3 -mx $** @$(MV) $. $(TARGET) user.obj: $(TARGET)SRC\user.cc $(CC) +$(CCCFG) -P -I$(INCDIR) -n$(TARGET) -c $** # ------------------------------------------------------------------------------ # create a ZIP file zip: -del spunk.zip -del /S *.bak $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -copy makefile make\borland.mak $(ZIP) $(ZIPFILE) copying.txt spunk.chg make\*.* $(ZIP) $(ZIPFILE) dossrc\*.cc dossrc\*.asm $(ZIP) $(ZIPFILE) dos32src\*.cc dos32src\*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc\*.cc os2src\*.cc bsdsrc\*.cc unixsrc\*.cc $(ZIP) $(ZIPFILE) xsrc\*.cc samples\*.* $(ZIP) $(ZIPFILE) doc\*.doc support\*.* data\*.* # ------------------------------------------------------------------------------ # clean up clean: -del $(TARGET)\*.bak $(TARGET)SRC\*.bak *.bak zap: clean -del $(TARGET)\*.obj estic-1.61.orig/spunk/make/djgpp.mak0100644000176100001440000001156407031424714016674 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for DJGPP and GNU make * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Zwehrenbuehlstrasse 33 * # * D-72070 Tuebingen * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = pkzip CC = gcc # Flags for the gnu compiler (use the second one for gcc >= 2.6.0) #CFLAGS = -DDOS32 -I. -g -O2 -Wall -x c++ CFLAGS = -DDOS32 -I. -g -O2 -Wall -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ kbd.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All SPUNK header files HDRS = bitset.h \ statdef.h \ charset.h \ chartype.h \ check.h \ circbuf.h \ coll.h \ cont.h \ crc.h \ crcstrm.h \ datetime.h \ errlog.h \ event.h \ filecoll.h \ filepath.h \ filesel.h \ filesys.h \ fviewer.h \ inifile.h \ itemwin.h \ kbd.h \ keydef.h \ keymap.h \ listbox.h \ listnode.h \ machine.h \ mempool.h \ memstrm.h \ menue.h \ menuedit.h \ menuitem.h \ msg.h \ msgcoll.h \ msgid.h \ national.h \ nullstrm.h \ object.h \ palette.h \ password.h \ program.h \ progutil.h \ rect.h \ rescoll.h \ resed.h \ resource.h \ screen.h \ sercom.h \ settings.h \ splitmsg.h \ stack.h \ statline.h \ stdmenue.h \ stdmsg.h \ str.h \ strcoll.h \ strcvt.h \ stream.h \ streamid.h \ strmable.h \ strparse.h \ strpool.h \ textstrm.h \ thread.h \ winattr.h \ window.h \ winflags.h \ winmgr.h \ winsize.h # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets resed: $(LIB) $(RESEDITOBJS) $(HDRS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -lg -lgpp -lpc lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) rs $(LIB) $? depend dep: @echo "Creating dependency information" $(CC) -DDOS32 -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files delay.o: dossrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c dossrc/delay.cc filesys.o: dossrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c dossrc/filesys.cc kbd.o: dossrc/kbd.cc $(HDRS) $(CC) $(CFLAGS) -c dossrc/kbd.cc nlsinit.o: djgppsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c djgppsrc/nlsinit.cc screen.o: dossrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c dossrc/screen.cc # ------------------------------------------------------------------------------ # Create a ZIP file zip: -del spunk.zip -del /S *.bak $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -copy makefile make\djgpp.mak $(ZIP) $(ZIPFILE) copying.txt spunk.chg make\*.* $(ZIP) $(ZIPFILE) dossrc\*.cc dossrc\*.asm $(ZIP) $(ZIPFILE) dos32src\*.cc dos32src\*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc\*.cc os2src\*.cc bsdsrc\*.cc unixsrc\*.cc $(ZIP) $(ZIPFILE) xsrc\*.cc samples\*.* $(ZIP) $(ZIPFILE) doc\*.doc support\*.* data\*.* # ------------------------------------------------------------------------------ # clean up clean: -del /S *.bak zap: clean -del *.o estic-1.61.orig/spunk/make/freebsd-x.mak0100644000176100001440000000763307031424714017451 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for the X Window System under FreeBSD using g++ * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DFREEBSD -DUSE_OLD_TTY -g -Wall -x c++ -I /usr/X11R6/include -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ console.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets xresed: $(LIB) $(RESEDITOBJS) $(CC) -g -o xresed $(RESEDITOBJS) $(LIB) -lg++ -L/usr/X11R6/lib -lX11 lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? ranlib $(LIB) depend dep: @echo "Creating dependency information" $(CC) -DFREEBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files console.o: xsrc/console.cc $(HDRS) $(CC) $(CFLAGS) -c $< delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: xsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: unixsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/freebsd-x.mak $(ZIP) $(ZIPFILE) copying.txt todo.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/freebsd.mak0100644000176100001440000000764607031424714017210 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for FreeBSD using g++ * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DFREEBSD -DUSE_OLD_TTY -g -Wall -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ kbd.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ screen2.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets resed: $(LIB) $(RESEDITOBJS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -ltermcap -lg++ lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? ranlib $(LIB) depend dep: @echo "Creating dependency information" $(CC) -DFREEBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< kbd.o: bsdsrc/kbd.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: bsdsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen2.o: unixsrc/screen2.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: unixsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/freebsd.mak $(ZIP) $(ZIPFILE) copying.txt todo.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/generic.mak0100644000176100001440000001216107031424714017176 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for a generic Unix system * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # This a generic unix makefile. "generic" does not mean that there's nothing # to change. # This makefile has no rule for the sercom module, since this module needs # changes on probably every architecture. # ------------------------------------------------------------------------------ # Definitions # Names of executables, assumes gcc is used AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DGENERIC_UNIX -g -O2 -Wall -pipe -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ kbd.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ screen2.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All SPUNK header files HDRS = bitset.h \ statdef.h \ charset.h \ chartype.h \ check.h \ circbuf.h \ coll.h \ cont.h \ crc.h \ crcstrm.h \ datetime.h \ errlog.h \ event.h \ filecoll.h \ filepath.h \ filesel.h \ filesys.h \ fviewer.h \ inifile.h \ itemwin.h \ kbd.h \ keydef.h \ keymap.h \ listbox.h \ listnode.h \ machine.h \ mempool.h \ memstrm.h \ menue.h \ menuedit.h \ menuitem.h \ msg.h \ msgcoll.h \ msgid.h \ national.h \ nullstrm.h \ object.h \ palette.h \ password.h \ program.h \ progutil.h \ rect.h \ rescoll.h \ resed.h \ resource.h \ screen.h \ sercom.h \ settings.h \ splitmsg.h \ stack.h \ statline.h \ stdmenue.h \ stdmsg.h \ str.h \ strcoll.h \ strcvt.h \ stream.h \ streamid.h \ strmable.h \ strparse.h \ strpool.h \ textstrm.h \ thread.h \ winattr.h \ window.h \ winflags.h \ winmgr.h \ winsize.h # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets resed: $(LIB) $(RESEDITOBJS) $(HDRS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -ltermcap -lg++ lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? ranlib $(LIB) depend dep: @echo "Creating dependency information" $(CC) -DGENERIC_UNIX -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< kbd.o: unixsrc/kbd.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: unixsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen2.o: unixsrc/screen2.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/generic.mak $(ZIP) $(ZIPFILE) copying.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/linux-x.mak0100644000176100001440000000763707031424714017202 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for the X Window System under Linux using g++ * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DLINUX -g -O2 -Wall -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ console.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets ifeq (.depend,$(wildcard .depend)) all: resed include .depend else all: depend endif resed: $(LIB) $(RESEDITOBJS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -lX11 lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) rs $(LIB) $? depend dep: @echo "Creating dependency information" $(CC) -DLINUX -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files console.o: xsrc/console.cc $(HDRS) $(CC) $(CFLAGS) -c $< delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: xsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: linuxsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/linux-x.mak $(ZIP) $(ZIPFILE) copying.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend -rm $(LIB) estic-1.61.orig/spunk/make/linux.mak0100644000176100001440000000773007031424714016727 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for Linux using g++ * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DLINUX -g -O2 -Wall -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ kbd.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ screen2.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets ifeq (.depend,$(wildcard .depend)) all: resed include .depend else all: depend endif resed: $(LIB) $(RESEDITOBJS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -lncurses lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) rs $(LIB) $? depend dep: @echo "Creating dependency information" $(CC) -DLINUX -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: linuxsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< kbd.o: linuxsrc/kbd.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: linuxsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen2.o: unixsrc/screen2.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: linuxsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/linux.mak $(ZIP) $(ZIPFILE) copying.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend -rm $(LIB) estic-1.61.orig/spunk/make/netbsd-x.mak0100644000176100001440000000754607031424714017321 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for the X Window System under NetBSD using g++ * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DNETBSD -x c++ -I /usr/X11/include -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ console.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ regtask.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets xresed: $(LIB) $(RESEDITOBJS) $(CC) -g -o xresed $(RESEDITOBJS) $(LIB) -lg -lg++ -lX11 lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? ranlib $(LIB) depend dep: @echo "Creating dependency information" $(CC) -DNETBSD -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files console.o: xsrc/console.cc $(HDRS) $(CC) $(CFLAGS) -c $< delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: xsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: unixsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/netbsd-x.mak $(ZIP) $(ZIPFILE) copying.txt todo.txt spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc samples/* $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/solaris-x.mak0100644000176100001440000001013707031424714017504 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for a Solaris 2.[45] Unix SPARC system * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # * Portierung Sparc Solaris 2.5 * # * * # * Martin Helmling * # * Lindenhofstr. 78 * # * 68163 Mannheim * # * email mh@guug.de oder mh@octogon.de * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables, assumes gcc is used AS = gas AR = ar LD = ld ZIP = zip CC = g++ # Flags for the gnu compiler CFLAGS = -DSOLARIS -g -O2 -Wall -pipe -I /usr/openwin/include -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a ZIPFILE = spunk.zip # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ console.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ scrmodes.h \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets resed: $(LIB) $(RESEDITOBJS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -lg++ -lX11 lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? ranlib $(LIB) depend dep: @echo "Creating dependency information" $(CC) -DSOLARIS -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files console.o: xsrc/console.cc $(HDRS) $(CC) $(CFLAGS) -c $< delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: xsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: unixsrc/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # Create a ZIP file zip: -rm -f spunk.zip -rm -f *.bak *~ $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -cp Makefile make/solaris-x.mak $(ZIP) $(ZIPFILE) spunk.chg make/* $(ZIP) $(ZIPFILE) dossrc/*.cc dossrc/*.asm $(ZIP) $(ZIPFILE) dos32src/*.cc dos32src/*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc/*.cc os2src/*.cc bsdsrc/*.cc unixsrc/*.cc $(ZIP) $(ZIPFILE) xsrc/*.cc $(ZIP) $(ZIPFILE) doc/*.doc support/* data/* # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/svr40-x.mak0100644000176100001440000000641407031424714017011 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for the X Window System under SVR4.0 using g++ * # * * # * (C) 1993-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables AS = gas AR = ar LD = ld CC = gcc # Flags for the gnu compiler CFLAGS = -DSVR4 -O2 -Wall -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ console.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets xresed: $(LIB) $(RESEDITOBJS) $(CC) -g -o xresed $(RESEDITOBJS) $(LIB) -lg++ -lX11 -lnsl -lsocket lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? depend dep: @echo "Creating dependency information" $(CC) -DSVR4 -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files console.o: xsrc/console.cc $(HDRS) $(CC) $(CFLAGS) -c $< delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: xsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: svr4src/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/svr40.mak0100644000176100001440000000652407031424714016546 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for a SVR4 Unix system * # * * # * (C) 1993-97 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Definitions # Names of executables, assumes gcc is used AS = gas AR = ar LD = ld CC = gcc # Flags for the gnu compiler CFLAGS = -DSVR4 -O2 -Wall -x c++ -fno-implicit-templates -DEXPLICIT_TEMPLATES LIB = spunk.a # ------------------------------------------------------------------------------ # Implicit rules .c.o: $(CC) $(CFLAGS) -c $< .cc.o: $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.o \ charset.o \ charstrm.o \ chartype.o \ check.o \ coll.o \ cont.o \ cpucvt.o \ crc16.o \ crc32.o \ crcccitt.o \ crcstrm.o \ datetime.o \ delay.o \ environ.o \ errlog.o \ event.o \ filecoll.o \ filepath.o \ filesel.o \ filesys.o \ frame.o \ fviewer.o \ inifile.o \ itemlbl.o \ itemwin.o \ kbd.o \ keydef.o \ keymap.o \ listnode.o \ memcheck.o \ memstrm.o \ menue.o \ menuedit.o \ menuitem.o \ msg.o \ msgcoll.o \ national.o \ nlsinit.o \ nullstrm.o \ object.o \ palette.o \ password.o \ program.o \ progutil.o \ rect.o \ rescoll.o \ resource.o \ rng.o \ screen.o \ screen2.o \ sercom.o \ serstrm.o \ settings.o \ splitmsg.o \ statline.o \ stdmenue.o \ stdmsg.o \ str.o \ strbox.o \ strcoll.o \ strcvt.o \ stream.o \ strmable.o \ strparse.o \ strpool.o \ syserror.o \ textitem.o \ textstrm.o \ thread.o \ winattr.o \ window.o \ winmgr.o \ winsize.o # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.o \ resedit.o \ resfile.o \ resitem.o \ resprint.o \ resutil.o \ reswin.o # ------------------------------------------------------------------------------ # Dummy targets resed: $(LIB) $(RESEDITOBJS) $(HDRS) $(CC) -g -o resed $(RESEDITOBJS) $(LIB) -ltermcap -lg++ lib: $(LIB) # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(AR) r $(LIB) $? depend dep: @echo "Creating dependency information" $(CC) -DSVR4 -MM *.cc > .depend # ------------------------------------------------------------------------------ # Target specific files delay.o: unixsrc/delay.cc $(HDRS) $(CC) $(CFLAGS) -c $< filesys.o: unixsrc/filesys.cc $(HDRS) $(CC) $(CFLAGS) -c $< kbd.o: unixsrc/kbd.cc $(HDRS) $(CC) $(CFLAGS) -c $< nlsinit.o: unixsrc/nlsinit.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen.o: unixsrc/screen.cc $(HDRS) $(CC) $(CFLAGS) -c $< screen2.o: unixsrc/screen2.cc $(HDRS) $(CC) $(CFLAGS) -c $< sercom.o: svr4src/sercom.cc $(HDRS) $(CC) $(CFLAGS) -c $< # ------------------------------------------------------------------------------ # clean up clean: -rm -f *~ linuxsrc/*~ bsdsrc/*~ unixsrc/*~ zap: clean -rm -f *.o -rm -f .depend estic-1.61.orig/spunk/make/watcom.mak0100644000176100001440000002371307031424714017061 0ustar debacleusers# ***************************************************************************** # * * # * SPUNK MAKEFILE for DOS, OS/2 and NT using the Watcom Compiler * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Generelle Einstellungen .AUTODEPEND .SUFFIXES .ASM .C .CC .CPP .SWAP # ------------------------------------------------------------------------------ # Allgemeine Definitionen # Names of executables AS = TASM AR = WLIB LD = WLINK # Files ZIPFILE = spunk.zip # Tools !if $d(__OS2__) ZIP = zip !else ZIP = pkzip !endif !if !$d(TARGET) !if $d(__OS2__) TARGET = OS2 !else TARGET = DOS !endif !endif # target specific macros. !if $(TARGET)==OS2 # --------------------- OS2 --------------------- SYSTEM = os2v2 CC = WPP386 CCCFG = -bm -bt=$(TARGET) -fo=$(TARGET)\ -d$(TARGET) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 !elif $(TARGET)==DOS32 # -------------------- DOS4G -------------------- SYSTEM = dos4g CC = WPP386 CCCFG = -bt=$(TARGET) -fo=$(TARGET)\ -d$(TARGET) -d1 -onatx -zp4 -5 -fpi -zq -w2 !elif $(TARGET)==DOS # --------------------- DOS --------------------- SYSTEM = dos CC = WPP # Optimize for size when running under plain DOS, but use 286 code. Don't # include ANY debugging code to make as many programs runable under plain DOS # as possible. CCCFG = -bt=$(TARGET) -fo=$(TARGET)\ -d$(TARGET) -dSPUNK_NODEBUG -d1 -oailmns -s -zp2 -zc -2 -fp2 -ml -zq -w2 -zt255 !elif $(TARGET)==NETWARE # --------------------- NETWARE ------------------- SYSTEM = netware CC = WPP386 CCCFG = -bm -bt=$(TARGET) -fo=$(TARGET)\ -d$(TARGET) -d1 -onatx -zp4 -5 -fpi -zq -w2 !elif $(TARGET)==NT # --------------------- NT ---------------------- SYSTEM = nt CC = WPP386 CCCFG = -bm -bt=$(TARGET) -fo=$(TARGET)\ -d$(TARGET) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 !else !error !endif !if !$d(LIBDIR) LIBDIR = $(TARGET) !endif LIB = $(LIBDIR)\spunk.lib .PRECIOUS $(LIB) # ------------------------------------------------------------------------------ # Implicit rules .c.obj: $(CC) $(CCCFG) $< .cc.obj: $(CC) $(CCCFG) $< .asm.obj: $(AS) -Mx $*.asm,$(TARGET)\$*.obj .path.obj = $(TARGET) # ------------------------------------------------------------------------------ # All SPUNK OBJ files OBJS = bitset.obj \ charset.obj \ charstrm.obj \ chartype.obj \ check.obj \ coll.obj \ cont.obj \ cpucvt.obj \ crc16.obj \ crc32.obj \ crcccitt.obj \ crcstrm.obj \ datetime.obj \ delay.obj \ environ.obj \ errlog.obj \ event.obj \ filecoll.obj \ filepath.obj \ filesel.obj \ filesys.obj \ frame.obj \ fviewer.obj \ inifile.obj \ itemlbl.obj \ itemwin.obj \ kbd.obj \ keydef.obj \ keymap.obj \ listnode.obj \ memcheck.obj \ memstrm.obj \ menue.obj \ menuedit.obj \ menuitem.obj \ msg.obj \ msgcoll.obj \ national.obj \ nlsinit.obj \ nullstrm.obj \ object.obj \ palette.obj \ password.obj \ program.obj \ progutil.obj \ rect.obj \ rescoll.obj \ resource.obj \ rng.obj \ screen.obj \ serstrm.obj \ settings.obj \ splitmsg.obj \ statline.obj \ stdmenue.obj \ stdmsg.obj \ str.obj \ strbox.obj \ strcoll.obj \ strcvt.obj \ stream.obj \ strmable.obj \ strparse.obj \ strpool.obj \ syserror.obj \ textitem.obj \ textstrm.obj \ thread.obj \ wildargs.obj \ winattr.obj \ window.obj \ winmgr.obj \ winsize.obj # # Additional target specific modules # !if $(TARGET)==DOS XOBJS = sercom.obj \ _sercom.obj !endif !if $(TARGET)==DOS32 XOBJS = sercom.obj \ _sercom.obj !endif !if $(TARGET)==OS2 XOBJS = sema.obj \ sercom.obj \ task.obj !endif !if $(TARGET)==NT XOBJS = sema.obj \ sercom.obj \ task.obj !endif .PRECIOUS $(OBJS:.obj=.cc) $(LIB) # ------------------------------------------------------------------------------ # All resedit OBJ files RESEDITOBJS = resed.obj \ resedit.obj \ resfile.obj \ resitem.obj \ resprint.obj \ resutil.obj \ reswin.obj # ------------------------------------------------------------------------------ # Dummy targets. Beware: resed must be the default target resed: $(TARGET)\resed.exe all: dos dos32 os2 netware nt libs: doslib dos32lib os2lib netwarelib ntlib lib: libdir $(LIB) dos: $(MAKE) -DTARGET=DOS os2: $(MAKE) -DTARGET=OS2 dos32: $(MAKE) -DTARGET=DOS32 netware: $(MAKE) -DTARGET=NETWARE resed.nlm nt: $(MAKE) -DTARGET=NT doslib: $(MAKE) -DTARGET=DOS lib os2lib: $(MAKE) -DTARGET=OS2 lib dos32lib: $(MAKE) -DTARGET=DOS32 lib netwarelib: $(MAKE) -DTARGET=NETWARE lib ntlib: $(MAKE) -DTARGET=NT lib # ------------------------------------------------------------------------------ # Make the needed directories libdir: @- if not exist $(LIBDIR) mkdir $(LIBDIR) > nul # ------------------------------------------------------------------------------ # Resource editor $(TARGET)\resed.exe: lib $(RESEDITOBJS) $(LD) system $(SYSTEM) @&&| DEBUG all NAME $(TARGET)\resed.exe OPTION DOSSEG OPTION STACK=32K FILE $(TARGET)\resed.obj FILE $(TARGET)\resedit.obj FILE $(TARGET)\resfile.obj FILE $(TARGET)\resitem.obj FILE $(TARGET)\resprint.obj FILE $(TARGET)\resutil.obj FILE $(TARGET)\reswin.obj LIBRARY $(LIB) | # Netware: Add this one if needed # MODULE aio # IMPORT @%WATCOM%\novi\aio.imp resed.nlm: lib $(RESEDITOBJS) $(LD) system $(SYSTEM) @&&| DEBUG all NAME $(TARGET)\resed.nlm OPTION DOSSEG OPTION STACK=32K FILE $(TARGET)\resed.obj FILE $(TARGET)\resedit.obj FILE $(TARGET)\resfile.obj FILE $(TARGET)\resitem.obj FILE $(TARGET)\resprint.obj FILE $(TARGET)\resutil.obj FILE $(TARGET)\reswin.obj LIBRARY $(LIB) | # ------------------------------------------------------------------------------ # File-Transfer program filetran: $(TARGET)\filetran.exe $(TARGET)\filetran.exe: lib filetran.obj $(LD) system $(SYSTEM) @&&| DEBUG all NAME $(TARGET)\filetran.exe OPTION DOSSEG OPTION STACK=32K FILE $(TARGET)\filetran.obj LIBRARY $(LIB) | # ------------------------------------------------------------------------------ # Library $(LIB): $(OBJS) $(XOBJS) -@copy makefile make\watcom.mak > nul @echo Creating library... &@$(AR) -q -b -P=128 $(LIB) +-$? @echo Done! # ------------------------------------------------------------------------------ # OS specific modules delay.obj: $(TARGET)SRC\delay.cc $(CC) $(CCCFG) $** filesys.obj: $(TARGET)SRC\filesys.cc $(CC) $(CCCFG) $** kbd.obj: $(TARGET)SRC\kbd.cc $(CC) $(CCCFG) $** nlsinit.obj: $(TARGET)SRC\nlsinit.cc $(CC) $(CCCFG) $** screen.obj: $(TARGET)SRC\screen.cc $(CC) $(CCCFG) $** sema.obj: $(TARGET)SRC\sema.cc $(CC) $(CCCFG) $** sercom.obj: $(TARGET)SRC\sercom.cc $(CC) $(CCCFG) $** _sercom.obj: $(TARGET)SRC\_sercom.asm $(AS) -m3 -mx -zi $(TARGET)src\_sercom.asm,$(TARGET)\_sercom.obj task.obj: $(TARGET)SRC\task.cc $(CC) $(CCCFG) $** # ------------------------------------------------------------------------------ # create a ZIP file zip: -del spunk.zip -del /S *.bak $(ZIP) $(ZIPFILE) *.cc *.h bccdos.cfg bccos2.cfg baseres.res resed.res -copy makefile make\watcom.mak $(ZIP) $(ZIPFILE) copying.txt todo.txt spunk.chg make\*.* $(ZIP) $(ZIPFILE) dossrc\*.cc dossrc\*.asm $(ZIP) $(ZIPFILE) dos32src\*.cc dos32src\*.asm djgppsrc\*.cc $(ZIP) $(ZIPFILE) linuxsrc\*.cc os2src\*.cc bsdsrc\*.cc unixsrc\*.cc $(ZIP) -r $(ZIPFILE) ntsrc\*.cc xsrc\*.cc samples\* $(ZIP) $(ZIPFILE) doc\*.doc nls\*.* # ------------------------------------------------------------------------------ # clean up clean: -del /S *.bak zap: clean -del $(TARGET)\*.obj estic-1.61.orig/spunk/itemlbl.h0100644000176100001440000000613407031424701015753 0ustar debacleusers/*****************************************************************************/ /* */ /* ITEMLBL.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Class ItemLabel is a special window item that acts as a label for another // window item. #ifndef __ITEMLBL_H #define __ITEMLBL_H #include "itemwin.h" /*****************************************************************************/ /* class ItemLabel */ /*****************************************************************************/ class ItemLabel: public WindowItem { friend class ResEditApp; // Resource editor is a friend protected: i16 CtrlID; // ID of item that is controlled i16 CtrlChoice; // Return code of Choose WindowItem* GetCtrlItem (); // Return a pointer to the controlled item or NULL ItemLabel (StreamableInit); // Build constructor public: ItemLabel (const String& aItemText, i16 aID, i16 aCtrlID, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); void SetCtrlID (i16 aCtrlID); // Set the ID of the item that is controlled by the label i16 GetCtrlID () const; // Get the ID of the item that is controlled by the label i16 GetCtrlChoice () const; // Choose returns the ID of the label item if the controlled item's // "Choose" returned a value other than 0. Use this function to retrieve // the return code of the controlled items Choose function. // Change the status virtual void Gray (); virtual void Select (); virtual void Deselect (); // Choose an entry virtual i16 Choose (); }; inline ItemLabel::ItemLabel (StreamableInit): WindowItem (Empty) { } inline void ItemLabel::SetCtrlID (i16 aCtrlID) // Set the ID of the item that is controlled by the label { CtrlID = aCtrlID; } inline i16 ItemLabel::GetCtrlID () const // Get the ID of the item that is controlled by the label { return CtrlID; } inline i16 ItemLabel::GetCtrlChoice () const // Choose returns the ID of the label item if the controlled item's // "Choose" returned a value other than 0. Use this function to retrieve // the return code of the controlled items Choose function. { return CtrlChoice; } // End of ITEMLBL.H #endif estic-1.61.orig/spunk/itemwin.cc0100644000176100001440000007054607031424701016145 0ustar debacleusers/*****************************************************************************/ /* */ /* ITEMWIN.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "itemwin.h" #include "national.h" #include "streamid.h" #include "thread.h" #include "program.h" #include "progutil.h" // Register class WindowItem and ItemWindow LINK(ItemWindow, ID_ItemWindow); LINK(WindowItem, ID_WindowItem); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListNode; #endif /*****************************************************************************/ /* class WindowItem */ /*****************************************************************************/ WindowItem::WindowItem (const String &aItemText, i16 aID, WindowItem *NextItem) : INode (this), ItemX (0), ItemY (0), ID (aID), Flags (0), AccelKey (kbNoKey), ItemText (aItemText) { // Check the given parameters PRECONDITION (aID <= MaxUserID && aID > 0); // Check the item text for a hot key HotPos = (i16) ItemText.Pos ('@'); if (HotPos >= 0) { // There is a hot key, delete the marker and grab it ItemText.Del (HotPos); HotKey = (Key) NLSUpCase (ItemText [HotPos]); } else { // No hotkey HotKey = kbNoKey; } // Init some other stuff AccelKey = kbNoKey; SetPos (0, 0); ItemWidth = MinWidth (); // If the next item is given, make up the list if (NextItem) { INode.InsertBefore (&NextItem->INode); } } u16 WindowItem::StreamableID () const { return ID_WindowItem; } Streamable* WindowItem::Build () { return new WindowItem (Empty); } void WindowItem::Store (Stream& S) const // Write instance data to the stream { S << ItemX << ItemY << ItemWidth << ID << Flags << HotKey << HotPos << AccelKey << ItemText << HelpKey; } void WindowItem::Load (Stream &S) // Load instance data from the stream { S >> ItemX >> ItemY >> ItemWidth >> ID >> Flags >> HotKey >> HotPos >> AccelKey >> ItemText >> HelpKey; } void WindowItem::RegisterKey () // If the item is active and has an accel key: Register the key at the // current thread. { if (IsActive () && AccelKey != kbNoKey) { CurThread () -> RegisterKey (AccelKey); } } void WindowItem::UnregisterKey () // If the item is active and has an accel key: Unregister the key at the // current thread. { if (IsActive () && AccelKey != kbNoKey) { CurThread () -> UnregisterKey (AccelKey); } } void WindowItem::SetPos (u16 X, u16 Y) { ItemX = X; ItemY = Y; } void WindowItem::SetWidth (u16 NewWidth) { ItemWidth = NewWidth; } ItemWindow* WindowItem::GetRootWindow () // Get the root of all windows in the current chain { ItemWindow *Win = Owner; while (Win->GetOwner ()) { Win = Win->GetOwner () -> GetOwner (); } CHECK (Win != NULL); return Win; } void WindowItem::SelectNew (WindowItem* NewItem) // Deselect the selected item and set NewItem as newly selected item. // Checks if this == NewItem and ignores a request in this case { // This item must be selected ! PRECONDITION (IsSelected ()); // No action if the new item and this item are the same if (NewItem != this) { Deselect (); // Deselect this item NewItem->Select (); // Select other item } } WindowItem* WindowItem::SelectNext () // Select the next item in the list. Return the item that is selected // after the operation has been performed. { // Get a pointer to the node of the item list ListNode* Node = &INode; WindowItem* Item; // Search the item list forward for the next matching item do { Node = Node->Next (); Item = Node->Contents (); } while (!Item->IsActive ()); // Select the new item, deselect current SelectNew (Item); // Return the new selected item return Item; } WindowItem* WindowItem::SelectPrev () // Select the previous item in the list. Return the item that is selected // after the operation has been performed. { // Get a pointer to the node of the item list ListNode* Node = &INode; WindowItem* Item; // Search the item list forward for the next matching item do { Node = Node->Prev (); Item = Node->Contents (); } while (!Item->IsActive ()); // Select the new item, deselect current SelectNew (Item); // Return the new selected item return Item; } u16 WindowItem::GetWidth () const { return ItemWidth; } u16 WindowItem::MinWidth () // Return the minimal needed width of the item { return ItemText.Len (); } i16 WindowItem::GetID () // Return the item id { return ID; } void WindowItem::SetItemText (const String& aItemText) { // Set new string ItemText = aItemText; // Adjust memory needed for the string ItemText.Settle (); // Reset width SetWidth (GetWidth ()); // Redraw the item Draw (); } void WindowItem::Draw () { unsigned TextAttr; // Attribute for normal text unsigned HotAttr; // Attribute for hot key // If the item text is empty, bail out early if (ItemText.IsEmpty ()) { // Nothing to do return; } // Set up attributes if (IsActive ()) { HotAttr = atTextHigh; TextAttr = IsSelected () ? atTextSelected : atTextNormal; } else { if (IsGrayed ()) { HotAttr = atTextGrayed; TextAttr = atTextGrayed; } else { HotAttr = atTextNormal; TextAttr = atTextNormal; } } // Lock the owner window Owner->Lock (); // Write out the item text Owner->Write (ItemX, ItemY, ItemText, TextAttr); // If there is a hotkey, show it if (HotPos >= 0) { Owner->Write (ItemX + HotPos, ItemY, ItemText [HotPos], HotAttr); } // Unlock the owner window Owner->Unlock (); } void WindowItem::Clear () { if (ItemWidth) { String S (ItemWidth); S.Set (0, ItemWidth, ' '); Owner->Write (ItemX, ItemY, S); } } void WindowItem::DrawItemText () { WindowItem::Draw (); } void WindowItem::ClearItemText () { unsigned Len = ItemText.Len (); if (Len) { String S (Len); S.Set (0, Len, ' '); Owner->Write (ItemX, ItemY, S); } } void WindowItem::Activate () { // Clear the gray and inactive attributes Flags &= ~(ifGrayed | ifInactive); // Redraw the item DrawItemText (); } void WindowItem::Deactivate () { // Set new state Flags |= ifInactive; Flags &= ~ifSelected; // Redraw the item DrawItemText (); } void WindowItem::Gray () { // Set new state Flags |= ifGrayed | ifInactive; Flags &= ~ifSelected; // Redraw the item DrawItemText (); } void WindowItem::Select () { // Set new state Flags |= ifSelected; // Redraw the item DrawItemText (); } void WindowItem::Deselect () { // Set new state Flags &= ~ifSelected; // Redraw the item DrawItemText (); } void WindowItem::CallHelp () // Call the help function with the help key of this item { if (HasHelp ()) { App->CallHelp (HelpKey); } } i16 WindowItem::Choose () // Choose an entry { // Item must be active PRECONDITION (IsActive ()); // Return entry id return ID; } WindowItem* WindowItem::ItemWithID (i16 aID) // { return (aID == ID) ? this : (WindowItem*) NULL; } WindowItem* WindowItem::ItemWithHotKey (Key aHotKey) { return (IsActive () && aHotKey == HotKey) ? this : (WindowItem*) NULL; } WindowItem* WindowItem::ItemWithAccelKey (Key aAccelKey) { return (IsActive () && aAccelKey == AccelKey) ? this : (WindowItem*) NULL; } /*****************************************************************************/ /* class ItemWindow */ /*****************************************************************************/ ItemWindow::ItemWindow (const Rect& Bounds, u16 aState, WindowItem* ItemList): Window (Bounds, aState, paGray, 0, 1), Owner (NULL), SelectedItem (NULL), FirstItem (ItemList) // Internal constructor, used by GenericMenue { // Set up the item count ItemCount = (u16) (FirstItem ? FirstItem->INode.NodeCount () : 0); // Set this as the owner of all items in ItemList SetItemListOwner (); } ItemWindow::ItemWindow (const Rect& Bounds, u16 aState, unsigned aPalette, unsigned Number, WindowItem* ItemList): Window (Bounds, aState, aPalette, Number, 1), Owner (NULL), SelectedItem (NULL), FirstItem (ItemList) { // Set up the item count ItemCount = FirstItem ? FirstItem->INode.NodeCount () : 0; // Set this as the owner of all items in ItemList SetItemListOwner (); // Set the positions of the items SetPos (); // Choose a selected item ValidateSelectedItem (); // Draw all items DrawItems (); // The parent class has been called with LockCount == 1, so we // have to unlock the screen output here Unlock (); } ItemWindow::~ItemWindow () // Destructor of class ItemWindow { // Delete the list of items if (FirstItem) { ListNode* N = &FirstItem->INode; ListNode* P; while (!N->IsEmpty ()) { P = N->Next (); P->Unlink (); delete P->Contents (); } delete N->Contents (); } } u16 ItemWindow::StreamableID () const { return ID_ItemWindow; } Streamable* ItemWindow::Build () { return new ItemWindow (Empty); } int ItemWindow::StoreOneItem (ListNode* N, void* S) // Helper function to store a WindowItem into the stream S { // Get a casted pointer to the stream Stream *Str = (Stream *) S; // Store the WindowItem Str->Put (N->Contents ()); // keep on traversing... return 0; } void ItemWindow::Store (Stream& S) const // Store the object into a stream { // Store parental data Window::Store (S); // Store the node number of the selected item. Note: If FirstItem is // NULL, SelectedItem cannot be != NULL i16 Selected; if (SelectedItem) { CHECK (FirstItem != NULL); Selected = (i16) FirstItem->INode.NumberOfNode (&SelectedItem->INode); } else { Selected = -1; } // Store the item count and each item S << Selected << ItemCount; Traverse (StoreOneItem, &S); } int ItemWindow::SetOneItemWidth (ListNode* N, void*) // Reset the width of one item { // Get a pointer to the item WindowItem* W = N->Contents (); // Reset the width W->SetWidth (W->GetWidth ()); // keep on traversing... return 0; } void ItemWindow::Load (Stream& S) // Load the window from the stream { i16 Selected; // Clear ItemCount and most of the pointers before calling the parental // Load function. This is because Window::Load is calling Redraw, which // tries to draw not existing items if the data is not initialized. ItemCount = 0; Owner = NULL; FirstItem = NULL; SelectedItem = NULL; // Now load the window data Window::Load (S); // Read the number of the selected item and the item count S >> Selected >> ItemCount; // Read in all items and put them into the linked list WindowItem *P; for (int I = 0; I < ItemCount; I++) { // Load the item from the stream P = (WindowItem *) S.Get (); // Insert the item into the item list if (FirstItem) { P->INode.InsertBefore (&FirstItem->INode); } else { FirstItem = P; } } // Set "this" as the owner of all the items in the list SetItemListOwner (); // Set the pointer to the selected item if (Selected == -1) { // No selected item SelectedItem = NULL; } else { CHECK (FirstItem != NULL); SelectedItem = FirstItem->INode.NodeWithNumber ((u16) Selected)->Contents (); } // Before redrawing the items, adjust for a changed size of the window and // changed language. Reset the width of all items. Traverse (SetOneItemWidth); // We have to redraw the items because Window::Redraw has not done this. // DrawItems is doing a lock, so we don't have to do this here DrawItems (); } void ItemWindow::DrawInterior () // Redraw the inner part of the window { // Clear the inner window, the redraw the items Lock (); Clear (); DrawItems (); Unlock (); } void ItemWindow::Activate () // Activate the window. This overrides Window::Activate and highlights // the selected item { // Activate the window Window::Activate (); // If there is a selected item, highlight it if (SelectedItem) { SelectedItem->Select (); } } void ItemWindow::Deactivate () // Activate the window. This overrides Window::Activate and deselects // the selected item { // Deactivate the window Window::Deactivate (); // If there is a selected item, deselect it if (SelectedItem) { SelectedItem->Deselect (); } } Key ItemWindow::Browse () // Make the window active and display the window contents in a suitable // manner. This function should be overridden for special derived // windows. It returns the key that ended the browse state. { // Remember the state of the window and the cursor form u16 OldState = GetState (); CursorType Cursor = GetCursor (); // new StatusLine PushStatusLine (CreateStatusLine (GetStatusFlags ())); // Activate the window Activate (); // Get all keys until abort or a registered key is read Key K; int Done = 0; while (!Done) { // Get a key K = KbdGet (); // Handle the key HandleKey (K); // Check for some other keys... switch (K) { case vkAbort: Done = 1; break; default: if (KeyIsRegistered (K)) { Done = 1; } break; } } // Restore the old status line PopStatusLine (); // Reset window to old state, then deselect the selected item. Do it // in this order, because often the menue is hidden after SetState, // so the call to Deselect will cause no additional screen output. SetState (OldState); if (SelectedItem) { SelectedItem->Deselect (); } // Set the old cursor SetCursor (Cursor); // Return the abort key return K; } u32 ItemWindow::GetStatusFlags () // Returns the flags that are used to build the status line in Browse { u32 Flags = siEnd; if (CanMove () || CanResize ()) { Flags |= siResize; } return Flags; } void ItemWindow::HandleKey (Key& K) // Key dispatcher used in Browse { // Handle some known keys switch (K) { case vkResize: MoveResize (); K = kbNoKey; break; } } void ItemWindow::AddItem (WindowItem* Item) // Add the given item to the item list of the window. After that, the // item is owned by the window and destroyed if the window destructor // is called. The given WindowItem is unlinked from the list it is // linked in before it is added to the windows item list. { // unlink the item from the list it is currently in Item->INode.Unlink (); // Insert the item into the list managed by the window if (FirstItem) { Item->INode.InsertBefore (&FirstItem->INode); } else { FirstItem = Item; } // Set the owner of the item Item->SetOwner (this); // Track the count of items in the list ItemCount++; // Validate the selected item ValidateSelectedItem (); } void ItemWindow::DeleteItem (WindowItem* Item) // Take the item from the item list and delete it. If Item is the // selected item, a new selected item is choosen. After deleting // Item, the window is redrawn. { ListNode *N; if (FirstItem) { // List is not empty N = &FirstItem->INode; do { if (N->Contents () == Item) { // Found the item, clear, then unlink it. Be carefull: // Item could be the item, FirstItem is pointing to! N->Contents () -> Clear (); if (Item == FirstItem) { // Take the next item if possible if (ItemCount > 1) { FirstItem = N->Next () -> Contents (); } else { // This is the last item, the list is empty FirstItem = NULL; } } N->Unlink (); // Keep track of the item count ItemCount--; // If Item was selected, choose a new selected item if (Item == SelectedItem) { SelectedItem = NULL; // Invalidate item ValidateSelectedItem (); // Choose a new one } // Now delete the item and exit delete Item; return; } else { // Not this item, try the next N = N->Next (); } // until the first item is reached again } while (Item != FirstItem); } // OOPS! There is no such item in the item list. FAIL ("ItemWindow::DeleteItem: Item not found"); } int ItemWindow::SetOneOwner (ListNode* N, void* P) // Helper function for ItemWindow::SetItemListOwner. Sets the owner window // for all items in the list { N->Contents () -> SetOwner ((ItemWindow *) P); return 0; } void ItemWindow::SetItemListOwner () // Traverse through all items and tell them their owner { Traverse (SetOneOwner, (void*) this); } int ItemWindow::SetOnePos (ListNode* N, void* P) // Helper function for ItemWindow::SetPos, sets the position of one item { // Get a casted pointer to the given Y position u16* Pos = (u16*) P; // Set the position for one item N->Contents () -> SetPos (0, *Pos); // Increment the Y position (*Pos)++; // Keep on traversing return 0; } void ItemWindow::SetPos () // Sets the positions of all window items. The items are lined up // vertically at the left window border. To change this behaviour, // overload this function. { // Position of first item is 0/0 u16 Y = 0; Traverse (SetOnePos, &Y); } int ItemWindow::DrawOneItem (ListNode* N, void*) // Helper function for DrawItems, draw on item { // Draw the given item N->Contents () -> Draw (); // Keep on traversing return 0; } void ItemWindow::DrawItems () // Draw all items { if (FirstItem) { // Use Lock/Unlock to speed up display processing Lock (); Traverse (DrawOneItem); Unlock (); } } int ItemWindow::CheckSelectedItem (ListNode* N, void*) // Helper function for ValidateSelectedItem, find active item { return N->Contents () -> IsActive (); } void ItemWindow::ValidateSelectedItem () // Check if the item pointed to by SelectedItem is still active. If // not, a new item is choosen. { if (FirstItem == NULL) { // No items SelectedItem = NULL; return; } if (SelectedItem == NULL || SelectedItem->IsActive () == 0) { // Selected item is invalid, choose a new one SelectedItem = Traverse (CheckSelectedItem); } // If a selected item exists and the window is active, show the new state if (SelectedItem && IsActive ()) { SelectedItem->Select (); } } void ItemWindow::SelectNextItem () // Choose the next item in the item list as selected { if (SelectedItem) { SelectedItem = SelectedItem->SelectNext (); } } void ItemWindow::SelectPrevItem () // Choose the previous item in the item list as selected { if (SelectedItem) { SelectedItem = SelectedItem->SelectPrev (); } } void ItemWindow::SelectNewItem (WindowItem* NewItem) // Select the new item, update SelectedItem { if (SelectedItem) { SelectedItem->SelectNew (NewItem); } else { NewItem->Select (); } SelectedItem = NewItem; } void ItemWindow::SelectNewItem (i16 NewID) // Select the new item, update SelectedItem { SelectNewItem (ForcedItemWithID (NewID)); } WindowItem* ItemWindow::Traverse (int (*F) (ListNode*, void*), void* Data) const // Use ListNode::Traverse to traverse through all window items starting // at FirstItem. Return value corresponds to ListNode::Traverse { ListNode *Node; if (FirstItem) { Node = FirstItem->INode.Traverse (1, F, Data); } else { Node = NULL; } // if Node is not NULL, return the item that Node contains return Node ? Node->Contents () : (WindowItem*) NULL; } void ItemWindow::PlaceNear (const Point& Pos) // Place the window near the given absolute position. If there is not enough // room to place the window below the given item, the window is placed above. { // Get the coords of the window and the screen Rect WinBounds (OuterBounds ()); Rect ScreenBounds (Background->OuterBounds ()); // Now move the window bounds so that the window is positioned // below the given item. WinBounds.Move (-WinBounds.A.X, -WinBounds.A.Y); // Move to 0/0 WinBounds.Move (Pos.X, Pos.Y+1); // Check if the Y position is inside the screen area if (WinBounds.B.Y > ScreenBounds.B.Y) { // This did not work. Parts of the window are outside the // screen area. Move the window to a position above the item WinBounds.Move (0, -WinBounds.A.Y); // Move to X/0 WinBounds.Move (0, Pos.Y-WinBounds.YSize ()); } // Check if the X position is correct. If the left border of the window // is outside the screen, correct that if (WinBounds.B.X > ScreenBounds.B.X) { WinBounds.Move (ScreenBounds.B.X-WinBounds.B.X, 0); } // Assume that the position is valid and move the window MoveAbs (WinBounds.A); } void ItemWindow::PlaceNear (WindowItem* Item) // Place the window below the given Item. Item must not be an item // owned by this window. If there is not enough room to place the // window below the given item, the window is placed above. { // Get the item position in absolute coords Point ItemPos (Item->ItemX, Item->ItemY); Item->Owner->Absolute (ItemPos); // Place the window near this position PlaceNear (ItemPos); } int ItemWindow::FindAccelKey (ListNode* N, void* I) // Helper function for ItemWithAccelKey { // Cast the pointer FindStruc2 *P = (FindStruc2 *) I; P->Item = N->Contents () -> ItemWithAccelKey (P->K); return (P->Item != NULL); } WindowItem* ItemWindow::ItemWithAccelKey (Key aAccelKey) // Try to find an item with the given accelerator key in the tree // below this window. If one is found, a pointer to the item is // returned, otherwise the function returns NULL. { FindStruc2 F; // Search the given ID F.Item = NULL; F.K = aAccelKey; Traverse (FindAccelKey, &F); return F.Item; } int ItemWindow::FindHotKey (ListNode* N, void* P) // Helper function for ItemWithHotKey { return (N->Contents () -> ItemWithHotKey (*(Key*)P) != NULL); } WindowItem* ItemWindow::ItemWithHotKey (Key aHotKey) // Try to find an item with the given hot key in the tree // below this window. If one is found, a pointer to the item is // returned, otherwise the function returns NULL. { // Searching for a null hotkey does not make sense PRECONDITION (aHotKey != kbNoKey); return Traverse (FindHotKey, &aHotKey); } int ItemWindow::FindID (ListNode* N, void* I) // Helper function for ItemWithID { // Cast the pointer FindStruc1* P = (FindStruc1*) I; P->Item = N->Contents () -> ItemWithID (P->ID); return (P->Item != NULL); } WindowItem* ItemWindow::ItemWithID (i16 aID) // Try to find an item with the given ID in the tree below this // window. If one is found, a pointer to the item is returned, // otherwise the function returns NULL. { FindStruc1 F; // Check the given parameter PRECONDITION (aID > 0 && aID <= MaxUserID); // Search the given ID F.Item = NULL; F.ID = aID; Traverse (FindID, &F); return F.Item; } WindowItem* ItemWindow::ForcedItemWithID (i16 aID) // Acts like ItemWithID but treats the case different, when no // matching ID is found: This is considered as a fatal error. { // Search for the ID WindowItem* Item = ItemWithID (aID); // Check if a item was found CHECK (Item != NULL); // Return the result return Item; } void ItemWindow::SetAccelKey (i16 aID, Key aAccelKey) // Sets the accelerator key for the item with the given ID. If no // item with this ID is found, this is considered as a fatal error. { ForcedItemWithID (aID) -> SetAccelKey (aAccelKey); } Key ItemWindow::GetHotKey (i16 aID) // Return the hot key of the item with the given ID. If no such item // is found, this is considered as a fatal error. { return ForcedItemWithID (aID) -> GetHotKey (); } Key ItemWindow::GetAccelKey (i16 aID) // Return the accelerator key of the item with the given ID. If no // such item is found, this is considered as a fatal error. { return ForcedItemWithID (aID) -> GetAccelKey (); } void ItemWindow::SetHelpKey (i16 aID, const String &aHelpKey) // Set the key for the help function for the item with the given ID. // If no item with that ID is found, this is handled as a fatal error. { ForcedItemWithID (aID) -> SetHelpKey (aHelpKey); } void ItemWindow::DrawItem (i16 aID) // Redraw the item with the given ID. { ForcedItemWithID (aID) -> Draw (); } void ItemWindow::ActivateItem (i16 aID) // Activate the item with the given ID { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Activate the item Item->Activate (); // If there has been no selected item before, choose this one ValidateSelectedItem (); } void ItemWindow::DeactivateItem (i16 aID) // Deactivate the item with the given ID { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Deactivate the item Item->Deactivate (); // If the inactive item is the selected item, choose another selected item ValidateSelectedItem (); } void ItemWindow::GrayItem (i16 aID) // Gray the item with the given ID { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Gray the item Item->Gray (); // If the grayed item is the selected item, choose another selected item ValidateSelectedItem (); } int ItemWindow::RegisterOneItemKey (ListNode *N, void *) // Register the accel key of one item { N->Contents () -> RegisterKey (); return 0; } int ItemWindow::UnregisterOneItemKey (ListNode *N, void *) // Unregister the accel key of one item { N->Contents () -> UnregisterKey (); return 0; } void ItemWindow::RegisterItemKeys () // Register the accel keys of all active items { Traverse (RegisterOneItemKey); } void ItemWindow::UnregisterItemKeys () // Unregister the accel keys of all active items { Traverse (UnregisterOneItemKey); } int ItemWindow::CanClose () // Return true if the window is allowed to close. This function is a hook // for derived windows, it returns always true. { // Simple ItemWindows are allways allowed to close return 1; } void ItemWindow::Zoom () // Interface function for derived classes. This function is a no op and // must be overloaded { } estic-1.61.orig/spunk/itemwin.h0100644000176100001440000003713007031424701015777 0ustar debacleusers/*****************************************************************************/ /* */ /* ITEMWIN.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _ITEMWIN_H #define _ITEMWIN_H #include "keydef.h" #include "event.h" #include "window.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Highest value for any item ID used by the application // Legal values are 1 <= ID <= MaxUserID const i16 MaxUserID = 0x7FFD; // Flags const u16 ifInactive = 0x0001; // Item is inactive const u16 ifGrayed = 0x0002; // Item is grayed const u16 ifSelected = 0x0004; // Item is selected const u16 ifVertical = 0x0008; // Reserved const u16 ifNoSub = 0x0010; // Don't show submenue /*****************************************************************************/ /* class WindowItem */ /*****************************************************************************/ class WindowItem : public Streamable { friend class ResEditApp; // Resource editor is a friend friend class ItemWindow; friend inline WindowItem* SetAccelKey (WindowItem* Item, Key AccelKey); // This is a friend of class WindowItem and a short and convienient way to // set the accel key when constructing a WindowItem. Just pass the created // item through this function, the accel key is set and the item is returned. protected: ListNode INode; // double linked list of items ItemWindow* Owner; // Owner window u16 ItemX, ItemY; // Window position u16 ItemWidth; // Entry width i16 ID; // item ID u16 Flags; // Flag word Key HotKey; // i16 HotPos; // Position of the hotkey Key AccelKey; // Accelerator key String ItemText; // String HelpKey; // Key for the online help virtual void SelectNew (WindowItem* NewItem); // Deselect the selected item and set NewItem as newly selected item. // Checks if this == NewItem and ignores a request in this case virtual WindowItem* SelectNext (); // Select the next item in the list. Return the item that is selected // after the operation has been performed. virtual WindowItem* SelectPrev (); // Select the previous item in the list. Return the item that is selected // after the operation has been performed. void RegisterKey (); // If the item is active and has an accel key: Register the key at the // current thread. void UnregisterKey (); // If the item is active and has an accel key: Unregister the key at the // current thread. WindowItem (StreamableInit); // Build constructor public: WindowItem (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // New functions void SetOwner (ItemWindow* aOwner); virtual void SetPos (u16 X, u16 Y); void SetPos (Point P); virtual void SetWidth (u16 NewWidth); void SetHelpKey (const String& NewKey); const String& GetHelpKey () const; void SetAccelKey (Key NewNewKey); void SetItemText (const String& aItemText); // Access class data ItemWindow* GetOwner () const; virtual u16 GetWidth () const; virtual u16 MinWidth (); u16 XPos () const; u16 YPos () const; Point Pos () const; Key GetHotKey () const; Key GetAccelKey () const; const String& GetItemText () const; virtual i16 GetID (); // Draw and clear the item and the item text virtual void Draw (); virtual void Clear (); virtual void DrawItemText (); virtual void ClearItemText (); // Change the status virtual void Activate (); virtual void Deactivate (); virtual void Gray (); virtual void Select (); virtual void Deselect (); // Check the status int IsSelected (); int IsActive (); int IsGrayed (); int HasHelp (); // Call the help function with the help key of this item virtual void CallHelp (); // Choose an entry virtual i16 Choose (); // Locate items virtual WindowItem* ItemWithID (i16 aID); virtual WindowItem* ItemWithAccelKey (Key aAccelKey); virtual WindowItem* ItemWithHotKey (Key aHotKey); ItemWindow* GetRootWindow (); // Get the root of all windows in the current chain }; inline WindowItem::WindowItem (StreamableInit) : INode (this), ItemText (Empty), HelpKey (Empty) { } inline void WindowItem::SetOwner (ItemWindow* aOwner) { Owner = aOwner; } inline void WindowItem::SetPos (Point P) { SetPos (P.X, P.Y); } inline void WindowItem::SetHelpKey (const String& NewKey) { HelpKey = NewKey; } inline const String& WindowItem::GetHelpKey () const { return HelpKey; } inline void WindowItem::SetAccelKey (Key NewAccelKey) { AccelKey = NewAccelKey; } inline ItemWindow* WindowItem::GetOwner () const { return Owner; } inline u16 WindowItem::XPos () const { return ItemX; } inline u16 WindowItem::YPos () const { return ItemY; } inline Point WindowItem::Pos () const { return Point (ItemX, ItemY); } inline Key WindowItem::GetHotKey () const { return HotKey; } inline Key WindowItem::GetAccelKey () const { return AccelKey; } inline const String& WindowItem::GetItemText () const { return ItemText; } inline int WindowItem::IsSelected () { return (Flags & ifSelected) != 0; } inline int WindowItem::IsActive () { return (Flags & ifInactive) == 0; } inline int WindowItem::IsGrayed () { return (Flags & ifGrayed) != 0; } inline int WindowItem::HasHelp () { return HelpKey.Len () > 0; } inline WindowItem* SetAccelKey (WindowItem* Item, Key AccelKey) // This is a friend of class WindowItem and a short and convienient way to // set the accel key when constructing a WindowItem. Just pass the created // item through this function, the accel key is set and the item is returned. { Item->AccelKey = AccelKey; return Item; } /*****************************************************************************/ /* class ItemWindow */ /*****************************************************************************/ class ItemWindow : public Window, public EventHandler { friend class ResEditApp; // Resource editor is a friend private: // Data structures for use in Traverse struct FindStruc1 { i16 ID; WindowItem* Item; }; struct FindStruc2 { Key K; WindowItem* Item; }; static int StoreOneItem (ListNode*, void*); // Helper function to store a WindowItem into the stream S static int SetOneItemWidth (ListNode*, void*); // Reset the width of one item static int SetOneOwner (ListNode*, void*); // Helper function for ItemWindow::SetItemListOwner. Sets the owner window // for all items in the list static int SetOnePos (ListNode*, void*); // Helper function for ItemWindow::SetPos, sets the position of one item static int DrawOneItem (ListNode*, void*); // Helper function for DrawItems, draw one item static int CheckSelectedItem (ListNode*, void*); // Helper function for ValidateSelectedItem, find active item static int FindAccelKey (ListNode*, void*); // Helper function for ItemWithAccelKey static int FindHotKey (ListNode*, void*); // Helper function for ItemWithHotKey static int FindID (ListNode*, void*); // Helper function for ItemWithID static int RegisterOneItemKey (ListNode*, void*); // Register the accel key of one item static int UnregisterOneItemKey (ListNode*, void*); // Unregister the accel key of one item protected: u16 ItemCount; // Number of items in the list WindowItem* Owner; // Owner of the window WindowItem* SelectedItem; // Pointer to selected item WindowItem* FirstItem; // Pointer to item (list) void SelectNextItem (); // Choose the next item in the item list as selected void SelectPrevItem (); // Choose the previous item in the item list as selected virtual void SetPos (); // Sets the positions of all window items. The items are lined up // vertically at the left window border. To change this behaviour, // overload this function. void SetItemListOwner (); // Traverse through all items and tell them their owner window void DrawItems (); // Draw all items void ValidateSelectedItem (); // Check if the item pointed to by SelectedItem is still active. If // not, a new item is choosen. WindowItem* Traverse (int (*F) (ListNode*, void*), void* DataPtr = NULL) const; // Use ListNode::Traverse to traverse through all window items starting // at FirstItem. Return value corresponds to ListNode::Traverse virtual u32 GetStatusFlags (); // Returns the flags that are used to build the status line in Browse virtual void HandleKey (Key& K); // Key dispatcher used in Browse ItemWindow (const Rect &Bounds, u16 aState, WindowItem* ItemList); // Internal used constructor, leaves with LockCount == 1 public: ItemWindow (StreamableInit); ItemWindow (const Rect &Bounds, u16 aState = wfFramed, unsigned aPalette = paGray, unsigned Number = 0, WindowItem* ItemList = NULL); virtual ~ItemWindow (); // -- Derived from class Streamable virtual void Store (Stream &) const; virtual void Load (Stream &); virtual u16 StreamableID () const; static Streamable* Build (); // -- Derived from class Window virtual void DrawInterior (); // Draw the window interior. This overrides Window::DrawInterior and // additionally draws the items virtual void Activate (); // Activate the window. This overrides Window::Activate and highlights // the selected item virtual void Deactivate (); // Activate the window. This overrides Window::Activate and deselects // the selected item // -- New functions virtual Key Browse (); // Make the window active and display the window contents in a suitable // manner. This function should be overridden for special derived // windows. It returns the key that ended the browse state. WindowItem* GetOwner (); // Retrieve the pointer to the owner window void SetOwner (WindowItem* aOwner); // Set the pointer to the owner window void SelectNewItem (WindowItem* NewItem); // Select the new item, update SelectedItem void SelectNewItem (i16 NewID); // Select the new item, update SelectedItem void PlaceNear (const Point& Pos); // Place the window near the given absolute position. If there is not enough // room to place the window below the given item, the window is placed above. void PlaceNear (WindowItem* Item); // Place the window below the given Item. Item must not be an item // owned by this window. If there is not enough room to place the // window below the given item, the window is placed above. virtual WindowItem* ItemWithAccelKey (Key aAccelKey); // Try to find an item with the given accelerator key in the tree // below this window. If one is found, a pointer to the item is // returned, otherwise the function returns NULL. virtual WindowItem* ItemWithHotKey (Key aHotKey); // Try to find an item with the given hot key in the tree // below this window. If one is found, a pointer to the item is // returned, otherwise the function returns NULL. virtual WindowItem* ItemWithID (i16 aID); // Try to find an item with the given ID in the tree below this // window. If one is found, a pointer to the item is returned, // otherwise the function returns NULL. virtual WindowItem* ForcedItemWithID (i16 aID); // Acts like ItemWithID but treats the case different, when no // matching ID is found: This is considered as a fatal error. void SetAccelKey (i16 aID, Key aAccelKey); // Sets the accelerator key for the item with the given ID. If no // item with this ID is found, this is considered as a fatal error. Key GetHotKey (i16 aID); // Return the hot key of the item with the given ID. If no such item // is found, this is considered as a fatal error. Key GetAccelKey (i16 aID); // Return the accelerator key of the item with the given ID. If no // such item is found, this is considered as a fatal error. void SetHelpKey (i16 aID, const String& aHelpKey); // Set the key for the help function for the item with the given ID. // If no item with that ID is found, this is handled as a fatal error. void AddItem (WindowItem* Item); // Add the given item to the item list of the window. After that, the // item is owned by the window and destroyed if the window destructor // is called. The given WindowItem is unlinked from the list it is // linked in before it is added to the windows item list. void DeleteItem (WindowItem* Item); // Take the item from the item list and delete it. If Item is the // selected item, a new selected item is choosen. After deleting // Item, the window is redrawn. void DrawItem (i16 aID); // Redraw the item with the given ID. void ActivateItem (i16 aID); // Activate the item with the given ID void DeactivateItem (i16 aID); // Deactivate the item with the given ID void GrayItem (i16 aID); // Gray the item with the given ID void RegisterItemKeys (); // Register the accel keys of all active items void UnregisterItemKeys (); // Unregister the accel keys of all active items virtual int CanClose (); // Return true if the window is allowed to close. This function is a hook // for derived windows, it returns always true. virtual void Zoom (); // Interface function for derived classes. This function is a no op and // must be overloaded }; inline ItemWindow::ItemWindow (StreamableInit X) : Window (X) { } inline WindowItem* ItemWindow::GetOwner () { return Owner; } inline void ItemWindow::SetOwner (WindowItem* aOwner) { Owner = aOwner; } // End of ITEMWIN.H #endif estic-1.61.orig/spunk/kbd.h0100644000176100001440000001041707031424701015062 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Class Keyboard has some inline functions that don't need to be inline // (because they are rather big and there is no need for speed), but they // are declared this way, because they are only used in a few places (so // no code size penalty) and this way they are out of the target specific // .cc files. #ifndef _KBD_H #define _KBD_H #include "machine.h" #include "object.h" #include "circbuf.h" #include "keydef.h" #include "str.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Instance to handle keyboard input extern class Keyboard* Kbd; /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ class Keyboard : public Object { private: CircularBuffer KeyBuf; int Console; unsigned char* TransTable; Key RawKey (); // Get a raw (unmapped) key from the os void GetMappedKey (int Wait = 1); // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. Key Translate (Key K); // Translate plain keys via the translation table (if valid) public: Keyboard (); // Construct a keyboard object ~Keyboard (); // Destruct a keyboard object Key Get (); // Return a key from the keyboard Key Peek (); // Return the next key but don't remove it from the queue. This function // returns kbNoKey if no key is currently available. void Put (Key); // Put back a key into the queue int KeyAvail (); // Return true if a key is available int IsConsole (); // Return true if the keyboard is the console keyboard String GetKeyName (Key K); // Return a string describing the give key }; inline Key Keyboard::Translate (Key K) // Translate plain keys via the translation table (if valid) { return IsPlainKey (K) && TransTable != NULL ? TransTable [K] : K; } inline Key Keyboard::Get () { if (KeyBuf.IsEmpty ()) { // Get a key from the os GetMappedKey (); } // In any case a key is now available return KeyBuf.Get (); } inline Key Keyboard::Peek () // Return the next key but don't remove it from the queue. This function // returns kbNoKey if no key is currently available. { if (KeyBuf.IsEmpty ()) { // Get new key but don't wait GetMappedKey (0); } // Return kbNoKey if no key is available, otherwise return the first // key in the buffer if (KeyBuf.IsEmpty ()) { return kbNoKey; } else { // Return top of stack return KeyBuf.Peek (); } } inline void Keyboard::Put (Key K) { KeyBuf.PutInFront (K); } inline int Keyboard::KeyAvail () { if (!KeyBuf.IsEmpty ()) { // Buffer contains characters return 1; } // Buffer is emtpy, read new keys if there are any GetMappedKey (0); // Now return the buffer status return KeyBuf.IsEmpty () == 0; } inline int Keyboard::IsConsole () // Return true if the keyboard is the console keyboard { return Console; } // End of KBD.H #endif estic-1.61.orig/spunk/keydef.cc0100644000176100001440000000666207031424701015736 0ustar debacleusers/*****************************************************************************/ /* */ /* KEYDEF.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "keydef.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ struct { Key Orig; // Original key Key Meta; // Meta version } MetaTable [] = { { '0', kbMeta0 }, { '1', kbMeta1 }, { '2', kbMeta2 }, { '3', kbMeta3 }, { '4', kbMeta4 }, { '5', kbMeta5 }, { '6', kbMeta6 }, { '7', kbMeta7 }, { '8', kbMeta8 }, { '9', kbMeta9 }, { 'A', kbMetaA }, { 'B', kbMetaB }, { 'C', kbMetaC }, { 'D', kbMetaD }, { 'E', kbMetaE }, { 'F', kbMetaF }, { 'G', kbMetaG }, { 'H', kbMetaH }, { 'I', kbMetaI }, { 'J', kbMetaJ }, { 'K', kbMetaK }, { 'L', kbMetaL }, { 'M', kbMetaM }, { 'N', kbMetaN }, { 'O', kbMetaO }, { 'P', kbMetaP }, { 'Q', kbMetaQ }, { 'R', kbMetaR }, { 'S', kbMetaS }, { 'T', kbMetaT }, { 'U', kbMetaU }, { 'V', kbMetaV }, { 'W', kbMetaW }, { 'X', kbMetaX }, { 'Y', kbMetaY }, { 'Z', kbMetaZ } }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ Key GetMetaCode (Key K) // Return the "meta version" of the given key K or kbNoKey if none exists { // Do a linear search (hmm..., is it worth a binary search?) for (size_t I = 0; I < sizeof (MetaTable) / sizeof (MetaTable [0]); I++) { if (MetaTable [I].Orig == K) { return MetaTable [I].Meta; } } // Not found return kbNoKey; } Key GetMetaKey (Key K) // Return the "normal key" of the meta key given key K or kbNoKey if none // exists { // Do a linear search (hmm..., is it worth a binary search?) for (size_t I = 0; I < sizeof (MetaTable) / sizeof (MetaTable [0]); I++) { if (MetaTable [I].Meta == K) { return MetaTable [I].Orig; } } // Not found return kbNoKey; } estic-1.61.orig/spunk/keydef.h0100644000176100001440000003345007031424701015573 0ustar debacleusers/*****************************************************************************/ /* */ /* KEYDEF.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __KEYDEF_H #define __KEYDEF_H #include "machine.h" /*****************************************************************************/ /* Keycodes */ /*****************************************************************************/ // Type of a key typedef u16 Key; // "Special" key static const Key kbNoKey = 0x0000; /*****************************************************************************/ /* "Plain" Keycodes */ /*****************************************************************************/ // Keys without any modifiers static const Key kbEnter = 0x000D; static const Key kbEsc = 0x001B; static const Key kbBack = 0x0008; static const Key kbTab = 0x0009; // Keys with ctrl modifier static const Key kbCtrlA = 0x0001; static const Key kbCtrlB = 0x0002; static const Key kbCtrlC = 0x0003; static const Key kbCtrlD = 0x0004; static const Key kbCtrlE = 0x0005; static const Key kbCtrlF = 0x0006; static const Key kbCtrlG = 0x0007; static const Key kbCtrlH = 0x0008; static const Key kbCtrlI = 0x0009; static const Key kbCtrlJ = 0x000A; static const Key kbCtrlK = 0x000B; static const Key kbCtrlL = 0x000C; static const Key kbCtrlM = 0x000D; static const Key kbCtrlN = 0x000E; static const Key kbCtrlO = 0x000F; static const Key kbCtrlP = 0x0010; static const Key kbCtrlQ = 0x0011; static const Key kbCtrlR = 0x0012; static const Key kbCtrlS = 0x0013; static const Key kbCtrlT = 0x0014; static const Key kbCtrlU = 0x0015; static const Key kbCtrlV = 0x0016; static const Key kbCtrlW = 0x0017; static const Key kbCtrlX = 0x0018; static const Key kbCtrlY = 0x0019; static const Key kbCtrlZ = 0x001A; inline int IsPlainKey (Key K) // Determine if K is a normal keycode { return ((K & 0xFF00) == 0x0000); } /*****************************************************************************/ /* Extended Keycodes */ /*****************************************************************************/ static const Key kbF1 = 0x013B; static const Key kbF2 = 0x013C; static const Key kbF3 = 0x013D; static const Key kbF4 = 0x013E; static const Key kbF5 = 0x013F; static const Key kbF6 = 0x0140; static const Key kbF7 = 0x0141; static const Key kbF8 = 0x0142; static const Key kbF9 = 0x0143; static const Key kbF10 = 0x0144; static const Key kbF11 = 0x0185; static const Key kbF12 = 0x0186; static const Key kbUp = 0x0148; static const Key kbDown = 0x0150; static const Key kbLeft = 0x014B; static const Key kbRight = 0x014D; static const Key kbPgDn = 0x0151; static const Key kbPgUp = 0x0149; static const Key kbIns = 0x0152; static const Key kbDel = 0x0153; static const Key kbHome = 0x0147; static const Key kbEnd = 0x014F; static const Key kbCtrlF1 = 0x015E; static const Key kbCtrlF2 = 0x015F; static const Key kbCtrlF3 = 0x0160; static const Key kbCtrlF4 = 0x0161; static const Key kbCtrlF5 = 0x0162; static const Key kbCtrlF6 = 0x0163; static const Key kbCtrlF7 = 0x0164; static const Key kbCtrlF8 = 0x0165; static const Key kbCtrlF9 = 0x0166; static const Key kbCtrlF10 = 0x0167; static const Key kbCtrlF11 = 0x0189; static const Key kbCtrlF12 = 0x018A; static const Key kbCtrlTab = 0x0194; static const Key kbCtrlUp = 0x018D; static const Key kbCtrlDown = 0x0191; static const Key kbCtrlLeft = 0x0173; static const Key kbCtrlRight = 0x0174; static const Key kbCtrlPgDn = 0x0176; static const Key kbCtrlPgUp = 0x0184; static const Key kbCtrlIns = 0x0104; static const Key kbCtrlDel = 0x0106; static const Key kbCtrlHome = 0x0177; static const Key kbCtrlEnd = 0x0175; // Keys with meta prefix static const Key kbMeta1 = 0x0178; static const Key kbMeta2 = 0x0179; static const Key kbMeta3 = 0x017A; static const Key kbMeta4 = 0x017B; static const Key kbMeta5 = 0x017C; static const Key kbMeta6 = 0x017D; static const Key kbMeta7 = 0x017E; static const Key kbMeta8 = 0x017F; static const Key kbMeta9 = 0x0180; static const Key kbMeta0 = 0x0181; static const Key kbMetaA = 0x011E; static const Key kbMetaB = 0x0130; static const Key kbMetaC = 0x012E; static const Key kbMetaD = 0x0120; static const Key kbMetaE = 0x0112; static const Key kbMetaF = 0x0121; static const Key kbMetaG = 0x0122; static const Key kbMetaH = 0x0123; static const Key kbMetaI = 0x0117; static const Key kbMetaJ = 0x0124; static const Key kbMetaK = 0x0125; static const Key kbMetaL = 0x0126; static const Key kbMetaM = 0x0132; static const Key kbMetaN = 0x0131; static const Key kbMetaO = 0x0118; static const Key kbMetaP = 0x0119; static const Key kbMetaQ = 0x0110; static const Key kbMetaR = 0x0113; static const Key kbMetaS = 0x011F; static const Key kbMetaT = 0x0114; static const Key kbMetaU = 0x0116; static const Key kbMetaV = 0x012F; static const Key kbMetaW = 0x0111; static const Key kbMetaX = 0x012D; static const Key kbMetaY = 0x0115; static const Key kbMetaZ = 0x012C; static const Key kbMetaF1 = 0x0168; static const Key kbMetaF2 = 0x0169; static const Key kbMetaF3 = 0x016A; static const Key kbMetaF4 = 0x016B; static const Key kbMetaF5 = 0x016C; static const Key kbMetaF6 = 0x016D; static const Key kbMetaF7 = 0x016E; static const Key kbMetaF8 = 0x016F; static const Key kbMetaF9 = 0x0170; static const Key kbMetaF10 = 0x0171; static const Key kbMetaF11 = 0x018B; static const Key kbMetaF12 = 0x018C; static const Key kbMetaEsc = 0x0101; static const Key kbMetaSpace = 0x0102; static const Key kbMetaTab = 0x01A5; static const Key kbMetaPgDn = 0x01A1; static const Key kbMetaPgUp = 0x0199; static const Key kbMetaIns = 0x01A2; static const Key kbMetaDel = 0x01A3; static const Key kbMetaHome = 0x0197; static const Key kbMetaEnd = 0x019F; static const Key kbMetaLeft = 0x019B; static const Key kbMetaRight = 0x019D; static const Key kbMetaUp = 0x0198; static const Key kbMetaDown = 0x01A0; // Keys with shift modifier static const Key kbShiftF1 = 0x0154; static const Key kbShiftF2 = 0x0155; static const Key kbShiftF3 = 0x0156; static const Key kbShiftF4 = 0x0157; static const Key kbShiftF5 = 0x0158; static const Key kbShiftF6 = 0x0159; static const Key kbShiftF7 = 0x015A; static const Key kbShiftF8 = 0x015B; static const Key kbShiftF9 = 0x015C; static const Key kbShiftF10 = 0x015D; static const Key kbShiftF11 = 0x0187; static const Key kbShiftF12 = 0x0188; static const Key kbShiftTab = 0x010F; static const Key kbShiftIns = 0x0105; static const Key kbShiftDel = 0x0107; // Some keys used in linux. Note: Those are not supported by the PC hardware // but mapped by key sequences from the key mapper. They are used to define // virtual keys when the corresponding extended keys are not available. // Beware: Don't use numbers defined above! static const Key kbEscCtrlA = 0x01B0; static const Key kbEscCtrlB = 0x01B1; static const Key kbEscCtrlC = 0x01B2; static const Key kbEscCtrlD = 0x01B3; static const Key kbEscCtrlE = 0x01B4; static const Key kbEscCtrlF = 0x01B5; static const Key kbEscCtrlG = 0x01B6; static const Key kbEscCtrlH = 0x01B7; static const Key kbEscCtrlI = 0x01B8; static const Key kbEscCtrlJ = 0x01B9; static const Key kbEscCtrlK = 0x01BA; static const Key kbEscCtrlL = 0x01BB; static const Key kbEscCtrlM = 0x01BC; static const Key kbEscCtrlN = 0x01BD; static const Key kbEscCtrlO = 0x01BE; static const Key kbEscCtrlP = 0x01BF; static const Key kbEscCtrlQ = 0x01C0; static const Key kbEscCtrlR = 0x01C1; static const Key kbEscCtrlS = 0x01C2; static const Key kbEscCtrlT = 0x01C3; static const Key kbEscCtrlU = 0x01C4; static const Key kbEscCtrlV = 0x01C5; static const Key kbEscCtrlW = 0x01C6; static const Key kbEscCtrlX = 0x01C7; static const Key kbEscCtrlY = 0x01C8; static const Key kbEscCtrlZ = 0x01C9; static const Key kbEscEsc = 0x01CA; // Mapped to vkAbort static const Key kbCtrlQS = 0x01CB; // Mapped to vkHome static const Key kbCtrlQD = 0x01CC; // Mapped to vkEnd static const Key kbCtrlQR = 0x01CD; // Mapped to vkCtrlPgUp static const Key kbCtrlQC = 0x01CE; // Mapped to vkCtrlPgDn static const Key kbCtrlQE = 0x01CF; // Mapped to vkCtrlHome static const Key kbCtrlQX = 0x01D0; // Mapped to vkCtrlEnd inline int IsExtendedKey (Key K) // Determine if K is a extended keycode { return ((K & 0xFF00) == 0x0100); } /*****************************************************************************/ /* Virtual Keycodes */ /*****************************************************************************/ // The following keys are garantied to exist static const Key vkAbort = 0x0201; static const Key vkHelp = 0x0202; static const Key vkAccept = 0x0203; static const Key vkPgUp = 0x0210; static const Key vkPgDn = 0x0211; static const Key vkCtrlPgUp = 0x0212; static const Key vkCtrlPgDn = 0x0213; static const Key vkUp = 0x0214; static const Key vkDown = 0x0215; static const Key vkLeft = 0x0216; static const Key vkRight = 0x0217; static const Key vkCtrlUp = 0x0218; static const Key vkCtrlDown = 0x0219; static const Key vkCtrlLeft = 0x021A; static const Key vkCtrlRight = 0x021B; static const Key vkIns = 0x021C; static const Key vkDel = 0x021D; static const Key vkHome = 0x021E; static const Key vkEnd = 0x021F; static const Key vkCtrlIns = 0x0220; static const Key vkCtrlDel = 0x0221; static const Key vkCtrlHome = 0x0222; static const Key vkCtrlEnd = 0x0223; static const Key vkZoom = 0x0230; static const Key vkClose = 0x0231; static const Key vkOpen = 0x0232; static const Key vkResize = 0x0233; static const Key vkQuit = 0x0234; static const Key vkSave = 0x0235; inline int IsVirtualKey (Key K) // Determine if K is a virtual keycode { return ((K & 0xFF00) == 0x0200); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ Key GetMetaCode (Key K); // Return the "meta version" of the given key K or kbNoKey if none exists Key GetMetaKey (Key K); // Return the "normal key" of the meta key given key K or kbNoKey if none // exists // End of KEYDEF.H #endif estic-1.61.orig/spunk/keymap.cc0100644000176100001440000000547207031424701015753 0ustar debacleusers/*****************************************************************************/ /* */ /* KEYMAP.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "keymap.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class KeyMapper */ /*****************************************************************************/ KeyMapper::KeyMapper () : SortedCollection (20, 10, 1) { } void KeyMapper::Add (const char* S, Key K) // If S is not NULL or empty, add an entry with the given mapping { if (S && *S != '\0') { Insert (new KeyMap (S, K)); } } void* KeyMapper::GetItem (Stream& S) { return (void*) S.Get (); } void KeyMapper::PutItem (Stream& S, void* Item) const { S.Put ((KeyMap*) Item); } int KeyMapper::Compare (const char* Key1, const char* Key2) { return strcmp (Key1, Key2); } const char* KeyMapper::KeyOf (const KeyMap* Item) { return Item->Sequence.GetStr (); } int KeyMapper::Find (const char* S, int& Index) // Try to find the string S. Return values are // 0: There has been no match and there will be no possible match, even // if we add more chars to S. Index is invalid on return. // 1: There has been a partial match. Maybe we get a full match if we // add more chars to S. Index is invalid on return. // 2: There has been a full match. Index is the index of the entry found. { if (Search (S, Index)) { // We have a full match return 2; } int Len = strlen (S); while (Index < GetCount ()) { if (strncmp (S, At (Index)->Sequence.GetStr (), Len) == 0) { // Partial match return 1; } Index++; } // No match return 0; } estic-1.61.orig/spunk/keymap.h0100644000176100001440000000622107031424701015606 0ustar debacleusers/*****************************************************************************/ /* */ /* KEYMAP.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __KEYMAP_H #define __KEYMAP_H #include "coll.h" #include "str.h" #include "keydef.h" /*****************************************************************************/ /* class KeyMap */ /*****************************************************************************/ // Forward class KeyMapper; class KeyMap: public Streamable { friend class KeyMapper; private: String Sequence; // ESC sequence from keyboard Key K; // Resulting key public: KeyMap (const String& S, Key aKey); // Construct a keymap object KeyMap (const char* S, Key aKey); // Construct a keymap object Key GetKey () const; // Return the key }; inline KeyMap::KeyMap (const String& S, Key aKey): Sequence (S), K (aKey) { } inline KeyMap::KeyMap (const char* S, Key aKey): Sequence (S), K (aKey) { } inline Key KeyMap::GetKey () const { return K; } /*****************************************************************************/ /* class KeyMapper */ /*****************************************************************************/ class KeyMapper: public SortedCollection { protected: // Derived from class Collection virtual void* GetItem (Stream& S); virtual void PutItem (Stream& S, void* Item) const; virtual int Compare (const char* Key1, const char* Key2); virtual const char* KeyOf (const KeyMap* Item); KeyMapper (StreamableInit); // Build constructor public: KeyMapper (); // Construct a KeyMapper object void Add (const char* S, Key K); // If S is not NULL or empty, add an entry with the given mapping int Find (const char* S, int& Index); // Try to find the string S. Return values are // 0: There has been no match and there will be no possible match, even // if we add more chars to S. Index is invalid on return. // 1: There has been a partial match. Maybe we get a full match if we // add more chars to S. Index is invalid on return. // 2: There has been a full match. Index is the index of the entry found. }; inline KeyMapper::KeyMapper (StreamableInit): SortedCollection (Empty) { } // End of KEYMAP.H #endif estic-1.61.orig/spunk/listbox.h0100644000176100001440000003512407031424701016010 0ustar debacleusers/*****************************************************************************/ /* */ /* LISTBOX.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file contains some unnecessary global scope overrides (::) to work // around a gcc bug (2.5.8) #ifndef __LISTBOX_H #define __LISTBOX_H #include "stream.h" #include "keydef.h" #include "palette.h" #include "itemwin.h" #include "progutil.h" /*****************************************************************************/ /* class ListBox */ /*****************************************************************************/ template class ListBox: public WindowItem { protected: Collection* Coll; // Collection used Point Size; // Size of the listbox i16 First; // First displayed entry i16 Selected; // Number of selected entry u16 NormAttr; // Attribute used for normal text u16 SelAttr; // Attribute used for selected text u16 HighAttr; // Selected text when inactive virtual void Up (); virtual void Down (); virtual void PgUp (); virtual void PgDn (); virtual void Home (); virtual void End (); // Handle a specific key void DrawSelected (u16 Attr); // Draw the selected entry with the given attribute virtual void Print (int Index, int X, int Y, u16 Attr) = 0; // Display one of the listbox entries virtual unsigned GetAttr (int Index); // Return the palette index for the entry with the given index ListBox (StreamableInit); // Build constructor public: ListBox (const String& aItemText, i16 aID, const Point& aSize, u16 aNormAttr, u16 aSelAttr, u16 aHighAttr, WindowItem* NextItem); ListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem); virtual ~ListBox (); // Derived from class Streamable virtual void Store (Stream& S) const; virtual void Load (Stream& S); virtual u16 StreamableID () const; // Make shure, ListBox is not stored into a stream (there is no compile time // error without that since the base class (WindowItem) has the needed // functionality, but the program will crash on a load. // Derived from class WindowItem virtual void SetWidth (u16 NewWidth); virtual void Draw (); virtual void Activate (); virtual void Deactivate (); virtual void Gray (); virtual void Select (); virtual void Deselect (); // -- New functions void SetHeight (u16 NewHeight); // Set the height of the box int GetCount (); // Return the number of entries in Coll or zero if no collection is // present Collection* GetColl (); // Return the collection in use void SetColl (Collection* C); // Set the collection to use void FreeCollection (); // Free the given Collection, set the pointer to NULL T* GetSelection (); // Return the item with index Selected from the collection. If Selected is // invalid (no items), return NULL. T* At (int Index); // Returns an entry from the collection void Delete (int Index); // Delete an entry from the listbox, then redraw the box. void Insert (T* Item); // Insert a new entry into the collection and redraw the listbox void Replace (int Index, T* Item); // Replace a entry in the collection by a new one virtual void Reset (); // Zero First and Selected virtual void SetSelected (int NewSel); // Set the number of the selected entry. If the box is the active item, // the bar is also redrawn. If the index of the new item is out of bounds, // the request is ignored. int GetSelected (); // Return the number of the selected entry or -1 if the collection is // empty or non-existant void SelectedToTop (); // Scroll the contents of the listbox. After the operation, the highlighted // entry is at the top of the box. virtual void HandleKey (Key& K); // Call one of the key specific handle functions. If the key is handled, // K is reset to kbNoKey, otherwise K is left unchanged. virtual i16 Choose (); // Overrides WindowItem::Choose. Allow browsing in the listbox. Returns // the ID if a selection (with enter) is made, return 0 otherwise. }; template ListBox::ListBox (const String& aItemText, i16 aID, const Point& aSize, u16 aNormAttr, u16 aSelAttr, u16 aHighAttr, WindowItem* NextItem): WindowItem (aItemText, aID, NextItem), Coll (NULL), Size (aSize), First (0), Selected (-1), NormAttr (aNormAttr), SelAttr (aSelAttr), HighAttr (aHighAttr) { // Set the correct item width (work around bugs in gcc) unsigned XSize = Size.X; if (XSize > ItemWidth) { ItemWidth = XSize; } } template ListBox::ListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem) : WindowItem (aItemText, aID, NextItem), Coll (NULL), Size (aSize), First (0), Selected (-1), NormAttr (atTextNormal), SelAttr (atTextInvers), HighAttr (atTextHigh) { // Set the correct item width (work around bugs in gcc) unsigned XSize = Size.X; if (XSize > ItemWidth) { ItemWidth = XSize; } } template ListBox::~ListBox () { FreeCollection (); } template inline ListBox::ListBox (StreamableInit): WindowItem (Empty) { } template void ListBox::Up () { SetSelected (Selected - 1); } template void ListBox::Down () { SetSelected (Selected + 1); } template void ListBox::PgUp () { if (Selected > 0) { int NewSel = Selected - Size.Y + 1; if (NewSel < 0) { NewSel = 0; } SetSelected (NewSel); } } template void ListBox::PgDn () { int Last = GetCount () - 1; if (Selected != Last) { int NewSel = Selected + Size.Y - 1; if (NewSel > Last) { NewSel = Last; } SetSelected (NewSel); } } template void ListBox::Home () { SetSelected (0); } template void ListBox::End () { SetSelected (GetCount () - 1); } template void ListBox::DrawSelected (u16 Attr) // Draw the selected entry with the given attribute { if (Selected == -1) { // Nothing to do return; } int YPos = ItemY + (Selected - First); if (ItemText.Len () > 0) { // Add one line for the item text YPos++; } Print (Selected, ItemX, YPos, Attr); } template void ListBox::Store (Stream& S) const { WindowItem::Store (S); S.Put (Coll); S << Size << First << Selected << NormAttr << SelAttr << HighAttr; } template void ListBox::Load (Stream& S) { WindowItem::Load (S); Coll = (Collection*) S.Get (); S >> Size >> First >> Selected >> NormAttr >> SelAttr >> HighAttr; } template u16 ListBox::StreamableID () const // Make shure, ListBox is not stored into a stream (there is no compile time // error without that since the base class (WindowItem) has the needed // functionality, but the program will crash on a load. { ABSTRACT (); return 0; } template void ListBox::SetWidth (u16 NewWidth) { if (NewWidth >= MinWidth ()) { ItemWidth = NewWidth; Size.X = NewWidth; } } template unsigned ListBox::GetAttr (int Index) // Return the palette index for the given entry { if (Index < 0 || Index >= Coll->GetCount ()) { // No valid index return NormAttr; } else if (Index == Selected) { // Selected entry if (IsSelected ()) { return SelAttr; } else { return HighAttr; } } else { return NormAttr; } } template void ListBox::Activate () { WindowItem::Activate (); DrawSelected (GetAttr (Selected)); } template void ListBox::Deactivate () { WindowItem::Deactivate (); DrawSelected (GetAttr (Selected)); } template void ListBox::Gray () { WindowItem::Gray (); DrawSelected (GetAttr (Selected)); } template void ListBox::Select () { WindowItem::Select (); DrawSelected (GetAttr (Selected)); } template void ListBox::Deselect () { WindowItem::Deselect (); DrawSelected (GetAttr (Selected)); } template void ListBox::Draw () { // Draw the item text WindowItem::Draw (); // Build an empty string to clear lines String S (Size.X); S.Set (0, Size.X); // Draw the box int Current = First; int StartY = ItemY; int EndY = StartY + Size.Y - 1; int Count = Coll->GetCount (); if (ItemText.Len () > 0) { StartY++; } // Lock the owner window, accumulate output Owner->Lock (); // Display all lines of the listbox for (int Y = StartY; Y <= EndY; Y++, Current++) { if (Current < Count) { // Valid entry, call Print Print (Current, ItemX, Y, GetAttr (Current)); } else { // Entry is not valid, clear the line Owner->Write (ItemX, Y, S, NormAttr); } } // Now unlock the output Owner->Unlock (); } template void ListBox::SetHeight (u16 NewHeight) // Set the height of the box { if (ItemText.Len () > 0) { if (NewHeight >= 2) { Size.Y = NewHeight; } } else { if (NewHeight >= 1) { Size.Y = NewHeight; } } } template int ListBox::GetCount () // Return the number of entries in Coll or zero if no collection is // present { return Coll->GetCount (); } template inline Collection* ListBox::GetColl () // Return the collection in use { return Coll; } template void ListBox::SetColl (Collection *C) // Set the collection to use { // Remember new collection Coll = C; // Reset the listbox Reset (); } template void ListBox::FreeCollection () // Free the given Collection, set the pointer to NULL { delete Coll; Coll = NULL; Reset (); } template T* ListBox::GetSelection () // Return the item with index Selected from the collection. If Selected is // invalid (no items), return NULL. { return Selected == -1? (T*) NULL : Coll->At (Selected); } template inline T* ListBox::At (int Index) // Returns an entry from the collection { return Coll->At (Index); } template void ListBox::Delete (int Index) // Delete an entry from the listbox, then redraw the box. { if (Index < 0 || Index >= GetCount ()) { // Index is not valid return; } // Index is valid, delete it Coll->AtDelete (Index); // Be carefull: this could be the last entry! if (Coll->GetCount () == 0) { // That's it, no more entries Selected = -1; } else { if (Index > 0) { Selected--; } } // Redraw the listbox Draw (); } template void ListBox::Insert (T * Item) // Insert a new entry into the collection and redraw the listbox { // Insert is possible only if the collection is valid PRECONDITION (Coll != NULL); // Insert the item into the collection Coll->Insert (Item); // In any case, we have a selected entry now if (Selected == -1) { Selected = 0; } // Redraw the listbox Draw (); } template void ListBox::Replace (int Index, T * Item) // Replace a entry in the collection by a new one { // Replace is possible only if the collection is valid PRECONDITION (Coll != NULL); // The entry must be in the valid range PRECONDITION (Index >= 0 && Index < GetCount ()); // Replace the item in the collection Coll->AtReplace (Index, Item); // If the index is in the visible range, we have to redraw this entry if (Index >= First && Index < (First + Size.Y)) { int Y = Index - First + ItemY; Print (Index, ItemX, Y, GetAttr (Index)); } } template void ListBox::Reset () // Zero First and Selected { First = 0; Selected = GetCount () ? 0 : -1; } template void ListBox::SetSelected (int NewSel) // Set the number of the selected entry. If the box is the active item, // the bar is also redrawn. If the index of the new item is out of bounds, // the request is ignored. { // Ignore invalid indizes int Count = GetCount (); if (NewSel >= Count || NewSel < 0) { return; } // Calculate the index of the last displayed entry int Last = First + Size.Y - 1; if (Last >= Count) { Last = Count - 1; } // Check if the new entry is inside the currently displayed area if (NewSel < First) { // The new entry is below the first displayed one First = NewSel; Selected = NewSel; Draw (); } else if (NewSel > Last) { // The new entry is above the last displayed one Selected = NewSel; First = NewSel - Size.Y + 1; Draw (); } else { // The new entry is inside the visible area DrawSelected (NormAttr); Selected = NewSel; DrawSelected (GetAttr (Selected)); } } template inline int ListBox::GetSelected () // Return the number of the selected entry or -1 if the collection is // empty or non-existant { return Selected; } template void ListBox::SelectedToTop () // Scroll the contents of the listbox. After the operation, the highlighted // entry is at the top of the box. { if (Selected >= 0 && Selected != First) { First = Selected; Draw (); } } template void ListBox::HandleKey (Key &K) // Call one of the key specific handle functions. If the key is handled, // K is reset to kbNoKey, otherwise K is left unchanged. { switch (K) { case vkHelp: CallHelp (); K = kbNoKey; break; case vkUp: Up (); K = kbNoKey; break; case vkDown: Down (); K = kbNoKey; break; case vkPgUp: PgUp (); K = kbNoKey; break; case vkPgDn: PgDn (); K = kbNoKey; break; case vkHome: Home (); K = kbNoKey; break; case vkEnd: End (); K = kbNoKey; break; } } template i16 ListBox::Choose () // Overrides WindowItem::Choose. Allow browsing in the listbox. Returns // the ID if a selection (with enter) is made, return 0 otherwise. { while (1) { // Get a key Key K = ::KbdGet (); // Handle listbox keys HandleKey (K); // Look if something is left switch (K) { case vkAbort: return 0; case kbEnter: case vkAccept: return ID; default: if (K != AccelKey && ::KeyIsRegistered (K)) { ::KbdPut (K); return 0; } break; } } } // End of LISTBOX.H #endif estic-1.61.orig/spunk/listnode.cc0100644000176100001440000000766107031424701016310 0ustar debacleusers/*****************************************************************************/ /* */ /* LISTNODE.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "listnode.h" /*****************************************************************************/ /* class _ListNode */ /*****************************************************************************/ _ListNode::_ListNode (void* DataPtr) { NextNode = PrevNode = this; ContentsPtr = DataPtr; } _ListNode::~_ListNode () { Unlink (); } void _ListNode::InsertAfter (_ListNode* N) // inserts one node after another { // the node cannot be inserted after itself PRECONDITION (N != this); // switch pointers NextNode = N->NextNode; PrevNode = N; N->NextNode = this; NextNode->PrevNode = this; } void _ListNode::InsertBefore (_ListNode* N) // inserts one node before another { // the node cannot be inserted before itself PRECONDITION (N != this); // switch pointers PrevNode = N->PrevNode; NextNode = N; N->PrevNode = this; PrevNode->NextNode = this; } void _ListNode::Unlink () // Unlinks a node from a list. { // If the list constists only of this element, no unlink is necessary if (NextNode == this) { return; } // unlink node PrevNode->NextNode = NextNode; NextNode->PrevNode = PrevNode; // the unlinked node is a list with one node NextNode = PrevNode = this; } _ListNode* _ListNode::Traverse (int Forward, int (*F) (_ListNode*, void*), void *UserPtr) // Traverse through a list, starting with the current node and calling the // given function F with every node as argument. Ends if finally the current // node is reached again (all nodes have been visited in this case) or if the // called function returns a value != 0. In the former case, Traverse returns // a NULL pointer, in the latter, a pointer to the node is returned. { _ListNode* N = this; do { if (F (N, UserPtr)) { // function returned true return N; } if (Forward) { N = N->NextNode; } else { N = N->PrevNode; } } while (N != this); // Walked through the whole list, return NULL return NULL; } u16 _ListNode::NodeCount () // Returns the node count of the list { register u16 Count = 0; _ListNode* N = this; do { Count++; N = N->NextNode; } while (N != this); return Count; } _ListNode* _ListNode::NodeWithNumber (u16 X) // Returns the node with number X. Counting begins with "this", (which has // number 0) and proceeds in "Next" direction. // Warning: If X is greater than the number of nodes in the list, the // result is undefined (wraping around). { _ListNode* N = this; while (X--) { N = N->NextNode; } return N; } u16 _ListNode::NumberOfNode (_ListNode* N) // Returns the number of node N. Counting begins with "this" node // (which has number 0) and proceeds in "Next" direction. { register u16 Count = 0; _ListNode* R = this; while (R != N) { Count++; R = R->NextNode; CHECK (R != this); // Means N is not in list } return Count; } estic-1.61.orig/spunk/listnode.h0100644000176100001440000001341707031424701016146 0ustar debacleusers/*****************************************************************************/ /* */ /* LISTNODE.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __LISTNODE_H #define __LISTNODE_H #include #include "machine.h" #include "check.h" #include "object.h" /*****************************************************************************/ /* class _ListNode */ /*****************************************************************************/ // This is an implementation class for the template class ListNode. It has // the complete functionality but uses void pointers instead of typed pointers. // This hopefully will result in smaller programs. class _ListNode: public Object { protected: // pointer to the data void* ContentsPtr; // pointers to the prevoius and next node _ListNode* PrevNode; _ListNode* NextNode; public: _ListNode (void* DataPtr = NULL); ~_ListNode (); // get contents of the node void* Contents (); // get the previous and next nodes _ListNode* Next (); _ListNode* Prev (); // check if the list is empty (one node only) int IsEmpty (); // linking in the list void InsertIn (_ListNode* R); void InsertAfter (_ListNode* N); void InsertBefore (_ListNode* N); // unlink a node void Unlink (); // traverse through all nodes _ListNode* Traverse (int Forward, int (*F) (_ListNode*, void*), void* UserPtr = NULL); // count number of nodes u16 NodeCount (); // convert node to number and vice versa _ListNode* NodeWithNumber (u16 X); u16 NumberOfNode (_ListNode* N); }; inline void* _ListNode::Contents () { return ContentsPtr; } inline _ListNode* _ListNode::Next () { return NextNode; } inline _ListNode* _ListNode::Prev () { return PrevNode; } inline int _ListNode::IsEmpty () { return (NextNode == this); } inline void _ListNode::InsertIn (_ListNode* R) { InsertAfter (R); } /*****************************************************************************/ /* class ListNode */ /*****************************************************************************/ template class ListNode: public _ListNode { public: ListNode (T* DataPtr = NULL); // get contents of the node T* Contents (); // get the previous and next nodes ListNode* Next (); ListNode* Prev (); // linking in the list void InsertIn (ListNode* R); void InsertAfter (ListNode* N); void InsertBefore (ListNode* N); // traverse through all nodes ListNode* Traverse (int Forward, int (*F) (ListNode*, void*), void* UserPtr = NULL); // convert node to number and vice versa ListNode* NodeWithNumber (u16 X); u16 NumberOfNode (ListNode* N); }; template inline ListNode::ListNode (T* DataPtr): _ListNode (DataPtr) { } template inline T* ListNode::Contents () { return (T*) _ListNode::Contents (); } template inline ListNode* ListNode::Next () { return (ListNode*) _ListNode::Next (); } template inline ListNode* ListNode::Prev () { return (ListNode*) _ListNode::Prev (); } template inline void ListNode::InsertIn (ListNode* R) { _ListNode::InsertIn ((_ListNode*) R); } template inline void ListNode::InsertAfter (ListNode* N) // inserts one node after another { _ListNode::InsertAfter ((_ListNode*) N); } template inline void ListNode::InsertBefore (ListNode* N) // inserts one node before another { _ListNode::InsertBefore ((_ListNode*) N); } template inline ListNode* ListNode::Traverse (int Forward, int (*F) (ListNode*, void*), void *UserPtr) // Traverse through a list, starting with the current node and calling the // given function F with every node as argument. Ends if finally the current // node is reached again (all nodes have been visited in this case) or if the // called function returns a value != 0. In the former case, Traverse returns // a NULL pointer, in the latter, a pointer to the node is returned. { typedef int (*UntypedFunc) (_ListNode*, void*); return (ListNode*) _ListNode::Traverse (Forward, (UntypedFunc) F, UserPtr); } template inline ListNode* ListNode::NodeWithNumber (u16 X) // Returns the node with number X. Counting begins with "this", (which has // number 0) and proceeds in "Next" direction. // Warning: If X is greater than the number of nodes in the list, the // result is undefined (wraping around). { return (ListNode*) _ListNode::NodeWithNumber (X); } template inline u16 ListNode::NumberOfNode (ListNode* N) // Returns the number of node N. Counting begins with "this" node // (which has number 0) and proceeds in "Next" direction. { return _ListNode::NumberOfNode ((_ListNode*) N); } // End of LISTNODE.H #endif estic-1.61.orig/spunk/machine.h0100644000176100001440000002334207031424701015727 0ustar debacleusers/*****************************************************************************/ /* */ /* MACHINE.H */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // #ifndef _MACHINE_H #define _MACHINE_H /*****************************************************************************/ /* DOS */ /*****************************************************************************/ #ifdef DOS // Endianess #define CPU_LITTLE_ENDIAN // File system supports drives #define FILESYS_HAS_DRIVES // data types typedef int i16; // int with 16 bits typedef unsigned u16; // unsigned with 16 bits typedef long i32; // int with 32 bits typedef unsigned long u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* DOS programs using a 32 bit extender */ /*****************************************************************************/ #ifdef DOS32 // Endianess #define CPU_LITTLE_ENDIAN // File system supports drives #define FILESYS_HAS_DRIVES // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* OS/2 */ /*****************************************************************************/ #ifdef OS2 // Endianess #define CPU_LITTLE_ENDIAN // File system supports drives #define FILESYS_HAS_DRIVES // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* WINDOWS 95/NT */ /*****************************************************************************/ #ifdef NT // Endianess #define CPU_LITTLE_ENDIAN // File system supports drives #define FILESYS_HAS_DRIVES // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* Novell Netware */ /*****************************************************************************/ #ifdef NETWARE // Endianess #define CPU_LITTLE_ENDIAN // File system supports volumes #define FILESYS_HAS_VOLUMES // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* SVR4 (Unixware, etc.) */ /*****************************************************************************/ #ifdef SVR4 // Uncomment one of the following #define CPU_LITTLE_ENDIAN // #define CPU_BIG_ENDIAN // If your machine has no usleep, uncomment the following // #define DONT_HAS_USLEEP // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* Generic Unix - make your own entry after porting */ /*****************************************************************************/ #ifdef GENERIC_UNIX // Uncomment one of the following #define CPU_LITTLE_ENDIAN // #define CPU_BIG_ENDIAN // If your machine has no usleep, uncomment the following // #define DONT_HAS_USLEEP // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* Linux */ /*****************************************************************************/ #ifdef LINUX // Endianess. The following code is not very clean as it accesses a reserved // implementation identifier, but there is no other way to determine byte // order under Linux (known to me). #include #if __BYTE_ORDER == 1234 # define CPU_LITTLE_ENDIAN #elif __BYTE_ORDER = 4321 # define CPU_BIG_ENDIAN #elif # error Byte order not defined! #endif // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* FreeBSD */ /*****************************************************************************/ #ifdef FREEBSD #include #if (BYTE_ORDER == LITTLE_ENDIAN) # define CPU_LITTLE_ENDIAN #elif (BYTE_ORDER == BIG_ENDIAN) # define CPU_BIG_ENDIAN #elif # error Byte order not defined! #endif // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* HP/UX */ /*****************************************************************************/ #ifdef HPUX #include #ifdef _BIG_ENDIAN # define CPU_BIG_ENDIAN #else # define CPU_LITTLE_ENDIAN #endif // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* NetBSD (Amiga) */ /*****************************************************************************/ #ifdef NETBSD #include #if (BYTE_ORDER == LITTLE_ENDIAN) # define CPU_LITTLE_ENDIAN #elif (BYTE_ORDER == BIG_ENDIAN) # define CPU_BIG_ENDIAN #elif # error Byte order not defined! #endif // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* Solaris */ /*****************************************************************************/ #ifdef SOLARIS #include #ifdef _BIG_ENDIAN # define CPU_BIG_ENDIAN #else # define CPU_LITTLE_ENDIAN #endif // data types typedef short int i16; // int with 16 bits typedef unsigned short u16; // unsigned with 16 bits typedef int i32; // int with 32 bits typedef unsigned int u32; // unsigned int with 32 bits #endif /*****************************************************************************/ /* Some other defines that simplify things */ /*****************************************************************************/ #if defined (DOS) || defined (DOS32) || defined (OS2) || defined(NT) #define DOSLIKE_OS #elif !defined(NETWARE) #define UNIXLIKE_OS #endif // End of MACHINE.H #endif estic-1.61.orig/spunk/memcheck.cc0100644000176100001440000003071207031424701016234 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMCHECK.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Poor man's memory checker. Overloads the global operators new and delete // and does some additional checks if the variable MemCheck is set to true: // // * Check if an allocated block is already allocated (heap corrupt) // * Check if a block that should be freed is allocated // * Check if there have been writes outside the blocks bounds (by // adding a signature to the end) // * Check if new does not provide a NULL pointer. #include #include #include #include "machine.h" #include "check.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Signature of a memory block static u32 MemSig = 0x12785634; // Switch memory checking on or off int MemCheck = 0; // Switch memory filling on or off int MemFill = 0; // Statistics u32 MemNewCount = 0; u32 MemDelCount = 0; u32 MemDelNULLCount = 0; u32 MemNewCheckCount = 0; u32 MemDelCheckCount = 0; u32 MemLargestBlock = 0; u32 MemUsage = 0; u32 MemMaxUsage = 0; // This is the fill value for memory blocks if MemFill is true. On intel // architectures, this is the code for "INT 3", an instruction that is // often used by debuggers as a breakpoint. const unsigned char FillVal = 0xCC; /*****************************************************************************/ /* struct BlockInfo */ /*****************************************************************************/ struct BlockInfo { unsigned char* Ptr; u32 Size; }; // const int FirstChunk = 2000; const int Delta = 1000; // Variables needed static int IsInitialized = 0; static int BlockCount = 0; static int BlockLimit = 0; static BlockInfo* Blocks = NULL; /*****************************************************************************/ /* class BlockInfoColl */ /*****************************************************************************/ static void MemSetCount (int NewCount) // Make shure, there is space for NewSize blocks in Blocks { if (NewCount > BlockLimit) { // OOPS, need realloc if (BlockLimit == 0 && NewCount <= FirstChunk) { BlockLimit = FirstChunk; } else { BlockLimit = ((NewCount / Delta) + 1) * Delta; } Blocks = (BlockInfo*) realloc (Blocks, BlockLimit * sizeof (BlockInfo)); } BlockCount = NewCount; } static int MemSearch (const unsigned char* Ptr, int& Index) // Search for the block. Return 1 if the block is found (Index holds the // block index in this case). Return 0 if the block is not found and return // in Index the index where the block should be inserted. { // do a binary search int First = 0; int Last = BlockCount - 1; int Current; int S = 0; while (First <= Last) { // Set current to mid of range Current = (Last + First) / 2; // Do a compare if (Blocks [Current].Ptr < Ptr) { First = Current + 1; } else { Last = Current - 1; if (Blocks [Current].Ptr == Ptr) { // Found. S = 1; // function result // Set condition to terminate loop First = Current; } } } Index = First; return S; } static void MemDelBlock (int Index) // Delete the block with the given index { BlockCount--; memmove (Blocks+Index, Blocks+Index+1, (BlockCount-Index) * sizeof (BlockInfo)); } static void MemInsBlock (int Index, unsigned char* Ptr, u32 Size) { // Set the new size MemSetCount (BlockCount + 1); // We can insert the element. If the item is not inserted at the end // of the collection, we must create a "hole" if (Index != BlockCount - 1) { memmove (Blocks + Index + 1, Blocks + Index, (BlockCount - 1 - Index) * sizeof (BlockInfo)); } // store the new data Blocks [Index].Ptr = Ptr; Blocks [Index].Size = Size; } u32 MemBlocksInUse () { return (u32) BlockCount; } void MemLogBlocksInUse (const char* Name) { FILE* F = fopen (Name, "w+t"); if (F == NULL) { // This is a debug function, so ignore the error return; } // Get the block count and log some statistics fprintf (F, "Blocks currently in use: %8lu\n\n" "Calls to operator new: %8lu\n" "Calls to operator delete: %8lu\n" "Checked calls to new: %8lu\n" "Checked calls to delete: %8lu\n" "Calls to delete with a NULL arg: %8lu\n\n" "Largest block allocated: %8lu\n" "Maximum memory usage: %8lu\n\n", (unsigned long) BlockCount, (unsigned long) MemNewCount, (unsigned long) MemDelCount, (unsigned long) MemNewCheckCount, (unsigned long) MemDelCheckCount, (unsigned long) MemDelNULLCount, (unsigned long) MemLargestBlock, (unsigned long) MemMaxUsage); // Log the blocks BlockInfo* Block = Blocks; for (int I = 0; I < BlockCount; I++, Block++) { // Print a line describing the block (convert pointers to hex values) fprintf (F, "Block %5u: Loc = 0x%08lX, Size = %5lu\n", I, (unsigned long) Block->Ptr, (unsigned long) Block->Size); } // Close the file fclose (F); } static void MemDone () // Log the memory blocks if requested. Does *not* delete the block array // since the startup code may release memory after calling the exit functions // and in this case we will work with a freed block, if we free the block // array here { // If the environment variable SPUNK_MEMLOGBLOCKS is set to something, use // this "something" as a filename to log a list of still allocated blocks const char* Name = getenv ("SPUNK_MEMLOGBLOCKS"); if (Name) { MemLogBlocksInUse (Name); } } static void MemInit () // Initialize the memory checker { // Get the defaults for the memory checker MemCheck = getenv ("SPUNK_MEMCHECK") != NULL; MemFill = getenv ("SPUNK_MEMFILL") != NULL; // Register the exit function atexit (MemDone); // Initialized now IsInitialized = 1; } #ifdef __WATCOMC__ /*****************************************************************************/ /* class MemCheckInit */ /*****************************************************************************/ // This section is needed to initialize the memory checker *before* any other // library modules. It does work with Watcom-C++ only, but probably other // compilers have similar ways to ensure library initialization. // // Create a class with a static instance. The constructor of the class will // call the memory initialization, a #pragma assures that the module // initialization code is executed very early. #pragma initialize library; class MemCheckInit { public: MemCheckInit (); }; inline MemCheckInit::MemCheckInit () { if (IsInitialized == 0) { MemInit (); } } static MemCheckInit Initializer; // End of WATCOM specific code #endif /*****************************************************************************/ /* Code */ /*****************************************************************************/ void* operator new (size_t Size) { // Initialize the memory checker on the first call if (IsInitialized == 0) { MemInit (); } // Count the calls to new MemNewCount++; // Update largest block info if (Size > MemLargestBlock) { MemLargestBlock = Size; } unsigned char* Ptr; if (MemCheck) { // Count the checked calls MemNewCheckCount++; // Update memory usage MemUsage += Size; if (MemUsage > MemMaxUsage) { MemMaxUsage = MemUsage; } // Get a memory block Ptr = (unsigned char*) malloc (Size + sizeof (MemSig)); // Make a signature at the end of the block memcpy (Ptr + Size, &MemSig, sizeof (MemSig)); // Search for the block int Index; if (MemSearch (Ptr, Index) != 0) { // An item with this key exists. This means that the heap is // corrupted FAIL ("MemCheck: Duplicate block!"); } else { // The returned pointer is not in the collection of already // allocated blocks, but it may point inside of an already // allocated block. Check this. // Note: Index is the index of the item _before the given // pointer, so simply check the range of the entry with index // Index. if (Index > 0) { // There is a block that's memory address is less than the // one returned by malloc const BlockInfo* BB = Blocks + Index - 1; if (Ptr < BB->Ptr + BB->Size) { // Pointer points inside the block below - heap corrupted FAIL ("MemCheck: Heap corrupt!"); } } // Heap ok, insert the new block MemInsBlock (Index, Ptr, Size); } } else { // No memory checking. Allocate a memory block, but beware: New is // defined so that "new char [0]" points to a distinct object every // time it is called, so one cannot return NULL for a size of 0! Ptr = (unsigned char*) malloc (Size ? Size : 1); } // Check if we got memory, fail otherwise if (Ptr == NULL) { FAIL ("MemCheck: Out of memory"); } // Fill the memory block if requested if (MemFill) { memset (Ptr, FillVal, Size); } // Return a pointer to the memory block return Ptr; } void operator delete (void* P) { // We cannot call delete if the memory system is not initialized if (IsInitialized == 0) { FAIL ("MemCheck: Trying to delete a block before the first call to new!"); } // Count the calls to delete MemDelCount++; // Deleting NULL pointers is always ok, nothing has to be done if (P == 0) { MemDelNULLCount++; return; } if (MemCheck) { // Count the calls MemDelCheckCount++; // Cast the pointer unsigned char* Ptr = (unsigned char*) P; // Search for the block int Index; if (MemSearch (Ptr, Index) != 0) { // The block exists. Check the signature, then delete it BlockInfo* BI = Blocks + Index; if (memcmp (Ptr + BI->Size, &MemSig, sizeof (MemSig)) != 0) { // Signature overwritten FAIL ("MemCheck: Block signature overwritten"); } // Fill the memory block if requested if (MemFill) { memset (Ptr, FillVal, BI->Size); } // Update memory usage MemUsage -= BI->Size; // Delete the entry MemDelBlock (Index); // Delete the memory block free (P); } else { // Trying to free a block that is not allocated FAIL ("MemCheck: Trying to free a block that is not allocated"); } } else { // Free the block without checks free (P); } } estic-1.61.orig/spunk/memcheck.h0100644000176100001440000000537607031424701016106 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMCHECK.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Poor man's memory checker. Overloads the global operators new and delete // and does some additional checks if the variable MemCheck is set to true: // // * Check if an allocated block is already allocated (heap corrupt) // * Check if a block that should be freed is allocated // * Check if there have been writes outside the blocks bounds (by // adding a signature to the end) // // When using Watcom-C, the simple existance of the overloaded operators is // enough to use them (no need to include this file). // This may not be the case with other compilers (not checked yet). // // Beware: This module is _not_ reentrant if MemCheck is set to true! Don't // use it under a multithreaded environment (e.g. OS/2)! // #ifndef _MEMCHECK_H #define _MEMCHECK_H /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Switch the memory checking on/off extern int MemCheck; // Switch memory filling on or off extern int MemFill; // Some statistics. It is usually not necessary to access these. extern u32 MemNewCount; extern u32 MemDelCount; extern u32 MemDelNULLCount; extern u32 MemNewCheckCount; extern u32 MemDelCheckCount; extern u32 MemLargestBlock; extern u32 MemUsage; extern u32 MemMaxUsage; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void* operator new (size_t); void operator delete (void*); // Overloaded operators new and delete u32 MemBlocksInUse (); // Returns the number of memory blocks currently allocated void MemLogBlocksInUse (const String& Name); // Write a list of all used blocks into a file // End of MEMCHECK.H #endif estic-1.61.orig/spunk/mempool.h0100644000176100001440000001450707031424701015776 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMPOOL.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __MEMPOOL_H #define __MEMPOOL_H #include #include "machine.h" #include "check.h" #include "object.h" #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* class MemPool */ /*****************************************************************************/ template class MemPool: public Streamable { protected: T* Buffer; // Pointer to buffer memory u32 BlockSize; // blocksize in sizeof (T) units u32 Limit; // Current memory limit in sizeof (T) units u32 Top; // Index of first free memory location virtual u32 CheckExpand (u32 NewTop); // Check if the buffer is big enough to hold NewTop items, if not, expand // the buffer. Top is set to NewTop by this function and the old top is // returned. public: MemPool (u32 aBlockSize = 1024); // Create an (empty) MemPool MemPool (T* aBuffer, u32 Size, u32 aBlockSize = 1024); // Create a MemPool from aBuffer. Size is the Size of aBuffer in sizeof (T) // units and is assumed to be fully used MemPool (StreamableInit); // Create an empty and uninitialized MemPool virtual ~MemPool (); // Destruct a MemPool // derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; static Streamable* Build (); virtual void Clear (); // Throw away all data - the pool is empty after calling Clear virtual void Use (T* aBuffer, u32 Size); // Throw away all current data, and use the given buffer instead. Size is // the count of T objects in this buffer. The buffer must be allocated // on free store as it is deleted when the destructor is called! virtual u32 Alloc (u32 Count = 1); // Allocate memory in sizeof (T) chunks virtual const T* Adr (u32 Index) const; virtual T* Adr (u32 Index); // Get the adress of the object Index virtual u32 Pos (const T* P); // Return the index for the given address u32 GetCount () const; // Return the count of T items stored }; template MemPool::MemPool (u32 aBlockSize): Buffer (NULL), BlockSize (aBlockSize), Limit (0), Top (0) { } template MemPool::MemPool (T* aBuffer, u32 Size, u32 aBlockSize): Buffer (aBuffer), BlockSize (aBlockSize), Limit (Size), Top (Size) // Create a MemPool from aBuffer. Size is the Size of aBuffer in sizeof (T) // units and is assumed to be fully used { } template inline MemPool::MemPool (StreamableInit) { } template MemPool::~MemPool () { delete [] Buffer; } template void MemPool::Clear () // Throw away all data - the pool is empty after calling Clear { // Delete the buffer, reset all counters delete [] Buffer; Top = Limit = 0; } template void MemPool::Use (T* aBuffer, u32 Size) // Throw away all current data, and use the given buffer instead. Size is // the count of T objects in this buffer. The buffer must be allocated // on free store as it is deleted when the destructor is called! { // Clear the current data Clear (); // Use the new buffer instead Buffer = aBuffer; Top = Limit = Size; } template u32 MemPool::CheckExpand (u32 NewTop) // Check if the buffer is big enough to hold NewTop items, if not, expand // the buffer. Top is set to NewTop by this function and the old top is // returned. { if (NewTop > Limit) { // We need to expand the buffer. Save the old buffer T* OldBuffer = Buffer; // Calculate the new limit and allocate memory for the new buffer Limit = ((NewTop + BlockSize - 1) / BlockSize) * BlockSize; Buffer = new T [Limit]; // Copy the old buffer memory to the new one memcpy (Buffer, OldBuffer, Top * sizeof (T)); // Release the old buffer delete [] OldBuffer; } // Adjust Top and return the old Top u32 OldTop = Top; Top = NewTop; return OldTop; } template void MemPool::Load (Stream& S) { // Read in the size variables S >> BlockSize >> Limit >> Top; if (Limit > 0) { // Allocate buffer memory Buffer = new T [Limit]; // Read in the data S.Read (Buffer, Top * sizeof (T)); } } template void MemPool::Store (Stream& S) const { // Write out the size variables S << BlockSize << Limit << Top; // Write the buffer to the file S.Write (Buffer, Top * sizeof (T)); } template Streamable* MemPool::Build () // Create an empty MemPool instance { return new MemPool (Empty); } template u32 MemPool::Alloc (u32 Count) // Allocate memory in sizeof (T) chunks { // Expand the buffer if necessary and return the index return CheckExpand (Top + Count); } template const T* MemPool::Adr (u32 Index) const // Get the adress of the object Index { CHECK (Index < Top); return Buffer + Index; } template T* MemPool::Adr (u32 Index) // Get the adress of the object Index { CHECK (Index < Top); return Buffer + Index; } template u32 MemPool::Pos (const T* P) // Return the index for the given address { return P - Buffer; } template inline u32 MemPool::GetCount () const // Return the count of T items stored { return Top; } // End of MEMPOOL.H #endif estic-1.61.orig/spunk/memstrm.cc0100644000176100001440000000727207031424701016151 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMSTRM.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" #include "check.h" #include "streamid.h" #include "memstrm.h" // Register the class LINK (MemoryStream, ID_MemoryStream); /*****************************************************************************/ /* class MemoryStream */ /*****************************************************************************/ void MemoryStream::Resize (u32 NewSize) { if (NewSize > Limit) { // Round up to full blocks NewSize = ((NewSize + Block - 1) / Block) * Block; // Allocate a new block char* P = new char [NewSize]; // Copy the old data to the new block memcpy (P, Memory, Size); // Free old memory block, take new one, remember new size delete [] Memory; Memory = P; Limit = NewSize; } } MemoryStream::MemoryStream (u32 BlockSize) : Memory (new char [BlockSize]), Block (BlockSize), Limit (BlockSize), Size (0), CurPos (0) { } MemoryStream::~MemoryStream () { delete [] Memory; } void MemoryStream::Load (Stream& S) { // A MemoryStream loaded has the error codes reset and stream position 0 Reset (); CurPos = 0; // Now load the data S >> Block >> Limit >> Size; CHECK (Limit > 0); Memory = new char [Limit]; if (Size) { S.Read (Memory, Size); } } void MemoryStream::Store (Stream& S) const { // Cannot store a stream that's status is not ok PRECONDITION (GetStatus () == stOk); // Write the data to the stream S << Block << Limit << Size; if (Size) { S.Write (Memory, Size); } } u16 MemoryStream::StreamableID () const { return ID_MemoryStream; } Streamable* MemoryStream::Build () { return new MemoryStream (Empty); } u32 MemoryStream::GetPos () { return CurPos; } u32 MemoryStream::GetSize () { return Size; } void MemoryStream::Truncate () { Size = CurPos; } void MemoryStream::Read (void* Buf, size_t Count) { PRECONDITION (Buf != NULL && Count != 0); // Check end of stream condition if ((CurPos + Count) > Size) { Error (stReadError, Count); return; } // Copy the data memcpy (Buf, &Memory [CurPos], Count); // Remember new position CurPos += Count; } void MemoryStream::Seek (unsigned long Pos) { // Make shure, the position is available Resize (Pos); // Remember the position CurPos = Pos; // Keep track of size if (CurPos > Size) { Size = CurPos; } } void MemoryStream::Write (const void* Buf, size_t Count) { // Make shure, the new data fits Resize (CurPos + Count); // Copy the data memcpy (&Memory [CurPos], Buf, Count); // Remember the new position CurPos += Count; // Keep track of size if (CurPos > Size) { Size = CurPos; } } estic-1.61.orig/spunk/memstrm.h0100644000176100001440000000375307031424702016014 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMSTRM.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __MEMSTRM_H #define __MEMSTRM_H #include #include "stream.h" /*****************************************************************************/ /* class MemoryStream */ /*****************************************************************************/ class MemoryStream : public Stream { protected: char* Memory; u32 Block; u32 Limit; u32 Size; u32 CurPos; void Resize (u32 NewSize); public: MemoryStream (u32 BlockSize = 1024); MemoryStream (StreamableInit); ~MemoryStream (); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class Stream virtual u32 GetPos (); virtual u32 GetSize (); virtual void Read (void* Buf, size_t Count); virtual void Seek (unsigned long Pos); virtual void Truncate (); virtual void Write (const void* Buf, size_t Count); }; inline MemoryStream::MemoryStream (StreamableInit) { } /*****************************************************************************/ /* Duplicate */ /*****************************************************************************/ // Function to duplicate an object template T* Duplicate (T* S) { MemoryStream MemStr; // Write the object into the memory stream MemStr.Put (S); // Seek to the start of the stream and retrieve a copy MemStr.Seek (0); return (T*) MemStr.Get (); } // End of MEMSTRM.H #endif estic-1.61.orig/spunk/menue.cc0100644000176100001440000011446407031424702015601 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUE.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifdef __WATCOMC__ // malloc contains alloca() #include #else #include #endif #include "keydef.h" #include "screen.h" #include "winattr.h" #include "menue.h" #include "menuitem.h" #include "menuedit.h" #include "national.h" #include "streamid.h" #include "progutil.h" #include "winsize.h" // Register the classes LINK (MenueBar, ID_MenueBar); LINK (TopMenueBar, ID_TopMenueBar); LINK (Menue, ID_Menue); LINK (MenueItem, ID_MenueItem); LINK (SubMenueItem, ID_SubMenueItem); LINK (MenueBarItem, ID_MenueBarItem); /*****************************************************************************/ /* class MenueItem */ /*****************************************************************************/ MenueItem::MenueItem (const String& aItemText, i16 aID, WindowItem *NextItem) : Entry (), WindowItem (aItemText, aID, NextItem) // Create a new menue item { } void MenueItem::Store (Stream& S) const // Store the item into a stream { // Store parental data WindowItem::Store (S); // Store instance data S << Entry; } void MenueItem::Load (Stream& S) // Load the item from a stream { // Load parental data WindowItem::Load (S); // Load instance data S >> Entry; } u16 MenueItem::StreamableID () const // Return the object ID { return ID_MenueItem; } Streamable* MenueItem::Build () // Return an empty object instance { return new MenueItem (Empty); } void MenueItem::BuildEntry (const String& S) // Rebuild Entry from ItemText and S. The new value of Entry after // calling BuildEntry has the form " " + ItemText + Fill + S + " ", // where Fill is a string of spaces so that Entry gets the length // Width. This behaviour can change in derived versions of BuildEntry { int FillWidth; // Calculate the length of the fill string and set up such a string FillWidth = ItemWidth - 2 - ItemText.Len () - S.Len (); CHECK (FillWidth >= 0); String Fill (FillWidth); Fill.Set (0, FillWidth, ' '); // Now build the new entry string Entry = ' ' + ItemText + Fill + S + ' '; // Adjust memory to memory needed Entry.Settle (); } void MenueItem::SetWidth (u16 NewWidth) { // Do not accept the new value if it is less than MinWidth if (NewWidth < MinWidth ()) { return; } // Remember the new width ItemWidth = NewWidth; // Change Entry according to the new width if (AccelKey == kbNoKey) { BuildEntry (""); } else { BuildEntry (GetKeyName (AccelKey)); } } u16 MenueItem::MinWidth () { // Minimum width includes text width plus two spaces (left + right) plus // space to add the accel key name (two space + length of the key name) unsigned Width = ItemText.Len () + 2; if (AccelKey != kbNoKey) { Width += 2 + GetKeyName (AccelKey).Len (); } return Width; } void MenueItem::CallHelp () { // Allow calling help only if the item is active if (IsActive ()) { WindowItem::CallHelp (); } } void MenueItem::Draw () { unsigned TextAttr; // Attribute for normal text unsigned HotAttr; // Attribute for hot key // Bail out if the entry is empty if (Entry.Len () == 0) { return; } // Set up attributes according to the state of the item if (IsGrayed ()) { if (IsSelected ()) { TextAttr = atTextGrayedInvers; HotAttr = atTextGrayedInvers; } else { TextAttr = atTextGrayed; HotAttr = atTextGrayed; } } else if (IsSelected ()) { TextAttr = atTextInvers; HotAttr = atTextHighInvers; } else { TextAttr = atTextNormal; HotAttr = atTextHigh; } // Lock the owner window Owner->Lock (); // Write out the item text Owner->Write (ItemX, ItemY, Entry, TextAttr); // If there is a hotkey, show it if (HotPos >= 0) { Owner->Write (ItemX + HotPos + 1, ItemY, ItemText [HotPos], HotAttr); } // Unlock the owner window Owner->Unlock (); } void MenueItem::DrawItemText () { MenueItem::Draw (); } /*****************************************************************************/ /* class GenericMenue */ /*****************************************************************************/ GenericMenue::GenericMenue (Key aPrevKey, Key aNextKey, u16 aState, WindowItem* ItemList) : ItemWindow (Rect (0, 0, 10, 10), aState, ItemList), PrevKey (aPrevKey), NextKey (aNextKey), AltPrevKey (kbNoKey), AltNextKey (kbNoKey), AbortKey (kbNoKey) // Create a new generic menue { } void GenericMenue::InitGenericMenue (const Point& Origin, const String& HeaderString) // Special internal function that completes the initialization. // Works together with the protected constructor and is only // to be called from the constructors of derived classes { // Set the header. This is crucial because the length of the header // influences the result of MinWidth used below. SetHeader (HeaderString); // Calculate the width and height of the menue u16 Width = MinWidth (); u16 Height = MinHeight (); Point WinSize (Width, Height); if (IsFramed ()) { WinSize.X += 2; WinSize.Y += 2; } // Set the positions of the items SetPos (); SetWidth (Width); // Choose a selected item ValidateSelectedItem (); // Calculate the new window size/pos Rect Bounds (Origin, WinSize); // Now do a resize which will also do a complete draw of the menue Resize (Bounds); // The parent class has been called with LockCount == 1, so we // have to unlock the screen output here Unlock (); } void GenericMenue::Store (Stream& S) const { // Store parental data ItemWindow::Store (S); // Store new data S << NextKey << PrevKey << AltNextKey << AltPrevKey << AbortKey; } void GenericMenue::Load (Stream& S) { // Load parental data ItemWindow::Load (S); // Load instance data S >> NextKey >> PrevKey >> AltNextKey >> AltPrevKey >> AbortKey; } void GenericMenue::SelectItem (i16 ItemID) // Select the entry with the given id { // Deselect the currently selected entry if (SelectedItem) { SelectedItem->Deselect (); } // Get pointer to new selected entry SelectedItem = ForcedItemWithID (ItemID); // Select new entry SelectedItem->Select (); } void GenericMenue::DeselectItem (i16 ItemID) // Deselect the entry with the given id { // The item with the given ID must be the selected item PRECONDITION (SelectedItem && SelectedItem == ForcedItemWithID (ItemID)); // Now deselect the item SelectedItem->Deselect (); SelectedItem = NULL; } void GenericMenue::SetAlternateKeys (Key aPrevKey, Key aNextKey) // Set the keys for the ids -1 and -2 { AltPrevKey = aPrevKey; AltNextKey = aNextKey; } int GenericMenue::TestItem (ListNode* Node, void* P) // Helper function for GenericMenue::GetChoice { return Node->Contents () == (WindowItem*) P; } int GenericMenue::StoreOneItem (ListNode* Node, void* P) // Helper function for GenericMenue::GetChoice. Insert all active items // into ItemBuf { // Cast the void pointer GenericMenue* M = (GenericMenue*) P; if (Node->Contents ()->IsActive ()) { // Item is active, insert it M->ItemBuf [M->ItemBufCount++] = Node->Contents (); } return 0; } void GenericMenue::BuildItemIndex () // Helper function for GenericMenue::GetChoice. Build the index from the // sorted item list { // Clear all counters and indices for (int I = 0; I <= MaxY (); I++) { ItemDesc [I].Base = -1; ItemDesc [I].Count = 0; } // Now build the index for (unsigned J = 0; J < ItemBufCount; J++) { YDesc* YD = &ItemDesc [ItemBuf [J]->YPos ()]; if (YD->Base == -1) { YD->Base = J; // Write the index } YD->Count++; // One entry more } } unsigned GenericMenue::FindItemInItemBuf (WindowItem* P) // Helper function for GenericMenue::GetChoice. Find an item in the item // buffer { // Get the base of all entries with the same Y position unsigned I = ItemDesc [P->YPos ()].Base; // Search from this position while (I < ItemBufCount) { if (ItemBuf [I] == P) { // Found the item return I; } I++; } // Item not found - should not happen FAIL ("GenericMenue::FindItemInBuf: Item not found"); return 0; } // The following function is used as a parameter to qsort, but since the // Borland C library is compiled using the _stdcall calling convention // and on the other side, static member functions have _cdecl calling // conventions by default, we have to redefine this one. Yuck! // Maybe it would be better to drop support for Borland-C... int #if defined (OS2) && defined (__BORLANDC__) _stdcall #endif GenericMenue::CompareItems (const void* I1, const void* I2) // Helper function for GenericMenue::GetChoice. Compare two items by position // when sorting the item list { // Cast the pointers WindowItem* W1 = * ((WindowItem**) I1); WindowItem* W2 = * ((WindowItem**) I2); if (W1->YPos () < W2->YPos ()) { return -1; } else if (W1->YPos () == W2->YPos ()) { if (W1->XPos () < W2->XPos ()) { return -1; } else if (W1->XPos () == W2->XPos ()) { return 0; } else { return 1; } } else { return 1; } } void GenericMenue::DynamicLeft () // Handle dynamic cursor movement to the left. { // Get the index of the selected item and the base index of all items // with the same y position unsigned Count = ItemDesc [SelectedItem->YPos ()].Count; unsigned Base = ItemDesc [SelectedItem->YPos ()].Base; unsigned I = FindItemInItemBuf (SelectedItem); // If there is more than one item in the same row, select a new item if (Count > 1) { if (I > Base) { // item to the left SelectNewItem (ItemBuf [I-1]); } else { // wrap to the right SelectNewItem (ItemBuf [Base + Count - 1]); } } } void GenericMenue::DynamicRight () // Handle dynamic cursor movement to the right. { // Get the index of the selected item and the base index of all items // with the same y position unsigned Count = ItemDesc [SelectedItem->YPos ()].Count; unsigned Base = ItemDesc [SelectedItem->YPos ()].Base; unsigned I = FindItemInItemBuf (SelectedItem); // If there is more than one item in the same row, select a new item if (Count > 1) { if (I < Base + Count - 1) { // item to the right SelectNewItem (ItemBuf [I+1]); } else { // wrap to the left SelectNewItem (ItemBuf [Base]); } } } i16 GenericMenue::GetChoice () { const AltNextKeyCode = MaxUserID + 1; const AltPrevKeyCode = MaxUserID + 2; // Remember old window state u16 OldState = GetState (); // If the left/right cursor movement is activated, build the internal // data structures that hold the needed information if (HasLRLink ()) { // Allocate memory ItemBuf = (WindowItem**) alloca (ItemCount * sizeof (WindowItem*)); ItemDesc = (YDesc*) alloca (IYSize () * sizeof (YDesc)); // Store the items in the array ItemBufCount = 0; Traverse (StoreOneItem, this); // Sort the items qsort (ItemBuf, ItemBufCount, sizeof (WindowItem*), CompareItems); // Build the item index BuildItemIndex (); } // Activate and show window, highlight selected entry. Do the // highlighting _before_ activating the menue. Often, menues are // submenues, that are hidden before Activate is called. If we // highlight the selected item when the menue is still hidden, // there is no actual screen I/O, which will speed things up ValidateSelectedItem (); if (SelectedItem) { SelectedItem->Select (); } Activate (); // Reset abort key AbortKey = kbNoKey; // Letz fetz... i16 Choice = 0; Key C; MenueItem* Item; while (!Choice) { // Get a key C = KbdGet (); // Check for cursor movement if (C == PrevKey) { SelectPrevItem (); } else if (C == NextKey) { SelectNextItem (); } else if (C == AltPrevKey) { Choice = AltPrevKeyCode; } else if (C == AltNextKey) { Choice = AltNextKeyCode; } else if (HasLRLink () && C == vkLeft) { // Dynamic left link if (SelectedItem) { DynamicLeft (); } } else if (HasLRLink () && C == vkRight) { // Dynamic right link if (SelectedItem) { DynamicRight (); } } else { switch (C) { case vkHelp: if (SelectedItem) { SelectedItem->CallHelp (); } break; case kbEnter: if (SelectedItem) { Choice = SelectedItem->Choose (); } break; case vkAbort: Choice = 0; AbortKey = vkAbort; goto ExitPoint; case vkResize: // Allow resizing if vkResize is not an accel key inside // the menue Item = (MenueItem*) ItemWithAccelKey (C); if (Item) { // It is an accel key. Check if the menue item with // this accel key is in this menue tree. // If so, select it. if (Traverse (TestItem, Item)) { // It is an item in this menue SelectNewItem (Item); } Choice = Item->Choose (); } else { // There is no item with this accel key. Allow resizing. MoveResize (); } break; case vkAccept: if (!IgnoreAccept ()) { Choice = 0; AbortKey = vkAccept; goto ExitPoint; } break; default: // Is the key a hotkey ? Item = NULL; if (IsPlainKey (C)) { Item = (MenueItem*) ItemWithHotKey (NLSUpCase ((char) C)); } if (Item) { // It is a hotkey, select the entry SelectNewItem (Item); Choice = Item->Choose (); } else { // Maybe it's an accelerator key Item = (MenueItem*) ItemWithAccelKey (C); if (Item) { // It is an accel key. Check if the menue item // with this accel key is in this menue tree. // If so, select it. if (Traverse (TestItem, Item)) { // It is an item in this menue SelectNewItem (Item); } Choice = Item->Choose (); } else { // There is no item in this menue tree with // the accel key. Get the root of the menue // and check for the accel key in the whole // menue tree. If we find the item with this // key, return it back with his negative id. // GetChoice knows how to handle this. if (Owner) { Item = (MenueItem*) Owner->GetRootWindow()->ItemWithAccelKey (C); if (Item) { // Found an item with this accel key Choice = -Item->GetID (); } } } } if (Item == NULL) { // No accel key. If the menue is not modal, check if // anyone has registered this key for other use. If // the menue is modal, silently drop the key. if (!IsModal () && KeyIsRegistered (C)) { // Put the key back and end GetChoice KbdPut (C); Choice = 0; AbortKey = C; goto ExitPoint; } } break; } // switch // Now check for special choice values while (Choice == AltPrevKeyCode || Choice == AltNextKeyCode || (Choice < 0 && Owner == NULL)) { // Check if the return value is negative. This is handled by // the root menue if (Choice < 0 && Owner == NULL) { // Accel key Choice = -Choice; // Check if the item with the accel key is in the direct // descendant menues Item = (MenueItem *) ForcedItemWithID (Choice); if (Traverse (TestItem, Item) != NULL) { // Direct descendant SelectNewItem (Item); } // Get the choice from the item with the accel key Choice = Item->Choose (); } else { if (Choice == AltPrevKeyCode) { SelectPrevItem (); } else if (Choice == AltNextKeyCode) { SelectNextItem (); } Choice = SelectedItem->Choose (); } } } } ExitPoint: // Reset window to old state, then deselect the selected item. Do it // in this order, because often the menue is hidden after SetState, // so the call to Deselect will cause no additional screen output. SetState (OldState); if (SelectedItem) { SelectedItem->Deselect (); } // Return the result return Choice; } Key GenericMenue::Browse () // Overrides ItemWindow::Browse. Uses GetChoice to display the menue but // ignores the menue choice. { // Call GetChoice but ignore the result GetChoice (); // Get the abort key Key K = GetAbortKey (); // If the key is registered, there is a key waiting in the queue that // is not needed any longer if (KeyIsRegistered (K)) { (void) KbdGet (); } // Return the abort key return K; } Key GenericMenue::GetAbortKey () // Function to return the key that caused an abort in GetChoice { return AbortKey; } i16 GenericMenue::GetSelectedItem () // Return the id of the currently selected item or return zero if // no item is currently selected { return SelectedItem ? SelectedItem->GetID () : 0; } double GenericMenue::GetFloatValue (i16 aID) // Get the float value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_FloatItem: return ((FloatItem*) Item)->GetValue (); case ID_FloatEdit: return ((FloatEdit*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetFloatValue: Unknown item type"); return 0; } i32 GenericMenue::GetLongValue (i16 aID) // Return the long value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_LongItem: return ((LongItem*) Item)->GetValue (); case ID_HexItem: return ((HexItem*) Item)->GetValue (); case ID_LongEdit: return ((LongEdit*) Item)->GetValue (); case ID_HexEdit: return ((HexEdit*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetLongValue: Unknown item type"); return 0; } const String& GenericMenue::GetStringValue (i16 aID) // Return the string value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_StringItem: return ((StringItem*) Item)->GetValue (); case ID_RStringItem: return ((RStringItem*) Item)->GetValue (); case ID_EditLine: return ((EditLine*) Item)->GetValue (); case ID_TextEdit: return ((TextEdit*) Item)->GetValue (); case ID_PasswordEdit: return ((PasswordEdit*) Item)->GetValue (); case ID_FileEdit: return ((FileEdit*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetStringValue: Unknown item type"); return *(String*) NULL; } u16 GenericMenue::GetToggleValue (i16 aID) // Return the toggle value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_ToggleItem: return ((ToggleItem*) Item)->GetValue (); case ID_OffOnItem: return ((OffOnItem*) Item)->GetValue (); case ID_NoYesItem: return ((NoYesItem*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetToggleValue: Unknown item type"); return 0; } const Time& GenericMenue::GetTimeValue (i16 aID) // Return the time value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_TimeItem: return ((TimeItem*) Item)->GetValue (); case ID_TimeEdit: return ((TimeEdit*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetTimeValue: Unknown item type"); return *(Time*) NULL; } const Time& GenericMenue::GetDateValue (i16 aID) // Return the date value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_DateItem: return ((DateItem*) Item)->GetValue (); case ID_DateEdit: return ((DateEdit*) Item)->GetValue (); } // Error, unknown type FAIL ("GenericMenue::GetDateValue: Unknown item type"); return *(Time*) NULL; } void GenericMenue::SetFloatValue (i16 aID, double NewVal) // Set the float value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_FloatItem: ((FloatItem*) Item)->SetValue (NewVal); break; case ID_FloatEdit: ((FloatEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetFloatValue: Unknown item type"); } } void GenericMenue::SetLongValue (i16 aID, i32 NewVal) // Set the long value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_LongItem: ((LongItem*) Item)->SetValue (NewVal); break; case ID_HexItem: ((HexItem*) Item)->SetValue (NewVal); break; case ID_LongEdit: ((LongEdit*) Item)->SetValue (NewVal); break; case ID_HexEdit: ((HexEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetLongValue: Unknown item type"); } } void GenericMenue::SetStringValue (i16 aID, const String & NewVal) // Set the string value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_StringItem: ((StringItem*) Item)->SetValue (NewVal); break; case ID_RStringItem: ((RStringItem*) Item)->SetValue (NewVal); break; case ID_EditLine: ((EditLine*) Item)->SetValue (NewVal); break; case ID_TextEdit: ((TextEdit*) Item)->SetValue (NewVal); break; case ID_PasswordEdit: ((PasswordEdit*) Item)->SetValue (NewVal); break; case ID_FileEdit: ((FileEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetStringValue: Unknown item type"); } } void GenericMenue::SetToggleValue (i16 aID, u16 NewVal) // Set the toggle value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_ToggleItem: ((ToggleItem*) Item)->SetValue (NewVal); break; case ID_OffOnItem: ((OffOnItem*) Item)->SetValue (NewVal); break; case ID_NoYesItem: ((NoYesItem*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetToggleValue: Unknown item type"); } } void GenericMenue::SetTimeValue (i16 aID, const Time& NewVal) // Set the time value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_TimeItem: ((TimeItem*) Item)->SetValue (NewVal); break; case ID_TimeEdit: ((TimeEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetTimeValue: Unknown item type"); } } void GenericMenue::SetTimeValue (i16 aID, u32 NewVal) // Set the time value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_TimeItem: ((TimeItem*) Item)->SetValue (NewVal); break; case ID_TimeEdit: ((TimeEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetTimeValue: Unknown item type"); } } void GenericMenue::SetDateValue (i16 aID, const Time& NewVal) // Set the date value of an item. { // Get a pointer to the item WindowItem* Item = ForcedItemWithID (aID); // Switch according to the item type switch (Item->StreamableID ()) { case ID_DateItem: ((DateItem*) Item)->SetValue (NewVal); break; case ID_DateEdit: ((DateEdit*) Item)->SetValue (NewVal); break; default: // Error, unknown type FAIL ("GenericMenue::SetDateValue: Unknown item type"); } } /*****************************************************************************/ /* class MenueBar */ /*****************************************************************************/ MenueBar::MenueBar (const Point& Origin, WindowItem* ItemList) : GenericMenue (vkLeft, vkRight, 0, ItemList) { InitGenericMenue (Origin, ""); } int MenueBar::SetOnePos (ListNode* Node, void* P) // Helper function for MenueBar::SetPos, sets the position of one item { // Get a pointer to the window item WindowItem* Item = Node->Contents (); // Set the position of the window item Item->SetPos (*((u16*) P), 0); // Calculate the position of the next item * ((u16*) P) += Item->MinWidth (); // Keep on traversing return 0; } void MenueBar::SetPos () { // First item at position one u16 X = 1; // Set up all item positions Traverse (SetOnePos, &X); } u16 MenueBar::StreamableID () const { return ID_MenueBar; } Streamable* MenueBar::Build () { return new MenueBar (Empty); } u16 MenueBar::MinHeight () { return 1; } static int AddWidth (ListNode* Node, void* P) // Helper function for MenueBar::MinWidth { *((u16*) P) += Node->Contents () -> MinWidth (); return 0; } u16 MenueBar::MinWidth () { // The width of the menuebar is the width of all entrys plus a space // to the left and right u16 W = 2; Traverse (AddWidth, &W); return W; } static int MenueBar_SetOneWidth (ListNode* Node, void*) // Helper function for SetWidth { // Get a pointer to the item WindowItem* Item = Node->Contents (); // Set the width of the entry to the minimum width of that entry Item->SetWidth (Item->MinWidth ()); // Keep on traversing return 0; } void MenueBar::SetWidth (u16) { Traverse (MenueBar_SetOneWidth); } /*****************************************************************************/ /* class TopMenueBar */ /*****************************************************************************/ TopMenueBar::TopMenueBar (WindowItem* ItemList) : MenueBar (Point (0, 0), ItemList) { // Expand the size of the bar from the left to the right screen border Resize (Rect (0, 0, TheScreen->GetXSize (), 1)); } u16 TopMenueBar::StreamableID () const { return ID_TopMenueBar; } Streamable* TopMenueBar::Build () { return new TopMenueBar (Empty); } void TopMenueBar::ScreenSizeChanged (const Rect& NewScreen) // Called when the screen got another resolution. NewScreen is the new // screen size. { // Expand the size of the bar from the left to the right screen border Resize (Rect (0, 0, NewScreen.XSize (), 1)); } void TopMenueBar::MoveResizeAfterLoad (const Point& /*OldRes*/) // This function is called after a load when most of the window is // constructed. It is used to move the window to a new position if this is // needed. OldRes is the old screen resolution that was active, when the // window was stored. // It is used to position the menuebar at the top of the screen after a // load. { Rect NewBounds = Background->OuterBounds (); NewBounds.B.Y = 1; Resize (NewBounds); } /*****************************************************************************/ /* class Menue */ /*****************************************************************************/ Menue::Menue (const Point& Origin, const String& HeaderString, WindowItem* ItemList): GenericMenue (vkUp, vkDown, wfFramed, ItemList) { InitGenericMenue (Origin, HeaderString); } u16 Menue::StreamableID () const { return ID_Menue; } Streamable* Menue::Build () { return new Menue (Empty); } u16 Menue::MinHeight () { return ItemCount; } static int CompareWidth (ListNode* Node, void* P) // Helper function for Menue::MinWidth { u16* W = (u16 *) P; u16 MinWidth = Node->Contents () -> MinWidth (); // Put the greater one into W if (*W < MinWidth) { *W = MinWidth; } // Keep on traversing return 0; } u16 Menue::MinWidth () { // Preset the minimum width with the length of the header string u16 W = Header.Len () + 2; // Now search for a wider item Traverse (CompareWidth, &W); // And return the result return W; } static int Menue_SetOneWidth (ListNode* Node, void* P) // Helper function for Menue::SetWidth { // Set the width to the given width Node->Contents () -> SetWidth (* ((u16 *) P)); // keep on traversing return 0; } void Menue::SetWidth (u16 NewWidth) { Traverse (Menue_SetOneWidth, &NewWidth); } /*****************************************************************************/ /* class SubMenueItem */ /*****************************************************************************/ SubMenueItem::SubMenueItem (const String& aItemText, i16 aID, WindowItem* MenueList, WindowItem* NextItem) : MenueItem (aItemText, aID, NextItem), SubMenue (NULL) { if (MenueList != NULL) { // Build the submenue at 0/0 Point Origin (0, 0); SubMenue = new Menue (Origin, "", MenueList); // Set this item as the owner of the submenue SubMenue->SetOwner (this); // Set the alternate keys SubMenue->SetAlternateKeys (vkUp, vkDown); } } SubMenueItem::~SubMenueItem () { // Delete the submenue delete SubMenue; } void SubMenueItem::Store (Stream& S) const // Store the object into a stream { // Store parental data MenueItem::Store (S); // Put the submenue into the stream S.Put (SubMenue); } void SubMenueItem::Load (Stream& S) // Load an object from a stream { // Load parental data MenueItem::Load (S); // Construct a complete submenue from the data in the stream SubMenue = (Menue*) S.Get (); } u16 SubMenueItem::StreamableID () const { return ID_SubMenueItem; } Streamable* SubMenueItem::Build () { return new SubMenueItem (Empty); } i16 SubMenueItem::Choose () { // Return "Abort" if the entry is not active if (!IsActive ()) { return 0; } // If the submenue is non existant, or the ifNoSub flag is set, // return the ID of the item itself if (SubMenue == NULL || Flags & ifNoSub) { return ID; } // Place the submenue below or above the SubMenueItem SubMenue->PlaceNear (this); // Get the choice from the submenue. This will activate the window and // restore the original (hidden) state afterwards. return SubMenue->GetChoice (); } WindowItem* SubMenueItem::ItemWithID (i16 aID) { if (aID == ID) { // The instance itself return this; } else { // Ask the submenue if one exists return SubMenue? SubMenue->ItemWithID (aID) : 0; } } WindowItem* SubMenueItem::ItemWithAccelKey (Key aAccelKey) { if (!IsActive ()) { // Not active, ignore request return NULL; } if (aAccelKey == AccelKey) { // The instance itself return this; } else { // Ask the submenue if one exists return SubMenue? SubMenue->ItemWithAccelKey (aAccelKey) : 0; } } u16 SubMenueItem::MinWidth () { // space + Length + space + rightarrow + space return ItemText.Len () + 4; } void SubMenueItem::SetWidth (u16 NewWidth) { if (NewWidth < MinWidth ()) { // Ignore the request return; } // Remember new value ItemWidth = NewWidth; // Build the new display string static char S [3] = { ' ', RightTriangle, '\0' }; BuildEntry (String (S)); } void SubMenueItem::SetSubMenue (Menue* NewSubMenue) { // Delete the old submenue, then set the new one delete SubMenue; SubMenue = NewSubMenue; // Set owner and keys for the new submenue if (SubMenue != NULL) { // Set this item as the owner of the submenue SubMenue->SetOwner (this); // Set the alternate keys SubMenue->SetAlternateKeys (vkUp, vkDown); } } /*****************************************************************************/ /* class MenueBarItem */ /*****************************************************************************/ MenueBarItem::MenueBarItem (const String& aItemText, i16 aID, WindowItem* MenueList, WindowItem* NextItem) : SubMenueItem (aItemText, aID, MenueList, NextItem) { // The constructor of SubMenueItem has set the wrong alternate keys, // correct this if (SubMenue) { SubMenue->SetAlternateKeys (vkLeft, vkRight); } // The MenueBarItem has the Meta-version of the hotkey as a // default accelerator key AccelKey = GetMetaCode (HotKey); } u16 MenueBarItem::StreamableID () const { return ID_MenueBarItem; } Streamable* MenueBarItem::Build () { return new MenueBarItem (Empty); } void MenueBarItem::SetWidth (u16 NewWidth) { // Do not accept the new value if it is less than MinWidth if (NewWidth < MinWidth ()) { return; } // Remember the new width ItemWidth = NewWidth; // Change Entry according to the new width BuildEntry (""); } u16 MenueBarItem::MinWidth () { // Minimum width includes text width plus two spaces (left + right). return ItemText.Len () + 2; } void MenueBarItem::SetSubMenue (Menue* NewSubMenue) { // Use the derived function, then reset the alternate keys SubMenueItem::SetSubMenue (NewSubMenue); if (SubMenue) { // Set the alternate keys SubMenue->SetAlternateKeys (vkLeft, vkRight); } } estic-1.61.orig/spunk/menue.h0100644000176100001440000002775207031424702015446 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUE.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _MENUE_H #define _MENUE_H #include "itemwin.h" #include "datetime.h" /*****************************************************************************/ /* class MenueItem */ /*****************************************************************************/ class MenueItem: public WindowItem { friend class ResEditApp; // Resource editor is a friend protected: String Entry; // Actual view of the item // Rebuild Entry from ItemText and S. The new value of Entry after // calling BuildEntry has the form " " + ItemText + Fill + S + " ", // where Fill is a string of spaces so that Entry gets the length // Width. This behaviour can change in derived versions of BuildEntry virtual void BuildEntry (const String &S); MenueItem (StreamableInit); // Build constructor public: MenueItem (const String &aItemText, i16 aID, WindowItem *NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class WindowItem virtual void SetWidth (u16 NewWidth); virtual u16 MinWidth (); virtual void CallHelp (); virtual void Draw (); virtual void DrawItemText (); }; inline MenueItem::MenueItem (StreamableInit) : WindowItem (Empty), Entry (Empty) { } /*****************************************************************************/ /* class GenericMenue */ /*****************************************************************************/ class GenericMenue : public ItemWindow { friend class ResEditApp; // Resource editor is a friend struct YDesc { int Base; int Count; }; private: Key PrevKey; // Key to reach the previous entry Key NextKey; // Key to reach the next entry Key AltPrevKey; Key AltNextKey; Key AbortKey; // Key that caused the abort in GetChoice WindowItem** ItemBuf; // Variables used internal in GetChoice unsigned ItemBufCount; YDesc* ItemDesc; static int TestItem (ListNode*, void*); // Helper function for GetChoice static int StoreOneItem (ListNode* Node, void* P); // Helper function for GenericMenue::GetChoice. Insert all active items // into ItemBuf #if defined (OS2) && defined (__BORLANDC__) // The following function is used as a parameter to qsort, but since the // Borland C library is compiled using the _stdcall calling convention // and on the other side, static member functions have _cdecl calling // conventions by default, we have to redefine this one. Yuck! // Maybe it would be better to drop support for Borland-C... static int _stdcall CompareItems (const void* I1, const void* I2); #else static int CompareItems (const void* I1, const void* I2); // Helper function for GenericMenue::GetChoice. Compare two items by position // when sorting the item list #endif void BuildItemIndex (); // Helper function for GenericMenue::GetChoice. Build the index from the // sorted item list unsigned FindItemInItemBuf (WindowItem* P); // Helper function for GenericMenue::GetChoice. Find an item in the item // buffer void DynamicLeft (); // Handle dynamic cursor movement to the left. void DynamicRight (); // Handle dynamic cursor movement to the right. protected: void SelectItem (i16 ItemID); // Select the entry with the given id void DeselectItem (i16 ItemID); // Deselect the entry with the given id void InitGenericMenue (const Point& Origin, const String& HeaderString); // Special internal function that completes the initialization. // Works together with the protected constructor and is only // to be called from the constructors of derived classes GenericMenue (Key aPrevKey, Key aNextKey, u16 aState = wfFramed, WindowItem* ItemList = NULL); // Internal used constructor. Can only be called by constructors // of derived types. See InitGenericMenue. GenericMenue (StreamableInit); // Build constructor public: // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); i16 GetChoice (); // virtual Key Browse (); // Overrides ItemWindow::Browse. Uses GetChoice to display the menue but // ignores the menue choice. Key GetAbortKey (); // Function to return the key that caused an abort in GetChoice i16 GetSelectedItem (); // Return the id of the currently selected item or return zero if // no item is currently selected virtual u16 MinWidth () = 0; // Return the minimum width of the menue virtual u16 MinHeight () = 0; // Return the minimum height of the menue virtual void SetWidth (u16 NewWidth) = 0; // Set a new width for the menue void SetAlternateKeys (Key aPrevKey, Key aNextKey); // Set the keys for the ids -1 and -2 // Support functions for using the items in the menue. // All functions determine the type of the item involved and act // according to the rules of the item. This means that you can use // SetStringValue to set the value of a StringItem, an EditLine or // a TextEdit. If the type of the item is not known, the program is // aborted with an error message. // All functions will also abort, if the given ID does not exist. double GetFloatValue (i16 aID); // Get the float value of an item. i32 GetLongValue (i16 aID); // Return the long value of an item. const String& GetStringValue (i16 aID); // Return the string value of an item. u16 GetToggleValue (i16 aID); // Return the toggle value of an item. const Time& GetTimeValue (i16 aID); // Return the time value of an item. const Time& GetDateValue (i16 aID); // Return the date value of an item. void SetFloatValue (i16 aID, double NewVal); // Set the float value of an item. void SetLongValue (i16 aID, i32 NewVal); // Set the long value of an item. void SetStringValue (i16 aID, const String & NewVal); // Set the string value of an item. void SetToggleValue (i16 aID, u16 NewVal); // Set the toggle value of an item. void SetTimeValue (i16 aID, const Time& NewVal); // Set the time value of an item. void SetTimeValue (i16 aID, u32 NewVal); // Set the value of an item. void SetDateValue (i16 aID, const Time& NewVal); // Set the date value of an item. }; inline GenericMenue::GenericMenue (StreamableInit) : ItemWindow (Empty) { } /*****************************************************************************/ /* class MenueBar */ /*****************************************************************************/ class MenueBar: public GenericMenue { friend class ResEditApp; // Resource editor is a friend private: static int SetOnePos (ListNode*, void*); // Helper function for MenueBar::SetPos, sets the position of one item protected: // Derived from class ItemWindow virtual void SetPos (); MenueBar (StreamableInit); // Creates an empty instance public: MenueBar (const Point& Origin, WindowItem* ItemList = NULL); // // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class GenericMenue virtual u16 MinHeight (); virtual u16 MinWidth (); virtual void SetWidth (u16 NewWidth); }; inline MenueBar::MenueBar (StreamableInit): GenericMenue (Empty) { } /*****************************************************************************/ /* class TopMenueBar */ /*****************************************************************************/ class TopMenueBar: public MenueBar { friend class ResEditApp; // Resource editor is a friend protected: virtual void ScreenSizeChanged (const Rect& NewScreen); // Called when the screen got another resolution. NewScreen is the new // screen size. virtual void MoveResizeAfterLoad (const Point& OldRes); // This function is called after a load when most of the window is // constructed. It is used to move the window to a new position if this is // needed. OldRes is the old screen resolution that was active, when the // window was stored. // It is used to position the menuebar at the top of the screen after a // load. TopMenueBar (StreamableInit); // Creates an empty instance public: TopMenueBar (WindowItem* ItemList = NULL); // // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); }; inline TopMenueBar::TopMenueBar (StreamableInit) : MenueBar (Empty) { } /*****************************************************************************/ /* class Menue */ /*****************************************************************************/ class Menue: public GenericMenue { friend class ResEditApp; // Resource editor is a friend protected: // Derived from class ItemWindow // virtual void SetPos (); Menue (StreamableInit); // Create an empty instance public: Menue (const Point& Origin, const String& HeaderString, WindowItem* ItemList = NULL); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class GenericMenue virtual u16 MinHeight (); virtual u16 MinWidth (); virtual void SetWidth (u16 NewWidth); }; inline Menue::Menue (StreamableInit) : GenericMenue (Empty) { } /*****************************************************************************/ /* class SubMenueItem */ /*****************************************************************************/ class SubMenueItem: public MenueItem { friend class ResEditApp; // Resource editor is a friend protected: Menue* SubMenue; // Pointer to submenue SubMenueItem (StreamableInit); // Create an empty instance public: SubMenueItem (const String& aItemText, i16 aID, WindowItem* MenueList, WindowItem* NextItem); virtual ~SubMenueItem (); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class WindowItem virtual i16 Choose (); virtual WindowItem* ItemWithID (i16 aID); virtual WindowItem* ItemWithAccelKey (Key aAccelKey); // Derived from class MenueItem virtual u16 MinWidth (); virtual void SetWidth (u16 NewWidth); // Additional member functions virtual void SetSubMenue (Menue* NewSubMenue); }; inline SubMenueItem::SubMenueItem (StreamableInit) : MenueItem (Empty) { } /*****************************************************************************/ /* class MenueBarItem */ /*****************************************************************************/ class MenueBarItem: public SubMenueItem { friend class ResEditApp; // Resource editor is a friend protected: MenueBarItem (StreamableInit); // Create an empty instance public: MenueBarItem (const String& aItemText, i16 aID, WindowItem* MenueList, WindowItem* NextItem); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class SubMenueItem virtual u16 MinWidth (); virtual void SetWidth (u16 NewWidth); virtual void SetSubMenue (Menue* NewSubMenue); }; inline MenueBarItem::MenueBarItem (StreamableInit) : SubMenueItem (Empty) { } // End of MENUE.H #endif estic-1.61.orig/spunk/menuedit.cc0100644000176100001440000007461607031424702016306 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUEDIT.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "filesys.h" #include "filepath.h" #include "menuedit.h" #include "winattr.h" #include "stdmsg.h" #include "progutil.h" #include "national.h" #include "chartype.h" #include "streamid.h" #include "strparse.h" #include "strcvt.h" #include "msgid.h" // Register the classes LINK (EditLine, ID_EditLine); LINK (FloatEdit, ID_FloatEdit); LINK (LongEdit, ID_LongEdit); LINK (HexEdit, ID_HexEdit); LINK (TextEdit, ID_TextEdit); LINK (TimeEdit, ID_TimeEdit); LINK (DateEdit, ID_DateEdit); LINK (PasswordEdit, ID_PasswordEdit); LINK (FileEdit, ID_FileEdit); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msErrIllegalInput = MSGBASE_MENUEDIT + 0; static const u16 msErrTrailingDigits = MSGBASE_MENUEDIT + 1; static const u16 msErrFTooSmall = MSGBASE_MENUEDIT + 2; static const u16 msErrFTooLarge = MSGBASE_MENUEDIT + 3; static const u16 msErrLTooSmall = MSGBASE_MENUEDIT + 4; static const u16 msErrLTooLarge = MSGBASE_MENUEDIT + 5; static const u16 msErrNoEmptyInput = MSGBASE_MENUEDIT + 6; static const u16 msErrNoExtension = MSGBASE_MENUEDIT + 7; /*****************************************************************************/ /* class EditLine */ /*****************************************************************************/ EditLine::EditLine (const String& aItemText, i16 aID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem) : WindowItem (aItemText, aID, NextItem), Line (aMaxLen), FieldLen (aFieldLen), InsertMode (0), MaxLen (aMaxLen), InsertPos (0), FirstChar (0), CursorX (0), FirstPos (0) { // Check the given length PRECONDITION (MaxLen >= 2); // Set the width to MinWidth. This function will calculate all // values. Warning: This may fail because every time // EditLine::MinWidth is called (we are inside the constructor!). // If this is a problem, think about a better solution. SetWidth (MinWidth ()); } int EditLine::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { // Disallow extended keys return IsPlainKey (K); } int EditLine::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // No check in EditLine::EndCheckOk return 1; } void EditLine::DrawLeftArrow (int Arrow) // Draws or clears the left arrow according to the given flag { char C = Arrow ? LeftTriangle : ' '; Owner->Write (LeftArrowX, ItemY, C, atEditHigh); } void EditLine::DrawRightArrow (int Arrow) // Draws or clears the right arrow according to the given flag { char C = Arrow ? RightTriangle : ' '; Owner->Write (RightArrowX, ItemY, C, atEditHigh); } void EditLine::DrawField () // This function is called from Edit and draws the editing field. // FirstPos is the position (in Line) of the first char that is // printed. CursorX is the position of the cursor in the window. // First is true if the user has not pressed any key. In this case, // a special attribuite for the text is used, because the first // keypress of a non cursor key will clear the line. { // Get the visible portion of the input line String S (Line.Cut (FirstPos, FieldLen)); S.Pad (String::Right, FieldLen); // Draw the line Owner->Write (FieldX, ItemY, S, FirstChar ? atEditHigh : atEditNormal); // Draw/delete both arrows DrawLeftArrow (FirstPos != 0); DrawRightArrow ((FirstPos + FieldLen) < Line.Len ()); // Reset the cursor Owner->SetCursorPos (Point (CursorX, ItemY)); } void EditLine::Store (Stream& S) const // Store an EditLine into a stream { WindowItem::Store (S); S << Line << FieldLen << FieldX << LeftArrowX << RightArrowX; S << InsertMode << MaxLen; } void EditLine::Load (Stream& S) // Load an EditLine from a stream { WindowItem::Load (S); S >> Line >> FieldLen >> FieldX >> LeftArrowX >> RightArrowX; S >> InsertMode >> MaxLen; // Set the working variables InsertPos = 0; FirstChar = 0; CursorX = 0; FirstPos = 0; } u16 EditLine::StreamableID () const { return ID_EditLine; } Streamable *EditLine::Build () { return new EditLine (Empty); } void EditLine::SetWidth (u16 NewWidth) { // Get the minimum acceptable width u16 Min = MinWidth (); // Bail out if the new width is invalid if (NewWidth < Min) { return; } // If the length of ItemText is zero, the only allowed width is MinWidth // Because SetWidth is also used to set the other variables, we cannot // ignore such an request if (ItemText.Len () == 0 && NewWidth > Min) { NewWidth = Min; } // Calculate the differnce between the min width and the new width u16 Fill = NewWidth - Min; // Set up the positions u16 Len = ItemText.Len (); FieldX = ItemX + 1 + Fill; if (Len > 0) { FieldX += Len + 2; } LeftArrowX = FieldX - 1; RightArrowX = FieldX + FieldLen; // Remember new value ItemWidth = NewWidth; } void EditLine::SetPos (u16 X, u16 Y) { ItemX = X; ItemY = Y; // Use SetWidth to recalculate all data SetWidth (ItemWidth); } void EditLine::Draw () { // Draw WindowItem WindowItem::Draw (); // The rest is done by DrawField DrawField (); } u16 EditLine::MinWidth () { u16 Width = ItemText.Len (); if (Width > 0) { Width += 2; // One space left and right } return Width + 2 + FieldLen; } void EditLine::SetValue (const String& NewVal) // Set a new value for Line { // Store the new string Line = NewVal; // Truncate the given String if it is too long if (Line.Len () > MaxLen) { Line.ForceLen (MaxLen); } // Redraw the item Draw (); } void EditLine::DrawIfFirstChar () // Is called to redraw the item if nothing has changed but the item // has to be redrawn (e.g. because the the state of FirstChar has // changed). { if (FirstChar) { FirstChar = 0; DrawField (); } } void EditLine::SetCursorForm () // Sets the cursor shape according to the state of InsertMode { if (InsertMode) { Owner->SetCursorFat (); } else { Owner->SetCursorOn (); } } void EditLine::AdjustPos () // Sets all working variables when InsertPos has changed { if (InsertPos < FirstPos) { FirstPos = InsertPos; } else if (InsertPos >= (FirstPos + FieldLen)) { FirstPos = InsertPos - FieldLen; } CursorX = FieldX + (InsertPos - FirstPos); if (CursorX < FieldX) { // Scroll left FirstPos--; CursorX++; } else if (CursorX >= (FieldX + FieldLen)) { // Scroll right FirstPos++; CursorX--; } } void EditLine::InputChar (Key K) // Inserts a normal char { // Check if the char is valid if (!CharIsOk (K)) { return; } // If this is the first char, clear the line if (FirstChar) { Line.Trunc (0); // Make an empty string FirstPos = 0; InsertPos = 0; FirstChar = 0; } // u16 Len = Line.Len (); if (InsertPos < Len) { // Insert in the mid if Line if (InsertMode) { // Insert only if line does not get too long if (Len < MaxLen) { Line.Ins (InsertPos, (char) K); InsertPos++; } } else { Line [InsertPos] = (char) K; InsertPos++; } } else { // Insert at the end if (Len < MaxLen) { Line += (char) K; InsertPos++; } } // Adjust variables and redraw the field AdjustPos (); DrawField (); } void EditLine::Edit (int& Abort) // Start editing mode. Abort is set to 1 if the user aborted the // input (Line is not changed in this case), 0 if the input was // accepted (by pressing enter). { // Bail out if the item is not active if (!IsActive ()) { Abort = 1; return; } // Remember the state of the owner window and the cursor form u16 OldState = Owner->GetState (); Window::CursorType Cursor = Owner->GetCursor (); // Update status line u32 StatusFlags = siAbort | siEnter; if (HasHelp ()) { StatusFlags |= siHelp; } PushStatusLine (StatusFlags); // Make the owner window active Owner->Activate (); // Remember the old input line. The line is restored if the input // is aborted String OldLine (Line); // Set up the cursor position, insert position etc. u16 Len = Line.Len (); if (Len < FieldLen) { FirstPos = 0; } else { FirstPos = Len - FieldLen + 1; } InsertPos = Len; AdjustPos (); // We are waiting for the first input char FirstChar = 1; // Draw the output field and set the cursor DrawField (); SetCursorForm (); // Now start editing loop int EditDone = 0; Key K; while (!EditDone) { // Get a key K = KbdGet (); // Check what it is... switch (K) { // Help key case vkHelp: CallHelp (); break; // Resize owner window case vkResize: Owner->MoveResize (); break; // Abort editing case vkAbort: Abort = 1; EditDone = 1; Line = OldLine; // Restore old input line break; // Accept the input line case kbEnter: case vkAccept: if (EndCheckOk ()) { Abort = 0; EditDone = 1; } break; // Switch insert mode case vkIns: InsertMode = !InsertMode; SetCursorForm (); DrawIfFirstChar (); break; // Cursor to the left case vkLeft: if (InsertPos > 0) { InsertPos--; AdjustPos (); FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // Cursor to the right case vkRight: if (InsertPos < Line.Len ()) { InsertPos++; AdjustPos (); FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // Destructive backspace case kbBack: if (InsertPos > 0) { InsertPos--; Line.Del (InsertPos, 1); AdjustPos (); if (InsertPos == Line.Len ()) { if (FirstPos > 0) { FirstPos--; CursorX ++; } } else if (CursorX == FieldX && FirstPos > 0) { CursorX++; FirstPos--; } FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // Delete char under cursor case vkDel: if (InsertPos < Line.Len ()) { Line.Del (InsertPos, 1); FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // Home key case vkHome: if (InsertPos > 0) { InsertPos = 0; AdjustPos (); FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // End key case vkEnd: Len = Line.Len (); if (InsertPos < Len) { InsertPos = Len; AdjustPos (); FirstChar = 0; DrawField (); } else { DrawIfFirstChar (); } break; // Insert all chars case kbCtrlP: DrawIfFirstChar (); K = KbdGet (); if (IsPlainKey (K)) { InputChar (K); } break; // All other keys default: if (K != AccelKey && KeyIsRegistered (K)) { // Key is reserved if (EndCheckOk ()) { // Input is valid, write back the key KbdPut (K); Abort = 0; EditDone = 1; } } else { // Just a normal char InputChar (K); } break; } // End switch } // End while // Reset variables and redraw the item CursorX = 0; FirstPos = 0; FirstChar = 0; DrawField (); // Set the old window state Owner->SetState (OldState); Owner->SetCursor (Cursor); // Restore the old status line PopStatusLine (); } i16 EditLine::Choose () // Calls Edit and returns the id of the entry if the editing was // not aborted. Otherwise 0 is returned. { int Abort; Edit (Abort); return Abort ? 0 : ID; } /*****************************************************************************/ /* class FloatEdit */ /*****************************************************************************/ FloatEdit::FloatEdit (const String& aItemText, i16 aID, u16 aLD, u16 aTD, WindowItem *NextItem) : EditLine (aItemText, aID, aTD ? aLD + aTD + 1 : aLD, aTD ? aLD + aTD + 2 : aLD + 1, NextItem), FValue (0), LD (aLD), TD (aTD), FMin (0), FMax (0) { // Set the value for the EditLine Line variable Line = FloatStr (FValue, LD, TD); } FloatEdit::FloatEdit (const String & aItemText, i16 aID, u16 aLD, u16 aTD, double Min, double Max, WindowItem *NextItem) : EditLine (aItemText, aID, aTD ? aLD + aTD + 1 : aLD, aTD ? aLD + aTD + 2 : aLD + 1, NextItem), FValue (Min), LD (aLD), TD (aTD), FMin (Min), FMax (Max) { // Set the value for the EditLine Line variable Line = FloatStr (FValue, LD, TD); } int FloatEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { // Examine the key if (IsDigit (K)) { return 1; } else if (K == (unsigned char) NLSData.DecSep) { // Decimal separator is allowed in one place only return Line.Pos (NLSData.DecSep) < 0; } else if (K == '-') { // Allowed in the first place only if minimum < 0 return ((FMin < 0 && InsertPos == 0) || (FMin < 0 && FirstChar)); } else { // Disallow all other chars return 0; } } int FloatEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { double NewVal; // Parse the line StringParser S (Line); unsigned Res = S.GetFloat (NewVal); if (Res != 0) { // cannot convert line ErrorMsg (S.GetMsg (Res)); return 0; } // String can be converted to a float. Check for leading/trailing digits int SepPos = Line.Pos (NLSData.DecSep); if (SepPos >= 0) { // Has a separator if (Line.Len () - SepPos - 1 > TD) { // Too many trailing digits ErrorMsg (msErrTrailingDigits); return 0; } } // Now check against the limits if (NewVal < FMin) { ErrorMsg (msErrFTooSmall, FMin); return 0; } if (NewVal > FMax) { ErrorMsg (msErrFTooLarge, FMax); return 0; } // That's it. The value is ok SetValue (NewVal); return 1; } void FloatEdit::Store (Stream& S) const // Store the object into a stream { EditLine::Store (S); S << FValue << LD << TD << FMin << FMax; } void FloatEdit::Load (Stream& S) // Load the object from a stream { EditLine::Load (S); S >> FValue >> LD >> TD >> FMin >> FMax; } u16 FloatEdit::StreamableID () const { return ID_FloatEdit; } Streamable* FloatEdit::Build () { return new FloatEdit (Empty); } void FloatEdit::SetValue (double NewVal) // Set a new value for FValue { // Remember the new value FValue = NewVal; // Set the input line EditLine::SetValue (FloatStr (FValue, LD, TD)); } void FloatEdit::SetMinMax (double Min, double Max) // Set the FMin/FMax values { PRECONDITION (Min <= Max); FMin = Min; FMax = Max; } /*****************************************************************************/ /* class LongEdit */ /*****************************************************************************/ LongEdit::LongEdit (const String &aItemText, i16 aID, u16 aDigits, WindowItem *NextItem) : EditLine (aItemText, aID, aDigits, aDigits + 1, NextItem), LValue (0), LMin (0), LMax (0), Digits (aDigits) { // Set the value for the EditLine Line variable Line = I32Str (LValue); } LongEdit::LongEdit (const String &aItemText, i16 aID, u16 aDigits, i32 Min, i32 Max, WindowItem *NextItem) : EditLine (aItemText, aID, aDigits, aDigits + 1, NextItem), LValue (Min), LMin (Min), LMax (Max), Digits (aDigits) { // Check Min/Max values PRECONDITION (Min <= Max); // Set the value for the EditLine Line variable Line = I32Str (LValue); } int LongEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { // Digits and a minus sign in the first place are ok return IsDigit (K) || (LMin < 0 && InsertPos == 0); } int LongEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // Convert the string i32 NewVal = 0; StringParser P (Line); unsigned Res = P.GetI32 (NewVal); if (Res != 0) { ErrorMsg (P.GetMsg (Res)); return 0; } // Now check against the limits if (NewVal < LMin) { ErrorMsg (msErrLTooSmall, LMin); return 0; } if (NewVal > LMax) { ErrorMsg (msErrLTooLarge, LMax); return 0; } // That's it. The value is ok SetValue (NewVal); return 1; } void LongEdit::Store (Stream& S) const // Store the object into a stream { EditLine::Store (S); S << LValue << LMin << LMax << Digits; } void LongEdit::Load (Stream& S) // Load an object from a stream { EditLine::Load (S); S >> LValue >> LMin >> LMax >> Digits; } u16 LongEdit::StreamableID () const { return ID_LongEdit; } Streamable* LongEdit::Build () { return new LongEdit (Empty); } void LongEdit::SetValue (i32 NewVal) // Set a new value for LValue { // Remember new value LValue = NewVal; // Set the input line EditLine::SetValue (I32Str (LValue)); } void LongEdit::SetMinMax (i32 Min, i32 Max) // Set the FMin/FMax values { // Check the parameters PRECONDITION (Min <= Max); // Remember the new values LMin = Min; LMax = Max; } /*****************************************************************************/ /* class HexEdit */ /*****************************************************************************/ int HexEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { if (IsXDigit (K)) { // These are ok, but convert to caps K = (Key) NLSUpCase ( (char) K); return 1; } else { return 0; } } int HexEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // Convert the string u32 NewVal = 0; StringParser P (Line); unsigned Res = P.GetU32 (NewVal); if (Res != 0) { ErrorMsg (P.GetMsg (Res)); return 0; } // Now check against the limits if (NewVal < u32 (LMin)) { ErrorMsg (msErrLTooSmall, LMin); return 0; } if (NewVal > u32 (LMax)) { ErrorMsg (msErrLTooLarge, LMax); return 0; } // That's it. The value is ok SetValue (NewVal); return 1; } u16 HexEdit::StreamableID () const { return ID_HexEdit; } Streamable * HexEdit::Build () { return new HexEdit (Empty); } void HexEdit::SetValue (u32 NewVal) // Set a new value for LValue { // Remember new value LValue = NewVal; // Set the input line EditLine::SetValue (U32Str (LValue, 16)); } /*****************************************************************************/ /* class TextEdit */ /*****************************************************************************/ TextEdit::TextEdit (const String& ItemText, i16 ItemID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem): EditLine (ItemText, ItemID, aMaxLen, aFieldLen, NextItem) { // Allow all chars but control chars, ASCII ONLY AllowedChars.AddRange (0x20, 0xFF); } TextEdit::TextEdit (StreamableInit): EditLine (Empty), AllowedChars (Empty) { } int TextEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { return IsPlainKey (K) && AllowedChars [K] != 0; } int TextEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // Char #0 is a flag that determines if an empty line is allowed if (AllowedChars [0] == 0 && Line.IsEmpty ()) { ErrorMsg (msErrNoEmptyInput); return 0; } else { return 1; } } void TextEdit::SetAllowedChars (const CharSet& CS) // Set the allowed input chars { AllowedChars = CS; } void TextEdit::Store (Stream& S) const { EditLine::Store (S); S << AllowedChars; } void TextEdit::Load (Stream& S) { EditLine::Load (S); // Use the else case instead reading AllowedChars to convert old resources #if 1 S >> AllowedChars; #else AllowedChars.Clear (); AllowedChars.AddRange (0x20, 0xFF); #endif } u16 TextEdit::StreamableID () const { return ID_TextEdit; } Streamable* TextEdit::Build () { return new TextEdit (Empty); } /*****************************************************************************/ /* class TimeEdit */ /*****************************************************************************/ int TimeEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { return IsDigit (K) || (K == (unsigned char) NLSData.TimeSep); } int TimeEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // Set up a string parser for Line Time NewVal; StringParser P (Line); unsigned Res = P.GetTime (NewVal); if (Res != 0) { ErrorMsg (P.GetMsg (Res)); return 0; } // That's it. The value is ok SetValue (NewVal); return 1; } TimeEdit::TimeEdit (const String& aItemText, i16 aID, WindowItem* NextItem) : EditLine (aItemText, aID, 8, 9, NextItem), TValue () { // Set the value for the EditLine Line variable Line = TValue.TimeStr (); } void TimeEdit::Store (Stream& S) const { // Store parental data EditLine::Store (S); // Store own data S << TValue; } void TimeEdit::Load (Stream& S) { // Load parental data EditLine::Load (S); // Load own data S >> TValue; } u16 TimeEdit::StreamableID () const { return ID_TimeEdit; } Streamable* TimeEdit::Build () { return new TimeEdit (Empty); } void TimeEdit::SetValue (const Time& NewVal) // Set a new value for TValue { // Remember new value TValue = NewVal; // Set the input line EditLine::SetValue (TValue.TimeStr ()); } void TimeEdit::SetValue (unsigned Hour, unsigned Min, unsigned Sec) { // Set the new value TValue.SetTime (Hour, Min, Sec); // Set the input line EditLine::SetValue (TValue.TimeStr ()); } void TimeEdit::SetValue (u32 Seconds) { unsigned Sec = Seconds % 60; Seconds /= 60; unsigned Min = Seconds % 60; unsigned Hour = Seconds / 60; CHECK (Hour < 24); // Set the new value SetValue (Hour, Min, Sec); } /*****************************************************************************/ /* class DateEdit */ /*****************************************************************************/ int DateEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { return IsDigit (K) || (K == (unsigned char) NLSData.DateSep); } int DateEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { // Set up a string parser for Line Time NewVal; StringParser P (Line); unsigned Res = P.GetDate (NewVal); if (Res != 0) { ErrorMsg (P.GetMsg (Res)); return 0; } // That's it. The value is ok SetValue (NewVal); return 1; } DateEdit::DateEdit (const String& aItemText, i16 aID, WindowItem* NextItem) : EditLine (aItemText, aID, 10, 11, NextItem) { // Set the value for the EditLine Line variable Line = TValue.DateStr (); } void DateEdit::Store (Stream& S) const { // Store parental data EditLine::Store (S); // Store own data S << TValue; } void DateEdit::Load (Stream& S) { // Load parental data EditLine::Load (S); // Load own data S >> TValue; } u16 DateEdit::StreamableID () const { return ID_DateEdit; } Streamable* DateEdit::Build () { return new DateEdit (Empty); } void DateEdit::SetValue (const Time& NewVal) // Set a new value for TValue { // Remember new value TValue = NewVal; // Set the input line EditLine::SetValue (TValue.DateStr ()); } void DateEdit::SetValue (unsigned Year, unsigned Month, unsigned Day) { // Set new value TValue.SetDate (Year, Month, Day); // Set the input line EditLine::SetValue (TValue.DateStr ()); } /*****************************************************************************/ /* class PasswordEdit */ /*****************************************************************************/ void PasswordEdit::DrawField () // This function is called from Edit and draws the editing field. // FirstPos is the position (in Line) of the first char that is // printed. CursorX is the position of the cursor in the window. // First is true if the user has not pressed any key. In this case, // a special attribuite for the text is used, because the first // keypress of a non cursor key will clear the line. // This functions overloads EditLine::DrawField and outputs '*'s // instead of the real line { // Create a new string with the length of the visible portion // of the input line String S (FieldLen); S.Set (0, Line.Len () - FirstPos, '*'); S.Pad (String::Right, FieldLen); // Draw the line Owner->Write (FieldX, ItemY, S, FirstChar ? atEditHigh : atEditNormal); // Draw/delete both arrows DrawLeftArrow (FirstPos != 0); DrawRightArrow ((FirstPos + FieldLen) < Line.Len ()); // Reset the cursor Owner->SetCursorPos (Point (CursorX, ItemY)); } u16 PasswordEdit::StreamableID () const { return ID_PasswordEdit; } Streamable* PasswordEdit::Build () { return new PasswordEdit (Empty); } /*****************************************************************************/ /* class FileEdit */ /*****************************************************************************/ int FileEdit::CharIsOk (Key& K) // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! { if (IsPlainKey (K) == 0 || IsCntrl (K)) { // Invalid char return 0; } // Normal character? if (FileSysValidChar ((char) K)) { // Ok return 1; } // Wildcard character? if (strchr ("*?[]{,}", K) != NULL) { // Wildcard are allowed if the corresponding flag is set return WildcardsOk (); } // Path separator? if (K == (unsigned char) FileSysPathSep) { return PathOk (); } #if defined(FILESYS_HAS_DRIVES) || defined(FILESYS_HAS_VOLUMES) // A colon is ok if paths are allowed and the file system supports // drives or volumes if (K == ':') { return PathOk () && Line.Pos (':') == -1; } #endif // invalid char return 0; } int FileEdit::EndCheckOk () // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. { if (!ExtensionOk ()) { // No extension allowed - check this String Path; String Name; String Ext; FSplit (Line, Path, Name, Ext); if (!Ext.IsEmpty ()) { ErrorMsg (msErrNoExtension); return 0; } } // Line is ok return 1; } FileEdit::FileEdit (const String& ItemText, i16 ItemID, u16 aMaxLen, u16 aFieldLen, u16 aFileFlags, WindowItem* NextItem): EditLine (ItemText, ItemID, aMaxLen, aFieldLen, NextItem), FileFlags (aFileFlags) { } void FileEdit::Store (Stream& S) const { // Store parental data EditLine::Store (S); // Store class data S << FileFlags; } void FileEdit::Load (Stream& S) { // Load parental data EditLine::Load (S); // Load class data S >> FileFlags; } u16 FileEdit::StreamableID () const { return ID_FileEdit; } Streamable* FileEdit::Build () { return new FileEdit (Empty); } void FileEdit::Draw () // Overloads function TEditLine::Draw. Cuts the path if it is to long // to be displayed { // Is the line too long to be displayed? if (Line.Len () > FieldLen - 3) { // It is too long, display a shortened version String LineTmp = Line; Line = ShortPath (Line, FieldLen - 3); // Use the draw function from EditLine now EditLine::Draw (); // Restore the old line contents Line = LineTmp; } else { // The line fits, just display it EditLine::Draw (); } } void FileEdit::SetFileFlags (u16 NewFlags) // Change the FileFlags settings { FileFlags = NewFlags; } estic-1.61.orig/spunk/menuedit.h0100644000176100001440000005055407031424702016143 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUEDIT.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __MENUEDIT_H #define __MENUEDIT_H #include "itemwin.h" #include "datetime.h" #include "charset.h" /*****************************************************************************/ /* Constants used by FileEdit */ /*****************************************************************************/ const u16 ffPathOk = 0x0001; // path accepted if set const u16 ffWildcardsOk = 0x0002; // wildcards accepted if set const u16 ffExtensionOk = 0x0004; // extension accepted if set /*****************************************************************************/ /* class EditLine */ /*****************************************************************************/ class EditLine: public WindowItem { friend class ResEditApp; // Resource editor is a friend private: void DrawIfFirstChar (); // Is called to redraw the item if nothing has changed but the item // has to be redrawn (e.g. because the the state of FirstChar has // changed). void SetCursorForm (); // Sets the cursor shape according to the state of InsertMode void AdjustPos (); // Sets all working variables when InsertPos has changed void InputChar (Key K); // Inserts a normal char protected: String Line; // The edit line u16 FieldLen; // Length of the entry field u16 FieldX; // Start pos of entry u16 LeftArrowX; // Position left arrow u16 RightArrowX; // Position right arrow i16 InsertMode; // Insert mode on/off u16 MaxLen; // max input length // Working variables u16 InsertPos; // Where is the next char inserted? int FirstChar; u16 CursorX; // Position of the cursor u16 FirstPos; // First position in field virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. void DrawLeftArrow (int Arrow); // Draws or clears the left arrow according to the given flag void DrawRightArrow (int Arrow); // Draws or clears the right arrow according to the given flag virtual void DrawField (); // This function is called from Edit and draws the editing field. // FirstPos is the position (in Line) of the first char that is // printed. CursorX is the position of the cursor in the window. // First is true if the user has not pressed any key. In this case, // a special attribuite for the text is used, because the first // keypress of a non cursor key will clear the line. EditLine (StreamableInit); // Build constructor public: EditLine (const String& ItemText, i16 ItemID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class WindowItem virtual void SetWidth (u16 NewWidth); virtual void SetPos (u16 X, u16 Y); virtual void Draw (); virtual u16 MinWidth (); // -- New functions void SetValue (const String& NewVal); // Set a new value for Line const String& GetValue () const; // Return the current value of Line void Edit (int& Abort); // Start editing mode. Abort is set to 1 if the user aborted the // input (Line is not changed in this case), 0 if the input was // accepted (by pressing enter). virtual i16 Choose (); // Calls Edit and returns the id of the entry if the editing was // not aborted. Otherwise 0 is returned. }; inline EditLine::EditLine (StreamableInit) : WindowItem (Empty), Line (Empty) { } inline const String& EditLine::GetValue () const // Return the value of Line { return Line; } /*****************************************************************************/ /* class FloatEdit */ /*****************************************************************************/ class FloatEdit: public EditLine { friend class ResEditApp; // Resource editor is a friend protected: double FValue; // Current value u16 LD, TD; // Leading and trailing digits double FMin; // Minimum double FMax; // Maximum virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. FloatEdit (StreamableInit); // Build constructor public: FloatEdit (const String& aItemText, i16 aID, u16 aLD, u16 aTD, WindowItem* NextItem); FloatEdit (const String& aItemText, i16 aID, u16 aLD, u16 aTD, double Min, double Max, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // -- new functions void SetValue (double NewVal); // Set a new value for FValue double GetValue () const; // Get the current value void SetMinMax (double Min, double Max); // Set the FMin/FMax values void GetMinMax (double& Min, double& Max) const; // Get the FMin/FMax values }; inline FloatEdit::FloatEdit (StreamableInit) : EditLine (Empty) { } inline double FloatEdit::GetValue () const { return FValue; } inline void FloatEdit::GetMinMax (double &Min, double &Max) const { Min = FMin; Max = FMax; } /*****************************************************************************/ /* class LongEdit */ /*****************************************************************************/ class LongEdit: public EditLine { friend class ResEditApp; // Resource editor is a friend protected: i32 LValue; // Current value i32 LMin; // Minimum value i32 LMax; // Maximum value u16 Digits; virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. LongEdit (StreamableInit); // Build constructor public: LongEdit (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem); LongEdit (const String& aItemText, i16 aID, u16 aDigits, i32 Min, i32 Max, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // -- new functions void SetValue (i32 NewVal); // Set a new value for LValue i32 GetValue () const; // Get the current value void SetMinMax (i32 Min, i32 Max); // Set the FMin/FMax values void GetMinMax (i32 &Min, i32 &Max) const; // Get the FMin/FMax values }; inline LongEdit::LongEdit (StreamableInit) : EditLine (Empty) { } inline i32 LongEdit::GetValue () const { return LValue; } inline void LongEdit::GetMinMax (i32 &Min, i32 &Max) const { Min = LMin; Max = LMax; } /*****************************************************************************/ /* class HexEdit */ /*****************************************************************************/ class HexEdit: public LongEdit { friend class ResEditApp; // Resource editor is a friend protected: virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. HexEdit (StreamableInit); // Build constructor public: HexEdit (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem); HexEdit (const String& aItemText, i16 aID, u16 aDigits, i32 Min, i32 Max, WindowItem* NextItem); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // -- new functions void SetValue (u32 NewVal); // Set a new value for LValue }; inline HexEdit::HexEdit (StreamableInit) : LongEdit (Empty) { } inline HexEdit::HexEdit (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem) : LongEdit (aItemText, aID, aDigits, NextItem) { } inline HexEdit::HexEdit (const String& aItemText, i16 aID, u16 aDigits, i32 Min, i32 Max, WindowItem* NextItem) : LongEdit (aItemText, aID, aDigits, Min, Max, NextItem) { } /*****************************************************************************/ /* class TextEdit */ /*****************************************************************************/ class TextEdit: public EditLine { friend class ResEditApp; // Resource editor is a friend protected: CharSet AllowedChars; // Set of allowed input chars virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. TextEdit (StreamableInit); // Build constructor public: TextEdit (const String& ItemText, i16 ItemID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); const CharSet& GetAllowedChars () const; // Get the set of allowed input chars void SetAllowedChars (const CharSet& CS); // Set the allowed input chars void AllowEmptyInput (); void DisallowEmptyInput (); // Allow or disallow an empty input line }; inline const CharSet& TextEdit::GetAllowedChars () const // Get the set of allowed input chars { return AllowedChars; } inline void TextEdit::AllowEmptyInput () // Allow an empty input line { AllowedChars += '\0'; } inline void TextEdit::DisallowEmptyInput () // Disallow an empty input line { AllowedChars -= '\0'; } /*****************************************************************************/ /* class TimeEdit */ /*****************************************************************************/ class TimeEdit: public EditLine { protected: Time TValue; virtual int CharIsOk (Key &K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. TimeEdit (StreamableInit); // Build constructor public: TimeEdit (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // -- new functions void SetValue (const Time& NewVal); void SetValue (unsigned Hour, unsigned Min, unsigned Sec); void SetValue (u32 Sec); // Set a new value for TValue const Time& GetValue () const; // Get the current value }; inline TimeEdit::TimeEdit (StreamableInit) : EditLine (Empty), TValue (Empty) { } inline const Time& TimeEdit::GetValue () const // Get the current value { return TValue; } /*****************************************************************************/ /* class DateEdit */ /*****************************************************************************/ class DateEdit: public EditLine { protected: Time TValue; virtual int CharIsOk (Key &K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. DateEdit (StreamableInit); // Build constructor public: DateEdit (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // -- new functions void SetValue (const Time& NewVal); void SetValue (unsigned Year, unsigned Month, unsigned Day); // Set a new value for TValue const Time& GetValue () const; // Get the current value }; inline DateEdit::DateEdit (StreamableInit) : EditLine (Empty), TValue (Empty) { } inline const Time& DateEdit::GetValue () const { return TValue; } /*****************************************************************************/ /* class PasswordEdit */ /*****************************************************************************/ class PasswordEdit: public EditLine { protected: PasswordEdit (StreamableInit); // Build constructor virtual void DrawField (); // This function is called from Edit and draws the editing field. // FirstPos is the position (in Line) of the first char that is // printed. CursorX is the position of the cursor in the window. // First is true if the user has not pressed any key. In this case, // a special attribuite for the text is used, because the first // keypress of a non cursor key will clear the line. // This functions overloads EditLine::DrawField and outputs '*'s // instead of the real line public: PasswordEdit (const String& aItemText, i16 aID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); }; inline PasswordEdit::PasswordEdit (const String& aItemText, i16 aID, u16 aMaxLen, u16 aFieldLen, WindowItem* NextItem) : EditLine (aItemText, aID, aMaxLen, aFieldLen, NextItem) { } inline PasswordEdit::PasswordEdit (StreamableInit) : EditLine (Empty) { } /*****************************************************************************/ /* class FileEdit */ /*****************************************************************************/ class FileEdit: public EditLine { friend class ResEditApp; // Resource editor is a friend protected: u16 FileFlags; // virtual int CharIsOk (Key& K); // This function is called with the users input to check if the // input is valid. The function returns 1 if the key is acceptable, // 0 otherwise. Overload this function for restricting input. // The function can change the given char! virtual int EndCheckOk (); // This function is called when the user has ended editing. It returns // 1 if the contents of Line are acceptable, 0 if not. In the latter // case it's up to this function to display an appropriate error // message. FileEdit (StreamableInit); // Build constructor public: FileEdit (const String& ItemText, i16 ItemID, u16 aMaxLen, u16 aFieldLen, u16 aFileFlags, WindowItem* NextItem); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); virtual void Draw (); // Overloads function TEditLine::Draw. Cuts the path if it is to long // to be displayed u16 GetFileFlags () const; // Return the current FileFlags settings virtual void SetFileFlags (u16 NewFlags); // Change the FileFlags settings int PathOk () const; // Return the setting from FileFlags int WildcardsOk () const; // Return the setting from FileFlags int ExtensionOk () const; // Return the setting from FileFlags }; inline FileEdit::FileEdit (StreamableInit): EditLine (Empty) { } inline u16 FileEdit::GetFileFlags () const { return FileFlags; } inline int FileEdit::PathOk () const // Return the setting from FileFlags { return (FileFlags & ffPathOk) != 0; } inline int FileEdit::WildcardsOk () const // Return the setting from FileFlags { return (FileFlags & ffWildcardsOk) != 0; } inline int FileEdit::ExtensionOk () const // Return the setting from FileFlags { return (FileFlags & ffExtensionOk) != 0; } // End of MENUEDIT.H #endif estic-1.61.orig/spunk/menuitem.cc0100644000176100001440000011136407031424702016307 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUITEM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "menuitem.h" #include "winattr.h" #include "menuedit.h" #include "progutil.h" #include "streamid.h" #include "strcvt.h" #include "msgid.h" // Register the classes LINK (MenueLine, ID_MenueLine); LINK (LongItem, ID_LongItem); LINK (HexItem, ID_HexItem); LINK (StringItem, ID_StringItem); LINK (ToggleItem, ID_ToggleItem); LINK (OffOnItem, ID_OffOnItem); LINK (NoYesItem, ID_NoYesItem); LINK (FloatItem, ID_FloatItem); LINK (TimeItem, ID_TimeItem); LINK (DateItem, ID_DateItem); LINK (RStringItem, ID_RStringItem); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msOffOn = MSGBASE_MENUITEM + 0; static const u16 msNoYes = MSGBASE_MENUITEM + 1; /*****************************************************************************/ /* class MenueLine */ /*****************************************************************************/ MenueLine::MenueLine (i16 aID, WindowItem *NextItem) : MenueItem ("", aID, NextItem) { // Menuelines are inactive objects Flags |= ifInactive; } u16 MenueLine::StreamableID () const { return ID_MenueLine; } Streamable* MenueLine::Build () { return new MenueLine (Empty); } void MenueLine::BuildEntry (const String&) // Rebuild Entry when the length has changed. The given String is // ignored. { // Cut the entry string if it is longer than the new width Entry.Trunc (ItemWidth); // Construct a new display string Entry.Set (0, ItemWidth, InactiveFrame [fcHorizontal]); // Optimize memory Entry.Settle (); } u16 MenueLine::MinWidth () { // A line has min width zero return 0; } /*****************************************************************************/ /* class EditMenueItem */ /*****************************************************************************/ EditMenueItem::EditMenueItem (const String& aItemText, i16 aID, i16 EditID, ItemWindow* EditWin, WindowItem* NextItem) : MenueItem (aItemText, aID, NextItem), EditWindow (EditWin), EditItemID (EditID) { } EditMenueItem::~EditMenueItem () { delete EditWindow; } void EditMenueItem::Store (Stream &S) const // Store the object data into a stream { // Store parental data MenueItem::Store (S); // Store instance data S << EditItemID; S.Put (EditWindow); } void EditMenueItem::Load (Stream &S) // Load the object data from a stream { // Load parental data MenueItem::Load (S); // Load instance data S >> EditItemID; EditWindow = (ItemWindow *) S.Get (); } void EditMenueItem::PlaceEditWindow () // Place the edit window below this entry if EditWindow has no position // (== has position 0/0). { if (EditWindow) { // Get the coords of the edit window Rect Bounds (EditWindow->OuterBounds ()); if (Bounds.A == Point (0, 0)) { // The edit window has no position. Get the coords of the // item and make them absolute Point P (ItemX, ItemY); Owner->Absolute (P); // Now place the edit window below the entry P.Y++; EditWindow->MoveRel (P); } } } WindowItem* EditMenueItem::ItemWithID (i16 aID) // Search for the item with the given ID. The editwindow (if one exists) // is also searched. { if (ID == aID) { return this; } else { return EditWindow ? EditWindow->ItemWithID (aID) : (WindowItem*) NULL; } } void EditMenueItem::SetEditWindow (ItemWindow *Win, i16 EditID) // Set the edit window. Beware: An already existing edit window is not // deleted! { // Check the given parameters PRECONDITION (Win == NULL || EditID != 0); // Store them EditWindow = Win; EditItemID = EditID; } /*****************************************************************************/ /* class LongItem */ /*****************************************************************************/ LongItem::LongItem (const String& aItemText, i16 aID, u16 aDigits, i16 EditID, i32 Min, i32 Max, WindowItem* NextItem) : EditMenueItem (aItemText, aID, EditID, NULL, NextItem), LValue (Min), Digits (aDigits), LMin (Min), LMax (Max) { } LongItem::LongItem (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem) : EditMenueItem (aItemText, aID, 0, NULL, NextItem), LValue (0), Digits (aDigits), LMin (0x80000000), LMax (0x7FFFFFFF) { } void LongItem::Load (Stream &S) // Load the object data from a stream { // Load parental data EditMenueItem::Load (S); // Load instance data S >> LValue >> Digits >> LMin >> LMax; } void LongItem::Store (Stream &S) const // Store the object data into a stream { // Store parental data EditMenueItem::Store (S); // Store instance data S << LValue << Digits << LMin << LMax; } u16 LongItem::StreamableID () const { return ID_LongItem; } Streamable* LongItem::Build () { return new LongItem (Empty); } void LongItem::SetWidth (u16 NewWidth) { // Check against the minimum width needed if (NewWidth < MinWidth ()) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Convert the number to string String S (I32Str (LValue)); S.ForceLen (Digits, String::Left); S.Ins (0, ' '); BuildEntry (S); } u16 LongItem::MinWidth () { u16 Len = ItemText.Len (); u16 Width = Len + Digits + 2; // One space to the left and right if (Len) { Width += 2; // Space between text and number } return Width; } i16 LongItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { LongEdit *P; int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value P = (LongEdit *) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (LValue); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one P = new LongEdit ("", EditItemID, Digits, NULL); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetMinMax (LMin, LMax); P->SetValue (LValue); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } void LongItem::SetValue (i32 Val) { // Store the new value LValue = Val; // Build the new display text. As the number of digits is fixed, // the length cannot change. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } void LongItem::SetMinMax (i32 Min, i32 Max) { // Check parameters PRECONDITION (Min <= Max); LMin = Min; LMax = Max; } /*****************************************************************************/ /* class HexItem */ /*****************************************************************************/ u16 HexItem::StreamableID () const { return ID_LongItem; } Streamable* HexItem::Build () { return new HexItem (Empty); } void HexItem::SetWidth (u16 NewWidth) { // Check against the minimum width needed if (NewWidth < MinWidth ()) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Convert the number to string String S (U32Str (LValue, 16)); S.ForceLen (Digits, String::Left); S.Ins (0, ' '); BuildEntry (S); } i16 HexItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { HexEdit *P; int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value P = (HexEdit *) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (LValue); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one P = new HexEdit ("", EditItemID, Digits, NULL); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetMinMax (LMin, LMax); P->SetValue (LValue); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } /*****************************************************************************/ /* class StringItem */ /*****************************************************************************/ StringItem::StringItem (const String& aItemText, i16 aID, i16 EditID, WindowItem* NextItem) : EditMenueItem (aItemText, aID, EditID, NULL, NextItem) { // Allow all input chars AllowedChars.SetAll (); } StringItem::StringItem (StreamableInit) : EditMenueItem (Empty), SValue (Empty) { // Allow all chars AllowedChars.SetAll (); } void StringItem::Load (Stream &S) // Load the object data from a stream { // Load parental data EditMenueItem::Load (S); // Load instance data S >> SValue; } void StringItem::Store (Stream &S) const // Store the object data into a stream { // Store parental data EditMenueItem::Store (S); // Store instance data S << SValue; } u16 StringItem::StreamableID () const { return ID_StringItem; } Streamable* StringItem::Build () { return new StringItem (Empty); } void StringItem::SetWidth (u16 NewWidth) { // Check against the minimum width needed u16 MinW = MinWidth (); if (NewWidth < MinW) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Get a copy of the value string, pad it left to the length needed String S (SValue); S.Pad (String::Left, ItemWidth - MinW); // Build the new entry S.Ins (0, ' '); BuildEntry (S); } u16 StringItem::MinWidth () { u16 Len = ItemText.Len (); u16 Width = Len + 2; // One space to the left and right if (Len > 0) { Width += 2; // Add two spaces between text and string } return Width; } i16 StringItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value TextEdit* P = (TextEdit*) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (SValue); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one u16 Len = ItemWidth - MinWidth () - 1; TextEdit* P = new TextEdit ("", EditItemID, Len-1, Len, NULL); // Set the allowed characters for input P->SetAllowedChars (AllowedChars); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetValue (SValue); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } void StringItem::SetValue (const String& NewVal) { // Store the new value SValue = NewVal; SValue.Settle (); // Build the new display text. As the number of digits is fixed, // the length cannot change. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } const CharSet& StringItem::GetAllowedChars () const // Get the set of allowed input chars { return AllowedChars; } void StringItem::SetAllowedChars (const CharSet& CS) // Set the allowed input chars { AllowedChars = CS; } void StringItem::AllowEmptyInput () // Allow an empty input { AllowedChars += '\0'; } void StringItem::DisallowEmptyInput () // Disallow an empty input line { AllowedChars -= '\0'; } /*****************************************************************************/ /* class ToggleItem */ /*****************************************************************************/ ToggleItem::ToggleItem (const String& aItemText, i16 aID, const String& ToggleList, unsigned ToggleCount, WindowItem* NextItem) : StringItem (aItemText, aID, 0, NextItem), TValue (0), TCount (ToggleCount), TList (ToggleList) { // Get the length of the value list u16 Len = TList.Len (); // Check the parameters PRECONDITION (Len != 0 && TCount != 0 && (Len % TCount) == 0); // Initialize variables ItemWidth = MinWidth (); TLen = Len / TCount; SValue = TList.Cut (0, TLen); } void ToggleItem::Load (Stream& S) // Load an object from a stream { // Load parental data StringItem::Load (S); // Load new data S >> TValue >> TCount >> TLen >> TList; } void ToggleItem::Store (Stream& S) const // Store an object into a stream { // Store parental data StringItem::Store (S); // Store new data S << TValue << TCount << TLen << TList; } u16 ToggleItem::StreamableID () const { return ID_ToggleItem; } Streamable* ToggleItem::Build () { return new ToggleItem (Empty); } void ToggleItem::SetValue (u16 NewVal) // Set the new value of the toggle item { // Check the new value PRECONDITION (NewVal < TCount); // Remember the new value TValue = NewVal; // Use the inherited function to set the actual value StringItem::SetValue (TList.Cut (TValue * TLen, TLen)); } void ToggleItem::Toggle () // Toggle the value { // Select the next value if (++TValue >= TCount) { TValue = 0; } SetValue (TValue); } void ToggleItem::SetWidth (u16 NewWidth) // Set the new entry width { // Check if the new width is acceptable u16 WMin = MinWidth (); if (NewWidth < WMin) { // Ignore the request return; } // Remember the new value ItemWidth = NewWidth; // Build the new entry if (SValue.Len () == 0) { BuildEntry (" "); } else { String S; S.Set (0, ItemWidth - WMin); // One space between value and itemtext if (ItemText.Len () != 0) { S += ' '; } BuildEntry (S + SValue); } } u16 ToggleItem::MinWidth () // return the width needed { u16 Len = ItemText.Len (); return Len ? Len + TLen + 4 : Len + TLen + 2; } WindowItem * ToggleItem::ItemWithID (i16 aID) // Return a pointer to this if the given ID is the ID of the object. // A ToggleItem uses all IDs from ID to ID + ToggleCount - 1 { if (aID >= ID && aID < (ID + TCount)) { return this; } else { return NULL; } } i16 ToggleItem::GetID () // Return the ID of the entry. The returned ID is the ID of the item plus // the current toggle value { return ID + TValue; } i16 ToggleItem::Choose () // Choose this entry. This implementation toggles to the next value and // returns the corresponding ID { // No chance if the item is inactive if (!IsActive ()) { return 0; } // Select and show the next toggle value Toggle (); // Now return the ID return GetID (); } /*****************************************************************************/ /* class OffOnItem */ /*****************************************************************************/ OffOnItem::OffOnItem (const String& aItemText, i16 aID, WindowItem* NextItem) : ToggleItem (aItemText, aID, LoadMsg (msOffOn), 2, NextItem) { } u16 OffOnItem::StreamableID () const { return ID_OffOnItem; } void OffOnItem::Load (Stream& S) { // Load data from ToggleItem ToggleItem::Load (S); // Now override the toggle text (loading this instance in a new language // environment should show the new language when loaded) TList = LoadMsg (msOffOn); TLen = TList.Len () / 2; SValue = TList.Cut (TValue * TLen, TLen); } Streamable* OffOnItem::Build () { return new OffOnItem (Empty); } /*****************************************************************************/ /* class NoYesItem */ /*****************************************************************************/ NoYesItem::NoYesItem (const String& aItemText, i16 aID, WindowItem* NextItem) : ToggleItem (aItemText, aID, LoadMsg (msNoYes), 2, NextItem) { } u16 NoYesItem::StreamableID () const { return ID_NoYesItem; } void NoYesItem::Load (Stream& S) { // Load data from ToggleItem ToggleItem::Load (S); // Now override the toggle text (loading this instance in a new language // environment should show the new language when loaded) TList = LoadMsg (msNoYes); TLen = TList.Len () / 2; SValue = TList.Cut (TValue * TLen, TLen); } Streamable* NoYesItem::Build () { return new NoYesItem (Empty); } /*****************************************************************************/ /* class FloatItem */ /*****************************************************************************/ FloatItem::FloatItem (const String& aItemText, i16 aID, u16 aLD, u16 aTD, u16 EditID, double Min, double Max, WindowItem* NextItem) : EditMenueItem (aItemText, aID, EditID, NULL, NextItem), FValue (Min), LD (aLD), TD (aTD), FMin (Min), FMax (Max) { } FloatItem::FloatItem (const String& aItemText, i16 aID, u16 aLD, u16 aTD, WindowItem* NextItem) : EditMenueItem (aItemText, aID, 0, NULL, NextItem), FValue (0), LD (aLD), TD (aTD), FMin (-100000), FMax (+100000) { } void FloatItem::Load (Stream &S) // Load the instance from a stream { EditMenueItem::Load (S); S >> FValue >> LD >> TD >> FMin >> FMax; } void FloatItem::Store (Stream &S) const // Store the instance into a stream { EditMenueItem::Store (S); S << FValue << LD << TD << FMin << FMax; } u16 FloatItem::StreamableID () const { return ID_FloatItem; } Streamable* FloatItem::Build () { return new FloatItem (Empty); } void FloatItem::SetValue (double Val) // Set the new value of the float item { // Store the new value FValue = Val; // Build the new display text. As the number of digits is fixed, // the length cannot change. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } void FloatItem::SetMinMax (double Min, double Max) // Set the values for FMin/FMax { FMin = Min; FMax = Max; } void FloatItem::SetWidth (u16 NewWidth) // Set the new entry width { // Check against the minimum width needed if (NewWidth < MinWidth ()) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Build the new entry String S (FloatStr (FValue, LD, TD)); S.ForceLen (TD ? LD + TD + 1 : LD, String::Left); BuildEntry (S); } u16 FloatItem::MinWidth () // return the width needed { u16 Len = ItemText.Len (); u16 Width = Len + 2 + LD + TD; // one space left and right if (TD > 0) { Width++; // Decimal point } if (Len > 0) { Width += 2; // Space between float and text } return Width; } i16 FloatItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { FloatEdit *P; int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value P = (FloatEdit *) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (FValue); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one P = new FloatEdit ("", EditItemID, LD, TD, NULL); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetMinMax (FMin, FMax); P->SetValue (FValue); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } /*****************************************************************************/ /* class TimeItem */ /*****************************************************************************/ TimeItem::TimeItem (const String& aItemText, i16 aID, i16 EditID, WindowItem* NextItem) : EditMenueItem (aItemText, aID, EditID, NULL, NextItem) { } TimeItem::TimeItem (const String& aItemText, i16 aID, WindowItem* NextItem) : EditMenueItem (aItemText, aID, 0, NULL, NextItem) { } void TimeItem::Load (Stream &S) { EditMenueItem::Load (S); S >> TimeVal; } void TimeItem::Store (Stream &S) const { EditMenueItem::Store (S); S << TimeVal; } u16 TimeItem::StreamableID () const { return ID_TimeItem; } Streamable* TimeItem::Build () { return new TimeItem (Empty); } void TimeItem::SetWidth (u16 NewWidth) { // Check against the minimum width needed if (NewWidth < MinWidth ()) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Build the new entry BuildEntry (TimeVal.TimeStr ()); } u16 TimeItem::MinWidth () { u16 Len = ItemText.Len (); u16 Width = Len + TimeVal.TimeStr().Len() + 2; if (Len) { Width += 2; } return Width; } i16 TimeItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { TimeEdit *P; int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value P = (TimeEdit *) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (TimeVal); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one P = new TimeEdit ("", EditItemID, NULL); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetValue (TimeVal); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } void TimeItem::SetValue (unsigned Hour, unsigned Minute, unsigned Second) { // Set the new value TimeVal.SetTime (Hour, Minute, Second); // Build the new display text. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } void TimeItem::SetValue (u32 Seconds) { unsigned Sec = Seconds % 60; Seconds /= 60; unsigned Min = Seconds % 60; unsigned Hour = Seconds / 60; CHECK (Hour < 24); // Set the new value SetValue (Hour, Min, Sec); } void TimeItem::SetValue (const Time& Val) { // Set the new value TimeVal = Val; // Build the new display text. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } /*****************************************************************************/ /* class DateItem */ /*****************************************************************************/ DateItem::DateItem (const String& aItemText, i16 aID, i16 EditID, WindowItem* NextItem) : EditMenueItem (aItemText, aID, EditID, NULL, NextItem) { } DateItem::DateItem (const String& aItemText, i16 aID, WindowItem* NextItem) : EditMenueItem (aItemText, aID, 0, NULL, NextItem) { } void DateItem::Load (Stream &S) { EditMenueItem::Load (S); S >> TimeVal; } void DateItem::Store (Stream &S) const { EditMenueItem::Store (S); S << TimeVal; } u16 DateItem::StreamableID () const { return ID_DateItem; } Streamable* DateItem::Build () { return new DateItem (Empty); } void DateItem::SetWidth (u16 NewWidth) { // Check against the minimum width needed if (NewWidth < MinWidth ()) { // Ignore the request return; } // Store the new width ItemWidth = NewWidth; // Build the new entry BuildEntry (TimeVal.DateStr ()); } u16 DateItem::MinWidth () { u16 Len = ItemText.Len (); u16 Width = Len + TimeVal.DateStr().Len() + 2; if (Len) { Width += 2; } return Width; } i16 DateItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { DateEdit *P; int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value P = (DateEdit *) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (TimeVal); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one P = new DateEdit ("", EditItemID, NULL); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetValue (TimeVal); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } void DateItem::SetValue (unsigned Year, unsigned Month, unsigned Day) { // Set the new value TimeVal.SetDate (Year, Month, Day); // Build the new display text. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } void DateItem::SetValue (const Time& Val) { // Set the new value TimeVal = Val; // Build the new display text. // Use SetWidth with the current width to do that SetWidth (ItemWidth); // Now redraw the item Draw (); } /*****************************************************************************/ /* class RStringItem */ /*****************************************************************************/ // Class RStringItem has the same functionality as class StringItem with one // exception: The set of allowed input characters is written out on a Store // and reloaded when calling Load. This has been a compatibility decision: // The complete functionality to restrict input has been added to class // StringItem (without changing the default behavior), but writing out the // additional class would have made existing resources unusable - so there // is a new class for that. RStringItem::RStringItem (StreamableInit): StringItem (Empty) // Build constructor { } RStringItem::RStringItem (const String& aItemText, i16 aID, i16 EditID, u16 aInputLength, WindowItem* NextItem): StringItem (aItemText, aID, EditID, NextItem), InputLength (aInputLength) { } void RStringItem::Load (Stream& S) { StringItem::Load (S); S >> AllowedChars >> InputLength; } void RStringItem::Store (Stream& S) const { StringItem::Store (S); S << AllowedChars << InputLength; } u16 RStringItem::StreamableID () const { return ID_RStringItem; } Streamable* RStringItem::Build () { return new RStringItem (Empty); } i16 RStringItem::Choose () // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. { int Abort; i16 Result; // If the edit id is zero, return the own id if (EditItemID == 0) { return ID; } // Check if a predefined window exists if (EditWindow) { // Move the window to the correct position PlaceEditWindow (); // Allow editing the value TextEdit* P = (TextEdit*) EditWindow->ForcedItemWithID (EditItemID); P->SetValue (SValue); P->Edit (Abort); // if no abort, set the value and return the id if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } } else { // No item defined, we have to create one u16 Len = ItemWidth - MinWidth () - 1; if (Len > InputLength + 1) { Len = InputLength + 1; } TextEdit* P = new TextEdit ("", EditItemID, InputLength, Len, NULL); // Set the allowed characters for input P->SetAllowedChars (AllowedChars); // Insert the item into the owner window Owner->AddItem (P); // Set the position of the newly created item P->SetPos (ItemX + ItemWidth - P->GetWidth (), ItemY); // Deselect "this" Deselect (); // Transfer the values from "this" to the new item. Calling // SetValue will also draw the edit item P->SetValue (SValue); // allow editing P->Edit (Abort); // Get the edited value if the editing was not aborted if (Abort) { Result = 0; } else { SetValue (P->GetValue ()); Result = ID; } // Delete the edit item from the owners list Owner->DeleteItem (P); // Select "this". This redraws the item and clears the edit field Select (); } // Return the result return Result; } estic-1.61.orig/spunk/menuitem.h0100644000176100001440000004503407031424702016151 0ustar debacleusers/*****************************************************************************/ /* */ /* MENUITEM.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _MENUITEM_H #define _MENUITEM_H #include "menue.h" #include "datetime.h" #include "charset.h" /*****************************************************************************/ /* class MenueLine */ /*****************************************************************************/ class MenueLine: public MenueItem { friend class ResEditApp; // Resource editor is a friend protected: // Rebuild Entry when the length has changed. The given String S is // ignored. virtual void BuildEntry (const String&); MenueLine (StreamableInit); // Build constructor public: MenueLine (i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class MenueItem virtual u16 MinWidth (); }; inline MenueLine::MenueLine (StreamableInit) : MenueItem (Empty) { } /*****************************************************************************/ /* class EditMenueItem */ /*****************************************************************************/ class EditMenueItem: public MenueItem { friend class ResEditApp; // Resource editor is a friend protected: ItemWindow *EditWindow; i16 EditItemID; EditMenueItem (StreamableInit); // Build constructor public: EditMenueItem (const String& aItemText, i16 aID, i16 EditID, ItemWindow* EditWin, WindowItem* NextItem); virtual ~EditMenueItem (); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual i16 Choose () = 0; // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. void PlaceEditWindow (); // Place the edit window below this entry if EditWindow has no position // (== has position 0/0). virtual WindowItem* ItemWithID (i16 aID); // Search for the item with the given ID. The editwindow (if one exists) // is also searched. void SetEditWindow (ItemWindow *Win, i16 EditID); // Set the edit window. Beware: An already existing edit window is not // deleted! ItemWindow* GetEditWindow () const; // Return the EditWindow pointer }; inline EditMenueItem::EditMenueItem (StreamableInit) : MenueItem (Empty) { } inline ItemWindow* EditMenueItem::GetEditWindow () const // Return the EditWindow pointer { return EditWindow; } /*****************************************************************************/ /* class LongItem */ /*****************************************************************************/ class LongItem: public EditMenueItem { friend class ResEditApp; // Resource editor is a friend protected: i32 LValue; // The value u16 Digits; // How many digits to display i32 LMin, LMax; // Limits for editing LongItem (StreamableInit); // Build constructor public: LongItem (const String& aItemText, i16 aID, u16 aDigits, i16 EditID, i32 Min, i32 Max, WindowItem* NextItem); LongItem (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class MenueItem virtual void SetWidth (u16 NewWidth); virtual u16 MinWidth (); // Derived from class EditMenueItem virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. // Handling the protected variables i32 GetValue () const; void SetValue (i32 Val); void SetMinMax (i32 Min, i32 Max); void GetMinMax (i32& Min, i32& Max) const; }; inline LongItem::LongItem (StreamableInit) : EditMenueItem (Empty) { } inline i32 LongItem::GetValue () const { return LValue; } inline void LongItem::GetMinMax (i32& Min, i32& Max) const { Min = LMin; Max = LMax; } /*****************************************************************************/ /* class HexItem */ /*****************************************************************************/ class HexItem: public LongItem { friend class ResEditApp; // Resource editor is a friend protected: HexItem (StreamableInit); // Build constructor public: HexItem (const String& aItemText, i16 aID, u16 aDigits, i16 EditID, i32 Min, i32 Max, WindowItem* NextItem); HexItem (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class MenueItem virtual void SetWidth (u16 NewWidth); virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. }; inline HexItem::HexItem (const String& aItemText, i16 aID, u16 aDigits, i16 EditID, i32 Min, i32 Max, WindowItem* NextItem) : LongItem (aItemText, aID, aDigits, EditID, Min, Max, NextItem) { } inline HexItem::HexItem (const String& aItemText, i16 aID, u16 aDigits, WindowItem* NextItem) : LongItem (aItemText, aID, aDigits, NextItem) { } inline HexItem::HexItem (StreamableInit) : LongItem (Empty) { } /*****************************************************************************/ /* class StringItem */ /*****************************************************************************/ class StringItem: public EditMenueItem { friend class ResEditApp; // Resource editor is a friend protected: String SValue; CharSet AllowedChars; StringItem (StreamableInit); // Build constructor public: StringItem (const String& aItemText, i16 aID, i16 EditID, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class WindowItem virtual void SetWidth (u16 NewWidth); virtual u16 MinWidth (); virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. void SetValue (const String& NewVal); // Set the current value const String& GetValue (); // Get the current value const CharSet& GetAllowedChars () const; // Get the set of allowed input chars void SetAllowedChars (const CharSet& CS); // Set the allowed input chars void AllowEmptyInput (); void DisallowEmptyInput (); // Allow or disallow an empty input line }; inline const String& StringItem::GetValue () { return SValue; } /*****************************************************************************/ /* class ToggleItem */ /*****************************************************************************/ class ToggleItem: public StringItem { friend class ResEditApp; // Resource editor is a friend protected: u16 TValue; // Current toggle value (0..n-1) u16 TCount; // Number of different values u16 TLen; // Length of one part String TList; // List of display values ToggleItem (StreamableInit); // Build constructor public: ToggleItem (const String& aItemText, i16 aID, const String& ToggleList, unsigned ToggleCount, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); void SetValue (u16 NewVal); // Set the new value of the toggle item u16 GetValue (); // Return the current toggle value void Toggle (); // Toggle the value virtual void SetWidth (u16 NewWidth); // Set the new entry width virtual u16 MinWidth (); // return the width needed virtual WindowItem* ItemWithID (i16 aID); // Return a pointer to this if the given ID is the ID of the object. // A ToggleItem uses all IDs from ID to ID + ToggleCount - 1 virtual i16 GetID (); // Return the ID of the entry. The returned ID is the ID of the item plus // the current toggle value virtual i16 Choose (); // Choose this entry. This implementation toggles to the next value and // returns the corresponding ID }; inline ToggleItem::ToggleItem (StreamableInit) : StringItem (Empty), TList (Empty) { } inline u16 ToggleItem::GetValue () { return TValue; } /*****************************************************************************/ /* class OffOnItem */ /*****************************************************************************/ class OffOnItem: public ToggleItem { friend class ResEditApp; // Resource editor is a friend protected: OffOnItem (StreamableInit); // Build constructor public: OffOnItem (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream& S); virtual u16 StreamableID () const; static Streamable* Build (); }; inline OffOnItem::OffOnItem (StreamableInit) : ToggleItem (Empty) { } /*****************************************************************************/ /* class NoYesItem */ /*****************************************************************************/ class NoYesItem: public ToggleItem { friend class ResEditApp; // Resource editor is a friend protected: NoYesItem (StreamableInit); // Build constructor public: NoYesItem (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream& S); virtual u16 StreamableID () const; static Streamable * Build (); }; inline NoYesItem::NoYesItem (StreamableInit) : ToggleItem (Empty) { } /*****************************************************************************/ /* class FloatItem */ /*****************************************************************************/ class FloatItem: public EditMenueItem { friend class ResEditApp; // Resource editor is a friend protected: double FValue; u16 LD, TD; // Leading and trailing digits double FMin; // Minimum value double FMax; // Maximum value FloatItem (StreamableInit); // Build constructor public: FloatItem (const String& aItemText, i16 aID, u16 aLD, u16 aTD, u16 EditID, double Min, double Max, WindowItem* NextItem); FloatItem (const String& aItemText, i16 aID, u16 aLD, u16 aTD, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); void SetValue (double NewVal); // Set the new value of the float item double GetValue () const; // Return the current value void SetMinMax (double Min, double Max); // Set the values for FMin/FMax void GetMinMax (double& Min, double& Max) const; // Get the values for FMin/FMax virtual void SetWidth (u16 NewWidth); // Set the new entry width virtual u16 MinWidth (); // return the width needed virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. }; inline FloatItem::FloatItem (StreamableInit) : EditMenueItem (Empty) { } inline double FloatItem::GetValue () const { return FValue; } inline void FloatItem::GetMinMax (double& Min, double& Max) const // Get the values for FMin/FMax { Min = FMin; Max = FMax; } /*****************************************************************************/ /* class TimeItem */ /*****************************************************************************/ class TimeItem: public EditMenueItem { protected: Time TimeVal; TimeItem (StreamableInit); // Build constructor public: TimeItem (const String& aItemText, i16 aID, i16 EditID, WindowItem* NextItem); TimeItem (const String& aItemText, i16 aID, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class MenueItem virtual void SetWidth (u16 NewWidth); virtual u16 MinWidth (); // Derived from class EditMenueItem virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. // Handling the protected variables const Time& GetValue () const; void SetValue (const Time& Val); void SetValue (unsigned Hours, unsigned Minutes, unsigned Seconds); void SetValue (u32 Sec); }; inline TimeItem::TimeItem (StreamableInit) : EditMenueItem (Empty), TimeVal (Empty) { } inline const Time& TimeItem::GetValue () const { return TimeVal; } /*****************************************************************************/ /* class DateItem */ /*****************************************************************************/ class DateItem: public EditMenueItem { protected: Time TimeVal; DateItem (StreamableInit); // Build constructor public: DateItem (const String & aItemText, i16 aID, i16 EditID, WindowItem *NextItem); DateItem (const String & aItemText, i16 aID, WindowItem *NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable * Build (); // Derived from class MenueItem virtual void SetWidth (u16 NewWidth); virtual u16 MinWidth (); // Derived from class EditMenueItem virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. // Handling the protected variables const Time& GetValue () const; void SetValue (const Time& Val); void SetValue (unsigned Year, unsigned Month, unsigned Day); }; inline DateItem::DateItem (StreamableInit) : EditMenueItem (Empty), TimeVal (Empty) { } inline const Time& DateItem::GetValue () const { return TimeVal; } /*****************************************************************************/ /* class RStringItem */ /*****************************************************************************/ // Class RStringItem has the same functionality as class StringItem with one // exception: The set of allowed input characters is written out on a Store // and reloaded when calling Load. This has been a compatibility decision: // The complete functionality to restrict input has been added to class // StringItem (without changing the default behavior), but writing out the // additional class would have made existing resources unusable - so there // is a new class for that. class RStringItem: public StringItem { friend class ResEditApp; // Resource editor is a friend protected: u16 InputLength; // Length of the input string RStringItem (StreamableInit); // Build constructor public: RStringItem (const String& aItemText, i16 aID, i16 EditID, u16 aInputLength, WindowItem* NextItem); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); virtual i16 Choose (); // Choose the entry. If an edit window is defined (EditWindow != NULL), // the entry with id EditItemID in EditWindow is called. If there was // no abort (or EditWindow is not defined), the id of this item is // returned. }; // End of MENUITEM.H #endif estic-1.61.orig/spunk/messages.it0100644000176100001440000003635707031424702016332 0ustar debacleusers ; Textstrings in der Codepage 437, zuerst spunk Strings, dann ESTIC Strings. ; ; Folgende Zeichencodes werden verwendet: ; ; \n newline, Zeilenumbruch in einem Menue ; \c center, Zeile zentrieren (Textfenster) ; \xXX Hex-Code des Zeichens (einfach mal in einer Zeichensatz- ; Tabelle fr CP437 nachsehen). Verwendet werden: ; ; \x12 Pfeil hoch/Pfeil runter ; \x1D Pfeil links/Pfeil rechts ; \x11 Dreieck, nach links weisend ; \x18 Pfeil hoch ; \x19 Pfeil runter ; \x1A Pfeil rechts ; \x1B Pfeil links. ACHTUNG: unter Linux nicht ; darstellbar (weil == ESC) ; ; '@' markiert den Hotkey in den Menues, z.T. haben die Strings C Format- ; Specifier drin (%ld u.„.). ; ; Ich habe dazugeschrieben, wie die Meldungen verwendet werden. ; ------------------------------------------------------------------------- ; SPUNK ; Texte in der Statuszeile 0 "Guida " 1 "Accetta " 2 "Annulla " 3 "Termina " 4 "Continua " 5 "Modifica " 6 "Stampa " 7 "Grafica " 8 "Inserisci " 9 "Cancella " 10 "Seleziona " 11 "Conferma " 12 "Muovi " 13 "Login " 14 "Logout " 15 "Termina " 16 "Zoom " 17 "Chiudi " 18 "Apri " 19 "Dimensione " 20 "Salva " 21 " ~\x12~ Seleziona " 22 " ~\x12\x11ÄŁ~ Seleziona " 23 " ~\x12 Pag-\x12~ sfoglia " 24 " ~\x12\x1D~ Muovi " 25 " ~Ctrl+\x12\x1D~ Dimensione " ; Vordefinierte Menues und Meldungen 100 "E' proprio sicuro?" 101 "Proprio terminare?" 102 "Annullare modifiche?" 103 "Salvare modifiche?" 104 "@S¨\n@No" 105 "@No\n@S¨" 200 " Errore " 201 " Informazione " 202 " Errore di sistema " 210 "Conferma " 211 "Annulla " 212 "Ignora " 213 "Ripeti " 214 "Fine " 215 "Un momento..." ; Fehlermeldungen 300 "Valore non valido" 301 "Troppi zero dopo la virgola" 302 "Valore troppo piccolo (al minimo %g)" 303 "Valore troppo grande (al massimo %g)" 304 "Valore troppo piccolo (al minimo %ld)" 305 "Valore troppo grande (al massimo %ld)" 306 "Ci vuole qualcosa!" 307 "Estensione file non ammessa" ; Werte fr Toggle-Items. Alle Teilstrings mssen denselben Platz ; belegen, "Aus An" == "Aus" + " An" 400 "Off On" 401 "No S¨" ; Fehlermeldungen fr Eingabe 500 "Valore troppo grande" 501 "Valore troppo piccolo" 502 "Valore sbagliato" ; INI Files 600 "%s: sezione %s, %s non trovata o sbagliata." ; Passwort-Verwaltung 700 "Errore di apertura del file delle password\n(%s)" 701 "Errore di lettura del file delle password\n(%s)" 702 "Errore di scrittura del file delle password\n(%s)" 703 "Ci vuole un ID utente!" 704 "Ci vuole un nome utente!" 705 "Ci vuole una password!" 706 "Un utente con questo ID esiste gi…!" 707 "ID utente o password non validi!" ; Wochentage und Monate 800 "Domenica" 801 "Luned¨" 802 "Marted¨" 803 "Mercoled¨" 804 "Gioved¨" 805 "Venerd¨" 806 "Sabato" 807 "Do" 808 "Lu" 809 "Ma" 810 "Me" 811 "Gi" 812 "Ve" 813 "Sa" 814 "Gennaio" 815 "Febbraio" 816 "Marzo" 817 "Aprile" 818 "Maggio" 819 "Giugno" 820 "Luglio" 821 "Agosto" 822 "Settembre" 823 "Ottobre" 824 "Novembre" 825 "Dicembre" 826 "Gen" 827 "Feb" 828 "Mar" 829 "Apr" 830 "Mag" 831 "Giu" 832 "Lug" 833 "Ago" 834 "Set" 835 "Ott" 836 "Nov" 837 "Dic" ; Fehlermeldungen 900 "Guida non disponibile" 901 "Guida non disponibile per questa parola chiave" ; Namen fr Tasten. Es sind 1024 Nummern reserviert, wobei gilt: ; ; 256 normale Tasten auf der Console ; 256 erweiterte Tasten auf der Console ; 256 normale Tasten auf dem Terminal ; 256 erweiterte Tasten auf dem Terminal ; ; Die letzten 512 werden unter DOS & OS/2 praktisch nicht verwendet, unter ; Linux unterscheiden sie sich u.a. darin, dass statt "Alt+X" "ESC-X" ; angezeigt wird. 1024 "" 1025 "Ctrl+A" 1026 "Ctrl+B" 1027 "Ctrl+C" 1028 "Ctrl+D" 1029 "Ctrl+E" 1030 "Ctrl+F" 1031 "Ctrl+G" 1032 "Ctrl+H" 1033 "Tab" 1034 "Ctrl+J" 1035 "Ctrl+K" 1036 "Ctrl+L" 1037 "\x11ÄŁ" 1038 "Ctrl+N" 1039 "Ctrl+O" 1040 "Ctrl+P" 1041 "Ctrl+Q" 1042 "Ctrl+R" 1043 "Ctrl+S" 1044 "Ctrl+T" 1045 "Ctrl+U" 1046 "Ctrl+V" 1047 "Ctrl+W" 1048 "Ctrl+X" 1049 "Ctrl+Y" 1050 "Ctrl+Z" 1051 "Esc" 1151 "Canc" 1281 "Alt+Esc" 1282 "Alt+Spazio" 1284 "Ctrl+Ins" 1285 "Shift+Ins" 1286 "Ctrl+Canc" 1287 "Shift+Canc" 1295 "Shift+Tab" 1296 "Alt+Q" 1297 "Alt+W" 1298 "Alt+E" 1299 "Alt+R" 1300 "Alt+T" 1301 "Alt+Y" 1302 "Alt+U" 1303 "Alt+I" 1304 "Alt+O" 1305 "Alt+P" 1310 "Alt+A" 1311 "Alt+S" 1312 "Alt+D" 1313 "Alt+F" 1314 "Alt+G" 1315 "Alt+H" 1316 "Alt+J" 1317 "Alt+K" 1318 "Alt+L" 1324 "Alt+Z" 1325 "Alt+X" 1326 "Alt+C" 1327 "Alt+V" 1328 "Alt+B" 1329 "Alt+N" 1330 "Alt+M" 1339 "F1" 1340 "F2" 1341 "F3" 1342 "F4" 1343 "F5" 1344 "F6" 1345 "F7" 1346 "F8" 1347 "F9" 1348 "F10" 1351 "Pos1" 1352 "\x18" 1353 "Pag-\x18" 1355 "\x1B" 1357 "\x1A" 1359 "Fine" 1360 "\x19" 1361 "Pag-\x19" 1362 "Ins" 1363 "Canc" 1364 "Shift+F1" 1365 "Shift+F2" 1366 "Shift+F3" 1367 "Shift+F4" 1368 "Shift+F5" 1369 "Shift+F6" 1370 "Shift+F7" 1371 "Shift+F8" 1372 "Shift+F9" 1373 "Shift+F10" 1374 "Ctrl+F1" 1375 "Ctrl+F2" 1376 "Ctrl+F3" 1377 "Ctrl+F4" 1378 "Ctrl+F5" 1379 "Ctrl+F6" 1380 "Ctrl+F7" 1381 "Ctrl+F8" 1382 "Ctrl+F9" 1383 "Ctrl+F10" 1384 "Alt+F1" 1385 "Alt+F2" 1386 "Alt+F3" 1387 "Alt+F4" 1388 "Alt+F5" 1389 "Alt+F6" 1390 "Alt+F7" 1391 "Alt+F8" 1392 "Alt+F9" 1393 "Alt+F10" 1395 "Ctrl+\x1B" 1396 "Ctrl+\x1A" 1397 "Ctrl+Fine" 1398 "Ctrl+Pag-\x19" 1399 "Ctrl+Pos1" 1400 "Alt+1" 1401 "Alt+2" 1402 "Alt+3" 1403 "Alt+4" 1404 "Alt+5" 1405 "Alt+6" 1406 "Alt+7" 1407 "Alt+8" 1408 "Alt+9" 1409 "Alt+0" 1412 "Ctrl+Pag-\x18" 1413 "F11" 1414 "F12" 1415 "Shift+F11" 1416 "Shift+F12" 1417 "Ctrl+F11" 1418 "Ctrl+F12" 1419 "Alt+F11" 1420 "Alt+F12" 1421 "Ctrl+\x18" 1425 "Ctrl+\x19" 1428 "Ctrl+Tab" 1431 "Alt+Pos1" 1433 "Alt+Pag-\x18" 1439 "Alt+Fine" 1441 "Alt+Pag-\x19" 1442 "Alt+Ins" 1443 "Alt+Canc" 1445 "Alt+Tab" 1456 "Alt+Ctrl+A" 1457 "Alt+Ctrl+B" 1458 "Alt+Ctrl+C" 1459 "Alt+Ctrl+D" 1460 "Alt+Ctrl+E" 1461 "Alt+Ctrl+F" 1462 "Alt+Ctrl+G" 1463 "Alt+Ctrl+H" 1464 "Alt+Ctrl+I" 1465 "Alt+Ctrl+J" 1466 "Alt+Ctrl+K" 1467 "Alt+Ctrl+L" 1468 "Alt+Ctrl+M" 1469 "Alt+Ctrl+N" 1470 "Alt+Ctrl+O" 1471 "Alt+Ctrl+P" 1472 "Alt+Ctrl+Q" 1473 "Alt+Ctrl+R" 1474 "Alt+Ctrl+S" 1475 "Alt+Ctrl+T" 1476 "Alt+Ctrl+U" 1477 "Alt+Ctrl+V" 1478 "Alt+Ctrl+W" 1479 "Alt+Ctrl+X" 1480 "Alt+Ctrl+Y" 1481 "Alt+Ctrl+Z" 1482 "Esc-Esc" 1483 "Ctrl+Q-S" 1484 "Ctrl+Q-D" 1485 "Ctrl+Q-R" 1486 "Ctrl+Q-C" 1487 "Ctrl+Q-E" 1488 "Ctrl+Q-X" ; Ab hier fangen die Tasten fr's Terminal an 1536 "" 1537 "Ctrl+A" 1538 "Ctrl+B" 1539 "Ctrl+C" 1540 "Ctrl+D" 1541 "Ctrl+E" 1542 "Ctrl+F" 1543 "Ctrl+G" 1544 "Ctrl+H" 1545 "Tab" 1546 "Ctrl+J" 1547 "Ctrl+K" 1548 "Ctrl+L" 1549 "Enter" 1550 "Ctrl+N" 1551 "Ctrl+O" 1552 "Ctrl+P" 1553 "Ctrl+Q" 1554 "Ctrl+R" 1555 "Ctrl+S" 1556 "Ctrl+T" 1557 "Ctrl+U" 1558 "Ctrl+V" 1559 "Ctrl+W" 1560 "Ctrl+X" 1561 "Ctrl+Y" 1562 "Ctrl+Z" 1563 "Esc" 1663 "Canc" 1793 "Alt+Esc" 1794 "Alt+Spazio" 1796 "Ctrl+Ins" 1797 "Shift+Ins" 1798 "Ctrl+Canc" 1799 "Shift+Canc" 1807 "Shift+Tab" 1808 "Esc-Q" 1809 "Esc-W" 1810 "Esc-E" 1811 "Esc-R" 1812 "Esc-T" 1813 "Esc-Y" 1814 "Esc-U" 1815 "Esc-I" 1816 "Esc-O" 1817 "Esc-P" 1822 "Esc-A" 1823 "Esc-S" 1824 "Esc-D" 1825 "Esc-F" 1826 "Esc-G" 1827 "Esc-H" 1828 "Esc-J" 1829 "Esc-K" 1830 "Esc-L" 1836 "Esc-Z" 1837 "Esc-X" 1838 "Esc-C" 1839 "Esc-V" 1840 "Esc-B" 1841 "Esc-N" 1842 "Esc-M" 1851 "F1" 1852 "F2" 1853 "F3" 1854 "F4" 1855 "F5" 1856 "F6" 1857 "F7" 1858 "F8" 1859 "F9" 1860 "F10" 1863 "Pos1" 1864 "\x18" 1865 "Pag-\x18" 1867 "\x1B" 1869 "\x1A" 1871 "Fine" 1872 "\x19" 1873 "Pag-\x19" 1874 "Ins" 1875 "Canc" 1876 "Shift+F1" 1877 "Shift+F2" 1878 "Shift+F3" 1879 "Shift+F4" 1880 "Shift+F5" 1881 "Shift+F6" 1882 "Shift+F7" 1883 "Shift+F8" 1884 "Shift+F9" 1885 "Shift+F10" 1886 "Ctrl+F1" 1887 "Ctrl+F2" 1888 "Ctrl+F3" 1889 "Ctrl+F4" 1890 "Ctrl+F5" 1891 "Ctrl+F6" 1892 "Ctrl+F7" 1893 "Ctrl+F8" 1894 "Ctrl+F9" 1895 "Ctrl+F10" 1896 "Esc-F1" 1897 "Esc-F2" 1898 "Esc-F3" 1899 "Esc-F4" 1900 "Esc-F5" 1901 "Esc-F6" 1902 "Esc-F7" 1903 "Esc-F8" 1904 "Esc-F9" 1905 "Esc-F10" 1907 "Ctrl+\x1B" 1908 "Ctrl+\x1A" 1909 "Ctrl+Fine" 1910 "Ctrl+PgDn" 1911 "Ctrl+Pos1" 1912 "Esc-1" 1913 "Esc-2" 1914 "Esc-3" 1915 "Esc-4" 1916 "Esc-5" 1917 "Esc-6" 1918 "Esc-7" 1919 "Esc-8" 1920 "Esc-9" 1921 "Esc-0" 1924 "Ctrl+PgUp" 1925 "F11" 1926 "F12" 1927 "Shift+F11" 1928 "Shift+F12" 1929 "Ctrl+F11" 1930 "Ctrl+F12" 1931 "Esc-F11" 1932 "Esc-F12" 1933 "Ctrl+\x18" 1937 "Ctrl+\x19" 1940 "Ctrl+Tab" 1943 "Esc-Pos1" 1945 "Esc-PgUp" 1951 "Esc-Fine" 1953 "Esc-PgDn" 1954 "Esc-Ins" 1955 "Esc-Canc" 1957 "Esc-Tab" 1968 "Esc-Ctrl+A" 1969 "Esc-Ctrl+B" 1970 "Esc-Ctrl+C" 1971 "Esc-Ctrl+D" 1972 "Esc-Ctrl+E" 1973 "Esc-Ctrl+F" 1974 "Esc-Ctrl+G" 1975 "Esc-Ctrl+H" 1976 "Esc-Ctrl+I" 1977 "Esc-Ctrl+J" 1978 "Esc-Ctrl+K" 1979 "Esc-Ctrl+L" 1980 "Esc-Ctrl+M" 1981 "Esc-Ctrl+N" 1982 "Esc-Ctrl+O" 1983 "Esc-Ctrl+P" 1984 "Esc-Ctrl+Q" 1985 "Esc-Ctrl+R" 1986 "Esc-Ctrl+S" 1987 "Esc-Ctrl+T" 1988 "Esc-Ctrl+U" 1989 "Esc-Ctrl+V" 1990 "Esc-Ctrl+W" 1991 "Esc-Ctrl+X" 1992 "Esc-Ctrl+Y" 1993 "Esc-Ctrl+Z" 1994 "Esc-Esc" 1995 "Ctrl+Q-S" 1996 "Ctrl+Q-D" 1997 "Ctrl+Q-R" 1998 "Ctrl+Q-C" 1999 "Ctrl+Q-E" 2000 "Ctrl+Q-X" ; Strings fr den Fileselektor. Die L„ngen sollten erhalten bleiben wenn ; m”glich. 2100 " Byte " 2101 " Directory " ; Fehlermeldungen fr Systemfehler. 2300 "Errore %d: %s" 2301 "Nessun errore (OOPS!)" 2302 "File o path non trovati" 2303 "Memoria insufficiente" 2304 "Accesso negato" 2305 "Troppi files aperti" 2306 "Memoria insufficiente sul device indirizzato" 2307 "Errore temporaneo - riprovare" 2308 "Device/file in uso" 2309 "File troppo grande" 2310 "Errore di I/O" 2311 "Il file una directory" 2312 "Il file non una directory" 2313 "Troppi links" 2314 "L'operazione possibile solo con block devices" 2315 "L'operazione possibile solo con char devices" 2316 "Device non esistente" 2317 "L'operazione possibile solo per il proprietario del file" 2318 "Broken Pipe" 2319 "Il file di sistema e' a sola lettura" 2320 "Seek non pu• essere eseguito su pipes" 2321 "Processo non esistente" 2322 "File eseguibile impegnato" 2323 "Nome troppo lungo" 2324 "Nessun lock disponibile" 2325 "La directory non vuota" 2326 "File non trovato" 2327 "Path non trovato" 2328 "Drive non valido" 2329 "La directory attuale non pu• essere cancellata" 2330 "Il file esiste gi…" 2331 "Errore sconosciuto (%d)" ; Fenstermanager 2500 "Sono aperte troppe finestre!" ; ------------------------------------------------------------------------- ; ESTIC ; Eintr„ge fr das Hauptmenue. '@' markiert den Hotkey. 0 "@ESTIC" 1 "@Di ESTIC..." 10 "@File" 11 "@Carica file" 12 "@Salva file" 13 "Visualizza l@ogfile ansehen" 14 "@Carica ISTEC" 15 "@Salva ISTEC" 16 "@Rendi le modifiche permanenti" 17 "@Leggi il file degli alias" 18 "@Esci" 20 "@Configurazione" 21 "@Versione" 22 "@Parametri centralino" 23 "@Parametri apparecchi" 24 "@Reset" 30 "@Costi" 31 "C@arica costi" 32 "@Visualizza costi" 33 "Configurazione @stampante" 34 "Stampa @costi" 35 "@Reset costi" 40 "@Finestra" 41 "@Apri" 42 "@Matrice collegamenti" 43 "@Costi" 44 "Chiamate @eseguite" 45 "@Isdn4Linux Monitor" 46 "@Affiancate" 47 "In casca@ta" 48 "Chiudi @tutte" 49 "Sche@rmo nuovo" 50 "@Posizione/dimensione" 51 "@Zoom" 52 "Chi@udi" 53 "Lista @finestre" ; About 60 "\n\cESTIC Version 1.30\n\c(Enhanced Supervisor Tool for ISTEC Configuration)\n\n\c(C) 1995 Ullrich von Bassewitz\n\c\n\n" ; ISTEC Info-Fenster 61 "Accesso base" 62 "Accesso primario" 63 "Accesso sconosciuto" 64 "\nTyp: %s\n\nVersione software: %d.%d\n\n%-2d Interfacce S0 esterne\n%-2d Interfacce S0 interne\n%-2d Interfaccie ab\n\nProtocollo: %s\nAccesso: %s\n\n" ; Titel des Fileselektors 65 " Carica configurazione " 66 " Salva configurazione " 67 "COM port non aperta " 68 "Timeout durante la comunicazione con la ISTEC" 69 "Salvare modifiche nella ISTEC?" 70 "Rendere modifiche permanenti?" ; Gebhrenausdruck 71 "Stampa costi %s %33s" 72 "----------------------------------------------------------------" 73 " Appar Scatti Costi " 74 " #%2d %4d " 75 "Errore d'inizializzazione della porta seriale" 76 "Receive buffer overflow!" 77 "Non abbastanza caratteri nel messaggio ricevuto!" 78 "Risposta non valida della ISTEC!" 79 "Numero device sbagliato nella risposta della ISTEC.\n\cComando annullato!" ; Titel File-Selektor 80 " Stampa in file " 81 " Visulizza logfile " 82 "Errore di apertura del file di configurazione" 200 "OOPS - Errore interno!\n\c(ignorato)" 300 "ISTEC XXXX" 301 "ISTEC 1003" 302 "ISTEC 1008" 303 "ISTEC 1016" 304 "ISTEC 1024" 305 "ISTEC 2016" 306 "ISTEC 2024" 307 "ISTEC 2400" 308 "ISTEC 2416" 309 "ISTEC 2424" ; Endger„tekonfiguration. L„ngen beachten! 400 "Accesso pieno " 401 "Nazionale " 402 "Urbano " 403 "Solo Ricezione " 404 "Solo Interni " 405 "Telefonia " 406 "Fax gruppo 3 " 407 "Data/modem " 408 "Datex-J/modem " 409 "Segreteria tel. " 410 "Servizi combinati " 411 " On " 412 " Off " 413 "------ " 414 "Esterno " 415 "Interno:%2d" 416 "Device #%d " 500 "\nPer ampliare i centralini \nda 16 utenti a/b a \na 24 utenti a/b bisogna \nleggere il manuale.\n\n" ; Fenster "Verbindungsmatrix" 600 " Matrice collegamenti" 601 " Nr. Lin1 Lin2 Int1 Int2 Int3 Suo WSuo Acc Chia Numero " ; Aliase 700 "Alias doppio per numero %s" 701 "Errore di apertura del file degli alias !" 702 "Errore di sintassi nel file degli alias, riga %d" ; isdn4linux Monitor, Positionen in der Titelzeile erhalten 800 " isdn4linux Monitor " 801 " Dr Ch On/Off Servizio Numero " 802 "-----------------------------------------------" ; Steht unter Ein/Aus 803 "On" 804 "Off" ; Servizi 805 "---" 806 "Raw" 807 "Modem" 808 "Rete" 809 "Voice" 810 "Fax" 811 "Sconosciuto" 812 "Errore di apertura %s" 813 "Errore di lettura %s -\nisdn4linux monitor viene terminato!" ; 900 "Errore di apertura del file di log per il debug" ; Fenster "Ausgehende Gespr„che", L„ngen bzw. Positionen erhalten 1100 " Chiamate eseguite " 1101 "Nr. Alias Data Inizio Durata Numero Scat. Lit " 1102 "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ" 1200 " Costi " 1201 " Nr. scatti" estic-1.61.orig/spunk/messages.txt0100644000176100001440000003661507031424702016532 0ustar debacleusers ; Textstrings in der Codepage 437, zuerst spunk Strings, dann ESTIC Strings. ; ; Folgende Zeichencodes werden verwendet: ; ; \n newline, Zeilenumbruch in einem Menue ; \c center, Zeile zentrieren (Textfenster) ; \xXX Hex-Code des Zeichens (einfach mal in einer Zeichensatz- ; Tabelle fr CP437 nachsehen). Verwendet werden: ; ; \x12 Pfeil hoch/Pfeil runter ; \x1D Pfeil links/Pfeil rechts ; \x11 Dreieck, nach links weisend ; \x18 Pfeil hoch ; \x19 Pfeil runter ; \x1A Pfeil rechts ; \x1B Pfeil links. ACHTUNG: unter Linux nicht ; darstellbar (weil == ESC) ; ; '@' markiert den Hotkey in den Menues, z.T. haben die Strings C Format- ; Specifier drin (%ld u.„.). ; ; Ich habe dazugeschrieben, wie die Meldungen verwendet werden. ; ------------------------------------------------------------------------- ; SPUNK ; Texte in der Statuszeile 0 "Hilfe " 1 "bernehmen " 2 "Abbruch " 3 "Ende " 4 "Weiter " 5 "ˇndern " 6 "Drucken " 7 "Grafik " 8 "Einfgen " 9 "L”schen " 10 "Auswahl " 11 "Best„tigen " 12 "Bewegen " 13 "Login " 14 "Logout " 15 "Ende " 16 "Zoom " 17 "Schliessen " 18 "™ffnen " 19 "Gr”įe " 20 "Speichern " 21 " ~\x12~ Auswahl " 22 " ~\x12\x11ÄŁ~ Auswahl " 23 " ~\x12 Bild-\x12~ Bl„ttern " 24 " ~\x12\x1D~ Bewegen " 25 " ~Ctrl+\x12\x1D~ Gr”įe " ; Vordefinierte Menues und Meldungen 100 "Sind Sie sicher?" 101 "Wirklich Ende?" 102 "ˇnderungen verwerfen?" 103 "ˇnderungen sichern?" 104 "@Ja\n@Nein" 105 "@Nein\n@Ja" 200 " Fehler " 201 " Information " 202 " Systemfehler " 210 "Best„tigen " 211 "Abbruch " 212 "Ignorieren " 213 "Wiederholen " 214 "Ende " 215 "Einen Moment bitte..." ; Fehlermeldungen 300 "Ungltige Eingabe" 301 "Zu viele Nachkommastellen" 302 "Wert ist zu klein (Minimum ist %g)" 303 "Wert ist zu groį (Maximum ist %g)" 304 "Wert ist zu klein (Minimum ist %ld)" 305 "Wert ist zu groį (Maximum ist %ld)" 306 "Leereingabe ist unzul„ssig" 307 "Keine Datei-Erweiterung erlaubt" ; Werte fr Toggle-Items. Alle Teilstrings mssen denselben Platz ; belegen, "Aus An" == "Aus" + " An" 400 "Aus An" 401 "Nein Ja" ; Fehlermeldungen fr Eingabe 500 "Wert ist zu groį" 501 "Wert ist zu klein" 502 "Fehlerhafte Eingabe" ; INI Files 600 "%s: Sektion %s, %s nicht gefunden oder fehlerhaft." ; Passwort-Verwaltung 700 "Fehler beim ™ffnen der Passwort-Datei\n(%s)" 701 "Fehler beim Lesen der Passwort-Datei\n(%s)" 702 "Fehler beim Schreiben auf die Passwort-Datei\n(%s)" 703 "Es muį eine Benutzer-ID angegeben werden!" 704 "Es muį ein Benutzername angegeben werden!" 705 "Es muį ein Passwort angegeben werden!" 706 "Ein Benutzer mit dieser ID existiert bereits!" 707 "Ungltige Benutzer-ID oder ungltiges Passwort!" ; Wochentage und Monate 800 "Sonntag" 801 "Montag" 802 "Dienstag" 803 "Mittwoch" 804 "Donnerstag" 805 "Freitag" 806 "Samstag" 807 "So" 808 "Mo" 809 "Di" 810 "Mi" 811 "Do" 812 "Fr" 813 "Sa" 814 "Januar" 815 "Februar" 816 "M„rz" 817 "April" 818 "Mai" 819 "Juni" 820 "Juli" 821 "August" 822 "September" 823 "Oktober" 824 "November" 825 "Dezember" 826 "Jan" 827 "Feb" 828 "M„r" 829 "Apr" 830 "Mai" 831 "Jun" 832 "Jul" 833 "Aug" 834 "Sep" 835 "Okt" 836 "Nov" 837 "Dez" ; Fehlermeldungen 900 "Keine Hilfe verfgbar" 901 "Keine Hilfe fr dieses Stichwort" ; Namen fr Tasten. Es sind 1024 Nummern reserviert, wobei gilt: ; ; 256 normale Tasten auf der Console ; 256 erweiterte Tasten auf der Console ; 256 normale Tasten auf dem Terminal ; 256 erweiterte Tasten auf dem Terminal ; ; Die letzten 512 werden unter DOS & OS/2 praktisch nicht verwendet, unter ; Linux unterscheiden sie sich u.a. darin, dass statt "Alt+X" "ESC-X" ; angezeigt wird. 1024 "" 1025 "Ctrl+A" 1026 "Ctrl+B" 1027 "Ctrl+C" 1028 "Ctrl+D" 1029 "Ctrl+E" 1030 "Ctrl+F" 1031 "Ctrl+G" 1032 "Ctrl+H" 1033 "Tab" 1034 "Ctrl+J" 1035 "Ctrl+K" 1036 "Ctrl+L" 1037 "\x11ÄŁ" 1038 "Ctrl+N" 1039 "Ctrl+O" 1040 "Ctrl+P" 1041 "Ctrl+Q" 1042 "Ctrl+R" 1043 "Ctrl+S" 1044 "Ctrl+T" 1045 "Ctrl+U" 1046 "Ctrl+V" 1047 "Ctrl+W" 1048 "Ctrl+X" 1049 "Ctrl+Y" 1050 "Ctrl+Z" 1051 "Esc" 1151 "Del" 1281 "Alt+Esc" 1282 "Alt+Leertaste" 1284 "Ctrl+Einfg" 1285 "Shift+Einfg" 1286 "Ctrl+Entf" 1287 "Shift+Entf" 1295 "Shift+Tab" 1296 "Alt+Q" 1297 "Alt+W" 1298 "Alt+E" 1299 "Alt+R" 1300 "Alt+T" 1301 "Alt+Y" 1302 "Alt+U" 1303 "Alt+I" 1304 "Alt+O" 1305 "Alt+P" 1310 "Alt+A" 1311 "Alt+S" 1312 "Alt+D" 1313 "Alt+F" 1314 "Alt+G" 1315 "Alt+H" 1316 "Alt+J" 1317 "Alt+K" 1318 "Alt+L" 1324 "Alt+Z" 1325 "Alt+X" 1326 "Alt+C" 1327 "Alt+V" 1328 "Alt+B" 1329 "Alt+N" 1330 "Alt+M" 1339 "F1" 1340 "F2" 1341 "F3" 1342 "F4" 1343 "F5" 1344 "F6" 1345 "F7" 1346 "F8" 1347 "F9" 1348 "F10" 1351 "Pos1" 1352 "\x18" 1353 "Bild-\x18" 1355 "\x1B" 1357 "\x1A" 1359 "Ende" 1360 "\x19" 1361 "Bild-\x19" 1362 "Einfg" 1363 "Entf" 1364 "Shift+F1" 1365 "Shift+F2" 1366 "Shift+F3" 1367 "Shift+F4" 1368 "Shift+F5" 1369 "Shift+F6" 1370 "Shift+F7" 1371 "Shift+F8" 1372 "Shift+F9" 1373 "Shift+F10" 1374 "Ctrl+F1" 1375 "Ctrl+F2" 1376 "Ctrl+F3" 1377 "Ctrl+F4" 1378 "Ctrl+F5" 1379 "Ctrl+F6" 1380 "Ctrl+F7" 1381 "Ctrl+F8" 1382 "Ctrl+F9" 1383 "Ctrl+F10" 1384 "Alt+F1" 1385 "Alt+F2" 1386 "Alt+F3" 1387 "Alt+F4" 1388 "Alt+F5" 1389 "Alt+F6" 1390 "Alt+F7" 1391 "Alt+F8" 1392 "Alt+F9" 1393 "Alt+F10" 1395 "Ctrl+\x1B" 1396 "Ctrl+\x1A" 1397 "Ctrl+Ende" 1398 "Ctrl+Bild-\x19" 1399 "Ctrl+Pos1" 1400 "Alt+1" 1401 "Alt+2" 1402 "Alt+3" 1403 "Alt+4" 1404 "Alt+5" 1405 "Alt+6" 1406 "Alt+7" 1407 "Alt+8" 1408 "Alt+9" 1409 "Alt+0" 1412 "Ctrl+Bild-\x18" 1413 "F11" 1414 "F12" 1415 "Shift+F11" 1416 "Shift+F12" 1417 "Ctrl+F11" 1418 "Ctrl+F12" 1419 "Alt+F11" 1420 "Alt+F12" 1421 "Ctrl+\x18" 1425 "Ctrl+\x19" 1428 "Ctrl+Tab" 1431 "Alt+Pos1" 1433 "Alt+Bild-\x18" 1439 "Alt+Ende" 1441 "Alt+Bild-\x19" 1442 "Alt+Einfg" 1443 "Alt+Entf" 1445 "Alt+Tab" 1456 "Alt+Ctrl+A" 1457 "Alt+Ctrl+B" 1458 "Alt+Ctrl+C" 1459 "Alt+Ctrl+D" 1460 "Alt+Ctrl+E" 1461 "Alt+Ctrl+F" 1462 "Alt+Ctrl+G" 1463 "Alt+Ctrl+H" 1464 "Alt+Ctrl+I" 1465 "Alt+Ctrl+J" 1466 "Alt+Ctrl+K" 1467 "Alt+Ctrl+L" 1468 "Alt+Ctrl+M" 1469 "Alt+Ctrl+N" 1470 "Alt+Ctrl+O" 1471 "Alt+Ctrl+P" 1472 "Alt+Ctrl+Q" 1473 "Alt+Ctrl+R" 1474 "Alt+Ctrl+S" 1475 "Alt+Ctrl+T" 1476 "Alt+Ctrl+U" 1477 "Alt+Ctrl+V" 1478 "Alt+Ctrl+W" 1479 "Alt+Ctrl+X" 1480 "Alt+Ctrl+Y" 1481 "Alt+Ctrl+Z" 1482 "Esc-Esc" 1483 "Ctrl+Q-S" 1484 "Ctrl+Q-D" 1485 "Ctrl+Q-R" 1486 "Ctrl+Q-C" 1487 "Ctrl+Q-E" 1488 "Ctrl+Q-X" ; Ab hier fangen die Tasten fr's Terminal an 1536 "" 1537 "Ctrl+A" 1538 "Ctrl+B" 1539 "Ctrl+C" 1540 "Ctrl+D" 1541 "Ctrl+E" 1542 "Ctrl+F" 1543 "Ctrl+G" 1544 "Ctrl+H" 1545 "Tab" 1546 "Ctrl+J" 1547 "Ctrl+K" 1548 "Ctrl+L" 1549 "Enter" 1550 "Ctrl+N" 1551 "Ctrl+O" 1552 "Ctrl+P" 1553 "Ctrl+Q" 1554 "Ctrl+R" 1555 "Ctrl+S" 1556 "Ctrl+T" 1557 "Ctrl+U" 1558 "Ctrl+V" 1559 "Ctrl+W" 1560 "Ctrl+X" 1561 "Ctrl+Y" 1562 "Ctrl+Z" 1563 "Esc" 1663 "Del" 1793 "Alt+Esc" 1794 "Alt+Leertaste" 1796 "Ctrl+Einfg" 1797 "Shift+Einfg" 1798 "Ctrl+Entf" 1799 "Shift+Entf" 1807 "Shift+Tab" 1808 "Esc-Q" 1809 "Esc-W" 1810 "Esc-E" 1811 "Esc-R" 1812 "Esc-T" 1813 "Esc-Y" 1814 "Esc-U" 1815 "Esc-I" 1816 "Esc-O" 1817 "Esc-P" 1822 "Esc-A" 1823 "Esc-S" 1824 "Esc-D" 1825 "Esc-F" 1826 "Esc-G" 1827 "Esc-H" 1828 "Esc-J" 1829 "Esc-K" 1830 "Esc-L" 1836 "Esc-Z" 1837 "Esc-X" 1838 "Esc-C" 1839 "Esc-V" 1840 "Esc-B" 1841 "Esc-N" 1842 "Esc-M" 1851 "F1" 1852 "F2" 1853 "F3" 1854 "F4" 1855 "F5" 1856 "F6" 1857 "F7" 1858 "F8" 1859 "F9" 1860 "F10" 1863 "Pos1" 1864 "\x18" 1865 "Bild-\x18" 1867 "\x1B" 1869 "\x1A" 1871 "Ende" 1872 "\x19" 1873 "Bild-\x19" 1874 "Einfg" 1875 "Entf" 1876 "Shift+F1" 1877 "Shift+F2" 1878 "Shift+F3" 1879 "Shift+F4" 1880 "Shift+F5" 1881 "Shift+F6" 1882 "Shift+F7" 1883 "Shift+F8" 1884 "Shift+F9" 1885 "Shift+F10" 1886 "Ctrl+F1" 1887 "Ctrl+F2" 1888 "Ctrl+F3" 1889 "Ctrl+F4" 1890 "Ctrl+F5" 1891 "Ctrl+F6" 1892 "Ctrl+F7" 1893 "Ctrl+F8" 1894 "Ctrl+F9" 1895 "Ctrl+F10" 1896 "Esc-F1" 1897 "Esc-F2" 1898 "Esc-F3" 1899 "Esc-F4" 1900 "Esc-F5" 1901 "Esc-F6" 1902 "Esc-F7" 1903 "Esc-F8" 1904 "Esc-F9" 1905 "Esc-F10" 1907 "Ctrl+\x1B" 1908 "Ctrl+\x1A" 1909 "Ctrl+Ende" 1910 "Ctrl+PgDn" 1911 "Ctrl+Pos1" 1912 "Esc-1" 1913 "Esc-2" 1914 "Esc-3" 1915 "Esc-4" 1916 "Esc-5" 1917 "Esc-6" 1918 "Esc-7" 1919 "Esc-8" 1920 "Esc-9" 1921 "Esc-0" 1924 "Ctrl+PgUp" 1925 "F11" 1926 "F12" 1927 "Shift+F11" 1928 "Shift+F12" 1929 "Ctrl+F11" 1930 "Ctrl+F12" 1931 "Esc-F11" 1932 "Esc-F12" 1933 "Ctrl+\x18" 1937 "Ctrl+\x19" 1940 "Ctrl+Tab" 1943 "Esc-Pos1" 1945 "Esc-PgUp" 1951 "Esc-Ende" 1953 "Esc-PgDn" 1954 "Esc-Einfg" 1955 "Esc-Entf" 1957 "Esc-Tab" 1968 "Esc-Ctrl+A" 1969 "Esc-Ctrl+B" 1970 "Esc-Ctrl+C" 1971 "Esc-Ctrl+D" 1972 "Esc-Ctrl+E" 1973 "Esc-Ctrl+F" 1974 "Esc-Ctrl+G" 1975 "Esc-Ctrl+H" 1976 "Esc-Ctrl+I" 1977 "Esc-Ctrl+J" 1978 "Esc-Ctrl+K" 1979 "Esc-Ctrl+L" 1980 "Esc-Ctrl+M" 1981 "Esc-Ctrl+N" 1982 "Esc-Ctrl+O" 1983 "Esc-Ctrl+P" 1984 "Esc-Ctrl+Q" 1985 "Esc-Ctrl+R" 1986 "Esc-Ctrl+S" 1987 "Esc-Ctrl+T" 1988 "Esc-Ctrl+U" 1989 "Esc-Ctrl+V" 1990 "Esc-Ctrl+W" 1991 "Esc-Ctrl+X" 1992 "Esc-Ctrl+Y" 1993 "Esc-Ctrl+Z" 1994 "Esc-Esc" 1995 "Ctrl+Q-S" 1996 "Ctrl+Q-D" 1997 "Ctrl+Q-R" 1998 "Ctrl+Q-C" 1999 "Ctrl+Q-E" 2000 "Ctrl+Q-X" ; Strings fr den Fileselektor. Die L„ngen sollten erhalten bleiben wenn ; m”glich. 2100 " Bytes " 2101 " Verzeichnis " ; Fehlermeldungen fr Systemfehler. 2300 "Fehler %d: %s" 2301 "Kein Fehler (OOPS!)" 2302 "Datei oder Pfad nicht gefunden" 2303 "Nicht genug Speicher" 2304 "Zugriff verweigert" 2305 "Zu viele offene Files" 2306 "Nicht gengend Speicherplatz auf dem angesprochenen Ger„t" 2307 "Tempor„rer Fehler - nochmal versuchen" 2308 "Ger„t/Datei ist in Benutzung" 2309 "Datei ist zu groį" 2310 "I/O Fehler" 2311 "Datei ist ein Verzeichnis" 2312 "Datei ist kein Verzeichnis" 2313 "Zu viele Links" 2314 "Operation nur mit Block Devices m”glich" 2315 "Operation nur mit Char Devices m”glich" 2316 "Device existiert nicht" 2317 "Operation ist nur fr den Besitzer der Datei m”glich" 2318 "Broken Pipe" 2319 "Dateisystem ist readonly" 2320 "Seek kann nicht auf Pipes ausgefhrt werden" 2321 "Prozess existiert nicht" 2322 "Ausfhrbare Datei ist busy" 2323 "Name ist zu lang" 2324 "Keine Locks verfgbar" 2325 "Verzeichnis ist nicht leer" 2326 "Datei nicht gefunden" 2327 "Pfad nicht gefunden" 2328 "Laufwerk ist ungltig" 2329 "Aktuelles Verzeichnis kann nicht gel”scht werden" 2330 "Datei existiert bereits" 2331 "Unbekannter Fehler (%d)" ; Fenstermanager 2500 "Es sind zu viele Fenster ge”ffnet!" ; ------------------------------------------------------------------------- ; ESTIC ; Eintr„ge fr das Hauptmenue. '@' markiert den Hotkey. 0 "@ESTIC" 1 "@ber ESTIC..." 10 "@Datei" 11 "D@atei laden" 12 "Datei s@peichern" 13 "L@ogfile ansehen" 14 "ISTEC @laden" 15 "ISTEC @speichern" 16 "@ˇnderungen permanent machen" 17 "Aliasdatei @einlesen" 18 "@Quit" 20 "@Konfiguration" 21 "@Version" 22 "@Anlagenparameter" 23 "@Endger„teparameter" 24 "@Zurcksetzen" 30 "@Gebhren" 31 "Gebhren @laden" 32 "Gebhren @anzeigen" 33 "Druck-@Einstellungen" 34 "Gebhren @drucken" 35 "Gebhren @rcksetzen" 40 "@Fenster" 41 "@™ffnen" 42 "@Verbindungsmatrix" 43 "@Gebhren" 44 "@Ausgehende Gespr„che" 45 "@Isdn4Linux Monitor" 46 "@Kacheln" 47 "Kaska@de" 48 "@Alle schlieįen" 49 "@Bildschirm neu" 50 "@Position/Gr”įe" 51 "@Zoom" 52 "@Schlieįen" 53 "@Fensterliste" ; About 60 "\n\cESTIC Version 1.30\n\c(Enhanced Supervisor Tool for ISTEC Configuration)\n\n\c(C) 1995 Ullrich von Bassewitz\n\c\n\n" ; ISTEC Info-Fenster 61 "Mehrger„teanschluį" 62 "Anlagenanschluį" 63 "Unbekannte Anschluįart" 64 "\nTyp: %s\n\nSoftware Version: %d.%d\n\n%-2d S0-Schnittstellen extern\n%-2d S0-Schnittstellen intern\n%-2d ab-Schnittstellen\n\nProtokoll: %s\nAnschluį: %s\n\n" ; Titel des Fileselektors 65 " Konfiguration laden " 66 " Konfiguration speichern " 67 "COM Port ist nicht offen" 68 "Timeout bei der Kommunikation mit der ISTEC" 69 "ˇnderungen in der ISTEC speichern?" 70 "ˇnderungen permanent machen?" ; Gebhrenausdruck 71 "Gebhrenausdruck %s %33s" 72 "----------------------------------------------------------------" 73 " Ger„t Einheiten Kosten" 74 " #%2d %4d " 75 "Fehler beim Initialisieren der seriellen Schnittstelle" 76 "Empfangspuffer-berlauf!" 77 "Zu wenig Zeichen in der empfangenen Nachricht!" 78 "Ungltige Antwort von der ISTEC!" 79 "Falsche Ger„tenummer in der ISTEC Antwort.\n\cKommando wird abgebrochen.!" ; Titel File-Selektor 80 " Drucken nach Datei " 81 " Logfile ansehen " 82 "Fehler beim ™ffnen der Einstellungsdatei" 200 "OOPS - Interner Fehler!\n\c(ignoriert)" 300 "ISTEC XXXX" 301 "ISTEC 1003" 302 "ISTEC 1008" 303 "ISTEC 1016" 304 "ISTEC 1024" 305 "ISTEC 2016" 306 "ISTEC 2024" 307 "ISTEC 2400" 308 "ISTEC 2416" 309 "ISTEC 2424" ; Endger„tekonfiguration. L„ngen beachten! 400 "Keine " 401 "Inland " 402 "Ort " 403 "Halbamt " 404 "Nichtamt " 405 "Fernsprechen " 406 "Fax Gruppe 3 " 407 "Daten/Modem " 408 "Datex-J/Modem " 409 "Anrufbeantworter " 410 "Kombidienste " 411 " An " 412 " Aus " 413 "------ " 414 "Extern " 415 "Intern: %2d" 416 " Ger„t #%d " 500 "\nZur Erweiterung der Anlagen \nmit 16 a/b-Teilnehmern auf \n24 a/b-Teilnehmer lesen Sie \nbitte im Handbuch nach.\n\n" ; Fenster "Verbindungsmatrix" 600 " Verbindungsmatrix " 601 " Nr. Amt1 Amt2 Int1 Int2 Int3 Ton WTon TFE Ruf Nummer " ; Aliase 700 "Doppelter Alias fr Nummer %s" 701 "Fehler beim ™ffnen der Alias-Datei!" 702 "Syntaxfehler im Aliasfile, Zeile %d" ; isdn4linux Monitor, Positionen in der Titelzeile erhalten 800 " isdn4linux Monitor " 801 " Dr Ch Ein/Aus Dienst Nummer " 802 "-----------------------------------------------" ; Steht unter Ein/Aus 803 "Ein" 804 "Aus" ; Unter Dienst 805 "---" 806 "Raw" 807 "Modem" 808 "Netz" 809 "Sprache" 810 "Fax" 811 "Unbekannt" 812 "Fehler beim ™ffnen von %s" 813 "Fehler beim Lesen von %s -\nisdn4linux Monitor wird beendet!" ; 900 "Fehler beim ™ffnen des Debug Logfiles" ; Fenster "Ausgehende Gespr„che", L„ngen bzw. Positionen erhalten 1100 " Ausgehende Gespr„che " 1101 "Nr. Alias Datum Startzeit L„nge Nummer Einh. DM " 1102 "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ" 1200 " Gebhren " 1201 " Nr. Einheiten" estic-1.61.orig/spunk/msg.cc0100644000176100001440000000317207031424702015247 0ustar debacleusers/*****************************************************************************/ /* */ /* STR.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "machine.h" #include "object.h" #include "strmable.h" #include "stream.h" #include "string.h" #include "msg.h" #include "streamid.h" // Link in class Msg LINK (Msg, ID_Msg); /*****************************************************************************/ /* class Msg */ /*****************************************************************************/ void Msg::Load (Stream &S) { String::Load (S); S >> MsgNum; } void Msg::Store (Stream &S) const { String::Store (S); S << MsgNum; } u16 Msg::StreamableID () const { return ID_Msg; } Streamable * Msg::Build () { return new Msg (Empty); } Msg & Msg::operator = (const Msg &S) { String::operator = (S); MsgNum = S.MsgNum; return *this; } estic-1.61.orig/spunk/msg.eng0100644000176100001440000002152307031424702015433 0ustar debacleusers 0 "Help" 1 "Accept " 2 "Abort " 3 "End " 4 "Proceed " 5 "Change " 6 "Print " 7 "Graphics " 8 "Insert " 9 "Delete " 10 "Select " 11 "Confirm " 12 "Move " 13 "Login " 14 "Logout " 15 "Exit " 16 "Zoom " 17 "Close " 18 "Open " 19 "Resize " 20 "Save " 21 " ~~ Select " 22 " ~ÄŁ~ Select " 23 " ~ PgDn PgUp~ Browse " 24 " ~~ Move " 25 " ~Ctrl-~ Resize " 100 "Are you shure?" 101 "Really quit?" 102 "Discard changes?" 103 "Save changes?" 104 "@Yes|@No" 105 "@No|@Yes" 200 " Error " 201 " Information " 202 " Fatal Error " 210 "Confirm " 211 "Abort " 212 "Ignore " 213 "Retry " 214 "End " 215 "One moment please..." 300 "Invalid input" 301 "Too many trailing digits" 302 "Value is too small (minimum is %g)" 303 "Value is too large (maximum is %g)" 304 "Value is too small (minimum is %ld)" 305 "Value is too large (maximum is %ld)" 306 "Input cannot be empty" 307 "No filename extension allowed" 400 "Off On" 401 " NoYes" 500 "Value is too large" 501 "Value is too small" 502 "Invalid input" 600 "%s: Section %s, key %s not found or invalid." 700 "Error opening the password file^(%s)" 701 "Error reading the password file^(%s)" 702 "Error writing to the password file^(%s)" 703 "The user id cannot be empty!" 704 "The user name cannot be empty!" 705 "An empty password is invalid!" 706 "A user with this ID does already exist!" 707 "Invalid user id or invalid password!" 800 "Sunday" 801 "Monday" 802 "Tuesday" 803 "Wednesday" 804 "Thursday" 805 "Friday" 806 "Saturday" 807 "Sun" 808 "Mon" 809 "Tue" 810 "Wed" 811 "Thu" 812 "Fri" 813 "Sat" 814 "January" 815 "February" 816 "March" 817 "April" 818 "May" 819 "June" 820 "July" 821 "August" 822 "September" 823 "October" 824 "November" 825 "December" 826 "Jan" 827 "Feb" 828 "Mar" 829 "Apr" 830 "May" 831 "Jun" 832 "Jul" 833 "Aug" 834 "Sep" 835 "Oct" 836 "Nov" 837 "Dec" 900 "No help available" 901 "No help on this topic" 1024 "" 1025 "Ctrl+A" 1026 "Ctrl+B" 1027 "Ctrl+C" 1028 "Ctrl+D" 1029 "Ctrl+E" 1030 "Ctrl+F" 1031 "Ctrl+G" 1032 "Ctrl+H" 1033 "Tab" 1034 "Ctrl+J" 1035 "Ctrl+K" 1036 "Ctrl+L" 1037 "ÄŁ" 1038 "Ctrl+N" 1039 "Ctrl+O" 1040 "Ctrl+P" 1041 "Ctrl+Q" 1042 "Ctrl+R" 1043 "Ctrl+S" 1044 "Ctrl+T" 1045 "Ctrl+U" 1046 "Ctrl+V" 1047 "Ctrl+W" 1048 "Ctrl+X" 1049 "Ctrl+Y" 1050 "Ctrl+Z" 1051 "Esc" 1151 "Del" 1281 "Alt+Esc" 1282 "Alt+Space" 1284 "Ctrl+Ins" 1285 "Shift+Ins" 1286 "Ctrl+Del" 1287 "Shift+Del" 1295 "Shift+Tab" 1296 "Alt+Q" 1297 "Alt+W" 1298 "Alt+E" 1299 "Alt+R" 1300 "Alt+T" 1301 "Alt+Y" 1302 "Alt+U" 1303 "Alt+I" 1304 "Alt+O" 1305 "Alt+P" 1310 "Alt+A" 1311 "Alt+S" 1312 "Alt+D" 1313 "Alt+F" 1314 "Alt+G" 1315 "Alt+H" 1316 "Alt+J" 1317 "Alt+K" 1318 "Alt+L" 1324 "Alt+Z" 1325 "Alt+X" 1326 "Alt+C" 1327 "Alt+V" 1328 "Alt+B" 1329 "Alt+N" 1330 "Alt+M" 1339 "F1" 1340 "F2" 1341 "F3" 1342 "F4" 1343 "F5" 1344 "F6" 1345 "F7" 1346 "F8" 1347 "F9" 1348 "F10" 1351 "Home" 1352 "" 1353 "PgUp" 1355 "" 1357 "" 1359 "End" 1360 "" 1361 "PgDn" 1362 "Ins" 1363 "Del" 1364 "Shift+F1" 1365 "Shift+F2" 1366 "Shift+F3" 1367 "Shift+F4" 1368 "Shift+F5" 1369 "Shift+F6" 1370 "Shift+F7" 1371 "Shift+F8" 1372 "Shift+F9" 1373 "Shift+F10" 1374 "Ctrl+F1" 1375 "Ctrl+F2" 1376 "Ctrl+F3" 1377 "Ctrl+F4" 1378 "Ctrl+F5" 1379 "Ctrl+F6" 1380 "Ctrl+F7" 1381 "Ctrl+F8" 1382 "Ctrl+F9" 1383 "Ctrl+F10" 1384 "Alt+F1" 1385 "Alt+F2" 1386 "Alt+F3" 1387 "Alt+F4" 1388 "Alt+F5" 1389 "Alt+F6" 1390 "Alt+F7" 1391 "Alt+F8" 1392 "Alt+F9" 1393 "Alt+F10" 1395 "Ctrl+" 1396 "Ctrl+" 1397 "Ctrl+End" 1398 "Ctrl+PgDn" 1399 "Ctrl+Home" 1400 "Alt+1" 1401 "Alt+2" 1402 "Alt+3" 1403 "Alt+4" 1404 "Alt+5" 1405 "Alt+6" 1406 "Alt+7" 1407 "Alt+8" 1408 "Alt+9" 1409 "Alt+0" 1412 "Ctrl+PgUp" 1413 "F11" 1414 "F12" 1415 "Shift+F11" 1416 "Shift+F12" 1417 "Ctrl+F11" 1418 "Ctrl+F12" 1419 "Alt+F11" 1420 "Alt+F12" 1421 "Ctrl+" 1425 "Ctrl+" 1428 "Ctrl+Tab" 1431 "Alt+Home" 1433 "Alt+PgUp" 1439 "Alt+End" 1441 "Alt+PgDn" 1442 "Alt+Ins" 1443 "Alt+Del" 1445 "Alt+Tab" 1456 "Alt+Ctrl+A" 1457 "Alt+Ctrl+B" 1458 "Alt+Ctrl+C" 1459 "Alt+Ctrl+D" 1460 "Alt+Ctrl+E" 1461 "Alt+Ctrl+F" 1462 "Alt+Ctrl+G" 1463 "Alt+Ctrl+H" 1464 "Alt+Ctrl+I" 1465 "Alt+Ctrl+J" 1466 "Alt+Ctrl+K" 1467 "Alt+Ctrl+L" 1468 "Alt+Ctrl+M" 1469 "Alt+Ctrl+N" 1470 "Alt+Ctrl+O" 1471 "Alt+Ctrl+P" 1472 "Alt+Ctrl+Q" 1473 "Alt+Ctrl+R" 1474 "Alt+Ctrl+S" 1475 "Alt+Ctrl+T" 1476 "Alt+Ctrl+U" 1477 "Alt+Ctrl+V" 1478 "Alt+Ctrl+W" 1479 "Alt+Ctrl+X" 1480 "Alt+Ctrl+Y" 1481 "Alt+Ctrl+Z" 1482 "Esc-Esc" 1483 "Ctrl+Q-S" 1484 "Ctrl+Q-D" 1485 "Ctrl+Q-R" 1486 "Ctrl+Q-C" 1487 "Ctrl+Q-E" 1488 "Ctrl+Q-X" 1536 "" 1537 "Ctrl+A" 1538 "Ctrl+B" 1539 "Ctrl+C" 1540 "Ctrl+D" 1541 "Ctrl+E" 1542 "Ctrl+F" 1543 "Ctrl+G" 1544 "Ctrl+H" 1545 "Tab" 1546 "Ctrl+J" 1547 "Ctrl+K" 1548 "Ctrl+L" 1549 "Enter" 1550 "Ctrl+N" 1551 "Ctrl+O" 1552 "Ctrl+P" 1553 "Ctrl+Q" 1554 "Ctrl+R" 1555 "Ctrl+S" 1556 "Ctrl+T" 1557 "Ctrl+U" 1558 "Ctrl+V" 1559 "Ctrl+W" 1560 "Ctrl+X" 1561 "Ctrl+Y" 1562 "Ctrl+Z" 1563 "Esc" 1663 "Del" 1793 "Alt+Esc" 1794 "Alt+Space" 1796 "Ctrl+Ins" 1797 "Shift+Ins" 1798 "Ctrl+Del" 1799 "Shift+Del" 1807 "Shift+Tab" 1808 "Esc-Q" 1809 "Esc-W" 1810 "Esc-E" 1811 "Esc-R" 1812 "Esc-T" 1813 "Esc-Y" 1814 "Esc-U" 1815 "Esc-I" 1816 "Esc-O" 1817 "Esc-P" 1822 "Esc-A" 1823 "Esc-S" 1824 "Esc-D" 1825 "Esc-F" 1826 "Esc-G" 1827 "Esc-H" 1828 "Esc-J" 1829 "Esc-K" 1830 "Esc-L" 1836 "Esc-Z" 1837 "Esc-X" 1838 "Esc-C" 1839 "Esc-V" 1840 "Esc-B" 1841 "Esc-N" 1842 "Esc-M" 1851 "F1" 1852 "F2" 1853 "F3" 1854 "F4" 1855 "F5" 1856 "F6" 1857 "F7" 1858 "F8" 1859 "F9" 1860 "F10" 1863 "Home" 1864 "" 1865 "PgUp" 1867 "" 1869 "" 1871 "End" 1872 "" 1873 "PgDn" 1874 "Ins" 1875 "Del" 1876 "Shift+F1" 1877 "Shift+F2" 1878 "Shift+F3" 1879 "Shift+F4" 1880 "Shift+F5" 1881 "Shift+F6" 1882 "Shift+F7" 1883 "Shift+F8" 1884 "Shift+F9" 1885 "Shift+F10" 1886 "Ctrl+F1" 1887 "Ctrl+F2" 1888 "Ctrl+F3" 1889 "Ctrl+F4" 1890 "Ctrl+F5" 1891 "Ctrl+F6" 1892 "Ctrl+F7" 1893 "Ctrl+F8" 1894 "Ctrl+F9" 1895 "Ctrl+F10" 1896 "Esc-F1" 1897 "Esc-F2" 1898 "Esc-F3" 1899 "Esc-F4" 1900 "Esc-F5" 1901 "Esc-F6" 1902 "Esc-F7" 1903 "Esc-F8" 1904 "Esc-F9" 1905 "Esc-F10" 1907 "Ctrl+" 1908 "Ctrl+" 1909 "Ctrl+End" 1910 "Ctrl+PgDn" 1911 "Ctrl+Home" 1912 "Esc-1" 1913 "Esc-2" 1914 "Esc-3" 1915 "Esc-4" 1916 "Esc-5" 1917 "Esc-6" 1918 "Esc-7" 1919 "Esc-8" 1920 "Esc-9" 1921 "Esc-0" 1924 "Ctrl+PgUp" 1925 "F11" 1926 "F12" 1927 "Shift+F11" 1928 "Shift+F12" 1929 "Ctrl+F11" 1930 "Ctrl+F12" 1931 "Esc-F11" 1932 "Esc-F12" 1933 "Ctrl+" 1937 "Ctrl+" 1940 "Ctrl+Tab" 1943 "Esc-Home" 1945 "Esc-PgUp" 1951 "Esc-End" 1953 "Esc-PgDn" 1954 "Esc-Ins" 1955 "Esc-Del" 1957 "Esc-Tab" 1968 "Esc-Ctrl+A" 1969 "Esc-Ctrl+B" 1970 "Esc-Ctrl+C" 1971 "Esc-Ctrl+D" 1972 "Esc-Ctrl+E" 1973 "Esc-Ctrl+F" 1974 "Esc-Ctrl+G" 1975 "Esc-Ctrl+H" 1976 "Esc-Ctrl+I" 1977 "Esc-Ctrl+J" 1978 "Esc-Ctrl+K" 1979 "Esc-Ctrl+L" 1980 "Esc-Ctrl+M" 1981 "Esc-Ctrl+N" 1982 "Esc-Ctrl+O" 1983 "Esc-Ctrl+P" 1984 "Esc-Ctrl+Q" 1985 "Esc-Ctrl+R" 1986 "Esc-Ctrl+S" 1987 "Esc-Ctrl+T" 1988 "Esc-Ctrl+U" 1989 "Esc-Ctrl+V" 1990 "Esc-Ctrl+W" 1991 "Esc-Ctrl+X" 1992 "Esc-Ctrl+Y" 1993 "Esc-Ctrl+Z" 1994 "Esc-Esc" 1995 "Ctrl+Q-S" 1996 "Ctrl+Q-D" 1997 "Ctrl+Q-R" 1998 "Ctrl+Q-C" 1999 "Ctrl+Q-E" 2000 "Ctrl+Q-X" 2100 " Bytes " 2101 " Directory " 2300 "Error %d: %s" 2301 "No error (OOPS!)" 2302 "File or path not found" 2303 "Not enough memory" 2304 "Access denied" 2305 "Too many open files" 2306 "No space left on device" 2307 "Try again" 2308 "Device or file is busy" 2309 "File is too large" 2310 "I/O error" 2311 "File is a directory" 2312 "File is no directory" 2313 "Too many links" 2314 "Block device required" 2315 "Char device required" 2316 "Device does not exist" 2317 "You are not the owner of the file" 2318 "Broken pipe" 2319 "File system is readonly" 2320 "Cannot seek on pipes" 2321 "Process does not exist" 2322 "Text file is busy" 2323 "Name is too long" 2324 "No locks available" 2325 "Directory is not empty" 2326 "File not found" 2327 "Path not found" 2328 "Drive is invalid" 2329 "Cannot remove current directory" 2330 "File exists" 2331 "Unknown error (%d)" estic-1.61.orig/spunk/msg.ger0100644000176100001440000002270107031424702015436 0ustar debacleusers 0 "Hilfe" 1 "bernehmen " 2 "Abbruch " 3 "Ende " 4 "Weiter " 5 "ˇndern " 6 "Drucken " 7 "Grafik " 8 "Einfgen " 9 "L”schen " 10 "Auswahl " 11 "Best„tigen " 12 "Bewegen " 13 "Login " 14 "Logout " 15 "Ende " 16 "Zoom " 17 "Schliessen " 18 "™ffnen " 19 "Gr”įe " 20 "Speichern " 21 " ~\x12~ Auswahl " 22 " ~\x12\x11ÄŁ~ Auswahl " 23 " ~\x12 Bild-\x12~ Bl„ttern " 24 " ~\x12\x1D~ Bewegen " 25 " ~Ctrl+\x12\x1D~ Gr”įe " 100 "Sind Sie sicher?" 101 "Wirklich Ende?" 102 "ˇnderungen verwerfen?" 103 "ˇnderungen sichern?" 104 "@Ja\n@Nein" 105 "@Nein\n@Ja" 200 " Fehler " 201 " Information " 202 " Systemfehler " 210 "Best„tigen " 211 "Abbruch " 212 "Ignorieren " 213 "Wiederholen " 214 "Ende " 215 "Einen Moment bitte..." 300 "Ungltige Eingabe" 301 "Zu viele Nachkommastellen" 302 "Wert ist zu klein (Minimum ist %g)" 303 "Wert ist zu groį (Maximum ist %g)" 304 "Wert ist zu klein (Minimum ist %ld)" 305 "Wert ist zu groį (Maximum ist %ld)" 306 "Leereingabe ist unzul„ssig" 307 "Keine Datei-Erweiterung erlaubt" 400 "Aus An" 401 "Nein Ja" 500 "Wert ist zu groį" 501 "Wert ist zu klein" 502 "Fehlerhafte Eingabe" 600 "%s: Sektion %s, %s nicht gefunden oder fehlerhaft." 700 "Fehler beim ™ffnen der Passwort-Datei^(%s)" 701 "Fehler beim Lesen der Passwort-Datei^(%s)" 702 "Fehler beim Schreiben auf die Passwort-Datei^(%s)" 703 "Es muį eine Benutzer-ID angegeben werden!" 704 "Es muį ein Benutzername angegeben werden!" 705 "Es muį ein Passwort angegeben werden!" 706 "Ein Benutzer mit dieser ID existiert bereits!" 707 "Ungltige Benutzer-ID oder ungltiges Passwort!" 800 "Sonntag" 801 "Montag" 802 "Dienstag" 803 "Mittwoch" 804 "Donnerstag" 805 "Freitag" 806 "Samstag" 807 "So" 808 "Mo" 809 "Di" 810 "Mi" 811 "Do" 812 "Fr" 813 "Sa" 814 "Januar" 815 "Februar" 816 "M„rz" 817 "April" 818 "Mai" 819 "Juni" 820 "Juli" 821 "August" 822 "September" 823 "Oktober" 824 "November" 825 "Dezember" 826 "Jan" 827 "Feb" 828 "M„r" 829 "Apr" 830 "Mai" 831 "Jun" 832 "Jul" 833 "Aug" 834 "Sep" 835 "Okt" 836 "Nov" 837 "Dez" 900 "Keine Hilfe verfgbar" 901 "Keine Hilfe fr dieses Stichwort" 1024 "" 1025 "Ctrl+A" 1026 "Ctrl+B" 1027 "Ctrl+C" 1028 "Ctrl+D" 1029 "Ctrl+E" 1030 "Ctrl+F" 1031 "Ctrl+G" 1032 "Ctrl+H" 1033 "Tab" 1034 "Ctrl+J" 1035 "Ctrl+K" 1036 "Ctrl+L" 1037 "\x11ÄŁ" 1038 "Ctrl+N" 1039 "Ctrl+O" 1040 "Ctrl+P" 1041 "Ctrl+Q" 1042 "Ctrl+R" 1043 "Ctrl+S" 1044 "Ctrl+T" 1045 "Ctrl+U" 1046 "Ctrl+V" 1047 "Ctrl+W" 1048 "Ctrl+X" 1049 "Ctrl+Y" 1050 "Ctrl+Z" 1051 "Esc" 1151 "Del" 1281 "Alt+Esc" 1282 "Alt+Leertaste" 1284 "Ctrl+Einfg" 1285 "Shift+Einfg" 1286 "Ctrl+Entf" 1287 "Shift+Entf" 1295 "Shift+Tab" 1296 "Alt+Q" 1297 "Alt+W" 1298 "Alt+E" 1299 "Alt+R" 1300 "Alt+T" 1301 "Alt+Y" 1302 "Alt+U" 1303 "Alt+I" 1304 "Alt+O" 1305 "Alt+P" 1310 "Alt+A" 1311 "Alt+S" 1312 "Alt+D" 1313 "Alt+F" 1314 "Alt+G" 1315 "Alt+H" 1316 "Alt+J" 1317 "Alt+K" 1318 "Alt+L" 1324 "Alt+Z" 1325 "Alt+X" 1326 "Alt+C" 1327 "Alt+V" 1328 "Alt+B" 1329 "Alt+N" 1330 "Alt+M" 1339 "F1" 1340 "F2" 1341 "F3" 1342 "F4" 1343 "F5" 1344 "F6" 1345 "F7" 1346 "F8" 1347 "F9" 1348 "F10" 1351 "Pos1" 1352 "\x18" 1353 "Bild-\x18" 1355 "\x1B" 1357 "\x1A" 1359 "Ende" 1360 "\x19" 1361 "Bild-\x19" 1362 "Einfg" 1363 "Entf" 1364 "Shift+F1" 1365 "Shift+F2" 1366 "Shift+F3" 1367 "Shift+F4" 1368 "Shift+F5" 1369 "Shift+F6" 1370 "Shift+F7" 1371 "Shift+F8" 1372 "Shift+F9" 1373 "Shift+F10" 1374 "Ctrl+F1" 1375 "Ctrl+F2" 1376 "Ctrl+F3" 1377 "Ctrl+F4" 1378 "Ctrl+F5" 1379 "Ctrl+F6" 1380 "Ctrl+F7" 1381 "Ctrl+F8" 1382 "Ctrl+F9" 1383 "Ctrl+F10" 1384 "Alt+F1" 1385 "Alt+F2" 1386 "Alt+F3" 1387 "Alt+F4" 1388 "Alt+F5" 1389 "Alt+F6" 1390 "Alt+F7" 1391 "Alt+F8" 1392 "Alt+F9" 1393 "Alt+F10" 1395 "Ctrl+\x1B" 1396 "Ctrl+\x1A" 1397 "Ctrl+Ende" 1398 "Ctrl+Bild-\x19" 1399 "Ctrl+Pos1" 1400 "Alt+1" 1401 "Alt+2" 1402 "Alt+3" 1403 "Alt+4" 1404 "Alt+5" 1405 "Alt+6" 1406 "Alt+7" 1407 "Alt+8" 1408 "Alt+9" 1409 "Alt+0" 1412 "Ctrl+Bild-\x18" 1413 "F11" 1414 "F12" 1415 "Shift+F11" 1416 "Shift+F12" 1417 "Ctrl+F11" 1418 "Ctrl+F12" 1419 "Alt+F11" 1420 "Alt+F12" 1421 "Ctrl+\x18" 1425 "Ctrl+\x19" 1428 "Ctrl+Tab" 1431 "Alt+Pos1" 1433 "Alt+Bild-\x18" 1439 "Alt+Ende" 1441 "Alt+Bild-\x19" 1442 "Alt+Einfg" 1443 "Alt+Entf" 1445 "Alt+Tab" 1456 "Alt+Ctrl+A" 1457 "Alt+Ctrl+B" 1458 "Alt+Ctrl+C" 1459 "Alt+Ctrl+D" 1460 "Alt+Ctrl+E" 1461 "Alt+Ctrl+F" 1462 "Alt+Ctrl+G" 1463 "Alt+Ctrl+H" 1464 "Alt+Ctrl+I" 1465 "Alt+Ctrl+J" 1466 "Alt+Ctrl+K" 1467 "Alt+Ctrl+L" 1468 "Alt+Ctrl+M" 1469 "Alt+Ctrl+N" 1470 "Alt+Ctrl+O" 1471 "Alt+Ctrl+P" 1472 "Alt+Ctrl+Q" 1473 "Alt+Ctrl+R" 1474 "Alt+Ctrl+S" 1475 "Alt+Ctrl+T" 1476 "Alt+Ctrl+U" 1477 "Alt+Ctrl+V" 1478 "Alt+Ctrl+W" 1479 "Alt+Ctrl+X" 1480 "Alt+Ctrl+Y" 1481 "Alt+Ctrl+Z" 1482 "Esc-Esc" 1483 "Ctrl+Q-S" 1484 "Ctrl+Q-D" 1485 "Ctrl+Q-R" 1486 "Ctrl+Q-C" 1487 "Ctrl+Q-E" 1488 "Ctrl+Q-X" 1536 "" 1537 "Ctrl+A" 1538 "Ctrl+B" 1539 "Ctrl+C" 1540 "Ctrl+D" 1541 "Ctrl+E" 1542 "Ctrl+F" 1543 "Ctrl+G" 1544 "Ctrl+H" 1545 "Tab" 1546 "Ctrl+J" 1547 "Ctrl+K" 1548 "Ctrl+L" 1549 "Enter" 1550 "Ctrl+N" 1551 "Ctrl+O" 1552 "Ctrl+P" 1553 "Ctrl+Q" 1554 "Ctrl+R" 1555 "Ctrl+S" 1556 "Ctrl+T" 1557 "Ctrl+U" 1558 "Ctrl+V" 1559 "Ctrl+W" 1560 "Ctrl+X" 1561 "Ctrl+Y" 1562 "Ctrl+Z" 1563 "Esc" 1663 "Del" 1793 "Alt+Esc" 1794 "Alt+Leertaste" 1796 "Ctrl+Einfg" 1797 "Shift+Einfg" 1798 "Ctrl+Entf" 1799 "Shift+Entf" 1807 "Shift+Tab" 1808 "Esc-Q" 1809 "Esc-W" 1810 "Esc-E" 1811 "Esc-R" 1812 "Esc-T" 1813 "Esc-Y" 1814 "Esc-U" 1815 "Esc-I" 1816 "Esc-O" 1817 "Esc-P" 1822 "Esc-A" 1823 "Esc-S" 1824 "Esc-D" 1825 "Esc-F" 1826 "Esc-G" 1827 "Esc-H" 1828 "Esc-J" 1829 "Esc-K" 1830 "Esc-L" 1836 "Esc-Z" 1837 "Esc-X" 1838 "Esc-C" 1839 "Esc-V" 1840 "Esc-B" 1841 "Esc-N" 1842 "Esc-M" 1851 "F1" 1852 "F2" 1853 "F3" 1854 "F4" 1855 "F5" 1856 "F6" 1857 "F7" 1858 "F8" 1859 "F9" 1860 "F10" 1863 "Pos1" 1864 "\x18" 1865 "Bild-\x18" 1867 "\x1B" 1869 "\x1A" 1871 "Ende" 1872 "\x19" 1873 "Bild-\x19" 1874 "Einfg" 1875 "Entf" 1876 "Shift+F1" 1877 "Shift+F2" 1878 "Shift+F3" 1879 "Shift+F4" 1880 "Shift+F5" 1881 "Shift+F6" 1882 "Shift+F7" 1883 "Shift+F8" 1884 "Shift+F9" 1885 "Shift+F10" 1886 "Ctrl+F1" 1887 "Ctrl+F2" 1888 "Ctrl+F3" 1889 "Ctrl+F4" 1890 "Ctrl+F5" 1891 "Ctrl+F6" 1892 "Ctrl+F7" 1893 "Ctrl+F8" 1894 "Ctrl+F9" 1895 "Ctrl+F10" 1896 "Esc-F1" 1897 "Esc-F2" 1898 "Esc-F3" 1899 "Esc-F4" 1900 "Esc-F5" 1901 "Esc-F6" 1902 "Esc-F7" 1903 "Esc-F8" 1904 "Esc-F9" 1905 "Esc-F10" 1907 "Ctrl+\x1B" 1908 "Ctrl+\x1A" 1909 "Ctrl+Ende" 1910 "Ctrl+PgDn" 1911 "Ctrl+Pos1" 1912 "Esc-1" 1913 "Esc-2" 1914 "Esc-3" 1915 "Esc-4" 1916 "Esc-5" 1917 "Esc-6" 1918 "Esc-7" 1919 "Esc-8" 1920 "Esc-9" 1921 "Esc-0" 1924 "Ctrl+PgUp" 1925 "F11" 1926 "F12" 1927 "Shift+F11" 1928 "Shift+F12" 1929 "Ctrl+F11" 1930 "Ctrl+F12" 1931 "Esc-F11" 1932 "Esc-F12" 1933 "Ctrl+\x18" 1937 "Ctrl+\x19" 1940 "Ctrl+Tab" 1943 "Esc-Pos1" 1945 "Esc-PgUp" 1951 "Esc-Ende" 1953 "Esc-PgDn" 1954 "Esc-Einfg" 1955 "Esc-Entf" 1957 "Esc-Tab" 1968 "Esc-Ctrl+A" 1969 "Esc-Ctrl+B" 1970 "Esc-Ctrl+C" 1971 "Esc-Ctrl+D" 1972 "Esc-Ctrl+E" 1973 "Esc-Ctrl+F" 1974 "Esc-Ctrl+G" 1975 "Esc-Ctrl+H" 1976 "Esc-Ctrl+I" 1977 "Esc-Ctrl+J" 1978 "Esc-Ctrl+K" 1979 "Esc-Ctrl+L" 1980 "Esc-Ctrl+M" 1981 "Esc-Ctrl+N" 1982 "Esc-Ctrl+O" 1983 "Esc-Ctrl+P" 1984 "Esc-Ctrl+Q" 1985 "Esc-Ctrl+R" 1986 "Esc-Ctrl+S" 1987 "Esc-Ctrl+T" 1988 "Esc-Ctrl+U" 1989 "Esc-Ctrl+V" 1990 "Esc-Ctrl+W" 1991 "Esc-Ctrl+X" 1992 "Esc-Ctrl+Y" 1993 "Esc-Ctrl+Z" 1994 "Esc-Esc" 1995 "Ctrl+Q-S" 1996 "Ctrl+Q-D" 1997 "Ctrl+Q-R" 1998 "Ctrl+Q-C" 1999 "Ctrl+Q-E" 2000 "Ctrl+Q-X" 2100 " Bytes " 2101 " Verzeichnis " 2300 "Fehler %d: %s" 2301 "Kein Fehler (OOPS!)" 2302 "Datei oder Pfad nicht gefunden" 2303 "Nicht genug Speicher" 2304 "Zugriff verweigert" 2305 "Zu viele offene Files" 2306 "Nicht gengend Speicherplatz auf dem angesprochenen Ger„t" 2307 "Tempor„rer Fehler - nochmal versuchen" 2308 "Ger„t/Datei ist in Benutzung" 2309 "Datei ist zu groį" 2310 "I/O Fehler" 2311 "Datei ist ein Verzeichnis" 2312 "Datei ist kein Verzeichnis" 2313 "Zu viele Links" 2314 "Operation nur mit Block Devices m”glich" 2315 "Operation nur mit Char Devices m”glich" 2316 "Device existiert nicht" 2317 "Operation ist nur fr den Besitzer der Datei m”glich" 2318 "Broken Pipe" 2319 "Dateisystem ist readonly" 2320 "Seek kann nicht auf Pipes ausgefhrt werden" 2321 "Prozess existiert nicht" 2322 "Ausfhrbare Datei ist busy" 2323 "Name ist zu lang" 2324 "Keine Locks verfgbar" 2325 "Verzeichnis ist nicht leer" 2326 "Datei nicht gefunden" 2327 "Pfad nicht gefunden" 2328 "Laufwerk ist ungltig" 2329 "Aktuelles Verzeichnis kann nicht gel”scht werden" 2330 "Datei existiert bereits" 2331 "Unbekannter Fehler (%d)" 2500 "Es sind zu viele Fenster ge”ffnet!" estic-1.61.orig/spunk/msg.h0100644000176100001440000000345207031424703015113 0ustar debacleusers/*****************************************************************************/ /* */ /* MSG.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _MSG_H #define _MSG_H #include "machine.h" #include "object.h" #include "strmable.h" #include "stream.h" #include "str.h" /*****************************************************************************/ /* class Msg */ /*****************************************************************************/ class Msg : public String { friend class MsgCollection; private: u16 MsgNum; public: Msg (u16 Num, u16 Size = 0); Msg (StreamableInit); Msg (u16 Num, const char* S); Msg (const Msg& M); Msg (u16 Num, const String& M); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // New member functions u16 GetNum () const; void SetNum (u16 Num); Msg& operator = (const Msg& S); }; inline Msg::Msg (u16 Num, u16 Size) : String (Size), MsgNum (Num) { } inline Msg::Msg (StreamableInit) : String (Empty) { } inline Msg::Msg (u16 Num, const char* S) : String (S), MsgNum (Num) { } inline Msg::Msg (const Msg& M) : String (M), MsgNum (M.MsgNum) { } inline Msg::Msg (u16 Num, const String& M) : String (M), MsgNum (Num) { } inline u16 Msg::GetNum () const { return MsgNum; } inline void Msg::SetNum (u16 Num) { MsgNum = Num; } // End of MSG.H #endif estic-1.61.orig/spunk/msgcoll.cc0100644000176100001440000000527607031424703016131 0ustar debacleusers/*****************************************************************************/ /* */ /* MSGCOLL.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "machine.h" #include "coll.h" #include "stream.h" #include "msg.h" #include "msgcoll.h" #include "streamid.h" // Register class MsgCollection if there are references in this module LINK(MsgCollection, ID_MsgCollection); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class MsgCollection */ /*****************************************************************************/ u16 MsgCollection::StreamableID () const { return ID_MsgCollection; } Streamable* MsgCollection::Build () { return new MsgCollection (Empty); } void* MsgCollection::GetItem (Stream& S) { // Create new Msg Msg *Item = new Msg (Empty); // Read data S >> Item; return (void*) Item; } void MsgCollection::PutItem (Stream& S, void* Item) const { S << (Msg*) Item; } int MsgCollection::Compare (const u16* Key1, const u16* Key2) { if (*Key1 > *Key2) { return 1; } else if (*Key1 < *Key2) { return -1; } else { return 0; } } const u16* MsgCollection::KeyOf (const Msg* Item) { return &Item->MsgNum; } const Msg& MsgCollection::GetMsg (u16 ID) { int Index; // Search for item with given ID if (Search (&ID, Index) == 0) { // Not found, set Index to -1 Index = -1; } // Check if found if (Index == -1) { String Msg = FormatStr ("GetMsg: Message #%u not found", ID); FAIL (Msg.GetStr ()); } // Return Msg return *At (Index); } estic-1.61.orig/spunk/msgcoll.h0100644000176100001440000000410707031424703015763 0ustar debacleusers/*****************************************************************************/ /* */ /* MSGCOLL.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __MSGCOLL_H #define __MSGCOLL_H #include "machine.h" #include "stream.h" #include "coll.h" #include "msg.h" /*****************************************************************************/ /* class MsgCollection */ /*****************************************************************************/ class MsgCollection : public SortedCollection { public: MsgCollection (int aLimit, int aDelta); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); protected: // Build constructor MsgCollection (StreamableInit); // Derived from class Collection virtual void* GetItem (Stream&); virtual void PutItem (Stream&, void* Item) const; // Derived from class SortedCollection virtual int Compare (const u16* Key1, const u16* Key2); virtual const u16* KeyOf (const Msg* Item); public: // New member functions const Msg& GetMsg (u16 ID); }; inline MsgCollection::MsgCollection (StreamableInit) : SortedCollection (Empty) { } inline MsgCollection::MsgCollection (int aLimit, int aDelta) : SortedCollection (aLimit, aDelta) { ShouldDelete = 1; } // End of MSGCOLL.H #endif estic-1.61.orig/spunk/msgid.h0100644000176100001440000000251007031424703015422 0ustar debacleusers/*****************************************************************************/ /* */ /* MSGID.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __MSGID_H #define __MSGID_H #include "machine.h" /*****************************************************************************/ /* Base ids for messages */ /*****************************************************************************/ const u16 MSGBASE_STATLINE = 0; const u16 MSGBASE_STDMENUE = 100; const u16 MSGBASE_STDMSG = 200; const u16 MSGBASE_MENUEDIT = 300; const u16 MSGBASE_MENUITEM = 400; const u16 MSGBASE_STRPARSE = 500; const u16 MSGBASE_INIFILE = 600; const u16 MSGBASE_PASSWORD = 700; const u16 MSGBASE_DATETIME = 800; const u16 MSGBASE_PROGRAM = 900; const u16 MSGBASE_KBD = 1024; // Needs 0x400 msgs! const u16 MSGBASE_FILESEL = 2100; const u16 MSGBASE_WINSIZE = 2200; const u16 MSGBASE_SYSERROR = 2300; // Reserve 200 messages const u16 MSGBASE_WINMGR = 2500; // END of MSGID.H #endif estic-1.61.orig/spunk/national.cc0100644000176100001440000003207607031424703016274 0ustar debacleusers/*****************************************************************************/ /* */ /* NATIONAL.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "check.h" #include "resource.h" #include "cont.h" #include "progutil.h" #include "nlsinfo.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Data structure used static _NLSData NLSD = { 0, // m/d/y 0, // 12 hour format 1, // Currency style: "$10" "$", // Currency string ',', // Thousands separator '.', // Decimal separator '/', // Date separator '.', // Time separator ';' // Data separator }; // The default country and language. This settings are used if no other // information about language/country is available and must be set _before_ // initialization of the application object. Default is USA and US english. unsigned DefaultCountry = 1; // USA unsigned DefaultLanguage = laEnglish; // An external reference to this object declared as const const _NLSData& NLSData = NLSD; // Language and country code static unsigned Country = 1; // USA static unsigned Language = laEnglish; // External const references to the language and country codes const unsigned& NLSCountry = Country; const unsigned& NLSLanguage = Language; // Translation table from a char to it's uppercase translation. This table // assumes strict ASCII. static _NLSTransTable UpCaseMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from a char to it's lowercase translation. This table // assumes strict ASCII static _NLSTransTable LoCaseMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // A collation table of all chars. Initially this is a no-op table, this may // be changed at runtime. static _NLSTransTable CollMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSUpCaseMap = UpCaseMap; const _NLSTransTable& NLSLoCaseMap = LoCaseMap; const _NLSTransTable& NLSCollMap = CollMap; /*****************************************************************************/ /* NLS functions */ /*****************************************************************************/ int NLSSetCountry (unsigned NewCountry) // Set up the NLS system for a new country. This affects the contents of the // NLSData structure above, and the 3 translation tables (UpCase, LoCase, // Coll). NLSCountry reflects the new country code after the call. If there // is no support for the new country found, the call will not change anything. // The old country code is returned if the change has been successfull, if // there is no support for the new country code, the function returns -1. { // Build the name of the data resource String ResName = FormatStr ("NATIONAL.%03d", NewCountry); // Check if the country data is available Container* C = (Container*) LoadResource (ResName, 0); if (C == NULL) { // No data available return -1; } // Retrieve the data from the container _NLSInfo* Info = (_NLSInfo*) C->GetData (); // Copy the data memcpy (&NLSD, &Info->Data, sizeof (NLSD)); memcpy (UpCaseMap, Info->UpCaseMap, sizeof (UpCaseMap)); memcpy (LoCaseMap, Info->LoCaseMap, sizeof (LoCaseMap)); memcpy (CollMap, Info->CollMap, sizeof (CollMap)); // Delete the container delete C; // Remember the new country code and return the old one unsigned OldCountry = Country; Country = NewCountry; return OldCountry; } int NLSSetLanguage (unsigned NewLanguage) // A new language code is set, the old one is returned. The complete resource // system will search for a resource in the given language, then for a generic // resource, then fall back to an english resource. The function will _not_ // detect if there is no support for the new language. { unsigned OldLanguage = Language; Language = NewLanguage; return OldLanguage; } unsigned NLSGetDefaultLanguage (unsigned Country) // Get the default language for the given country { static struct { u16 Country; u16 Language; } Map [] = { { 1, laEnglish }, { 44, laEnglish }, { 33, laFrench }, { 49, laGerman }, { 61, laEnglish }, { 99, laEnglish }, { 31, laDutch }, { 34, laSpanish }, { 39, laItalian }, { 41, laGerman }, // ? Swiss? { 2, laFrench }, // The following are incorrect set { 32, laEnglish }, // Belgium { 42, laEnglish }, // Czechoslovakia { 45, laEnglish }, // Denmark { 358, laEnglish }, // Finland { 36, laEnglish }, // Hungary { 354, laEnglish }, // Iceland { 3, laEnglish }, // Latin america { 47, laEnglish }, // Norway { 48, laEnglish }, // Poland { 351, laEnglish }, // Portugal { 46, laEnglish }, // Sweden { 90, laEnglish } // Turkey }; // Linear search for (unsigned I = 0; I < sizeof (Map) / sizeof (Map [0]); I++) { if (Map [I].Country == Country) { return Map [I].Language; } } // Not found, use english return laEnglish; } char* NLSUpStr (char* S) // Converts the given string to upper case according to the country information // currently set. S is returned. { char *P = S; while (*P) { *P = NLSUpCaseMap [(unsigned char) *P]; P++; } return S; } char* NLSLoStr (char* S) // Converts the given string to lower case according to the country information // currently set. S is returned. { char *P = S; while (*P) { *P = NLSLoCaseMap [(unsigned char) *P]; P++; } return S; } int NLSCmpStr (const char* S1, const char* S2) // Compare both strings according to the local collating sequence. { int Diff = 0; while (1) { Diff = ((int)(unsigned char) NLSCollMap [(unsigned char) *S1]) - ((int)(unsigned char) NLSCollMap [(unsigned char) *S2]); if (Diff != 0 || *S1 == '\0') { return Diff; } S1++; S2++; } } /*****************************************************************************/ /* Converting between internal and extern character representation */ /*****************************************************************************/ char* InputCvt (char* S) // Transform the given string S from the local input character set to the // internal used character set { char* P = S; while (*P) { *P = NLSInputMap [(unsigned char) *P]; P++; } return S; } char* OutputCvt (char* S) // Transform the given string S from the internal used character set to the // local output character set { char* P = S; while (*P) { *P = NLSOutputMap [(unsigned char) *P]; P++; } return S; } estic-1.61.orig/spunk/national.h0100644000176100001440000001200707031424703016126 0ustar debacleusers/*****************************************************************************/ /* */ /* NATIONAL.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _NATIONAL_H #define _NATIONAL_H #include "machine.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Language constants const unsigned laGerman = 1; const unsigned laEnglish = 2; const unsigned laFrench = 3; const unsigned laDutch = 4; const unsigned laSpanish = 5; const unsigned laItalian = 6; // Struct holding NLS information struct _NLSData { char Date; // Date format, 0=m/d/y, 1=d/m/y, 2=y/m/d char Time; // Time format, 0 = am/pm, 1 = military/european char Curr; // Currency style char CurrStr [5]; // Currency string char ThSep; // Thousands separator char DecSep; // Decimal separator char DateSep; // Date separator char TimeSep; // Time separator char DataSep; // Data separator char _Fill [19]; // Pad to 32 bytes }; // The default country and language. This settings are used if no other // information about language/country is available and must be set _before_ // initialization of the application object. Default is USA and US english. extern unsigned DefaultCountry; extern unsigned DefaultLanguage; // A _NLSData struct set up for the local country the current country and // the language to use. extern const _NLSData& NLSData; extern const unsigned& NLSLanguage; extern const unsigned& NLSCountry; // A translation table typedef char _NLSTransTable [256]; // References to several translation tables extern const _NLSTransTable& NLSUpCaseMap; extern const _NLSTransTable& NLSLoCaseMap; extern const _NLSTransTable& NLSInputMap; extern const _NLSTransTable& NLSOutputMap; extern const _NLSTransTable& NLSCollMap; /*****************************************************************************/ /* NLS functions */ /*****************************************************************************/ int NLSSetCountry (unsigned CountryCode); // Set up the NLS system for a new country. This affects the contents of the // NLSData structure above, and the 3 translation tables (UpCase, LoCase, // Coll). NLSCountry reflects the new country code after the call. If there // is no support for the new country found, the call will not change anything. // The old country code is returned if the change has been successfull, if // there is no support for the new country code, the function returns -1. int NLSSetLanguage (unsigned Language); // A new language code is set, the old one is returned. The complete resource // system will search for a resource in the given language, then for a generic // resource, then fall back to an english resource. The function will _not_ // detect if there is no support for the new language. unsigned NLSGetDefaultLanguage (unsigned Country); // Get the default language for the given country inline char NLSUpCase (char C) // Converts the given char to upper case according to the country information // currently set { return NLSUpCaseMap [(unsigned char) C]; } inline char NLSLoCase (char C) // Converts the given char to lower case according to the country information // currently set { return NLSLoCaseMap [(unsigned char) C]; } char* NLSUpStr (char* S); // Converts the given string to upper case according to the country information // currently set. S is returned. char* NLSLoStr (char* S); // Converts the given string to lower case according to the country information // currently set. S is returned. int NLSCmpStr (const char* S1, const char* S2); // Compare both strings according to the local collating sequence. void NLSInit (); // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! /*****************************************************************************/ /* Converting between internal and extern character representation */ /*****************************************************************************/ inline char InputCvt (char C) // Transform the given character C from the local input character set to the // internal used character set { return NLSInputMap [(unsigned char) C]; } char* InputCvt (char* S); // Transform the given string S from the local input character set to the // internal used character set inline char OutputCvt (char C) // Transform the given character C from the internal used character set to the // local output character set { return NLSOutputMap [(unsigned char) C]; } char* OutputCvt (char* S); // Transform the given string S from the internal used character set to the // local output character set // End of NATIONAL.H #endif estic-1.61.orig/spunk/nlsinfo.h0100644000176100001440000000255707031424703016002 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINFO.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Information in this file is used internal by the library. #ifndef _NLSINFO_H #define _NLSINFO_H #include "national.h" /*****************************************************************************/ /* struct _NLSInfo */ /*****************************************************************************/ struct _NLSInfo { _NLSData Data; _NLSTransTable UpCaseMap; _NLSTransTable LoCaseMap; _NLSTransTable CollMap; }; // End of NLSINFO.H #endif estic-1.61.orig/spunk/nullstrm.cc0100644000176100001440000000142207031424703016336 0ustar debacleusers/*****************************************************************************/ /* */ /* NULLSTRM.CC */ /* */ /* (C) 1993 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@moppi.sunflower.sub.org */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "strmable.h" #include "stream.h" #include "nullstrm.h" // Return the data size of an instance u32 GetSize (const Streamable *O) { // Create a null stream NullStream S; // Write the object to the stream S.Put (O); // Current stream position is the size of the object return S.GetPos (); } estic-1.61.orig/spunk/nullstrm.h0100644000176100001440000000307007031424703016201 0ustar debacleusers/*****************************************************************************/ /* */ /* NULLSTRM.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __NULLSTRM_H #define __NULLSTRM_H #include "machine.h" #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* class NullStream */ /*****************************************************************************/ class NullStream : public Stream { protected: u32 CurrentPos; public: NullStream (); virtual u32 GetPos (); virtual void Write (const void* Buf, size_t Count); }; inline NullStream::NullStream (): Stream (), CurrentPos (0) { } inline u32 NullStream::GetPos () { return CurrentPos; } inline void NullStream::Write (const void*, size_t Count) { CurrentPos += Count; } /*****************************************************************************/ /* Outside the classes */ /*****************************************************************************/ u32 GetSize (const Streamable*); // Return the data size of an instance inline u32 GetSize (const Streamable& O) // Return the data size of an instance { return GetSize (&O); } // End of NULLSTRM.H #endif estic-1.61.orig/spunk/object.cc0100644000176100001440000000214407031424703015726 0ustar debacleusers/*****************************************************************************/ /* */ /* OBJECT.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "object.h" /*****************************************************************************/ /* class Object */ /*****************************************************************************/ Object::~Object () { } estic-1.61.orig/spunk/object.h0100644000176100001440000000205007031424703015564 0ustar debacleusers/*****************************************************************************/ /* */ /* OBJECT.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __OBJECT_H #define __OBJECT_H #include /*****************************************************************************/ /* class Object */ /*****************************************************************************/ class Object { private: // Hide the copy constructor and the '=' operator to discourage // creating one instance from another. If needed, you have to override // this. Object (const Object&); Object& operator = (const Object&); public: Object (); virtual ~Object (); }; inline Object::Object () { } // End of OBJECT.H #endif estic-1.61.orig/spunk/palette.cc0100644000176100001440000000614107031424703016117 0ustar debacleusers/*****************************************************************************/ /* */ /* PALETTE.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "palette.h" #include "screen.h" #include "streamid.h" // Register the classes LINK (Palette, ID_Palette); // Instance of class Palette Palette* Pal; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; #endif /*****************************************************************************/ /* class Palette */ /*****************************************************************************/ void Palette::FreeItem (void* Item) { delete [] (unsigned char*) Item; } void* Palette::GetItem (Stream& S) { return (void*) S.ReadStr (); } void Palette::PutItem (Stream& S, void* Item) const { S.WriteStr ((char*) Item); } Palette::Palette () : Collection (10, 5, 1), Debug (0) { } void Palette::Load (Stream& S) { Collection::Load (S); S >> Debug; } void Palette::Store (Stream& S) const { Collection::Store (S); S << Debug; } u16 Palette::StreamableID () const { return ID_Palette; } Streamable *Palette::Build () { return new Palette (Empty); } unsigned Palette::Add (const unsigned char* Mono, const unsigned char* Color) // Function to add a palette entry, returns the palette number { unsigned PalNum = Count / 2; Insert ((unsigned char*) strcpy (new char [strlen ((char*) Mono)+1], (char*) Mono)); Insert ((unsigned char*) strcpy (new char [strlen ((char*) Color)+1], (char*) Color)); return PalNum; } u16 Palette::BuildAttr (unsigned PalNum, unsigned AttrIndex, unsigned char C) // Builds an attribute char from the given palette and index and the given char. { unsigned char *P; if (TheScreen->IsColor () == 0) { // Mono P = At (PalNum * 2); } else { // Color P = At (PalNum * 2 + 1); } if (Debug) { // Slows things down, so check only if Debug set PRECONDITION (AttrIndex < strlen ((char*) P)); } return (u16) ((u16 (P [AttrIndex]) << 8) | u16 (C)); } estic-1.61.orig/spunk/palette.h0100644000176100001440000001023007031424703015753 0ustar debacleusers/*****************************************************************************/ /* */ /* PALETTE.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __PALETTE_H #define __PALETTE_H #include "coll.h" // Instance of class Palette extern class Palette* Pal; /*****************************************************************************/ /* Palette stuff */ /*****************************************************************************/ // Indices into the palette arrays static const atFrameInactive = 0; // passive frame static const atFrameActive = 1; // active frame static const atFrameResizing = 2; // resizing frame static const atTextNormal = 3; // normal text static const atTextInvers = 4; // inverted text static const atTextSelected = 5; // selected static text static const atTextHigh = 6; // selected text (i.e. hotkeys) static const atTextHighInvers = 7; // inverted selected text static const atTextGrayed = 8; // grey (inactive) text static const atTextGrayedInvers = 9; // dito inverted static const atEditNormal = 10; // normal text in an edit window static const atEditHigh = 11; // i.e. left/right arrows static const atEditBar = 12; // scroll bar (use atEditNormal for text) // Palette numbers static const u16 paBlue = 0; // blue palette static const u16 paGray = 1; // grey palette (standard) static const u16 paCyan = 2; // cyan palette static const u16 paRed = 3; // red palette static const u16 paBlack = 4; // black palette static const u16 paError = 5; // errorwindow palette static const u16 paRoot = 6; // root window palette static const u16 paHelp = 7; // help window palette static const u16 paFSel = 8; // file selector palette /*****************************************************************************/ /* class Palette */ /*****************************************************************************/ class Palette: private Collection { protected: virtual void FreeItem (void* Item); virtual void* GetItem (Stream& S); virtual void PutItem (Stream& S, void* Item) const; Palette (StreamableInit); // Build constructor public: i16 Debug; public: Palette (); // Derived from class Streamable virtual void Load (Stream& S); virtual void Store (Stream& S) const; virtual u16 StreamableID () const; static Streamable* Build (); // Function to add a palette entry, returns the palette number unsigned Add (const unsigned char *Mono, const unsigned char *Color); // Functions to build palette entries u16 BuildAttr (unsigned PalNum, unsigned AttrIndex, unsigned char C); static u16 BuildAttr (u16 Attr, unsigned char C); static u16 BuildAttr (unsigned char Attr, unsigned char C = '\0'); }; inline Palette::Palette (StreamableInit) : Collection (Empty) { } inline u16 Palette::BuildAttr (u16 Attr, unsigned char C) // Builds an attribute char with the given attribute char and new char C { return (u16) ((Attr & 0xFF00) | u16 (C)); } inline u16 Palette::BuildAttr (unsigned char Attr, unsigned char C) // Builds an attribute char with the given attribute and char. { return (u16) ((((u16) Attr) << 8) | C); } // End of PALETTE.H #endif estic-1.61.orig/spunk/password.cc0100644000176100001440000005640507031424703016333 0ustar debacleusers/*****************************************************************************/ /* */ /* PASSWORD.CC */ /* */ /* (C) 1994-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "password.h" #include "streamid.h" #include "msgid.h" #include "listbox.h" #include "menue.h" #include "crcstrm.h" #include "memstrm.h" #include "progutil.h" #include "stdmenue.h" #include "stdmsg.h" #include "strcvt.h" #include "menuedit.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msCannotOpenPasswordFile = MSGBASE_PASSWORD + 0; static const u16 msCannotReadPasswordFile = MSGBASE_PASSWORD + 1; static const u16 msCannotWritePasswordFile = MSGBASE_PASSWORD + 2; static const u16 msUserIDEmpty = MSGBASE_PASSWORD + 3; static const u16 msUserNameEmpty = MSGBASE_PASSWORD + 4; static const u16 msPasswordEmpty = MSGBASE_PASSWORD + 5; static const u16 msUserIDExists = MSGBASE_PASSWORD + 6; static const u16 msInvalidLogin = MSGBASE_PASSWORD + 7; /*****************************************************************************/ /* Global data */ /*****************************************************************************/ static String _CUN; extern const String& CUN = _CUN; static String _CUID; extern const String& CUID = _CUID; static u32 _CPL; extern const u32& CPL = _CPL; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; template class ListBox; #endif /*****************************************************************************/ /* class PasswordEntry */ /*****************************************************************************/ class PasswordEntry: public Streamable { friend class PasswordColl; friend class PasswordListBox; friend void Login (const String&, const String&); friend inline void EntryEditor (class PasswordEntry*, int&, int&); // EntryEditor is not inline but static, but this way gcc don't displays // a warning protected: String UserName; String UserID; String Password; u32 Level; void Crypt (); void Decrypt (); PasswordEntry (StreamableInit); public: PasswordEntry (); PasswordEntry (const String& Name, const String& ID, const String& PW, u32 aLevel); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); }; PasswordEntry::PasswordEntry (): Level (0) { } inline PasswordEntry::PasswordEntry (StreamableInit): UserName (Empty), UserID (Empty), Password (Empty) { } PasswordEntry::PasswordEntry (const String& Name, const String& ID, const String& PW, u32 aLevel): UserName (Name), UserID (ID), Password (PW), Level (aLevel) { } void PasswordEntry::Crypt () { UserName.Crypt (); UserID.Crypt (); Password.Crypt (); Level ^= Password.Len (); } void PasswordEntry::Decrypt () { UserName.Decrypt (); UserID.Decrypt (); Password.Decrypt (); Level ^= Password.Len (); } void PasswordEntry::Load (Stream& S) { S >> UserName >> UserID >> Password >> Level; Decrypt (); } void PasswordEntry::Store (Stream& S) const { // Because we crypt and later decrypt *this, we cast away constness... ((PasswordEntry*) this)->Crypt (); S << UserName << UserID << Password << Level; ((PasswordEntry*) this)->Decrypt (); } u16 PasswordEntry::StreamableID () const { return ID_PasswordEntry; } Streamable* PasswordEntry::Build () { return new PasswordEntry (Empty); } /*****************************************************************************/ /* class PWLogEntry */ /*****************************************************************************/ class PWLogEntry: public Streamable { public: enum _What { Login, Logout, Fail }; protected: String UserName; String UserID; u32 Level; Time Now; _What What; void Crypt (); void Decrypt (); PWLogEntry (StreamableInit); // Build constructor public: PWLogEntry (const String& Name, const String& ID, u32 aLevel, _What Action); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); }; PWLogEntry::PWLogEntry (const String& Name, const String& ID, u32 aLevel, _What Action): UserName (Name), UserID (ID), Level (aLevel), What (Action) { } inline PWLogEntry::PWLogEntry (StreamableInit): UserName (Empty), UserID (Empty), Now (Empty) { } void PWLogEntry::Crypt () { UserName.Crypt (); UserID.Crypt (); Level ^= UserID.Len (); } void PWLogEntry::Decrypt () { UserName.Decrypt (); UserID.Decrypt (); Level ^= UserID.Len (); } void PWLogEntry::Load (Stream& S) { u32 Tmp; S >> UserName >> UserID >> Level >> Now >> Tmp; What = (_What) Tmp; Decrypt (); } void PWLogEntry::Store (Stream& S) const { // Because we crypt and later decrypt *this, we cast away constness... ((PWLogEntry*) this)->Crypt (); u32 Tmp = What; S << UserName << UserID << Level << Now << Tmp; ((PWLogEntry*) this)->Decrypt (); } u16 PWLogEntry::StreamableID () const { return ID_PWLogEntry; } Streamable* PWLogEntry::Build () { return new PWLogEntry (Empty); } /*****************************************************************************/ /* class PasswordColl */ /*****************************************************************************/ class PasswordColl: public SortedCollection { protected: // Derived from class Collection virtual void* GetItem (Stream& S); virtual void PutItem (Stream& S, void* Item) const; // Derived from class SortedCollection virtual int Compare (const String* Key1, const String* Key2); virtual const String* KeyOf (const PasswordEntry* Item); PasswordColl (StreamableInit); // Build constructor public: PasswordColl (); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); u32 GetLevel (const String& ID, const String& PW); // Search for ID in the collection and compare the password. Return 0 if // the ID is not found or the password does not match, return the user // level otherwise int UserIDExists (PasswordEntry* Entry); // Check if the user id in Entry exists already in the collection PasswordEntry* Extract (int Index); // Get the entry from the collection and return it. Delete it from the // collection }; PasswordColl::PasswordColl (): SortedCollection (50, 10) { ShouldDelete = 1; } PasswordColl::PasswordColl (StreamableInit): SortedCollection (Empty) // Build constructor { } int PasswordColl::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } const String* PasswordColl::KeyOf (const PasswordEntry* Item) { return &Item->UserID; } u16 PasswordColl::StreamableID () const { return ID_PasswordColl; } Streamable* PasswordColl::Build () { return new PasswordColl (Empty); } void* PasswordColl::GetItem (Stream& S) { return (void*) S.Get (); } void PasswordColl::PutItem (Stream& S, void* Item) const { S.Put ((PasswordEntry*) Item); } u32 PasswordColl::GetLevel (const String& ID, const String& PW) { int Index; if (Search (&ID, Index) == 0) { // Not found, level is zero return 0; } PasswordEntry* Entry = At (Index); return (Entry->Password == PW) ? Entry->Level : 0; } int PasswordColl::UserIDExists (PasswordEntry* Entry) // Check if the user id in Entry exists already in the collection { int Index; return (Search (&Entry->UserID, Index)); } PasswordEntry* PasswordColl::Extract (int Index) // Get the entry from the collection and return it. Delete it from the // collection { // Remember old ShouldDelete value and reset it int OldShouldDelete = ShouldDelete; ShouldDelete = 0; // Get the entry PasswordEntry* Entry = At (Index); // Delete it from the collection AtDelete (Index); // Reset ShouldDelete value ShouldDelete = OldShouldDelete; // Return the extracted PasswordEntry return Entry; } /*****************************************************************************/ /* class PasswordListBox */ /*****************************************************************************/ class PasswordListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: PasswordListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem); }; inline PasswordListBox::PasswordListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem): ListBox (aItemText, aID, aSize, atEditNormal, atEditBar, atEditHigh, NextItem) { } void PasswordListBox::Print (int Index, int X, int Y, u16 Attr) // Display one of the listbox entries { // Zeiger auf den Eintrag holen PasswordEntry* E = Coll->At (Index); // Strings bauen String Password = E->Password; String UserID = E->UserID; String UserName = E->UserName; String Line (" "); Line += UserID.Trunc (14).Pad (String::Right, 17); Line += UserName.Trunc (30).Pad (String::Right, 34); Line += Password.Pad (String::Right, 18); Line += U32Str (E->Level).Pad (String::Left, 4); Owner->Write (X, Y, Line.Pad (String::Right, Size.X), Attr); } /*****************************************************************************/ /* Registering the classes */ /*****************************************************************************/ LINK (PasswordEntry, ID_PasswordEntry); LINK (PWLogEntry, ID_PWLogEntry); LINK (PasswordColl, ID_PasswordColl); /*****************************************************************************/ /* PasswordEditor */ /*****************************************************************************/ static void EntryEditor (PasswordEntry* E, int& Abort, int& Changed) // Allow editing of one password entry { // ID's of the menue items const miUserID = 1; const miUserName = 2; const miPassword = 3; const miLevel = 4; // Remember the crc of the entry u32 OldCRC = GetCRC (E); // Store the old data in a memory stream MemoryStream MS (256); MS << *E; // Load the editor window and register all accel keys Menue* M = (Menue*) LoadResource ("PASSWORD.EntryEditwindow"); M->RegisterItemKeys (); // Set the menue entries M->SetStringValue (miUserID, E->UserID); M->SetStringValue (miUserName, E->UserName); M->SetStringValue (miPassword, E->Password); M->SetLongValue (miLevel, E->Level); // Set a new status line and activate the window PushStatusLine (siAbort | siAccept | siUpDnCR_Select); M->Activate (); // Allow editing int Done = 0; Changed = 0; while (!Done) { switch (M->GetChoice ()) { case 0: // Accept or abort if (M->GetAbortKey () == vkAbort) { // Editing aborted if (GetCRC (E) != OldCRC) { // Entry has been changed if (AskDiscardChanges () == 2) { MS >> *E; Changed = 0; Abort = 1; Done = 1; } } else { Changed = 0; Abort = 1; Done = 1; } } else { // Accept, check if all entries are valid if (E->UserID.IsEmpty ()) { ErrorMsg (msUserIDEmpty); } else if (E->UserName.IsEmpty ()) { ErrorMsg (msUserNameEmpty); } else if (E->Password.IsEmpty ()) { ErrorMsg (msPasswordEmpty); } else { // Entry is valid Changed = (GetCRC (E) != OldCRC); Abort = 0; Done = 1; } } break; case miUserID: E->UserID = M->GetStringValue (miUserID); break; case miUserName: E->UserName = M->GetStringValue (miUserName); break; case miPassword: E->Password = M->GetStringValue (miPassword); break; case miLevel: E->Level = M->GetLongValue (miLevel); break; } } // Delete window and status line M->UnregisterItemKeys (); delete M; PopStatusLine (); } static void PasswordEditor (PasswordColl* PC, int& Abort, int& Changed) // Allow editing of the given password collection { // Create a memory stream and store the old password data MemoryStream MS; MS << *PC; // Store the crc of the collection to determine if any data has changed u32 OldCRC = GetCRC (PC); // Load the editor window and adjust its size to the screen size Menue* M = (Menue*) LoadResource ("PASSWORD.Editorwindow"); Rect WindowSize = M->OuterBounds (); WindowSize.A.Y = 2; WindowSize.B.Y = Background->IYSize () - 2; M->Resize (WindowSize); // Create a listbox and place it in the window PasswordListBox* L = new PasswordListBox ("", 2, Point (WindowSize.XSize (), WindowSize.YSize () - 1), NULL); L->SetColl (PC); L->SetPos (0, 1); M->AddItem (L); L->Select (); // Push a new statusline and activate (show) the window PushStatusLine (siAbort | siAccept | siInsert | siDelete | siChange); M->Activate (); // User loop int Done = 0; Abort = 0; while (!Done) { // Get a key from the user Key K = KbdGet (); // Feed the key to the listbox L->HandleKey (K); // Get the current listbox entry int Current = L->GetSelected (); PasswordEntry* Entry; PasswordEntry* NewEntry; int EAbort; int EChanged; // Look if there's anything left switch (K) { case vkAbort: // Ask if anything has changed if (GetCRC (PC) != OldCRC) { if (AskDiscardChanges () == 2) { // Discard changes, end editing PC->DeleteAll (); MS >> *PC; Changed = 0; Abort = 1; Done = 1; } } else { Changed = 0; Abort = 1; Done = 1; } break; case vkAccept: Changed = (GetCRC (PC) != OldCRC); Abort = 0; Done = 1; break; case kbEnter: // Change an entry if (Current != -1) { // Get the current entry and delete it from the collection Entry = PC->Extract (Current); // Create a duplicate of the entry NewEntry = Duplicate (Entry); EntryEditor (NewEntry, EAbort, EChanged); if (!EAbort && EChanged) { // Check if the user id already exists if (PC->UserIDExists (NewEntry)) { // The id exists, delete the entry ErrorMsg (msUserIDExists); delete NewEntry; PC->Insert (Entry); } else { delete Entry; L->Insert (NewEntry); L->Reset (); } } else { delete NewEntry; PC->Insert (Entry); } } break; case vkIns: // Insert a new entry Entry = new PasswordEntry; EntryEditor (Entry, EAbort, EChanged); if (!EAbort && EChanged) { // Check if the user id already exists if (PC->UserIDExists (Entry)) { // The id exists, delete the entry ErrorMsg (msUserIDExists); delete Entry; } else { // User id is unique, insert it L->Insert (Entry); } } else { // Editing was aborted, delete the entry delete Entry; } break; case vkDel: // Delete the current entry if (Current != -1 && AskAreYouShure () == 2) { L->Delete (Current); } break; } } // The listbox will delete the owned collection if we don't set it to NULL // before deleting the window (including the listbox) L->SetColl (NULL); delete M; // Restore the old status line PopStatusLine (); } static PasswordColl* ReadPasswordFile (const String& Filename) // Read the password file and return the password collection. If there is no // password file, return an empty collection { PasswordColl* PC; // Try to open the file FileStream S (Filename, "rb"); if (S.GetStatus () != stOk) { // new file, create a collection PC = new PasswordColl; } else { // Load a password collection from the stream and check for errors PC = (PasswordColl*) S.Get (); if (!PC || S.GetStatus () != stOk) { ErrorMsg (msCannotReadPasswordFile, Filename.GetStr ()); } } return PC; } void PasswordEditor (const String& Filename) // Loads a password collection from the given file and allows editing users/ // passwords { // Load the password collection from the file PasswordColl* PC = ReadPasswordFile (Filename); // Allow editing int Abort; int Changed; PasswordEditor (PC, Abort, Changed); // If the collection has been changed, store it if (!Abort && Changed) { FileStream S (Filename, "wb"); if (S.GetStatus () != stOk) { ErrorMsg (msCannotOpenPasswordFile, Filename.GetStr ()); return; } S.Truncate (); S.Put (PC); if (S.GetStatus () != stOk) { ErrorMsg (msCannotWritePasswordFile, Filename.GetStr ()); return; } } } /*****************************************************************************/ /* Login/Logout */ /*****************************************************************************/ static void ResetLoginData () // Reset the login data { _CUN = ""; _CUID = ""; _CPL = 0; } static void Log (const String& Logname, const String& Name, const String& ID, u32 Level, PWLogEntry::_What What) { if (Logname.IsEmpty ()) { return; } FileStream S (Logname); S.SeekToEnd (); if (S.GetStatus () == stOk) { PWLogEntry LE (Name, ID, Level, What); S.Put (LE); } } void Login (const String& PWName, const String& Logname) // Ask for user id and password and set the variables CUN CUID and CPL // according to the users password entry. // If Logname is not empty, a binary log of all login attempts is stored there. { int Abort; // Read in the user id Menue* M = (Menue*) LoadResource ("PASSWORD.UserID-Window"); TextEdit* TE = (TextEdit*) M->ForcedItemWithID (1); TE->Edit (Abort); String UserID = TE->GetValue (); delete M; if (Abort) { return; } // Read in the password M = (Menue*) LoadResource ("PASSWORD.Password-Window"); PasswordEdit* PE = (PasswordEdit*) M->ForcedItemWithID (1); PE->Edit (Abort); String Password = PE->GetValue (); delete M; if (Abort) { return; } // Load the password collection from the file PasswordColl* PC = ReadPasswordFile (PWName); // Search for the user id int Index; if (PC->Search (&UserID, Index) == 0 || PC->At (Index)->Password != Password) { // Not found, pop up an error message, reset data ErrorMsg (msInvalidLogin); Log (Logname, "", UserID, 0, PWLogEntry::Fail); ResetLoginData (); return; } else { // Found, set the login data, log the login PasswordEntry* PE = PC->At (Index); _CUN = PE->UserName; _CUID = PE->UserID; _CPL = PE->Level; Log (Logname, CUN, CUID, CPL, PWLogEntry::Login); } } void Logout (const String& Logname) // Reset the user data. If Logname is not empty, a binary log of the // login/logout sequences is kept there. { // First, check if a logout is necessary if (CPL == 0) { return; } // Log the logout if (!Logname.IsEmpty ()) { PWLogEntry LE (CUN, CUID, CPL, PWLogEntry::Logout); FileStream S (Logname); S.Put (LE); } // Reset the data ResetLoginData (); } estic-1.61.orig/spunk/password.h0100644000176100001440000000453307031424703016170 0ustar debacleusers/*****************************************************************************/ /* */ /* PASSWORD.H */ /* */ /* (C) 1994 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __PASSWORD_H #define __PASSWORD_H #include "coll.h" /*****************************************************************************/ /* Global data */ /*****************************************************************************/ extern const String& CUN; // Current user name extern const String& CUID; // Current user id extern const u32& CPL; // Current users security level /*****************************************************************************/ /* PasswordEditor */ /*****************************************************************************/ void PasswordEditor (const String& Filename); // Loads a password collection from the given file and allows editing users/ // passwords /*****************************************************************************/ /* Login/Logout */ /*****************************************************************************/ void Login (const String& PWName, const String& Logname); // Ask for user id and password and set the variables CUN CUID and CPL // according to the users password entry. // If Logname is not empty, a binary log of all login attempts is stored there. void Logout (const String& Logname); // Reset the user data. If Logname is not empty, a binary log of the // login/logout sequences is kept there. // End of PASSWORD.H #endif estic-1.61.orig/spunk/program.cc0100644000176100001440000004516307031424703016137 0ustar debacleusers/*****************************************************************************/ /* */ /* PROGRAM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #if defined(DOS) || defined(DOS32) || defined(OS2) || defined(NT) || defined(NETWARE) # include # include # include # include #else # include #endif #include #include "msgid.h" #include "eventid.h" #include "filesys.h" #include "kbd.h" #include "screen.h" #include "winattr.h" #include "palette.h" #include "environ.h" #include "program.h" #include "national.h" #include "stdmsg.h" #include "filepath.h" #include "wildargs.h" #include "progutil.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msNoHelpAvailable = MSGBASE_PROGRAM + 0; const u16 msNoHelpOnThisTopic = MSGBASE_PROGRAM + 1; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Global visible instance of class Program Program* App; /*****************************************************************************/ /* class Program */ /*****************************************************************************/ Program::Program (int argc, char** argv, TopMenueBar* (*GetMenueBar) (), BottomStatusLine* (*GetStatusLine) (), const String& ProgBaseName): MainResource (NULL), MsgBase (NULL), AppMsgBase (NULL), ProgramName (ProgBaseName), #ifdef NETWARE PID (0), #else PID (getpid ()), #endif GotSigWinCh (0), LastIdleTime (Now ()), StatusLine (NULL), MainMenue (NULL), ArgCount (argc), ArgVec (argv) { // Initialize App pointer App = this; // Actions to be taken if we have an OS/2 or DOS system: #if defined(DOS) || defined(DOS32) || defined(OS2) || defined(NETWARE) // Explode the argv vector ExpandArgs (ArgCount, ArgVec); // Use binary mode as default open mode for files _fmode = O_BINARY; #endif // Define the search path for the resource file #if defined(OS2) String SearchPath = GetEnvVar ("DPATH"); #else String SearchPath = GetEnvVar ("PATH"); #endif // Add the path of the executable to the search path if (ArgVec) { String Path, Name; FSplit (ArgVec [0], Path, Name); if (Path.Len () > 0) { Path = CleanPath (Path); // Make the path absolute DelPathSep (Path); // Remove the trailing path separator Path += FileSysListSep; // Add a file list separator SearchPath = Path + SearchPath; } } // Get the current directory and remove the trailing separator String CurrentDir = GetCurrentDir (); DelPathSep (CurrentDir); // Expand the search path with the current directory SearchPath = CurrentDir + FileSysListSep + SearchPath; // Set up the support path if it is fixed by giving an environment // variable. // The environment variable is created from the program basename in // capital letters with "PATH" added. String EnvPath = ProgBaseName; EnvPath.ToUpper (); EnvPath += "PATH"; SupportPath = GetEnvVar (EnvPath); if (!SupportPath.IsEmpty ()) { // An environment variable has been defined. Use this path as an // additional search path for the resource file SearchPath = SupportPath + FileSysListSep + SearchPath; } #ifdef NETWARE SearchPath += "sys:system;"; // ## #endif // Check if the resource file exists String ResName = ProgBaseName + ".res"; String ResDir = FSearch (SearchPath, ResName, R_OK); // If the resource file exists, open the resource for reading only. If // there is no support path defined (by the environment variable), use the // path of the resource file as support path. if (!ResDir.IsEmpty ()) { // Try to open the file MainResource = new ResourceFile (new FileStream (ResDir + ResName, "rb")); if (MainResource->GetStatus () != reOk) { // Cannot use ErrorMsg here FAIL ("Cannot open resource file"); } // Ok, resource file is open. Eventually use the path as support path if (SupportPath.IsEmpty ()) { SupportPath = ResDir; } } else { String Msg = FormatStr ("Error loading resource file %s", ResName.GetStr ()); FAIL (Msg.GetStr ()); } // The support path is no definitely non empty. Add a path separator to // the support path AddPathSep (SupportPath); // Search for the help file, but don't open it HelpFileName = SupportPath + ProgBaseName + ".hlp"; if (!FExists (HelpFileName, R_OK)) { // File does not exist or is not accessible, clear the name HelpFileName.Clear (); } // Initialize the window attributes InitWinAttr (); // Initialize the national language system NLSInit (); // Create an instance of class Screen to handle screen output // Beware: This must be done before creating the keyboard object, // because in Linux, both interact, and Kbd expects Screen to read // in the termcap entry. TheScreen = new Screen; // Create an instance of class Keyboard to handle keyboard input Kbd = new Keyboard; // Create the root window (void) new RootWindow; // Ok, screen and kbd initialization is complete, grab and replace the // fail vector. Do use an intermediate function for that, since the // menue and statusline are not initialized - this will result in a // crash if some resources are not found and high level functions of // spunk are called. OldFailVec = CheckFailed; CheckFailed = _InitCheckFailed; // Before calling user supplied functions, make shure the programs // message base is loaded if (MsgBase == 0) { MsgBase = (MsgCollection*) LoadResource ("PROGRAM.Messages"); } // Now create the menue bar and the status line if (GetMenueBar != NULL) { MainMenue = GetMenueBar (); if (MainMenue != NULL) { MainMenue->Show (); } } if (GetStatusLine != NULL) { StatusLine = GetStatusLine (); } // Ok, done. Now use the right CheckFailed function CheckFailed = _CheckFailed; } Program::~Program () { // Clean up screen and other stuff Cleanup (); } void Program::Cleanup () // Clean up in the destructor or in a emergeny situation { // Reset the _CheckFailed vector to catch errors in the shutdown phase CheckFailed = OldFailVec; // Delete program objects delete MainResource; MainResource = NULL; delete StatusLine; StatusLine = NULL; delete MainMenue; MainMenue = NULL; delete Background; Background = NULL; delete TheScreen; TheScreen = NULL; delete Kbd; Kbd = NULL; // We do not need the message bases any longer FreeMsgBase (); FreeAppMsgBase (); // Free the window attributes DoneWinAttr (); } Streamable* Program::LoadResource (const String& Name, int MustHave) // Load a resource from the resource file. If MustHave is true, this function // never returns a NULL pointer, it will abort the program if the needed // resource is not found { // Check if a resource exists if (MainResource == NULL) { if (MustHave) { FAIL ("LoadResource called but resource file doesn't exist"); } else { return NULL; } } // Try to find the language specific version of the resource. Build the // name of the language specific version String NewKey = FormatStr ("%03d.%s", NLSLanguage, Name.GetStr ()); // First try to find the language specific version int Index; if ((Index = MainResource->FindKey (NewKey)) == -1) { // Not found. Now try the generic version if ((Index = MainResource->FindKey (Name)) == -1) { // Last resort: Try to find an english version NewKey = FormatStr ("%03d.%s", laEnglish, Name.GetStr ()); Index = MainResource->FindKey (NewKey); } } // Load the resource if the key could be found Streamable* R = (Index != -1)? MainResource->Get (Index) : 0; // Check if we could load the resource if (R == NULL) { // Get a pointer to the resource stream const Stream& S = MainResource->GetStream (); // if (MustHave) { // Check the cause of the error switch (S.GetStatus ()) { case stGetError: // ID not found FAIL (FormatStr ("Resource %s: ID %d not registered", Name.GetStr (), S.GetErrorInfo ()).GetStr ()); default: // Cannot use ErrorMsg here! String Msg (String ("Missing resource: ") + Name); FAIL (Msg.GetStr ()); } } else { // Not found, check the stream status. If the stream status is ok // the resource was not found if (S.GetStatus () != stOk) { String Msg = FormatStr ("Resource %s: Stream error, status = %d", Name.GetStr (), S.GetStatus ()); FAIL (Msg.GetStr ()); } } } // Return a pointer to the resource or NULL return R; } String Program::AppMsgBaseName () // This function builds the name for the application message resource. // The default is to use ProgramName in uppercase, preceeded by a '@' // and with '.Messages' added (e.g. "@RESED.Messages"). { String ResName = '@' + ProgramName; ResName.ToUpper (); return ResName + ".Messages"; } const Msg& Program::LoadMsg (u16 MsgNum) // Load a message from the library message base. Application functions // should use LoadAppMsg instead. If the MsgBase is not already loaded, // this function will load it. { if (MsgBase == NULL) { // MsgBase not loaded, load it now MsgBase = (MsgCollection*) LoadResource ("PROGRAM.Messages"); } // Retrieve the message return MsgBase->GetMsg (MsgNum); } const Msg& Program::LoadAppMsg (u16 MsgNum) // Load a message from the application message base. Library functions // should use LoadMsg instead. If AppMsgBase is not already loaded, // this function will load it. { if (AppMsgBase == NULL) { // AppMsgBase not loaded, load it now AppMsgBase = (MsgCollection*) LoadResource (AppMsgBaseName ()); } // Retrieve the message return AppMsgBase->GetMsg (MsgNum); } void Program::FreeMsgBase () // The library message base will be deleted. This is useful if you are // temporary short on memory. The next call to LoadMsg will reload the // MsgBase, so repeatedly calling this function will slow down the // program. Beware: After calling this function, references to messages // are no longer valid! { delete MsgBase; MsgBase = NULL; } void Program::FreeAppMsgBase () // The application message base will be deleted. This is useful if you are // temporary short on memory. The next call to LoadAppMsg will reload the // AppMsgBase, so repeatedly calling this function will slow down the // program. Beware: After calling this function, references to messages // are no longer valid! { delete AppMsgBase; AppMsgBase = NULL; } void Program::_InitCheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line) // Temporary function that is installed while initializing. It avoids // calling other high level spunk functions since they may not be // initialized. { // Beware: To avoid an endless loop, reset the fail vector! CheckFailed = App->OldFailVec; // Post an appropriate event ::PostEvent (evAbort); // Use cleanup to clear the screen etc. App->Cleanup (); // Now call the old fail vector - this will print a message on stderr // and end the program CheckFailed (Msg, Cond, Code, File, Line); // Safety: Do not return! exit (EXIT_FAILURE); } void Program::_CheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line) // Function that is called if a fatal error occurs. The function simply // calls the virtual function AppError, which can be overridden by derived // classes. After returning from CheckFailed, the screen is cleared and // the program is aborted. { // Beware: To avoid an endless loop, reset the fail vector! CheckFailed = App->OldFailVec; // Post an appropriate event ::PostEvent (evAbort); // Call the virtual function App->AppError (Msg, Cond, Code, File, Line); // Use cleanup to clear the screen etc App->Cleanup (); // Use exit instead of abort. This cleans up any global instances exit (EXIT_FAILURE); } void Program::AppError (const char* Msg, const char* Cond, int Code, const char* File, int Line) // Function that is called from _CheckFailed if a fatal error occurs. { // Create the string String S = FormatStr ("%s%s (= %d)\nfile %s\nline %d", Msg, Cond, Code, File, Line); // place a msg window FatalErrorMsg (S); } void Program::CallHelp (const String& /*HelpTopic*/) // Call the help for a specific topic { if (!HasHelp ()) { ErrorMsg (msNoHelpAvailable); } else { // Temporary - this will hopefully change... ErrorMsg (msNoHelpOnThisTopic); } } int Program::SigUsr3 () // Handle the SIGUSR3 signal. This is used as a replacement for // SIGWINCH under NT. The function will do nothing if not running // under NT. { #ifdef NT // Set the global flag GotSigWinCh = 1; // Signal has been handled... return 1; #else return 0; #endif } int Program::SigWinCh () { // Set the global flag GotSigWinCh = 1; // Signal has been handled... return 1; } void Program::Idle () // This is the idle function of the application class. Default is to // do some housekeeping. This function may be called by anyone // at anytime but it's not guaranteed to be called regularly. { // Handle the SIGWINCH signal under linux if (GotSigWinCh) { // Reset the flag GotSigWinCh = 0; // Change the mode. TheScreen->SetMode (vmAsk); // Now tell all windows that the video resolution has changed Event* E = new Event (evScreenSizeChange); E->Info.O = new Rect (TheScreen->GetSize ()); PostEvent (E); } // Get the system time and check if the time has changed Time Current = Now (); u32 Sec = Current.GetSec (); u32 LastSec = LastIdleTime.GetSec (); // Remember the last update time. Be shure to do this before delivering // evSecondChange and evMinuteChange events in case this function is // called recursively. LastIdleTime = Current; // Post an idle event Event* E = new Event (evIdle); E->Info.O = new Time (Current); PostEvent (E); // If the seconds have changed post another event if (Sec != LastSec) { E = new Event (evSecondChange); E->Info.O = new Time (Current); PostEvent (E); // If the minutes have changed, post a third event if ((Sec % 60) == 0) { E = new Event (evMinuteChange); E->Info.O = new Time (Current); PostEvent (E); } } } void Program::ChangeVideoMode (u16 NewMode) // Change video mode to NewMode. Use the constants from screen.h { // Change only if mode is different to current mode if (NewMode != TheScreen->GetMode ()) { // Change the mode TheScreen->SetMode (NewMode); // Now tell all windows that the video resolution has changed Rect NewSize (0, 0, TheScreen->GetXSize (), TheScreen->GetYSize ()); Background->ChangeScreenSize (NewSize); } } void Program::RedrawScreen () // Redraw the complete screen in case it's garbled { Background->RedrawScreen (); } void Program::PostEvent (Event* E, int ImmediateDelivery) // Post an event to the event queue, then call DeliverEvents. { // Put the event into the queue EvQueue.Put (E, 0); // Deliver events from the queue if requested if (ImmediateDelivery) { DeliverEvents (); } } void Program::DeliverEvents () // Deliver all events currently in the event queue. { // Deliver until queue is empty while (EvQueue.IsEmpty () == 0) { // Retrieve the next event from the queue Event* E = EvQueue.Get (); // Deliver this event, then delete it SendEvent (E); } } void Program::SendEvent (Event* E) // Send the event to all event handlers without going over the event // queue. E is deleted after delivery. Use with care! { // Prepare the event E->Handled = 0; // Get the first node ListNode* Node = EventHandler::EventHandlerList; if (Node) { // Now loop through all event handlers until the root is reached again do { // Deliver the event Node->Contents () -> HandleEvent (*E); // Get the next node Node = Node->Next (); } while (Node != EventHandler::EventHandlerList && E->Handled == 0); } // Event has been delivered (or tried to), delete it delete E; } void Program::RemoveArg (int Index) // Remove the program argument with the given index. The function will // call FAIL if the index is invalid. { // Assure that the index is valid PRECONDITION (Index >= 0 && Index < ArgCount); // Copy the other args down while (++Index <= ArgCount) { // Include the NULL vector ArgVec [Index-1] = ArgVec [Index]; } // We now have one argument less ArgCount--; } estic-1.61.orig/spunk/program.h0100644000176100001440000002116707031424703015777 0ustar debacleusers/*****************************************************************************/ /* */ /* PROGRAM.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _PROGRAM_H #define _PROGRAM_H #include "statline.h" #include "event.h" #include "thread.h" #include "menue.h" #include "msgcoll.h" #include "resource.h" #include "datetime.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Instance of class Program extern class Program *App; /*****************************************************************************/ /* class Program */ /*****************************************************************************/ class Program: public EventHandler, public Thread { private: void (*OldFailVec) (const char*, const char*, int, const char*, int); // Old fail vector static void _CheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line); // Function that is called if a fatal error occurs. The function simply // calls the virtual function AppError, which can be overridden by derived // classes. After returning from CheckFailed, the screen is cleared and // the program is aborted. static void _InitCheckFailed (const char* Msg, const char* Cond, int Code, const char* File, int Line); // Temporary function that is installed while initializing. It avoids // calling other high level spunk functions since they may not be // initialized. protected: ResourceFile* MainResource; MsgCollection* MsgBase; // Messages for the library MsgCollection* AppMsgBase; // Messages for the application String ProgramName; // Base name for the program String SupportPath; // Path for support files String HelpFileName; // Name+path of the help file unsigned PID; // Process ID int GotSigWinCh; // true if a SIGWINCH occured EventQueue EvQueue; // EventQueue Time LastIdleTime; // Time of last update virtual int SigUsr3 (); // Handle the SIGUSR3 signal. This is used as a replacement for // SIGWINCH under NT. The function will do nothing if not running // under NT. virtual int SigWinCh (); // Handle the SIGWINCH signal (Unices only) virtual void Cleanup (); // Clean up in the destructor or in a emergeny situation virtual void AppError (const char* Msg, const char* Cond, int Code, const char* File, int Line); // Function that is called in case of errors. The function is usually // called from _CheckFailed. It should not be called directly because // it does no cleanup and simply returns to the caller after displaying // an error message. virtual String AppMsgBaseName (); // This function builds the name for the application message resource. // The default is to use ProgramName in uppercase, preceeded by a '@' // and with '.Messages' added (e.g. "@RESED.Messages"). virtual void DeliverEvents (); // Deliver all events currently in the event queue. virtual void SendEvent (Event* E); // Send the event to all event handlers without going over the event // queue. E is deleted after delivery. Use with care! public: // Public accessible variables BottomStatusLine* StatusLine; TopMenueBar* MainMenue; int ArgCount; // Expanded argc from main() char** ArgVec; // Expanded argv from main() public: Program (int argc, char** argv, TopMenueBar* (*GetMenueBar) (), BottomStatusLine* (*GetStatusLine) (), const String& ProgBaseName); // Create a program object. argc/argv are the arguments from main. On // OS/2 and DOS systems, they will be expanded, on all systems they end up // in the global accessible variables ArgCount and ArgVec. // GetMenueBar ist a function pointer that is called to create the menue // bar. GetStatusLine is a function pointer that is called to create the // status line. Both may be NULL if no menue bar and/or status line is // needed. Beware: Many functions of the library assume that a statusline // exists! // ProgBaseName is the base name of the program. It is used as basename // for resource and help files and for window titles (if needed). virtual ~Program (); // Destruct a program object Streamable* LoadResource (const String& Name, int MustHave = 1); // Load a program resource from the resource file. The usual language // resolving algorithm is applied. If MustHave is set to 1, the function // will abort the program (via FAIL) if the resource is not available virtual const Msg& LoadMsg (u16 MsgNum); // Load a message from the library message base. Application functions // should use LoadAppMsg instead. If the MsgBase is not already loaded, // this function will load it. virtual const Msg& LoadAppMsg (u16 MsgNum); // Load a message from the application message base. Library functions // should use LoadMsg instead. If AppMsgBase is not already loaded, // this function will load it. virtual void FreeMsgBase (); // The library message base will be deleted. This is useful if you are // temporary short on memory. The next call to LoadMsg will reload the // MsgBase, so repeatedly calling this function will slow down the // program. Beware: After calling this function, references to messages // are no longer valid! virtual void FreeAppMsgBase (); // The application message base will be deleted. This is useful if you are // temporary short on memory. The next call to LoadAppMsg will reload the // AppMsgBase, so repeatedly calling this function will slow down the // program. Beware: After calling this function, references to messages // are no longer valid! virtual void Idle (); // This is the idle function of the application class. Default is to // do some housekeeping. This function may be called by anyone // at anytime but it's not guaranteed to be called regularly. void ChangeVideoMode (u16 NewMode); // Change video mode to NewMode. Use the constants from screen.h void RedrawScreen (); // Redraw the complete screen in case it's garbled unsigned GetPID () const; // Get process ID const String& GetSupportPath () const; // Access the protected variable const String& GetProgName () const; // Return the program base name int HasHelp () const; // Return true if we have help available. This is assumed to be true if // the help file exists and is readable. void CallHelp (const String& HelpTopic); // Call the help with the specified topic virtual void PostEvent (Event* E, int ImmediateDelivery = 1); // Post an event to the event queue, eventually call DeliverEvents. // The event will be deleted after successful delivery. void RemoveArg (int Index); // Remove the program argument with the given index. The function will // call FAIL if the index is invalid. }; inline unsigned Program::GetPID () const { return PID; } inline const String& Program::GetSupportPath () const // Access the protected variable { return SupportPath; } inline const String& Program::GetProgName () const // Access the protected variable { return ProgramName; } inline int Program::HasHelp () const // Return true if we have help available. This is assumed to be true if the // help file exists and is readable. { return HelpFileName.IsEmpty () == 0; } // End of PROGRAM.H #endif estic-1.61.orig/spunk/progutil.cc0100644000176100001440000001212007031424703016320 0ustar debacleusers/*****************************************************************************/ /* */ /* PROGUTIL.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module contains utility functions for message handling. Most of the // functions do nothing but call some other functions. This functions are // easier to use and you need only one include file. #include "kbd.h" #include "program.h" #include "progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ char** GetArgVec () // Get the program arguments { return App->ArgVec; } int GetArgCount () // Get the program argument count { return App->ArgCount; } void RemoveArg (int Index) // Remove the argument with the given index { App->RemoveArg (Index); } void Idle () // Call the applications Idle() method { // No harm done if App does not exist... if (App) { App->Idle (); } } const String& GetProgName () // Return the program base name { return App->GetProgName (); } int HelpAvail () // Calls App->HasHelp, see there { return App->HasHelp (); } void CallHelp (const String& HelpKey) // Calls App->CallHelp, see there { App->CallHelp (HelpKey); } const Msg& LoadMsg (u16 MsgNum) // Calls App->LoadMsg, see there { return App->LoadMsg (MsgNum); } const Msg& LoadAppMsg (u16 MsgNum) // Calls App->LoadAppMsg, see there { return App->LoadAppMsg (MsgNum); } void FreeMsgBase () // Calls App->FreeMsgBase, see there { App->FreeMsgBase (); } void FreeAppMsgBase () // Calls App->FreeAppMsgbase, see there { App->FreeAppMsgBase (); } Streamable* LoadResource (const String& ResName, int MustHave) // Calls App->LoadResource, see there { return App->LoadResource (ResName, MustHave); } void PushStatusLine (const String& NewLine) // Push the new status line { App->StatusLine->Push (NewLine); } void PushStatusLine (u32 StatusFlags) // Push a standard status line described by StatusFlags { App->StatusLine->Push (StatusFlags); } void PopStatusLine () // Pops the next saved status line from the stack { App->StatusLine->Pop (); } void ReplaceStatusLine (const String& NewLine) // Replace the current statusline contents by the given string { App->StatusLine->Replace (NewLine); } void ReplaceStatusLine (u32 NewFlags) // Replace the current statusline contents by the given string { App->StatusLine->Replace (NewFlags); } String CreateStatusLine (u32 StatusFlags) // Create a standard status line string { return StatusLine::CreateLine (StatusFlags); } String GetKeyName (Key K) // Return the name of the given key. { return Kbd->GetKeyName (K); } String GetKeyName2 (Key K) // Return the name of the given key with a '~' before and after it. { return '~' + Kbd->GetKeyName (K) + '~'; } String GetKeyName3 (Key K) // Return the name of the given key with " ~" before, and "~ " after the key // name, ready for a use in the status line. { return " ~" + Kbd->GetKeyName (K) + "~ "; } Key KbdGet () // Get a key from the keyboard. Calls CurThread()->KbdGet { return CurThread () -> KbdGet (); } void KbdPut (Key K) // Put a key back into the keyboard queue. Calls CurThread()->KbdPut (K) { CurThread () -> KbdPut (K); } void RegisterKey (Key K) // Calls CurThread()->RegisterKey() { CurThread () -> RegisterKey (K); } void UnregisterKey (Key K) // Calls CurThread()->UnregisterKey() { CurThread () -> UnregisterKey (K); } int KeyIsRegistered (Key K) // Calls CurThread()->KeyIsRegistered() { return CurThread () -> KeyIsRegistered (K); } void PostEvent (Event* E) // Post an event to the programs event queue and deliver it { App->PostEvent (E); } void PostEvent (unsigned What) // Post an event to the programs event queue and deliver it { App->PostEvent (new Event (What)); } void PostEvent (unsigned What, unsigned long Info) // Post an event to the programs event queue and deliver it { App->PostEvent (new Event (What, Info)); } void PostEvent (unsigned What, void* Info) // Post an event to the programs event queue and deliver it { App->PostEvent (new Event (What, Info)); } void PostEvent (unsigned What, Object* Info) // Post an event to the programs event queue and deliver it { App->PostEvent (new Event (What, Info)); } estic-1.61.orig/spunk/progutil.h0100644000176100001440000000757407031424703016203 0ustar debacleusers/*****************************************************************************/ /* */ /* PROGUTIL.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module contains utility functions for message handling. Most of the // functions do nathing but call some other functions. This functions are // easier to use and you need only one include file. #ifndef __PROGUTIL_H #define __PROGUTIL_H #include "keydef.h" #include "statflag.h" #include "msg.h" #include "event.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ char** GetArgVec (); // Get the program arguments int GetArgCount (); // Get the program argument count void RemoveArg (int Index); // Remove the argument with the given index void Idle (); // Call the applications Idle() method const String& GetProgName (); // Return the program base name int HelpAvail (); // Calls App->HasHelp, see there void CallHelp (const String& HelpKey); // Calls App->CallHelp, see there const Msg& LoadMsg (u16 MsgNum); // Calls App->LoadMsg, see there const Msg& LoadAppMsg (u16 MsgNum); // Calls App->LoadAppMsg, see there void FreeMsgBase (); // Calls App->FreeMsgBase, see there void FreeAppMsgBase (); // Calls App->FreeAppMsgbase, see there Streamable* LoadResource (const String& ResName, int MustHave = 1); // Calls App->LoadResource, see there void PushStatusLine (const String& NewLine); // Push the new status line void PushStatusLine (u32 StatusFlags); // Push a standard status line described by StatusFlags void PopStatusLine (); // Pops the next saved status line from the stack String GetKeyName (Key K); // Return the name of the given key. String GetKeyName2 (Key K); // Return the name of the given key with a '~' before and after it. String GetKeyName3 (Key K); // Return the name of the given key with " ~" before, and "~ " after the key // name, ready for a use in the status line. void ReplaceStatusLine (const String& NewLine); // Replace the current statusline contents by the given string void ReplaceStatusLine (u32 NewFlags); // Replace the current statusline contents by the given string String CreateStatusLine (u32 StatusFlags); // Create a standard status line string Key KbdGet (); // Get a key from the keyboard. Calls CurThread()->KbdGet void KbdPut (Key K); // Put a key back into the keyboard queue. Calls CurThread()->KbdPut (K) void RegisterKey (Key K); // Calls CurThread()->RegisterKey() void UnregisterKey (Key K); // Calls CurThread()->UnregisterKey() int KeyIsRegistered (Key K); // Calls CurThread()->KeyIsRegistered() void PostEvent (Event* E); // Post an event to the programs event queue and deliver it void PostEvent (unsigned What); // Post an event to the programs event queue and deliver it void PostEvent (unsigned What, unsigned long Info); // Post an event to the programs event queue and deliver it void PostEvent (unsigned What, void* Info); // Post an event to the programs event queue and deliver it void PostEvent (unsigned What, Object* Info); // Post an event to the programs event queue and deliver it // End of PROGUTIL.H #endif estic-1.61.orig/spunk/rect.cc0100644000176100001440000000670307031424703015422 0ustar debacleusers/*****************************************************************************/ /* */ /* RECT.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "machine.h" #include "rect.h" /*****************************************************************************/ /* class Point */ /*****************************************************************************/ void Point::Load (Stream& S) { S >> X >> Y; } void Point::Store (Stream& S) const { S << X << Y; } /*****************************************************************************/ /* class Rect */ /*****************************************************************************/ void Rect::Load (Stream& S) { S >> A >> B; } void Rect::Store (Stream& S) const { S << A << B; } int Rect::Contains (const Rect& R) const { return (R.A.X >= A.X && R.A.Y >= A.Y && R.B.X <= B.X && R.B.Y <= B.Y); } void Rect::Move (i16 dX, i16 dY) // Change the position of the rectangle as follows: // A.X += dX; B.X += dX; // A.Y += dY; B.Y += dY; // If one of the resulting values is less than 0, the rectangle is moved // so that this value gets 0. { i16 Min; A.X += dX; B.X += dX; A.Y += dY; B.Y += dY; Min = (A.X < B.X) ? A.X : B.X; if (Min < 0) { A.X -= Min; B.X -= Min; } Min = (A.Y < B.Y) ? A.Y : B.Y; if (Min < 0) { A.Y -= Min; B.Y -= Min; } } void Rect::Center (const Rect& R, u16 Option) { // Calculate Size of surrounding rectangle Point S = Size (); // Center in X if (Option & cfCenterX) { // BC++ issues a warning if the cast to i16 is missing A.X = i16 (R.A.X + ((R.B.X - R.A.X - S.X) / 2)); B.X = i16 (A.X + S.X); } // Center in Y if (Option & cfCenterY) { A.Y = i16 (R.A.Y + ((R.B.Y - R.A.Y - S.Y) / 2)); B.Y = i16 (A.Y + S.Y); } } Rect Intersection (const Rect& R1, const Rect& R2) { return Rect (R1.A.X > R2.A.X ? R1.A.X : R2.A.X, R1.A.Y > R2.A.Y ? R1.A.Y : R2.A.Y, R1.B.X < R2.B.X ? R1.B.X : R2.B.X, R1.B.Y < R2.B.Y ? R1.B.Y : R2.B.Y); } Rect Union (const Rect& R1, const Rect& R2) { return Rect (R1.A.X < R2.A.X ? R1.A.X : R2.A.X, R1.A.Y < R2.A.Y ? R1.A.Y : R2.A.Y, R1.B.X > R2.B.X ? R1.B.X : R2.B.X, R1.B.Y > R2.B.Y ? R1.B.Y : R2.B.Y); } int Rect::OutOfRange (i16 MaxX, i16 MaxY) const { return (A.X < 0 || A.X > MaxX || B.X < 0 || B.X > MaxX || A.Y < 0 || A.Y > MaxY || B.Y < 0 || B.Y > MaxY); } Rect& Rect::operator = (const Rect& R) { A = R.A; B = R.B; return *this; } estic-1.61.orig/spunk/rect.h0100644000176100001440000001414007031424703015256 0ustar debacleusers/*****************************************************************************/ /* */ /* RECT.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _RECT_H #define _RECT_H #include "machine.h" #include "stream.h" // flags for centering a rect object static const u16 cfCenterX = 0x0001; // center in X direction static const u16 cfCenterY = 0x0002; // center in Y direction static const u16 cfCenterAll = 0x0003; // center in both directions /*****************************************************************************/ /* class Point */ /*****************************************************************************/ // a point in nowhere class Point: public Streamable { public: i16 X, Y; Point (); Point (i16 A, i16 B); Point (const Point& P); virtual void Load (Stream&); virtual void Store (Stream&) const; Point& operator = (const Point& P); Point& operator += (const Point& P); Point& operator -= (const Point& P); friend inline Point operator + (const Point& P1, const Point& P2); friend inline Point operator - (const Point& P1, const Point& P2); friend inline int operator == (const Point& P1, const Point& P2); friend inline int operator != (const Point& P1, const Point& P2); }; inline Point::Point () { } inline Point::Point (i16 A, i16 B) : X (A), Y (B) { } inline Point::Point (const Point& P): X (P.X), Y (P.Y) { } inline Point& Point::operator = (const Point& P) { X = P.X; Y = P.Y; return *this; } inline Point& Point::operator += (const Point& P) { X += P.X; Y += P.Y; return *this; } inline Point& Point::operator -= (const Point& P) { X -= P.X; Y -= P.Y; return *this; } inline Point operator + (const Point& P1, const Point& P2) { return Point (i16 (P1.X + P2.X), i16 (P1.Y + P2.Y)); } inline Point operator - (const Point& P1, const Point& P2) { return Point (i16 (P1.X - P2.X), i16 (P1.Y - P2.Y)); } inline int operator == (const Point& P1, const Point& P2) { return (P1.X == P2.X && P1.Y == P2.Y); } inline int operator != (const Point& P1, const Point& P2) { return (P1.X != P2.X || P1.Y != P2.Y); } /*****************************************************************************/ /* class Rect */ /*****************************************************************************/ // A rectangle. FYI: all elements of a struct are public by default class Rect: public Streamable { public: Point A; // upper left corner Point B; // lower right corner // constructors Rect (); Rect (const Point& Origin, const Point& Size); Rect (i16 X1, i16 Y1, i16 X2, i16 Y2); Rect (const Rect& R); // Stream stuff virtual void Load (Stream&); virtual void Store (Stream&) const; // methods void Assign (i16 X1, i16 Y1, i16 X2, i16 Y2); void Assign (const Point& Origin, const Point& Size); void Move (i16 dX, i16 dY); void Grow (i16 dX, i16 dY); Point Size () const; int XSize () const; int YSize () const; unsigned long Chars () const; int Contains (const Point& P) const; int Contains (const Rect& R) const; int IsEmpty () const; int OutOfRange (i16 MaxX, i16 MaxY) const; void Center (const Rect& R, u16 Option); Rect& operator = (const Rect& R); friend Rect Intersection (const Rect& R1, const Rect& R2); friend Rect Union (const Rect& R1, const Rect& R2); friend inline int operator == (const Rect& R1, const Rect& R2); friend inline int operator != (const Rect& R1, const Rect& R2); }; inline Rect::Rect () { } inline Rect::Rect (const Point& Origin, const Point& Size) : A (Origin.X, Origin.Y), B (i16 (Origin.X + Size.X), i16 (Origin.Y + Size.Y)) { } inline Rect::Rect (i16 X1, i16 Y1, i16 X2, i16 Y2) : A (X1, Y1), B (X2, Y2) { } inline Rect::Rect (const Rect& R): A (R.A), B (R.B) { } inline void Rect::Assign (const Point& Origin, const Point& Size) { A.X = Origin.X; B.X = i16 (Origin.X + Size.X); A.Y = Origin.Y; B.Y = i16 (Origin.Y + Size.Y); } inline void Rect::Assign (i16 X1, i16 Y1, i16 X2, i16 Y2) { A.X = X1; A.Y = Y1; B.X = X2; B.Y = Y2; } inline int Rect::XSize () const { return B.X - A.X; } inline int Rect::YSize () const { return B.Y - A.Y; } inline Point Rect::Size () const { return Point ((u16) XSize (), (u16) YSize ()); } inline unsigned long Rect::Chars () const { return ( (unsigned long) (B.X - A.X) * (unsigned long) (B.Y - A.Y) ); } inline int Rect::Contains (const Point& P) const { return (P.X >= A.X && P.X < B.X && P.Y >= A.Y && P.Y < B.Y); } inline int operator == (const Rect& R1, const Rect& R2) { return (R1.A.X == R2.A.X && R1.A.Y == R2.A.Y && R1.B.X == R2.B.X && R1.B.Y == R2.B.Y); } inline int operator != (const Rect& R1, const Rect& R2) { return (R1.A.X != R2.A.X || R1.A.Y != R2.A.Y || R1.B.X != R2.B.X || R1.B.Y != R2.B.Y); } inline int Rect::IsEmpty () const { return (A.X >= B.X || A.Y >= B.Y); } inline void Rect::Grow (i16 dX, i16 dY) // Change the size of the rectangle as follows: // A.X -= dX; B.X += dX; // A.Y -= dY; B.Y += dY; { A.X -= dX; B.X += dX; A.Y -= dY; B.Y += dY; } // End of RECT.H #endif estic-1.61.orig/spunk/rescoll.cc0100644000176100001440000000470007031424704016124 0ustar debacleusers/*****************************************************************************/ /* */ /* RESCOLL.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" #include "stream.h" #include "rescoll.h" #include "streamid.h" // Register classes LINK (ResourceIndex, ID_ResourceIndex); LINK (ResourceCollection, ID_ResourceCollection); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class ResourceIndex */ /*****************************************************************************/ ResourceIndex::ResourceIndex (StreamableInit) : Name (Empty) { } void ResourceIndex::Load (Stream& S) { S >> Name >> Offset >> Size; } void ResourceIndex::Store (Stream& S) const { S << Name << Offset << Size; } u16 ResourceIndex::StreamableID () const { return ID_ResourceIndex; } Streamable* ResourceIndex::Build () { return new ResourceIndex (Empty); } /*****************************************************************************/ /* class ResourceCollection */ /*****************************************************************************/ ResourceCollection::ResourceCollection (StreamableInit X) : SortedCollection (X) { } u16 ResourceCollection::StreamableID () const { return ID_ResourceCollection; } Streamable* ResourceCollection::Build () { return new ResourceCollection (Empty); } void* ResourceCollection::GetItem (Stream &S) { return (void*) S.Get (); } void ResourceCollection::PutItem (Stream& S, void* O) const { S.Put ((ResourceIndex*) O); } int ResourceCollection::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } const String* ResourceCollection::KeyOf (const ResourceIndex* Item) { return &Item->Name; } estic-1.61.orig/spunk/rescoll.h0100644000176100001440000000560607031424704015774 0ustar debacleusers/*****************************************************************************/ /* */ /* RESCOLL.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _RESCOLL_H #define _RESCOLL_H #include "strmable.h" #include "stream.h" #include "str.h" #include "strcoll.h" /*****************************************************************************/ /* class ResourceIndex */ /*****************************************************************************/ class ResourceIndex : public Streamable { friend class ResourceCollection; friend class ResourceFile; private: String Name; u32 Offset; u32 Size; protected: ResourceIndex (StreamableInit X); // Build constructor public: ResourceIndex (const String & aName); // Derived from class Streamable. virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // New functions const String& GetName () const; }; inline ResourceIndex::ResourceIndex (const String& aName) : Name (aName) { } inline const String& ResourceIndex::GetName () const { return Name; } /*****************************************************************************/ /* class ResourceCollection */ /*****************************************************************************/ class ResourceCollection: public SortedCollection { protected: // Derived from class Collection virtual void* GetItem (Stream& S); virtual void PutItem (Stream& S, void* Item) const; // Derived from class SortedCollection virtual int Compare (const String* Key1, const String* Key2); virtual const String* KeyOf (const ResourceIndex* Item); public: ResourceCollection (StreamableInit X); ResourceCollection (int aLimit, int aDelta); // Derived from class Streamable virtual u16 StreamableID () const; static Streamable * Build (); }; inline ResourceCollection::ResourceCollection (int aLimit, int aDelta) : SortedCollection (aLimit, aDelta, 1) { } // End of RESCOLL.H #endif estic-1.61.orig/spunk/resed.cc0100644000176100001440000005531207031424704015570 0ustar debacleusers/*****************************************************************************/ /* */ /* RESED.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "resed.h" #include "screen.h" #include "filepath.h" #include "progutil.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListBox; #endif /*****************************************************************************/ /* class ResourceListBox */ /*****************************************************************************/ class ResourceListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: ResourceListBox (i16 aID, const Point & aSize, WindowItem *NextItem); }; ResourceListBox::ResourceListBox (i16 aID, const Point & aSize, WindowItem * NextItem) : ListBox ("", aID, aSize, NextItem) { } void ResourceListBox::Print (int Index, int X, int Y, u16 Attr) { ResourceIndex *P = Coll->At (Index); String S (P->GetName ()); S.Ins (0, ' '); S.Pad (String::Right, Size.X, ' '); Owner->Write (X, Y, S, Attr); } /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ ResEditApp::ResEditApp (int argc, char** argv): Program (argc, argv, CreateMenueBar, CreateStatusLine, "resed"), ResFile (NULL), Res (NULL), ResChanged (0), ResID (0) { // If a filename was given, load that file if (ArgCount > 1) { ResFileName = ArgVec [1]; AddDefaultExtension (ResFileName, ".res"); OpenResourceFile (ResFileName); } } void ResEditApp::ReadResource (const String& Name) { // Allow saving if the current resource has changed if (!SaveResource ()) { return; } // Remember the new resource name ResName = Name; // Try to load the resource Streamable* NewRes = LoadRes (ResName); // Check if the load has been successful if (!NewRes) { return; } // Delete the old and assign the new resource AssignRes (NewRes); // If possible, edit the loaded resource EditResource (); } void ResEditApp::WriteResource (const String & Name) { // save the resource ResFile->Put (Res, Name); // Safety: Flush the resource file (writing out index and header). If // anything goes wrong, the chance of an uncorrupted resource file is // higher this way... ResFile->Flush (); } Streamable* ResEditApp::LoadRes (const String& Name) // Load the resource with the given namen from the resource file. Return // a NULL pointer in case of errors. { // Try to load the resource Streamable* Res = ResFile->Get (Name); // Check if the load has been successful if (Res == 0) { ErrorMsg (String ("\"") + Name + String ("\" not found")); } // Return the result return Res; } String ResEditApp::ChooseRes () // Choose a resource from the file and return it's name. The function // returns the empty string on a user abort. { // The name of the resource String Name; // Check if any resources are available if (ResFile == 0) { ErrorMsg ("No resource file - cannot load resource"); return Name; } if (ResFile->GetCount () == 0) { ErrorMsg (ResFileName + " is empty"); return Name; } // Make a window not covering the menuebar and the statusline Rect WinBounds (Background->OuterBounds ()); WinBounds.A.Y = 1; WinBounds.B.Y--; // create an empty listbox Point BoxSize (WinBounds.XSize () - 2, WinBounds.YSize () - 2); ResourceListBox* R = new ResourceListBox (1, BoxSize, NULL); // Assign the collection for the listbox R->SetColl (ResFile->GetIndex ()); // Create the window and set the header ItemWindow *Win = new ItemWindow (WinBounds, wfFramed, paBlack, 0, R); Win->SetHeader (" Contents of " + ResFileName + ' '); // Make a statusline and activate the window StatusLine->Push (siEsc_Abort | siDel_Delete); Win->Activate (); // Ask for the keys and handle them Key K; int Done = 0; while (!Done) { K = KbdGet (); R->HandleKey (K); switch (K) { case vkAbort: Done = 1; break; case vkDel: if (R->GetSelected () >= 0 && AskAreYouShure () == 2) { ResFile->Delete (ResFile->KeyAt (R->GetSelected ())); R->Reset (); R->Draw (); } break; case vkAccept: case kbEnter: if (R->GetSelected () >= 0) { Name = ResFile->KeyAt (R->GetSelected ()); Done = 1; } break; } } // Take the collection from the listbox R->SetColl (NULL); // Delete the window including the listbox delete Win; // Restore the old status line StatusLine->Pop (); // Return the result return Name; } void ResEditApp::Read () { // Choose the resource String ResName = ChooseRes (); // Use the new resource if (!ResName.IsEmpty ()) { ReadResource (ResName); } } void ResEditApp::Write () { int Abort; NamePrompt (" Resource name", ResName, Abort); if (!Abort) { WriteResource (ResName); ResChanged = 0; } } void ResEditApp::New () // Create a new resource { GenericMenue* M; // Allow a save if the resource has changed if (!SaveResource ()) { return; } switch (SimpleMenue ("New Resource", "@TopMenueBar\n@Menue\nMsg@Collection")) { case 0: // Aborted return; case 1: // TopMenueBar M = new TopMenueBar (NULL); M->MoveAbs (Point (0, 1)); // Otherwise editing difficult AssignRes (M); return; case 2: // Menue M = new Menue (Point (10, 10), "", NULL); M->Resize (Rect (10, 10, 20, 15)); M->Show (); AssignRes (M); break; case 3: // MsgColl AssignRes (new MsgCollection (20, 10)); EditResource (); break; } } void ResEditApp::GetEvent () { // Call derived function Program::GetEvent (); // Add free heap count to the menueline #if defined(DOS) && defined(__BORLANDC__) MainMenue->CWrite (MainMenue->MaxX () - 21, 0, FormatStr ("Core left: %8d", coreleft())); #endif } static MenueBarItem* GetMenueBarItem (char* ItemText, i16 ItemID, WindowItem* MenueList, WindowItem* NextItem) { return new MenueBarItem (ItemText, ItemID, MenueList, NextItem); } static SubMenueItem* GetSubMenueItem (char* ItemText, i16 ItemID, WindowItem* MenueList, WindowItem* NextItem) { return new SubMenueItem (ItemText, ItemID, MenueList, NextItem); } static MenueItem* GetMenueItem (char* ItemText, i16 ItemID, Key AccelKey, WindowItem* NextItem) { return (MenueItem*) SetAccelKey (new MenueItem (ItemText, ItemID, NextItem), AccelKey); } static MenueLine* GetMenueLine (WindowItem* NextItem) { return new MenueLine (miNone, NextItem); } TopMenueBar* ResEditApp::CreateMenueBar () { TopMenueBar* M = new TopMenueBar ( GetMenueBarItem ("@Resed", miSystem, GetMenueItem ("@About", miAbout, kbNoKey, GetMenueLine ( GetMenueItem ("@Quit", miQuit, vkQuit, NULL ))), GetMenueBarItem ("@File", miFile, GetMenueItem ("@Open resourcefile", miOpen, kbNoKey, GetMenueItem ("@Close resourcefile", miClose, kbNoKey, GetMenueItem ("P@ack resourcefile", miPack, kbNoKey, GetMenueLine ( GetMenueItem ("@Read resource", miRead, vkOpen, GetMenueItem ("@Write resource", miWrite, vkSave, GetMenueItem ("@Print resource", miPrint, kbNoKey, GetMenueItem ("@New resource", miNew, kbNoKey, GetMenueLine ( GetMenueItem ("Add @datafile", miAddData, kbNoKey, GetMenueItem ("Add @stream", miAddStream, kbNoKey, GetMenueItem ("@Merge resourcefile", miMerge, kbNoKey, NULL )))))))))))), GetMenueBarItem ("@Window", miWindow, GetMenueItem ("@Header", miHeader, kbNoKey, GetMenueItem ("@Footer", miFooter, kbNoKey, GetMenueItem ("@Color", miColor, kbNoKey, GetMenueItem ("@Background", miBackgroundChar, kbNoKey, GetMenueItem ("@Size/Move", miSize, kbMetaS, GetMenueItem ("@Number", miNumber, kbNoKey, GetSubMenueItem ("F@lags", miFlags, new NoYesItem ("Can @move", miCanMove, new NoYesItem ("Can @resize", miCanResize, new NoYesItem ("@Ignore accept key", miIgnoreAccept, new NoYesItem ("@Modal", miModal, new NoYesItem ("@LR link", miLRLink, new NoYesItem ("Save @visible", miVisible, new OffOnItem ("Center@X", miCenterX, new OffOnItem ("Center@Y", miCenterY, NULL )))))))), GetMenueLine ( GetMenueItem ("@Test", miTest, kbMetaT, NULL ))))))))), GetMenueBarItem ("@Items", miItems, GetSubMenueItem ("@Add", miAddItem, GetMenueItem ("@WindowItem", miAddWindowItem, kbNoKey, GetMenueItem ("@TextItem", miAddTextItem, kbNoKey, GetMenueItem ("Item@Label", miAddItemLabel, kbNoKey, GetMenueItem ("Menue@Line", miAddMenueLine, kbNoKey, GetSubMenueItem ("Menue@Items", miAddMenueItems, GetMenueItem ("@MenueItem", miAddMenueItem, kbNoKey, GetMenueItem ("S@ubMenueItem", miAddSubMenueItem, kbNoKey, GetMenueItem ("Menue@BarItem", miAddMenueBarItem, kbNoKey, GetMenueItem ("@FloatItem", miAddFloatItem, kbNoKey, GetMenueItem ("E@xpFloatItem", miAddExpFloatItem, kbNoKey, GetMenueItem ("@LongItem", miAddLongItem, kbNoKey, GetMenueItem ("@HexItem", miAddHexItem, kbNoKey, GetMenueItem ("@DateItem", miAddDateItem, kbNoKey, GetMenueItem ("@TimeItem", miAddTimeItem, kbNoKey, GetMenueItem ("@StringItem", miAddStringItem, kbNoKey, GetMenueItem ("@RStringItem", miAddRStringItem, kbNoKey, GetMenueItem ("T@oggleItem", miAddToggleItem, kbNoKey, GetMenueItem ("@OffOnItem", miAddOnOffItem, kbNoKey, GetMenueItem ("@NoYesItem", miAddNoYesItem, kbNoKey, NULL )))))))))))))), GetSubMenueItem ("Menue@Edits", miAddMenueEdits, GetMenueItem ("@EditLine", miAddEditLine, kbNoKey, GetMenueItem ("@TextEdit", miAddTextEdit, kbNoKey, GetMenueItem ("@FloatEdit", miAddFloatEdit, kbNoKey, GetMenueItem ("E@xpFloatEdit", miAddExpFloatEdit, kbNoKey, GetMenueItem ("@LongEdit", miAddLongEdit, kbNoKey, GetMenueItem ("@HexEdit", miAddHexEdit, kbNoKey, GetMenueItem ("@DateEdit", miAddDateEdit, kbNoKey, GetMenueItem ("T@imeEdit", miAddTimeEdit, kbNoKey, GetMenueItem ("@PasswordEdit", miAddPasswordEdit, kbNoKey, GetMenueItem ("Fi@leEdit", miAddFileEdit, kbNoKey, NULL )))))))))), NULL )))))), GetMenueItem ("@Delete", miDelete, kbNoKey, GetMenueItem ("@Copy", miCopy, kbNoKey, GetMenueItem ("@Edit", miEdit, kbMetaM, GetMenueItem ("Move A@rea", miMoveArea, kbMetaR, GetMenueItem ("@Order", miOrder, kbNoKey, NULL )))))), GetMenueBarItem ("@Edit", miEditActions, GetMenueItem ("@Go", miEditResource, kbMetaG, GetMenueItem ("@Merge message file", miMergeMsgText, kbNoKey, NULL )), GetMenueBarItem ("@Options", miOptions, GetSubMenueItem ("@VideoMode", miMode, GetMenueItem ("@Mono", miMono, kbNoKey, GetMenueItem ("@Color", mi80x25, kbNoKey, GetMenueItem ("Color 80x@30", mi80x30, kbNoKey, GetMenueItem ("Color 80x3@4", mi80x34, kbNoKey, GetMenueItem ("Color @94x34", mi94x34, kbNoKey, GetMenueItem ("@100x40 (ET4000)", mi2A, kbNoKey, NULL )))))), NULL ), NULL ))))))); // Gray currently unused items M->GrayItem (miClose); M->GrayItem (miPack); M->GrayItem (miRead); M->GrayItem (miWrite); M->GrayItem (miPrint); M->GrayItem (miWindow); M->GrayItem (miItems); M->GrayItem (miEditActions); M->GrayItem (miAddStream); M->GrayItem (miAddData); M->GrayItem (miMerge); // Return the result return M; } BottomStatusLine* ResEditApp::CreateStatusLine () { return new BottomStatusLine (siAltX_Exit); } int ResEditApp::Run () { MainMenue->Activate (); while (!Quitting ()) { switch (MainMenue->GetChoice ()) { case miAbout: InformationMsg ("\n" "\x01Resource Editor\n" "\n" "\x01(C) 1994 Ullrich von Bassewitz\n" "\n"); break; case miQuit: if (AskReallyQuit () == 2) { // Allow saving resource if (SaveResource ()) { Quit = 1; } } break; case miOpen: Open (); break; case miClose: Close (); break; case miPack: Pack (); break; case miRead: Read (); break; case miWrite: Write (); break; case miPrint: Print (); break; case miNew: New (); break; case miAddData: AddData (); break; case miAddStream: AddStream (); break; case miMerge: Merge (); break; case miHeader: Header (); break; case miFooter: Footer (); break; case miSize: Size (); break; case miColor: Color (); break; case miBackgroundChar: BackgroundChar (); break; case miNumber: Number (); break; case miCanMove: CanMove (0); break; case miCanMove+1: CanMove (1); break; case miCanResize: CanResize (0); break; case miCanResize+1: CanResize (1); break; case miIgnoreAccept: IgnoreAccept (0); break; case miIgnoreAccept+1: IgnoreAccept (1); break; case miModal: Modal (0); break; case miModal+1: Modal (1); break; case miLRLink: LRLink (0); break; case miLRLink+1: LRLink (1); break; case miCenterX: CenterX (0); break; case miCenterX+1: CenterX (1); break; case miCenterY: CenterY (0); break; case miCenterY+1: CenterY (1); break; case miTest: Test (); break; case miAddWindowItem: AddWindowItem (); break; case miAddTextItem: AddTextItem (); break; case miAddItemLabel: AddItemLabel (); break; case miAddMenueItem: AddMenueItem (); break; case miAddSubMenueItem: AddSubMenueItem (); break; case miAddMenueBarItem: AddMenueBarItem (); break; case miAddFloatItem: AddFloatItem (); break; case miAddExpFloatItem: AddExpFloatItem (); break; case miAddLongItem: AddLongItem (); break; case miAddHexItem: AddHexItem (); break; case miAddStringItem: AddStringItem (); break; case miAddRStringItem: AddRStringItem (); break; case miAddToggleItem: AddToggleItem (); break; case miAddOnOffItem: AddOffOnItem (); break; case miAddNoYesItem: AddNoYesItem (); break; case miAddDateItem: AddDateItem (); break; case miAddTimeItem: AddTimeItem (); break; case miAddEditLine: AddEditLine (); break; case miAddFloatEdit: AddFloatEdit (); break; case miAddExpFloatEdit: AddExpFloatEdit (); break; case miAddLongEdit: AddLongEdit (); break; case miAddHexEdit: AddHexEdit (); break; case miAddPasswordEdit: AddPasswordEdit (); break; case miAddFileEdit: AddFileEdit (); break; case miAddDateEdit: AddDateEdit (); break; case miAddTimeEdit: AddTimeEdit (); break; case miAddTextEdit: AddTextEdit (); break; case miAddListBox: break; case miAddFloatListBox: break; case miAddMenueLine: AddMenueLine (); break; case miDelete: Delete (); break; case miCopy: Copy (); break; case miEdit: Edit (); break; case miMoveArea: MoveArea (); break; case miOrder: Order (); break; case miVisible: Visible (0); break; case miVisible+1: Visible (1); break; case miMono: ChangeVideoMode (vmMono); break; case mi80x25: ChangeVideoMode (vmCO80); break; case mi80x30: ChangeVideoMode (vmVGA_80x30); break; case mi80x34: ChangeVideoMode (vmVGA_80x34); break; case mi94x34: ChangeVideoMode (vmVGA_94x34); break; case mi2A: ChangeVideoMode (vmET4_100x40); break; case miEditResource: EditResource (); break; case miMergeMsgText: MergeMsgText (); break; } } // Delete the current resource DeleteRes (); // Close the resource file CloseResourceFile (); return 0; } int main (int argc, char* argv []) { ResEditApp MyApp (argc, argv); return MyApp.Run (); } estic-1.61.orig/spunk/resed.h0100644000176100001440000002355707031424704015440 0ustar debacleusers/*****************************************************************************/ /* */ /* RESED.H */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _RESED_H #define _RESED_H #if defined(DOS) && defined(__BORLANDC__) #include #endif #include #include "strcoll.h" #include "msgcoll.h" #include "resource.h" #include "statline.h" #include "menue.h" #include "menuitem.h" #include "program.h" #include "stdmenue.h" #include "stdmsg.h" #include "menuedit.h" #include "listbox.h" #include "streamid.h" /*****************************************************************************/ /* Menue constants */ /*****************************************************************************/ const i16 miNone = 1; const i16 miSystem = 1000; const i16 miAbout = 1100; const i16 miQuit = 1200; const i16 miFile = 2000; const i16 miOpen = 2100; const i16 miClose = 2200; const i16 miPack = 2300; const i16 miRead = 2400; const i16 miWrite = 2500; const i16 miPrint = 2600; const i16 miNew = 2700; const i16 miAddData = 2800; const i16 miAddStream = 2900; const i16 miMerge = 3100; const i16 miWindow = 4000; const i16 miHeader = 4100; const i16 miFooter = 4200; const i16 miSize = 4300; const i16 miColor = 4400; const i16 miBackgroundChar = 4500; const i16 miNumber = 4600; const i16 miFlags = 4700; const i16 miCanMove = 4710; const i16 miCanResize = 4720; const i16 miIgnoreAccept = 4730; const i16 miModal = 4740; const i16 miCenterX = 4750; const i16 miCenterY = 4760; const i16 miLRLink = 4770; const i16 miTest = 4800; const i16 miItems = 5000; const i16 miAddItem = 5100; const i16 miAddWindowItem = 5110; const i16 miAddTextItem = 5112; const i16 miAddItemLabel = 5115; const i16 miAddMenueItems = 5120; const i16 miAddMenueItem = 5121; const i16 miAddSubMenueItem = 5122; const i16 miAddMenueBarItem = 5123; const i16 miAddFloatItem = 5124; const i16 miAddExpFloatItem = 5125; const i16 miAddLongItem = 5126; const i16 miAddHexItem = 5127; const i16 miAddStringItem = 5128; const i16 miAddRStringItem = 5129; const i16 miAddToggleItem = 5130; const i16 miAddOnOffItem = 5131; const i16 miAddNoYesItem = 5132; const i16 miAddDateItem = 5133; const i16 miAddTimeItem = 5134; const i16 miAddMenueEdits = 5140; const i16 miAddEditLine = 5141; const i16 miAddFloatEdit = 5142; const i16 miAddExpFloatEdit = 5143; const i16 miAddLongEdit = 5144; const i16 miAddHexEdit = 5145; const i16 miAddPasswordEdit = 5146; const i16 miAddFileEdit = 5147; const i16 miAddDateEdit = 5148; const i16 miAddTimeEdit = 5149; const i16 miAddTextEdit = 5150; const i16 miAddListBox = 5160; const i16 miAddFloatListBox = 5161; const i16 miAddMenueLine = 5170; const i16 miDelete = 5300; const i16 miCopy = 5400; const i16 miEdit = 5500; const i16 miMoveArea = 5600; const i16 miOrder = 5700; const i16 miOptions = 7000; const i16 miVisible = 7100; const i16 miMode = 7200; const i16 miMono = 7210; const i16 mi80x25 = 7220; const i16 mi80x30 = 7230; const i16 mi80x34 = 7240; const i16 mi94x34 = 7250; const i16 mi2A = 7260; const i16 miEditActions = 8000; const i16 miEditResource = 8100; const i16 miMergeMsgText = 8200; /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ class ResEditApp: public Program { ResourceFile* ResFile; String ResFileName; Streamable* Res; String ResName; int ResChanged; u16 ResID; private: static int PrintOneItem (ListNode* Node, void* _F); // Print the data of one menue item static int PrintOneMsg (Msg* M, void* _F); // Print one message from a message collection protected: virtual void GetEvent (); // void CloseResourceFile (); void OpenResourceFile (const String & Name); void ReadResource (const String &Name); void WriteResource (const String &Name); int SaveResource (); void NamePrompt (const String &Name, String &Val, int &Abort); void FloatPrompt (const String& Text, double& Val, double Min, double Max, int& Abort); void LongPrompt (const String& Text, i32& Val, i32 Min, i32 Max, int& Abort); void IDPrompt (i16& ID, int& Abort); void EditIDPrompt (i16& ID, int& Abort); void MinMaxPrompt (i32& Min, i32& Max, i32 MinVal, i32 MaxVal, int& Abort); void ResEditApp::FMinMaxPrompt (double& Min, double& Max, double MinVal, double MaxVal, int& Abort); void TextIDPrompt (String& Text, i16& ID, int& Abort); void DeleteRes (); void AssignRes (Streamable *); WindowItem * ChooseItem (); i16 NextID (i16 StartID = 1); i16 SearchItemYPos (); i16 SearchItemXPos (); int SearchMsgID (MsgCollection *M, u16 StartNum = 0); void AddItem (WindowItem *Item); void EditMsgCollection (); void PrintMsgCollection (FILE* F); void PrintMenue (FILE* F); void MoveResizeInside (Window* W, GenericMenue* M, int Resize, int& Abort); String GetItemText (WindowItem* Item); // Extract and return the text of a window item. void SetItemText (WindowItem* Item, String NewText); // Set the new item text, handle @ as the hotkey position. unsigned GetItemState (WindowItem* Item); // Extract and return the item state 0..2 void SetItemState (WindowItem* Item, unsigned State); // Set the state according to the state given (0..2) String GetCharSetString (WindowItem* I); // Get a character set from a window item as a string void SetCharSetString (WindowItem* I, String Set); // Set a character set of a window item from a string const CharSet& GetCharSet (WindowItem* I); // Get a character set from an item void SetCharSet (WindowItem* I, const CharSet& CS); // Set a character set unsigned MakeToggleText (String& Text, unsigned Count); // Make a toggle text from the user supplied form. Return the new toggle // count or the old one (from Count) if the new one cannot be determined. void SetToggleText (ToggleItem* Item, String NewText); // Set a new toggle text. The function will set the toggle count also. String ChooseRes (); // Choose a resource from the file and return it's name. The function // returns the empty string on a user abort. Streamable* LoadRes (const String& Name); // Load the resource with the given namen from the resource file. Return // a NULL pointer in case of errors. public: ResEditApp (int argc, char** argv); static TopMenueBar *CreateMenueBar (); static BottomStatusLine *CreateStatusLine (); virtual int Run (); void Open (); void Close (); void Pack (); void Read (); void Write (); void Print (); void New (); void AddData (); void AddStream (); void Merge (); void Header (); void Footer (); void Size (); void Color (); void BackgroundChar (); void Number (); void CanMove (int On); void CanResize (int On); void IgnoreAccept (int On); void Modal (int On); void LRLink (int On); void CenterX (int On); void CenterY (int On); void Test (); void AddWindowItem (); void AddTextItem (); void AddItemLabel (); void AddMenueItem (); void AddSubMenueItem (); void AddMenueBarItem (); void AddFloatItem (); void AddExpFloatItem (); void AddLongItem (); void AddHexItem (); void AddStringItem (); void AddRStringItem (); void AddToggleItem (); void AddOffOnItem (); void AddNoYesItem (); void AddDateItem (); void AddTimeItem (); void AddEditLine (); void AddFloatEdit (); void AddExpFloatEdit (); void AddLongEdit (); void AddHexEdit (); void AddPasswordEdit (); void AddFileEdit (); void AddDateEdit (); void AddTimeEdit (); void AddTextEdit (); void AddMenueLine (); void Delete (); void Copy (); void Edit (); void MoveArea (); void Order (); void ItemMenue (WindowItem* Item); void ChangeLimits (WindowItem* Item); void ChangeSubMenue (WindowItem* Item); void ChangeCharset (WindowItem* Item); void Visible (int On); void EditResource (); void MergeMsgText (); // Merge a text file containing messages }; // End of RESED.H #endif estic-1.61.orig/spunk/resed.res0100644000176100001440000020232307031424704015770 0ustar debacleusersAnnaÓć˙6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpfpapdp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pDtaptpepipepnp p p p p p p p p p p p p p p p p p p pVteprpzpepipcphpnpipspspep p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6D Dateien`6V/ Verzeichnisse2N1Name( 3ž`6é˙˙Pfadb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp p p p p p pBpepnpuptpzpeprpnpapmpep p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprptp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KBenutzer-ID Benutzername Passwort Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pItDp p p p p p p p p p p p p p p                       p³p³p pBpepnpuptpzpeprp-pNtapmpep p p                                 p³p³p pPtapspspwpoprptp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStipcphpeprphpepiptpsp-pEpbpepnpep p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/I  Benutzer-ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N 1 Benutzer-Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPasswort "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSicherheits-Ebene0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprptp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp— ˙˙ Passwort:  6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ Benutzer-ID: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōHilfe bernehmen Abbruch Ende Weiter ˇndern Drucken Grafik  Einfgen L”schen Auswahl Best„tigen Bewegen Login Logout Ende Zoom  Schliessen ™ffnen Gr”įe  Speichern  ~~ Auswahl  ~ÄŁ~ Auswahl  ~ Bild-~ Bl„ttern  ~~ Bewegen  ~Ctrl+~ Gr”įe Sind Sie sicher?dWirklich Ende?eˇnderungen verwerfen?fˇnderungen sichern?g @Ja @Neinh @Nein @Jai Fehler Č Information É Systemfehler Ź Best„tigen ŅAbbruch Ó Ignorieren Ō Wiederholen ÕEnde ÖEinen Moment bitte...×Ungltige Eingabe,Zu viele Nachkommastellen-"Wert ist zu klein (Minimum ist %g).!Wert ist zu groį (Maximum ist %g)/#Wert ist zu klein (Minimum ist %ld)0"Wert ist zu groį (Maximum ist %ld)1Leereingabe ist unzul„ssig2Keine Datei-Erweiterung erlaubt3Aus AnNein Ja‘Wert ist zu groįōWert ist zu kleinõFehlerhafte Eingabeö2%s: Sektion %s, %s nicht gefunden oder fehlerhaft.X*Fehler beim ™ffnen der Passwort-Datei^(%s)¼)Fehler beim Lesen der Passwort-Datei^(%s)½1Fehler beim Schreiben auf die Passwort-Datei^(%s)¾)Es muį eine Benutzer-ID angegeben werden!æ)Es muį ein Benutzername angegeben werden!Ą%Es muį ein Passwort angegeben werden!Į-Ein Benutzer mit dieser ID existiert bereits!Ā/Ungltige Benutzer-ID oder ungltiges Passwort!ĆSonntag Montag!Dienstag"Mittwoch# Donnerstag$Freitag%Samstag&So'Mo(Di)Mi*Do+Fr,Sa-Januar.Februar/M„rz0April1Mai2Juni3Juli4August5 September6Oktober7November8Dezember9Jan:Feb;M„r<Apr=Mai>Jun?Jul@AugASepBOktCNovDDezEKeine Hilfe verfgbar„ Keine Hilfe fr dieses Stichwort… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+Bild-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Bild-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Bild-™Alt+Ende Alt+Bild- Alt+Einfg¢Alt+Entf£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-EndeEsc-PgDn Esc-Einfg¢Esc-Entf£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Verzeichnis 5 Fehler %d: %süKein Fehler (OOPS!)żDatei oder Pfad nicht gefundenžNicht genug Speicher˙Zugriff verweigert Zu viele offene Files 9Nicht gengend Speicherplatz auf dem angesprochenen Ger„t %Tempor„rer Fehler - nochmal versuchen Ger„t/Datei ist in Benutzung Datei ist zu groį I/O Fehler Datei ist ein Verzeichnis Datei ist kein Verzeichnis Zu viele Links 'Operation nur mit Block Devices m”glich &Operation nur mit Char Devices m”glich Device existiert nicht 4Operation ist nur fr den Besitzer der Datei m”glich Broken Pipe Dateisystem ist readonly +Seek kann nicht auf Pipes ausgefhrt werden Prozess existiert nicht Ausfhrbare Datei ist busy Name ist zu lang Keine Locks verfgbar Verzeichnis ist nicht leer Datei nicht gefunden Pfad nicht gefunden Laufwerk ist ungltig 0Aktuelles Verzeichnis kann nicht gel”scht werden Datei existiert bereits Unbekannter Fehler (%d) "Es sind zu viele Fenster ge”ffnet!Ä 6P > = Fensterliste  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pFpepnpsptpeprplpipsptpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpaptphp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pFtiplpepsp p p p p p p p p p p p p p p p p p p p p pDtiprpepcptpoprpipepsp p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6F!Files`6D  Directories2N1Name( 3ž`6é˙˙Pathb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp p p p p p p p p p pUpspeprp pNpapmpep p p p p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprpdp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KUser ID User Name Password Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pItDp p p p p p p p p p p p p p p p p p p                       p³p³p pUpspeprp pNtapmpep p p p p p p                                 p³p³p pPtapspspwpoprpdp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStepcpuprpiptpyp pLpepvpeplp p p p p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/IUser ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N1 User Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPassword "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSecurity Level0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  6P :9 ŲŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp” ˙˙User ID:  ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōHelpAccept Abort End Proceed Change Print  Graphics Insert Delete Select Confirm Move Login Logout Exit Zoom Close Open Resize Save  ~~ Select  ~ÄŁ~ Select  ~ PgDn PgUp~ Browse  ~~ Move  ~Ctrl-~ Resize Are you shure?d Really quit?eDiscard changes?f Save changes?g@Yes @Noh@No @Yesi Error Č Information É Fatal Error ŹConfirm ŅAbort ÓIgnore ŌRetry ÕEnd ÖOne moment please...× Invalid input,Too many trailing digits-"Value is too small (minimum is %g)."Value is too large (maximum is %g)/#Value is too small (minimum is %ld)0#Value is too large (maximum is %ld)1Input cannot be empty2No filename extension allowed3Off On NoYes‘Value is too largeōValue is too smallõ Invalid inputö,%s: Section %s, key %s not found or invalid.X$Error opening the password file^(%s)¼$Error reading the password file^(%s)½'Error writing to the password file^(%s)¾The user id cannot be empty!æThe user name cannot be empty!ĄAn empty password is invalid!Į'A user with this ID does already exist!Ā$Invalid user id or invalid password!ĆSunday Monday!Tuesday" Wednesday#Thursday$Friday%Saturday&Sun'Mon(Tue)Wed*Thu+Fri,Sat-January.February/March0April1May2June3July4August5 September6October7November8December9Jan:Feb;Mar<Apr=May>Jun?Jul@AugASepBOctCNovDDecENo help available„No help on this topic… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+PgUp™Alt+EndAlt+PgDnAlt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Error %d: %süNo error (OOPS!)żFile or path not foundžNot enough memory˙ Access denied Too many open files No space left on device Try again Device or file is busy File is too large I/O error File is a directory File is no directory Too many links Block device required Char device required Device does not exist !You are not the owner of the file Broken pipe File system is readonly Cannot seek on pipes Process does not exist Text file is busy Name is too long No locks available Directory is not empty File not found Path not found Drive is invalid Cannot remove current directory File exists Unknown error (%d) There are too many windows open!Ä 6P > = Window list  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pWpipnpdpopwp plpipsptp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙š ōHelp Overnemen  Afbreken Einde Verder  Veranderen  Afdrukken Grafiek  Invoegen  Verwijderen Keuze Bevestigen Bewegen Login Logout Einde Zoom Sluiten Openen Grootte Opslaan  ~~ Keuze  ~ÄŁ~ Keuze  ~ Beeld-~ bladeren  ~~ Bewegen  ~Ctrl+~ Groote  Bent U zeker?dEcht verlaten?eWijzigingen ongedaan maken?fVeranderinge schrijven?g@Ja @Neeh@Nee @Jai Fout Č Informatie É Systeemfout Ź Bevestigen Ņ Ophouden ÓNegeren Ō Herhalen ÕEinde ÖEven wachten a.u.b...×Ongeldige invoer,Te veel cijfers na de Komma-"Waarde is te klein (Minimum is %g)."Waarde is te groot (Maximum is %g)/#Waarde is te klein (Minimum is %ld)0#Waarde is te groot (Maximum is %ld)1Lege invoer is niet toegelaten2Geen Bestand ending toegelaten3UitAanNeeJaa‘Waarde is te grootōWaarde is te klijnõ Foute invoerö(%s: Sektie %s, %s niet gevonden of fout.X5Fout bij het openen van het wachtwoorden-bestand^(%s)¼4Fout bij het lezen van het wachtwoorden-bestand^(%s)½8Fout bij het schrijven van het wachtwoorden-bestand^(%s)¾"De User-ID moet aangegeven worden!æ#De Usernaam moet aangegeven worden!Ą&Een wachtwoord moet aangegeven worden!Į Een User met deze ID bestaat al!Ā*Ongeldige User-ID of ongeldige wachtwoord!ĆZondag Maandag!Dinsdag"Woensdag# Donderdag$Vrijdag%Zaterdag&So'Ma(Di)Wo*Do+Fr,Za-Januari.Februari/Maart0April1Mei2Juni3Juli4Augustus5 September6Oktober7November8December9Jan:Feb;Maa<Apr=Mai>Jun?Jul@AugASepBOktCNovDDecEGeen Hulp beschikbaar„Geen Hulp voor dit Steekword… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpatieCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+Pg-v Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pg-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+Pg-™Alt+EndAlt+Pg-Alt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+EscAlt+spacetoutsCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPg-IKMEndOPPg-QInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Fout %d: %süGeen fout (OOPS!)żBestand of pad niet gevondenžTe weinig geheugen˙Ingreep geweigerd Te veel geopende bestanden ,Te weinig ruimte op het angesproken apparaat &Tijdelijke fout - Probeer het nog eens Apparaat/Bestand is in gebruik Bestand te groot I/O Fout Bestand is een directory Bestand is geen directory Te veel links *Operatie alleen mogelijk met block devices )Operatie alleen mogelijk met char devices Device bestaat niet <Operatie is alleen voor de eigenaar van dit bestand mogelijk Broken Pipe Bestandsysteem is alleen-lezen (Seek kan niet op Pipes uitgevoerd worden Proces bestaat niet !Uitvourbare bestand is in gebruik Naam is te lang Geen lockings beschikbaar Directory is niet leeg Bestand niet gevonden Path niet gevonden Schijf is onjuist ,Huidige directory kan niet verwijderd worden Bestand bestaat al Onbekende fout (%d) Te veel vensters geopend!Ä 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p zIpDp puptpepnptpep:p z z z z                       z³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ ID utente: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙š ōGuida Accetta Annulla Termina  Continua  Modifica Stampa Grafica  Inserisci  Cancella Seleziona Conferma Muovi Login Logout Termina Zoom Chiudi Apri  Dimensione Salva  ~~ Seleziona  ~ÄŁ~ Seleziona  ~ Pag-~ sfoglia  ~~ Muovi  ~Ctrl+~ Dimensione E' proprio sicuro?dProprio terminare?eAnnullare modifiche?fSalvare modifiche?g@S¨ @Noh@No @S¨i Errore Č Informazione É Errore di sistema Ź Conferma ŅAnnulla ÓIgnora ŌRipeti ÕFine Ö Un momento...×Valore non valido,Troppi zero dopo la virgola-$Valore troppo piccolo (al minimo %g).$Valore troppo grande (al massimo %g)/%Valore troppo piccolo (al minimo %ld)0%Valore troppo grande (al massimo %ld)1Ci vuole qualcosa!2Estensione file non ammessa3Off OnNoS¨‘Valore troppo grandeōValore troppo piccoloõValore sbagliatoö+%s: sezione %s, %s non trovata o sbagliata.X/Errore di apertura del file delle password (%s)¼.Errore di lettura del file delle password (%s)½0Errore di scrittura del file delle password (%s)¾Ci vuole un ID utente!æCi vuole un nome utente!ĄCi vuole una password!Į#Un utente con questo ID esiste gi…!Ā ID utente o password non validi!ĆDomenica Luned¨!Marted¨" Mercoled¨#Gioved¨$Venerd¨%Sabato&Do'Lu(Ma)Me*Gi+Ve,Sa-Gennaio.Febbraio/Marzo0Aprile1Maggio2Giugno3Luglio4Agosto5 Settembre6Ottobre7Novembre8Dicembre9Gen:Feb;Mar<Apr=Mag>Giu?Lug@AgoASetBOttCNovDDicEGuida non disponibile„.Guida non disponibile per questa parola chiave… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+Pag-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pag-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Pag-™Alt+Fine Alt+Pag-Alt+Ins¢Alt+Canc£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-FineEsc-PgDnEsc-Ins¢Esc-Canc£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Byte 4 Directory 5 Errore %d: %süNessun errore (OOPS!)żFile o path non trovatižMemoria insufficiente˙Accesso negato Troppi files aperti ,Memoria insufficiente sul device indirizzato Errore temporaneo - riprovare Device/file in uso File troppo grande Errore di I/O Il file una directory Il file non una directory Troppi links /L'operazione possibile solo con block devices .L'operazione possibile solo con char devices Device non esistente :L'operazione possibile solo per il proprietario del file Broken Pipe $Il file di sistema e' a sola lettura %Seek non pu• essere eseguito su pipes Processo non esistente File eseguibile impegnato Nome troppo lungo Nessun lock disponibile La directory non vuota File non trovato Path non trovato Drive non valido .La directory attuale non pu• essere cancellata Il file esiste gi… Errore sconosciuto (%d) Sono aperte troppe finestre!Ä 6P > = Lista finestre  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pLpipsptpap pfpipnpepsptprpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙6P1 3 2 Charset  ˛ŚpÄpÄpÄpÄpÄpÄp pCphpaprpspeptp pÄpÄpÄpÄpÄpÄpæp³p pRtepspeptp p p p p p p p p p p p p p p p³p³p pApdpdp pdtipgpiptpsp p p p p p p p p p p³p³p pApdpdp phtepxp pdpipgpiptpsp p p p p p p³p³p pApdpdp patlppphpap p p p p p p p p p p p³p³p pApdpdp papltlp pnpopnp-pcpopnptprpoplp p³p³p pCtupsptpopmp pcphpaprpspeptp p p p p p p³p³p pAplplpopwp petmppptpyp pipnpppuptp p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁppRReset Reset pD Add digits Add digits pHAdd hex digits Add hex digits pA Add alpha Add alpha pLAdd all non-control Add all non-control pCCustom charset Custom charset pEAllow empty input Allow empty input 6P K J ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pItDp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p1p p³p³p pTtepxptp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pSttpaptpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p pIpnpapcptpipvpep p³p³p pAtcpcpeplpkpepyp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pHteplpppkpepyp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p xCxhxaxrxaxcxtxexrx xsxextx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x³p³p xLxixmxixtxsx.x.x.x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x³p³p xSxuxbxmxexnxuxex x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x³p³p xTxoxgxgxlxex-xTxexxxtx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x³p³p xTxoxgxgxlxex-xCxoxuxnxtx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x2x x³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp tD IIDD ID 1 }}DTTextD Text ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙dwDSStateD State Inactive Inactive ActiveInactive GrayuD(AAccelkeyD Accelkey }D2HHelpkeyD Helpkey ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ uD<C Character setD Character set pDFL Limits...D Limits... pDPMSubmenueD Submenue }DZO Toggle-TextD Toggle-Text ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙t DdC Toggle-CountD Toggle-Count 2 6P10 / ŗŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pLpopcpaplp poppptpipopnpsp p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pTtepxptp p p p p p p p p p p³p³p pSttpaptpep p p p p p p p p p³p³p pItDp p p p p p p p p p p p p³p³p pKtepyp p p p p p p p p p p p³p³p pHteplppp p p p p p p p p p p³p³p pCthpaprpspeptp p p p p p p p³p³p pLtipmpiptpsp p p p p p p p p³p³p pSpupbpmtepnpupep p p p p p p³p³p pTpotgpgplpeptpepxptp p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp `d˙˙ Local optionss0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpTText Text pSState State pIID ID pKKey Key pHHelp Help pCCharset Charset pLLimits Limits p MSubmenue Submenue p  O Toggletext Toggletext ° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,./:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° .,-:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAA¸€EEEIIIA¸E’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨ˇ†‘‘“”•–—™›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° BEF.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙!"#$%&˙()*+,˙./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU›¯˛AIOUNN¦§Ø©Ŗ«¬­®Æ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüż˙˙° F ,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° ˛.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° L..,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° Fr'...,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙ČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚ¨ŪÜŻŽßąįāćä<=>?@ABCDEFGHIJ !"#$%&'()KLMNOPQ RST4U3 VWX6Y oZp–\ ]—_`abcdefghi™›klmn¯qrstuvw˛xyz{|}~ ¢£¤¦§Ø©€‚Ŗ«…¬­®Æ°†±²³´µ¶·ø¹ŗ‰»¼½¾ˇæ¸ĄĮĀ“”° ,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° SEK.,-.;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° DM.,.:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° mk ,..;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° >< ^ >< ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ° »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±>; #endif /*****************************************************************************/ /* MsgListBox */ /*****************************************************************************/ class MsgListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: MsgListBox (i16 aID, const Point & aSize, WindowItem *NextItem); }; MsgListBox::MsgListBox (i16 aID, const Point & aSize, WindowItem * NextItem) : ListBox ("", aID, aSize, NextItem) { } void MsgListBox::Print (int Index, int X, int Y, u16 Attr) { Msg *M = Coll->At (Index); // Create the index number as a string String S (::ShowControls (FormatStr ("%6u %s", M->GetNum (), M->GetStr ()), ccHex | ccCStyle | ccSpunk)); S.Pad (String::Right, Size.X); Owner->Write (X, Y, S, Attr); } /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ void ResEditApp::EditResource () { switch (ResID) { case ID_MsgCollection: EditMsgCollection (); break; } } int ResEditApp::SearchMsgID (MsgCollection *M, u16 StartNum) // Search for a free Message ID. Will fail silently if all 65536 message // numbers are in use ... { int Index; // Search for the first number M->Search (&StartNum, Index); // Proceed until a free id is found while (Index < M->GetCount () && M->At (Index)->GetNum () == StartNum) { Index++; StartNum++; } return StartNum; } void ResEditApp::EditMsgCollection () // { // Last used Msg number static u16 MsgNum = 0; // Get a correct casted pointer MsgCollection *M = (MsgCollection *) Res; // Make a window not covering the menuebar and the statusline Rect WinBounds (Background->OuterBounds ()); WinBounds.A.Y = 1; WinBounds.B.Y--; // create an empty listbox Point BoxSize (WinBounds.XSize () - 2, WinBounds.YSize () - 2); MsgListBox *L = new MsgListBox (1, BoxSize, NULL); // Assign the collection for the listbox L->SetColl (M); // Create the window and set the header ItemWindow *Win = new ItemWindow (WinBounds, wfFramed, paGray, 0, L); Win->SetHeader (" Available Messages "); // Make a statusline and activate the window u32 StatusFlags = siEsc_End | siDel_Delete | siIns_Insert | siCR_Change; StatusLine->Push (StatusLine::CreateLine (StatusFlags) + " ~Alt-N~ Change number"); Win->Activate (); // Ask for the keys and handle them Key K; int Done = 0; int Selected; int Index; int Abort; i32 Val; Msg *OldMsg, *NewMsg; while (!Done) { K = KbdGet (); L->HandleKey (K); Selected = L->GetSelected (); switch (K) { case vkAbort: case kbEsc: Done = 1; break; case vkDel: L->Delete (Selected); ResChanged = 1; break; case kbMetaN: if (Selected >= 0) { OldMsg = M->At (Selected); Val = OldMsg->GetNum (); LongPrompt (" New message number", Val, 0, 0xFFFF, Abort); if (!Abort) { // Check if the message number is in use MsgNum = (u16) Val; if (M->Search (&MsgNum, Index)) { ErrorMsg ("Message id is in use"); } else { NewMsg = new Msg (MsgNum, *OldMsg); L->Delete (Selected); L->Insert (NewMsg); ResChanged = 1; } } } break; case vkIns: // Search for a free message number Val = SearchMsgID (M, MsgNum); // Edit that number LongPrompt (" New message number", Val, 0, 0xFFFF, Abort); if (!Abort) { // Check if the message number is in use MsgNum = (u16) Val; if (M->Search (&MsgNum, Index)) { ErrorMsg ("Message id is in use"); } else { NewMsg = new Msg (MsgNum); NamePrompt (" New message", *NewMsg, Abort); if (!Abort) { NewMsg->HideControls (); L->Insert (NewMsg); L->SetSelected (M->IndexOf (NewMsg)); ResChanged = 1; } else { delete NewMsg; } } } break; case kbEnter: if (Selected >= 0) { NewMsg = new Msg (*(M->At (Selected))); NewMsg->ShowControls (ccHex | ccCStyle | ccSpunk); NamePrompt (" New Message", *NewMsg, Abort); if (!Abort) { NewMsg->HideControls (); L->Replace (Selected, NewMsg); ResChanged = 1; } else { delete NewMsg; } } break; } } // Take the collection from the listbox L->SetColl (NULL); // Delete the window including the listbox delete Win; // Restore the old status line StatusLine->Pop (); } void ResEditApp::MergeMsgText () // Merge a text file containing messages { // Ask for the file name FileSelector FS (" Open a merge file ", ".msg"); String MergeFile = FS.GetChoice (); if (MergeFile.IsEmpty ()) { return; } // Open the file FILE* F; if ((F = fopen (MergeFile.GetStr (), "rb")) == NULL) { ErrorMsg (FormatStr ("Cannot open %s", MergeFile.GetStr ())); return; } // Get a casted pointer to the message collection MsgCollection* M = (MsgCollection*) Res; // Read line by line, convert and set up a new message int Line = 0; while (1) { char Buf [512]; if (fgets (Buf, sizeof (Buf), F) == NULL) { // End of file reached break; } Line++; // Put the line into a string, then skip white space at the beginning String S (Buf); while (S.IsEmpty () == 0 && S [0] == ' ') { S.Del (0, 1); } // Delete the trailine newline int Len = S.Len (); while (S.IsEmpty () == 0 && (S [Len-1] == '\n' || S [Len-1] == '\n')) { Len--; S.Trunc (Len); } // Ignore empty and comment lines if (S.IsEmpty () || S [0] == ';') { continue; } // Convert the line to the current input charset S.InputCvt (); // Check if the number at the beginning is hexadecimal. unsigned Base = 10; if (S.Len () > 2 && S [0] == '0' && S [1] == 'x') { S.Del (0, 2); Base = 16; } // Now parse for the message number u32 MsgNum; StringParser P (S, StringParser::SkipWS | StringParser::PascalHex | StringParser::CHex); if (P.GetU32 (MsgNum, Base) != 0) { ErrorMsg (FormatStr ("Invalid message number in line %d", Line)); continue; } // Check the message number for valid values if (MsgNum >= 0x10000) { ErrorMsg (FormatStr ("Invalid message number in line %d", Line)); continue; } // Skip white space and check for double quotes P.SkipWhite (); if (S [P.GetPos ()] != '"') { ErrorMsg (FormatStr ("Missing leading quotes in line %d", Line)); continue; } // Extract the message String MsgText (S.Cut (P.GetPos () + 1, S.Len () - P.GetPos ())); // Cut anything behind the trailing double quote int Pos = MsgText.ScanL ('"'); if (Pos < 0) { ErrorMsg (FormatStr ("Unterminated message in line %d", Line)); continue; } MsgText.Trunc (Pos); // Convert visible control chars to binary values and create a new msg Msg* NewMsg = new Msg (MsgNum, ::HideControls (MsgText)); // Check if the message collection already has a message with the given // message number. If so, delete this message u16 Key = MsgNum; int Index; if (M->Search (&Key, Index) != 0) { // A msg with this number exists, delete it M->AtDelete (Index); } // Now insert the new message M->Insert (NewMsg); } // Close the file and mark the resource as modified ResChanged = 1; fclose (F); } estic-1.61.orig/spunk/resfile.cc0100644000176100001440000001544607031424704016123 0ustar debacleusers/*****************************************************************************/ /* */ /* RESFILE.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "cont.h" #include "filepath.h" #include "filesel.h" #include "resed.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ void ResEditApp::CloseResourceFile () { if (ResFile) { delete ResFile; ResFile = NULL; MainMenue->GrayItem (miClose); MainMenue->GrayItem (miPack); MainMenue->GrayItem (miWrite); MainMenue->GrayItem (miRead); MainMenue->GrayItem (miAddStream); MainMenue->GrayItem (miAddData); MainMenue->GrayItem (miMerge); } } void ResEditApp::OpenResourceFile (const String& Name) { // Close the resource file if one is open CloseResourceFile (); // Now try to open the resource file ResFile = new ResourceFile (new FileStream (Name)); if (ResFile->GetStatus () != reOk) { ErrorMsg (String ("Error opening \"") + Name + '\"'); delete ResFile; ResFile = NULL; return; } // Activate the corresponding menue entries MainMenue->ActivateItem (miClose); MainMenue->ActivateItem (miRead); MainMenue->ActivateItem (miPack); MainMenue->ActivateItem (miAddStream); MainMenue->ActivateItem (miAddData); MainMenue->ActivateItem (miMerge); if (Res) { MainMenue->ActivateItem (miWrite); } } void ResEditApp::Open () { FileSelector FS (" Open a file ", ".res", fsFileMayNotExist); String Sel = FS.GetChoice ("*.res"); if (!Sel.IsEmpty ()) { ResFileName = Sel; OpenResourceFile (ResFileName); } } void ResEditApp::Close () { CloseResourceFile (); } void ResEditApp::Pack () { // This may last a while, pop up a message Window *Win = PleaseWaitWindow (); // Pack the file ResFile->Pack (); // Safety: Write out the index to the resource file. Otherwise the file // is unusable if the editor crashes (who knows?) ResFile->Flush (); // Delete the mesage window delete Win; } void ResEditApp::AddData () // Add a container object with arbitrary data { int Abort; // Get file name FileSelector FS (" Open a file "); String Filename = FS.GetChoice ("*.dat"); if (Filename.IsEmpty ()) { return; } // Create container and try to load the data Container C; if (C.LoadData (Filename) == 0) { ErrorMsg ("Error loading data from " + Filename); return; } // Now write the container to the stream (use the filename as default // for the resource name) NamePrompt (" Resource name", Filename, Abort); if (!Abort) { ResFile->Put (C, Filename); } } void ResEditApp::AddStream () // Add an object from a file stream to the resource file { // Get name of the stream FileSelector FS (" Open a file "); String FileName = FS.GetChoice (); if (FileName.IsEmpty ()) { return; } // Get the name of the resource int Abort; String Name; NamePrompt (" Name of resource", Name, Abort); if (Abort) { return; } // Try to open the stream FileStream* S = new FileStream (FileName, "rb"); if (S->GetStatus () != stOk) { ErrorMsg (String ("Error opening \"") + FileName + '\"'); delete S; return; } // Read an object from the stream, check status Streamable* Obj = S->Get (); if (S->GetStatus () != stOk) { ErrorMsg ("Error reading from stream"); delete S; return; } // Write the object into the resource file ResFile->Put (Obj, Name); // Delete the object and the stream delete S; delete Obj; } static Key MapKey (Key K) // Map a extended cursor key fix to it's virtual counterpart { switch (K) { case kbUp: return vkUp; case kbDown: return vkDown; case kbLeft: return vkLeft; case kbRight: return vkRight; default: return K; } } void ResEditApp::Merge () // Merge two resource files { // Get name of second resource file FileSelector FS (" Open a file ", ".res"); String Name = FS.GetChoice ("*.res"); if (Name.IsEmpty ()) { return; } // Try to open second resource file ResourceFile* NewResFile = new ResourceFile (new FileStream (Name)); if (NewResFile->GetStatus () != reOk) { ErrorMsg (String ("Error opening \"") + Name + '\"'); delete NewResFile; return; } // Check if the new resource file contains resources int ResCount = NewResFile->GetCount (); if (ResCount == 0) { ErrorMsg (Name + " is empty"); delete NewResFile; return; } // Show the user that we are working hard... String Msg ("Copying " + FormatStr ("%i", ResCount) + " resources from\n" + Name); Window* Win = MsgWindow (Msg, "", paCyan); // Copy the resources Streamable* Resource; for (int ResNum = 0; ResNum < ResCount; ResNum++) { // Get the name of the resource const String& Key = NewResFile->KeyAt (ResNum); // Load the resource from the new file Resource = NewResFile->Get (Key); // Compatibility hack: If the resource is a menue, adjust the cursor // key variables. Remove that in the near future! if (Resource->StreamableID () == ID_Menue) { Menue* M = (Menue*) Resource; M->PrevKey = MapKey (M->PrevKey); M->NextKey = MapKey (M->NextKey); M->AltPrevKey = MapKey (M->AltPrevKey); M->AltNextKey = MapKey (M->AltNextKey); } // Write the resource to the old resource file (overwriting any // resource object with the same name) ResFile->Put (Resource, Key); // Delete the object delete Resource; } // Delete the new resource file delete NewResFile; // Clear the message window delete Win; } estic-1.61.orig/spunk/resitem.cc0100644000176100001440000012672407031424704016144 0ustar debacleusers/*****************************************************************************/ /* */ /* RESITEM.CC */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "itemlbl.h" #include "textitem.h" #include "stdmsg.h" #include "resed.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ WindowItem* ResEditApp::ChooseItem () { u16 Flags [100]; // Cast the resource to something that is able to hold items and choose // from those items GenericMenue* M = (GenericMenue*) Res; // Check if there are any items to choose if (M->ItemCount == 0) { ErrorMsg ("No items"); return NULL; } // Check if we have enough room to store the flags if (M->ItemCount > (sizeof (Flags) / sizeof (u16))) { ErrorMsg ("Sorry, too many items (change ResItem source)"); return NULL; } // Save the item attributes into the save area, activate all items, // set the ifNoSub flag WindowItem *I = M->FirstItem; int F = 0; do { Flags [F] = I->Flags & ~ifSelected; I->Activate (); I->Flags |= ifNoSub; // No harm done on other items F++; I = I->INode.Next () -> Contents (); } while (I != M->FirstItem); // Now choose an item StatusLine->Push (" Choose an item"); // ##### int Result = M->GetChoice (); StatusLine->Pop (); // ##### // Restore the flags and redraw the items I = M->FirstItem; F = 0; do { I->Flags = Flags [F]; I->Draw (); F++; I = I->INode.Next ()->Contents (); } while (I != M->FirstItem); // Return the result return Result ? M->ForcedItemWithID (Result) : (WindowItem*) NULL; } i16 ResEditApp::NextID (i16 StartID) // Choose a new ID { // Cast the resource pointer ItemWindow *Win = (ItemWindow *) Res; // Search for a free ID while (Win->ItemWithID (StartID) != NULL) { StartID++; } return StartID; } i16 ResEditApp::SearchItemYPos () // Search the first free Y position in the Menue { // Cast to a ItemWindow ItemWindow * Win = (ItemWindow *) Res; // If the window is empty, stop here if (Win->ItemCount == 0) { return 0; } // Search for a free Y position int Y = 0; WindowItem *Item; int Found; while (Y <= Win->MaxY ()) { // Search for this Y pos Found = 0; Item = Win->FirstItem; do { if (Item->ItemY == Y) { // Already occupied Found = 1; break; } Item = Item->INode.Next () -> Contents (); } while (Item != Win->FirstItem); if (!Found) { // This Y pos is free return (i16) Y; } Y++; } // Not found return 0; } i16 ResEditApp::SearchItemXPos () // Search the first free X position in the Menue { // Cast to a ItemWindow ItemWindow * Win = (ItemWindow *) Res; // If the window is empty, stop here if (Win->ItemCount == 0) { return 1; } // Search for a free X position i16 X = 1; WindowItem *Item = Win->FirstItem; do { i16 MaxX = Item->ItemX + Item->GetWidth (); if (MaxX > X) { X = MaxX; } Item = Item->INode.Next () -> Contents (); } while (Item != Win->FirstItem); if (X >= Win->MaxX ()) { X = 0; } return X; } void ResEditApp::AddItem (WindowItem *Item) // { // Cast the resource to something that is able to hold a WindowItem ItemWindow *Win = (ItemWindow *) Res; // Search for a free Y position i16 YPos = SearchItemYPos (); // Add the item Win->AddItem (Item); Item->SetPos (0, YPos); i16 Width = Win->InnerBounds ().XSize (); i16 MinWidth = Item->MinWidth (); Item->SetWidth (Width >= MinWidth ? Width : MinWidth); Win->ValidateSelectedItem (); Win->DrawInterior (); ResChanged = 1; } void ResEditApp::AddWindowItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new WindowItem (ItemText, ID, NULL)); } void ResEditApp::AddTextItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the attribute of the text unsigned Attr = SimpleMenue (" Attribute ", "atFrameInactive\n" "atFrameActive\n" "atFrameResizing\n" "atTextNormal\n" "atTextInvers\n" "atTextSelected\n" "atTextHigh\n" "atTextHighInvers\n" "atTextGrayed\n" "atTextGrayedInvers\n" "atEditNormal\n" "atEditHigh\n" "atEditBar"); if (Attr == 0) { // User abort return; } Attr--; // Create and add the item AddItem (new TextItem (ItemText, ID, Attr, NULL)); } void ResEditApp::AddItemLabel () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the id of the controlled item i32 CtrlID = 0; LongPrompt (" Ctrl-ID", CtrlID, 1, 32000, Abort); if (Abort) { return; } // Create and add the item AddItem (new ItemLabel (ItemText, ID, CtrlID, NULL)); } void ResEditApp::AddMenueItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new MenueItem (ItemText, ID, NULL)); } void ResEditApp::AddSubMenueItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Try to load the submenue for the item String MenueName = ChooseRes (); if (MenueName.IsEmpty ()) { return; } Streamable* M = LoadRes (MenueName); if (M == 0) { return; } // Check if we really have a menue if (M->StreamableID () != ID_Menue) { ErrorMsg ("Must have a menue object for assignment"); delete M; return; } // Create the item SubMenueItem* S = new SubMenueItem (ItemText, ID, 0, 0); // Add the item AddItem (S); // Add the submenue S->SetSubMenue ((Menue*) M); } void ResEditApp::AddMenueBarItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Try to load the submenue for the item String MenueName = ChooseRes (); if (MenueName.IsEmpty ()) { return; } Streamable* M = LoadRes (MenueName); if (M == 0) { return; } // Check if we really have a menue if (M->StreamableID () != ID_Menue) { ErrorMsg ("Must have a menue object for assignment"); delete M; return; } // Create the item MenueBarItem* S = new MenueBarItem (ItemText, ID, 0, 0); // Add the item. This must not be done with AddItem since AddItem will // align items verticaly, which is wrong in this case. ItemWindow *Win = (ItemWindow *) Res; // Search for a free X position i16 XPos = SearchItemXPos (); // Add the item Win->AddItem (S); S->SetPos (XPos, 0); S->SetWidth (S->MinWidth ()); Win->ValidateSelectedItem (); Win->DrawInterior (); ResChanged = 1; // Add the submenue S->SetSubMenue ((Menue*) M); } void ResEditApp::AddFloatItem () { int Abort; double Min, Max; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for leading digit count i32 LD = 4; LongPrompt (" Leading digits", LD, 1, 10, Abort); if (Abort) { return; } // Ask for trailing digit count i32 TD = 4; LongPrompt (" Trailing digits", TD, 0, 10, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Initialize Min/Max Min = Max = 0; if (EditID != 0) { // We have an edit item, choose Min/Max FMinMaxPrompt (Min, Max, -1000000000, 1000000000, Abort); if (Abort) { return; } } // Create and add the item AddItem (new FloatItem (ItemText, ID, LD, TD, EditID, Min, Max, NULL)); } void ResEditApp::AddExpFloatItem () { ErrorMsg ("Not implemented"); } void ResEditApp::AddLongItem () { int Abort; i32 Min, Max; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for digit count i32 Digits = 4; LongPrompt (" Digit count", Digits, 1, 10, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Initialize Min/Max Min = Max = 0; if (EditID != 0) { // We have an edit item, choose Min/Max MinMaxPrompt (Min, Max, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } } // Create and add the item AddItem (new LongItem (ItemText, ID, Digits, EditID, Min, Max, NULL)); } void ResEditApp::AddHexItem () { int Abort; i32 Min, Max; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for digit count i32 Digits = 4; LongPrompt (" Digit count", Digits, 2, 8, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Initialize Min/Max Min = Max = 0; if (EditID != 0) { MinMaxPrompt (Min, Max, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } } // Create and add the item AddItem (new HexItem (ItemText, ID, Digits, EditID, Min, Max, NULL)); } void ResEditApp::AddStringItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Create and add the item AddItem (new StringItem (ItemText, ID, EditID, NULL)); } void ResEditApp::AddRStringItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } i32 InputLength = 0; LongPrompt (" Input length:", InputLength, 1, 255, Abort); if (Abort) { return; } // Create and add the item AddItem (new RStringItem (ItemText, ID, EditID, InputLength, NULL)); } void ResEditApp::AddToggleItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the toggle string String ToggleText; NamePrompt (" Toggle values", ToggleText, Abort); if (Abort || ToggleText.IsEmpty ()) { return; } // Make a correct toggle string and set the default for the toggle value i32 ToggleCount = MakeToggleText (ToggleText, 2); // Ask for the toggle count LongPrompt (" Toggle count", ToggleCount, 2, 25, Abort); if (Abort) { return; } // Validate the toggle text if (ToggleText.Len () % ToggleCount != 0) { ErrorMsg ("Invalid toggle count / toggle values"); return; } // Create and add the item AddItem (new ToggleItem (ItemText, ID, ToggleText, ToggleCount, NULL)); } void ResEditApp::AddOffOnItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new OffOnItem (ItemText, ID, NULL)); } void ResEditApp::AddNoYesItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new NoYesItem (ItemText, ID, NULL)); } void ResEditApp::AddDateItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Create and add the item AddItem (new DateItem (ItemText, ID, EditID, NULL)); } void ResEditApp::AddTimeItem () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for Edit ID i16 EditID = 0; EditIDPrompt (EditID, Abort); if (Abort) { return; } // Create and add the item AddItem (new TimeItem (ItemText, ID, EditID, NULL)); } void ResEditApp::AddEditLine () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the field length i32 FieldLen = 4; LongPrompt (" Field length", FieldLen, 2, 255, Abort); if (Abort) { return; } // Ask for the maximum input length i32 MaxLen = FieldLen - 1; LongPrompt (" Input length", MaxLen, FieldLen - 1, 254, Abort); if (Abort) { return; } // Create and add the item AddItem (new EditLine (ItemText, ID, MaxLen, FieldLen, NULL)); } void ResEditApp::AddFloatEdit () { int Abort; double Min, Max; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for leading digit count i32 LD = 4; LongPrompt (" Leading digits", LD, 1, 10, Abort); if (Abort) { return; } // Ask for trailing digit count i32 TD = 4; LongPrompt (" Trailing digits", TD, 0, 10, Abort); if (Abort) { return; } // Initialize Min/Max Min = Max = 0; // choose Min/Max FMinMaxPrompt (Min, Max, -1000000000, 1000000000, Abort); if (Abort) { return; } // Create and add the item AddItem (new FloatEdit (ItemText, ID, LD, TD, Min, Max, NULL)); } void ResEditApp::AddExpFloatEdit () { ErrorMsg ("Not implemented"); } void ResEditApp::AddLongEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for digit count i32 Digits = 4; LongPrompt (" Digit count", Digits, 1, 10, Abort); if (Abort) { return; } // choose Min/Max i32 Min = 0; i32 Max = 0; MinMaxPrompt (Min, Max, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } // Create and add the item AddItem (new LongEdit (ItemText, ID, Digits, Min, Max, NULL)); } void ResEditApp::AddHexEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for digit count i32 Digits = 4; LongPrompt (" Digit count", Digits, 2, 8, Abort); if (Abort) { return; } // choose Min/Max i32 Min = 0; i32 Max = 0; MinMaxPrompt (Min, Max, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } // Create and add the item AddItem (new HexEdit (ItemText, ID, Digits, Min, Max, NULL)); } void ResEditApp::AddPasswordEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the field length i32 FieldLen = 13; LongPrompt (" Field length", FieldLen, 2, 255, Abort); if (Abort) { return; } // Ask for the maximum input length i32 MaxLen = FieldLen - 1; LongPrompt (" Input length", MaxLen, FieldLen - 1, 254, Abort); if (Abort) { return; } // Create and add the item AddItem (new PasswordEdit (ItemText, ID, MaxLen, FieldLen, NULL)); } void ResEditApp::AddFileEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the field length i32 FieldLen = 13; LongPrompt (" Field length", FieldLen, 2, 255, Abort); if (Abort) { return; } // Ask for the maximum input length i32 MaxLen = FieldLen - 1; LongPrompt (" Input length", MaxLen, FieldLen - 1, 254, Abort); if (Abort) { return; } // Create and add the item AddItem (new FileEdit (ItemText, ID, MaxLen, FieldLen, 0, NULL)); } void ResEditApp::AddDateEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new DateEdit (ItemText, ID, NULL)); } void ResEditApp::AddTimeEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Create and add the item AddItem (new TimeEdit (ItemText, ID, NULL)); } void ResEditApp::AddTextEdit () { int Abort; // Ask for item id and item text i16 ID; String ItemText; TextIDPrompt (ItemText, ID, Abort); if (Abort) { return; } // Ask for the field length i32 FieldLen = 4; LongPrompt (" Field length", FieldLen, 2, 255, Abort); if (Abort) { return; } // Ask for the maximum input length i32 MaxLen = FieldLen - 1; LongPrompt (" Input length", MaxLen, FieldLen - 1, 254, Abort); if (Abort) { return; } // Create and add the item AddItem (new TextEdit (ItemText, ID, MaxLen, FieldLen, NULL)); } void ResEditApp::AddMenueLine () { i16 ID = NextID (30000); int Abort; // Ask for item id IDPrompt (ID, Abort); if (Abort) { return; } AddItem (new MenueLine (ID, NULL)); } void ResEditApp::Delete () { // Choose the item to delete WindowItem *Item = ChooseItem (); if (Item == NULL) { // abort return; } // if (AskAreYouShure () != 2) { // Aborted! return; } ItemWindow *Win = (ItemWindow *) Res; Win->DeleteItem (Item); Win->DrawInterior (); ResChanged = 1; } void ResEditApp::Copy () { ErrorMsg ("Not implemented"); } void ResEditApp::MoveResizeInside (Window* W, GenericMenue* M, int Resize, int& Abort) // Move/Resize a window inside a menue { // Allow moving and sizing the window // New status line according to the resize flag if (Resize) { // Resizing allowed StatusLine->Push (" ~Esc~ Abort ~Enter~ Accept " "~Cursor keys~ Move " "~Ctrl-Cursor keys~ Size"); } else { StatusLine->Push (" ~Esc~ Abort ~Enter~ Accept " "~Cursor keys~ Move"); } // Now let's size/move... Rect Bounds; int Done = 0; Abort = 0; while (!Done) { switch (KbdGet ()) { case vkAbort: case kbEsc: // Abort the operation Done = 1; Abort = 1; break; case vkAccept: case kbEnter: Done = 1; break; case vkUp: if (W->OuterBounds().A.Y > M->InnerBounds().A.Y) { W->MoveRel (Point (0, -1)); } break; case vkDown: if (W->OuterBounds().B.Y < M->InnerBounds().B.Y) { W->MoveRel (Point (0, 1)); } break; case vkLeft: if (W->OuterBounds().A.X > M->InnerBounds().A.X) { W->MoveRel (Point (-1, 0)); } break; case vkRight: if (W->OuterBounds().B.X < M->InnerBounds().B.X) { W->MoveRel (Point (1, 0)); } break; case vkCtrlUp: if (Resize) { Bounds = W->OuterBounds (); if (Bounds.YSize () > 1) { Bounds.B.Y--; W->Resize (Bounds); } } break; case vkCtrlLeft: if (Resize) { Bounds = W->OuterBounds (); if (Bounds.XSize () > 2) { Bounds.B.X--; W->Resize (Bounds); } } break; case vkCtrlDown: if (Resize) { Bounds = W->OuterBounds (); if (Bounds.B.Y < M->InnerBounds().B.Y) { Bounds.B.Y++; W->Resize (Bounds); } } break; case vkCtrlRight: if (Resize) { Bounds = W->OuterBounds (); if (Bounds.B.X < M->InnerBounds().B.X) { Bounds.B.X++; W->Resize (Bounds); } } break; } } // Restore old statusline StatusLine->Pop (); } void ResEditApp::MoveArea () { // Cast the resource to a menue GenericMenue* M = (GenericMenue*) Res; // Create a window in the upper left corner of the resource window Rect WBounds (M->InnerBounds().A, Point (1, 1)); Window* W = new Window (WBounds, 0, paBlack); // Put the window on top of the menue and activate it W->PutOnTop (); W->Activate (); // Now let's size/move... int Abort; MoveResizeInside (W, M, 1, Abort); if (Abort) { delete W; return; } // Remember the area to move Rect Bounds (W->OuterBounds ()); // Move the window to the target position MoveResizeInside (W, M, 0, Abort); if (Abort) { delete W; return; } // Remember the move vector Point Vec (Bounds.A.X - W->OuterBounds().A.X, Bounds.A.Y - W->OuterBounds().A.Y); // delete the upper window delete W; // Now move all items inside the source area by the move vector WindowItem* I = M->FirstItem; if (I && Vec != Point (0, 0)) { do { Point P (I->Pos ()); M->Absolute (P); if (Bounds.Contains (P)) { // The item is inside the source area P -= Vec; M->Relative (P); I->SetPos (P); ResChanged = 1; } I = I->INode.Next () -> Contents (); } while (I != M->FirstItem); // Redraw the items inside the window M->DrawInterior (); } } void ResEditApp::Edit () { // Choose the item to move WindowItem* Item = ChooseItem (); if (Item == NULL) { return; } // Get a pointer to the owner window ItemWindow* Win = (ItemWindow*) Res; // Create new status line StatusLine->Push (siEnd | siMoveKeys); Win->ValidateSelectedItem (); Win->Activate (); int Done = 0; while (!Done) { switch (KbdGet ()) { case vkAccept: case vkAbort: Done = 1; ResChanged = 1; break; case vkUp: if (Item->YPos () > 0) { Item->Clear (); Item->SetPos (Item->XPos (), Item->YPos () - 1); Win->DrawInterior (); } break; case vkDown: if (Item->YPos () < Win->MaxY ()) { Item->Clear (); Item->SetPos (Item->XPos (), Item->YPos () + 1); Win->DrawInterior (); } break; case vkLeft: if (Item->XPos () > 0) { Item->Clear (); Item->SetPos (Item->XPos () - 1, Item->YPos ()); Win->DrawInterior (); } break; case vkRight: if (Item->XPos () < Win->MaxX ()) { Item->Clear (); Item->SetPos (Item->XPos () + 1, Item->YPos ()); Win->DrawInterior (); } break; case vkCtrlLeft: Item->Clear (); Item->SetWidth (Item->GetWidth () - 1); Item->Draw (); break; case vkCtrlRight: Item->Clear (); Item->SetWidth (Item->GetWidth () + 1); Item->Draw (); break; case kbEnter: ItemMenue (Item); break; } } // Win->Deactivate (); // Restore the old status line PopStatusLine (); } String ResEditApp::GetItemText (WindowItem* Item) // Extract and return the text of a window item. { // Get the text String Text = Item->ItemText; // Insert a '@' if a hotkey exists if (Item->HotPos != -1) { Text.Ins (Item->HotPos, '@'); } // Return the result return Text; } void ResEditApp::SetItemText (WindowItem* Item, String Text) // Set the new item text, handle @ as the hotkey position. { // Clear the old text before setting the new one Item->ClearItemText (); // Check for a hotkey int Pos = Text.Pos ('@'); Item->HotPos = Pos; if (Pos != -1) { Text.Del (Pos, 1); Item->HotKey = NLSUpCase (Text [Pos]); } else { Item->HotKey = kbNoKey; } Item->ItemText = Text; Item->SetWidth (Item->GetWidth ()); Item->DrawItemText (); // Resource has changed ResChanged = 1; } unsigned ResEditApp::GetItemState (WindowItem* Item) // Extract and return the item state 0..2 { if (Item->IsActive ()) { return 0; } else if (Item->IsGrayed ()) { return 2; } else { // Inactive return 1; } } void ResEditApp::SetItemState (WindowItem* Item, unsigned State) // Set the state according to the state given (0..2) { switch (State) { case 0: Item->Activate (); break; case 1: Item->Deactivate (); break; case 2: Item->Gray (); break; default: FAIL ("ResEditApp::SetItemState: Invalid item state"); } } String ResEditApp::GetCharSetString (WindowItem* Item) // Get a character set from a window item as a string { CharSet CS = GetCharSet (Item); // Convert to string String S (256); for (unsigned I = 1; I < 256; I++) { if (CS [(char)I] != 0) { S += (char)I; } } S.ShowControls (); // Return the string return S; } void ResEditApp::SetCharSetString (WindowItem* I, String S) // Set a character set of a window item from a string { // Make a character set from a string S.HideControls (); CharSet CS = S; // Set the new characters switch (I->StreamableID ()) { case ID_RStringItem: ((RStringItem*) I)->SetAllowedChars (CS); break; case ID_TextEdit: ((TextEdit*) I)->SetAllowedChars (CS); break; default: // Error FAIL ("GetCharset: Invalid item type"); } } const CharSet& ResEditApp::GetCharSet (WindowItem* I) // Get a character set from an item { if (I->StreamableID () == ID_RStringItem) { return ((RStringItem*) I)->GetAllowedChars (); } else if (I->StreamableID () == ID_TextEdit) { return ((TextEdit*) I)->GetAllowedChars (); } else { // Error FAIL ("GetCharset: Invalid item type"); return * (CharSet*) NULL; } } void ResEditApp::SetCharSet (WindowItem* I, const CharSet& CS) // Set a character set { if (I->StreamableID () == ID_RStringItem) { ((RStringItem*) I)->SetAllowedChars (CS); } else if (I->StreamableID () == ID_TextEdit) { ((TextEdit*) I)->SetAllowedChars (CS); } else { // Error FAIL ("GetCharset: Invalid item type"); } } void ResEditApp::SetToggleText (ToggleItem* Item, String NewText) // Set a new toggle text. The function will set the toggle count also. { // Make the new text, set the new count Item->TCount = MakeToggleText (NewText, Item->TCount); // Set the new text Item->TList = NewText; } unsigned ResEditApp::MakeToggleText (String& Text, unsigned Count) // Make a toggle text from the user supplied form. Return the new toggle // count or the old one (from Count) if the new one cannot be determined. { // There are two possibilities to set a text. One is, to separate the // items by a newline, the second (and original one) is to pad each // single value by length. // First, convert control char literals into there native form Text.HideControls (); // Check which format of the string value is used int P = Text.Pos ('\n'); if (P >= 0) { // We have a newline, first method. Make shure, the string is newline // terminated. if (Text [Text.Len () - 1] != '\n') { Text += '\n'; } // Split up the string int MaxLen = 0; Collection Values (10, 10, 1); while (Text.NotEmpty ()) { int P = Text.Pos ('\n'); CHECK (P >= 0); // Should never happen String S = Text.Cut (0, P); Text.Del (0, P+1); if (S.Len () > MaxLen) { MaxLen = S.Len (); } Values.Insert (new String (S)); } // Make a new string, padding each value for (int I = 0; I < Values.GetCount (); I++) { // Get the string String& S = *Values [I]; // Pad it and add it to the complete string Text += S.Pad (String::Left, (u16) MaxLen); } // Set the new count Count = (unsigned) Values.GetCount (); } // Return the new count return Count; } void ResEditApp::ItemMenue (WindowItem* Item) // Data edit menue { // Menue IDs const miID = 10; const miText = 20; const miState = 30; const miAccelKey = 40; const miHelpKey = 50; const miCharset = 60; const miLimits = 70; const miSubMenue = 80; const miToggleText = 90; const miToggleCount = 100; // Load the menue from the resource Menue* M = (Menue*) LoadResource ("@RESITEM.ItemDataMenue"); // Place the menue near the item to edit M->PlaceNear (Item); // Transfer generic item data to the menue M->SetLongValue (miID, Item->GetID ()); M->SetStringValue (miText, GetItemText (Item)); M->SetToggleValue (miState, GetItemState (Item)); M->SetStringValue (miAccelKey, GetKeyName (Item->AccelKey)); M->SetStringValue (miHelpKey, Item->HelpKey); // Some menue items have special data: int IsToggle = 0; switch (Item->StreamableID ()) { case ID_RStringItem: case ID_TextEdit: M->SetStringValue (miCharset, GetCharSetString (Item)); M->ActivateItem (miCharset); break; case ID_HexEdit: case ID_LongEdit: case ID_FloatEdit: case ID_HexItem: case ID_LongItem: case ID_FloatItem: M->ActivateItem (miLimits); break; case ID_MenueBarItem: case ID_SubMenueItem: M->ActivateItem (miSubMenue); break; case ID_ToggleItem: case ID_NoYesItem: case ID_OffOnItem: IsToggle = 1; M->SetStringValue (miToggleText, ((ToggleItem*)Item)->TList); M->SetLongValue (miToggleCount, ((ToggleItem*)Item)->TCount); M->ActivateItem (miToggleText); M->ActivateItem (miToggleCount); break; } // New statusline StatusLine->Push (siAccept | siSelectChooseKeys); // Now let the user decide what to do int Done = 0; M->Activate (); while (!Done) { // Variables needed in the loop Window* W; int ID; Key K; // Get a choice int Choice = M->GetChoice (); // Actions... switch (Choice) { case miID: // Check if the ID is not already in use ID = M->GetLongValue (miID); if (((GenericMenue*)Res)->ItemWithID (ID) != NULL) { ErrorMsg ("ID is already in use"); } else { // Assign the new ID Item->ID = ID; // Resource has been changed ResChanged = 1; } break; case miText: // Set the new text SetItemText (Item, M->GetStringValue (miText)); ResChanged = 1; break; case miState: case miState+1: case miState+2: SetItemState (Item, Choice - miState); ResChanged = 1; break; case miAccelKey: // Choose the accel key to assign W = MsgWindow (" Press accelerator key or Esc to abort", "", paCyan); K = KbdGet (); if (K != vkAbort && K != kbEsc) { // Set the accel key Item->SetAccelKey (K); // Redraw the item, rebuild the item string before Item->SetWidth (Item->GetWidth ()); Item->Draw (); // Display the accel key in the menue M->SetStringValue (miAccelKey, GetKeyName (K)); // Resource has changed ResChanged = 1; } // Delete the window delete W; break; case miHelpKey: Item->SetHelpKey (M->GetStringValue (miHelpKey)); ResChanged = 1; break; case miCharset: ChangeCharset (Item); M->SetStringValue (miCharset, GetCharSetString (Item)); break; case miLimits: ChangeLimits (Item); break; case miSubMenue: ChangeSubMenue (Item); break; case miToggleText: SetToggleText ((ToggleItem*) Item, M->GetStringValue (miToggleText)); M->SetStringValue (miToggleText, ((ToggleItem*) Item)->TValue); M->SetLongValue (miToggleCount, ((ToggleItem*) Item)->TCount); ResChanged = 1; break; case miToggleCount: ((ToggleItem*)Item)->TCount = M->GetLongValue (miToggleCount); ResChanged = 1; break; case 0: // Check some stuff before end if (IsToggle) { ToggleItem* TI = (ToggleItem*) Item; if (TI->TList.Len () % TI->TCount != 0) { ErrorMsg ("Invalid toggle count/length"); } else { TI->TLen = TI->TList.Len () / TI->TCount; TI->Draw (); Done = 1; } } else { Done = 1; } break; } } // Restore the statusline, delete the menue PopStatusLine (); delete M; } void ResEditApp::ChangeLimits (WindowItem* Item) { i32 LMin, LMax; double FMin, FMax; int Abort; // Switch according to the item type switch (Item->StreamableID ()) { case ID_HexEdit: case ID_LongEdit: ((LongEdit*) Item)->GetMinMax (LMin, LMax); MinMaxPrompt (LMin, LMax, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } ((LongEdit *) Item)->SetMinMax (LMin, LMax); ResChanged = 1; break; case ID_HexItem: case ID_LongItem: ((LongItem*) Item)->GetMinMax (LMin, LMax); MinMaxPrompt (LMin, LMax, (i32) 0x80000000, 0x7FFFFFFF, Abort); if (Abort) { return; } ((LongItem *) Item)->SetMinMax (LMin, LMax); ResChanged = 1; break; case ID_FloatEdit: ((FloatEdit*) Item)->GetMinMax (FMin, FMax); FMinMaxPrompt (FMin, FMax, -1000000000, 1000000000, Abort); if (Abort) { return; } ((FloatEdit*) Item)->SetMinMax (FMin, FMax); ResChanged = 1; break; case ID_FloatItem: ((FloatItem*) Item)->GetMinMax (FMin, FMax); FMinMaxPrompt (FMin, FMax, -1000000000, 1000000000, Abort); if (Abort) { return; } ((FloatItem*) Item)->SetMinMax (FMin, FMax); ResChanged = 1; break; default: ErrorMsg ("Cannot change limits of this item type"); break; } } void ResEditApp::ChangeCharset (WindowItem* Item) { const miReset = 1; const miAddDigits = 2; const miAddHex = 3; const miAddAlpha = 4; const miAddAll = 5; const miCustom = 6; const miAllowEmpty = 7; // Only RStringItem and TextEdits are allowed to change the charset unsigned ID = Item->StreamableID (); if (ID != ID_RStringItem && ID != ID_TextEdit) { ErrorMsg ("Operation not allowed on this type of item"); return; } // Load the menue Menue* M = (Menue*) LoadResource ("@RESITEM.CharsetMenue"); // Change the statusline and activate the menue PushStatusLine (siEnd | siSelectChooseKeys); M->Activate (); CharSet CS; int Done = 0; while (!Done) { String S; int Abort; switch (M->GetChoice ()) { case 0: Done = 1; break; case miReset: CS.Clear (); SetCharSet (Item, CS); ResChanged = 1; break; case miAddDigits: CS = GetCharSet (Item); CS.AddRange ('0', '9'); SetCharSet (Item, CS); ResChanged = 1; break; case miAddHex: CS = GetCharSet (Item); CS.AddRange ('0', '9'); CS.AddRange ('A', 'F'); CS.AddRange ('a', 'f'); SetCharSet (Item, CS); ResChanged = 1; break; case miAddAlpha: CS = GetCharSet (Item); CS.AddRange ('a', 'z'); CS.AddRange ('A', 'Z'); SetCharSet (Item, CS); ResChanged = 1; break; case miAddAll: CS = GetCharSet (Item); CS.AddRange (0x20, 0xFF); SetCharSet (Item, CS); ResChanged = 1; break; case miCustom: S = GetCharSetString (Item); NamePrompt ("Charset", S, Abort); if (!Abort) { SetCharSetString (Item, S); ResChanged = 1; } break; case miAllowEmpty: if (ID == ID_RStringItem) { ((RStringItem*) Item)->AllowEmptyInput (); } else if (ID == ID_TextEdit) { ((TextEdit*) Item)->AllowEmptyInput (); } break; } } // Pop the status line, delete the menue PopStatusLine (); delete M; } void ResEditApp::ChangeSubMenue (WindowItem* Item) { // Try to load the submenue for the item String MenueName = ChooseRes (); if (MenueName.IsEmpty ()) { return; } Streamable* M = LoadRes (MenueName); if (M == 0) { return; } // Check if we really have a menue if (M->StreamableID () != ID_Menue) { ErrorMsg ("Must have a menue object for assignment"); delete M; return; } // Change the submenue ((SubMenueItem*) Item)->SetSubMenue ((Menue*) M); // Resource has changed ResChanged = 1; } void ResEditApp::Order () { // Cast the resource pointer ItemWindow * Win = (ItemWindow *) Res; // Check if the window has items if (Win->ItemCount == 0) { ErrorMsg ("No items - sorry"); return; } PushStatusLine (" Choose the first item"); // Choose the first item WindowItem *Item = ChooseItem (); if (Item == NULL) { // Abort return; } // Unlink this item and place it in front of all other items Win->FirstItem = Item; StatusLine->Replace (" Choose next item"); // Now get one item after the other and place it in a row WindowItem *NextItem; while ((NextItem = ChooseItem ()) != NULL && NextItem != Win->FirstItem) { // If the same item is selected twice, this would result in an error. // Since this happens usually as a result of pressing the wrong key, // print an error message and ignore it. if (NextItem == Item) { ErrorMsg ("Cannot select the same item twice"); } else { NextItem->INode.Unlink (); NextItem->INode.InsertAfter (&Item->INode); Item = NextItem; } } PopStatusLine (); ResChanged = 1; } estic-1.61.orig/spunk/resopt.cc0100644000176100001440000000211307031424704015771 0ustar debacleusers/*****************************************************************************/ /* */ /* RESOPT.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "resed.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ estic-1.61.orig/spunk/resource.cc0100644000176100001440000002726407031424704016322 0ustar debacleusers/*****************************************************************************/ /* */ /* RESOURCE.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "machine.h" #include "object.h" #include "strmable.h" #include "stream.h" #include "nullstrm.h" #include "rescoll.h" #include "resource.h" /*****************************************************************************/ /* struct ResFileHeader */ /*****************************************************************************/ // A valid ResourceFile must have this signature static const u32 ResFileSig = 0x616E6E41; // Header of a resource file struct ResFileHeader { u32 Sig; // Signature u32 Size; // Size including header u32 IndexPos; // Position of index friend Stream& operator << (Stream& S, const ResFileHeader& Header); friend Stream& operator >> (Stream& S, ResFileHeader& Header); // Reading and writing from/to a stream }; Stream& operator << (Stream& S, const ResFileHeader& Header) { S << Header.Sig << Header.Size << Header.IndexPos; return S; } Stream& operator >> (Stream& S, ResFileHeader& Header) { S >> Header.Sig >> Header.Size >> Header.IndexPos; return S; } /*****************************************************************************/ /* class ResourceFile */ /*****************************************************************************/ ResourceFile::ResourceFile (Stream* aStream) : S (aStream), Status (0), Dirty (0), BasePos (0), IndexPos (0), Index (NULL) { // Stream cannot be NULL PRECONDITION (S != NULL); // Get the current stream position BasePos = S->GetPos (); // If the current position is at the end of the stream, this is a new // resource if (BasePos == S->GetSize ()) { // Create a new index collection Index = new ResourceCollection (40, 20); // The index position is after the header IndexPos = BasePos + sizeof (ResFileHeader); // A new ResourceFile is always dirty, because the index is not // written Dirty = 1; } else { // Read the Header of the file ResFileHeader Header; *S >> Header; // Check if the header is correct and the stream status is ok if (S->GetStatus () != stOk) { Status = reStreamError; return; } if (Header.Sig != ResFileSig) { Status = reNoResource; return; } // Get the position of the index from the header IndexPos = Header.IndexPos; // Read the index S->Seek (IndexPos); Index = (ResourceCollection*) S->Get (); if (!Index) { Status = reNoIndex; return; } } // Check for any stream errors (maybe a use for an exception) if (S->GetStatus () != stOk) { Status = reStreamError; } } ResourceFile::~ResourceFile () { // Write changes to the stream (ignore errors) Flush (); // Delete the index delete Index; // Delete the stream delete S; } void ResourceFile::Delete (const String& Key) { int I; // Search the entry if (Index->Search (&Key, I)) { // Found, delete it in the index Index->AtDelete (I); // ResourceFile is dirty now Dirty = 1; } } void ResourceFile::Flush () { // No work if not dirty if (!IsDirty ()) { return; } // Seek to the index position and write the index S->Seek (IndexPos); S->Put (Index); // Create a new header ResFileHeader Header; Header.Sig = ResFileSig; Header.Size = S->GetPos () - BasePos; Header.IndexPos = IndexPos; // Write the header S->Seek (BasePos); *S << Header; // ResourceFile is clean now Dirty = 0; } Streamable* ResourceFile::Get (int Idx) // Get by index { PRECONDITION (Idx >= 0 && Idx < Index->GetCount ()); // Get a pointer to the descriptor ResourceIndex* P = Index->At (Idx); // Load the object S->Seek (P->Offset + BasePos); Streamable* O = S->Get (); // Check the stream status if (S->GetStatus () != stOk) { Status = reStreamError; O = NULL; } // Return the new instance return O; } Streamable* ResourceFile::Get (const String& Key) { int I; // Search for the key if (Index->Search (&Key, I) == 0) { // Not found, return NULL return NULL; } // Now get the object by index return Get (I); } const String& ResourceFile::KeyAt (int I) { // Check the given index PRECONDITION (I >= 0 && I < Index->GetCount ()); // Return a reference to the the name (index is ok now) return Index->At (I)->Name; } int ResourceFile::FindKey (const String& Key) // Try to find the resource with the given name and return the index. // Returns -1 if the key was not found. { int I; // Search for the key if (Index->Search (&Key, I) == 0) { // Not found return -1; } // Found, return the index return I; } void ResourceFile::Put (const Streamable* O, const String& Key) { int I; ResourceIndex* P; // Check if an entry with this key already exists int Found = Index->Search (&Key, I); // Test if the size of the object has changed. If the new size is less // or equal than the old size, we can store the object at the same // position. If the object has grown, it is deleted at the old position // and the Found flag is reset, so that the object is stored at the end // of the stream. if (Found) { // Get a pointer to the entry P = Index->At (I); // Check the new size - the global namespace override handles a bug // in gcc 2.5.8 and is not needed by other compilers size_t NewSize = ::GetSize (*O); if (NewSize <= P->Size) { // The new size is less or equal than the old. Write the object // to the old position S->Seek (P->Offset); S->Put (O); // Remember the new size P->Size = NewSize; } else { // The object has grown. Delete the entry from the index and // reset the Found flag Index->AtDelete (I); Found = 0; } } if (!Found) { // Allocate a new index entry P = new ResourceIndex (Key); // Write the object at the end of the stream S->Seek (IndexPos); S->Put (O); // Store size and position of the object u32 CurPos = S->GetPos (); P->Size = CurPos - IndexPos; P->Offset = IndexPos - BasePos; // New IndexPos is at the end of the stream IndexPos = CurPos; // Insert the entry in the index Index->Insert (P); } // The resource file has been modified Dirty = 1; } Stream* ResourceFile::SwitchTo (Stream* aStream, int PackRes) // Copy the resource file into the stream aStream. If PackRes is not equal // to zero, try to compress the resource file by not copying unused areas. // After calling SwitchTo, the ResourceFile uses the new stream aStream, // the old one is returned (and should be deleted). { // Check parameters PRECONDITION (aStream != 0); // If the new stream is in an error condition, there is not much we can do. // Set the status code and return the given (instead of the old) stream. if (aStream->GetStatus () != stOk) { Status = reStreamError; return aStream; } // Now flush all unwritten stuff Flush (); // Remember the old byte position and use the new one u32 OldBasePos = BasePos; BasePos = aStream->GetPos (); // Handle requests according to PackRes if (!PackRes) { // Calculate how many bytes to copy u32 BytesToCopy = IndexPos - OldBasePos; // Just copy all data S->Seek (OldBasePos); aStream->CopyFrom (*S, BytesToCopy); } else { // Skip the header aStream->Seek (BasePos + sizeof (ResFileHeader)); // Current position is unknown u32 CurPos = 0xFFFFFFFF; // Copy each and every object u32 NewPos; ResourceIndex* P; int Count = Index->GetCount (); for (int I = 0; I < Count; I++) { // Get a pointer to the directory entry P = Index->At (I); // Calculate the position of the object NewPos = P->Offset + OldBasePos; // Seek to the object position if needed if (NewPos != CurPos) { S->Seek (NewPos); } // Store the new object offset (in the new stream!) P->Offset = aStream->GetPos () - BasePos; // Copy the object data aStream->CopyFrom (*S, P->Size); // Remember the current position in the old stream CurPos = NewPos + P->Size; } } // Remember the end position IndexPos = aStream->GetPos (); // Mark the resource file as dirty (the index is still unwritten) Dirty = 1; // Switch to the new stream and return the old one Stream* Res = S; S = aStream; return Res; } int ResourceFile::ObjHasPos (ResourceIndex* P, void* Data) { return (P->Offset == * ((u32 *) Data)); } int ResourceFile::NotMarked (ResourceIndex* P, void*) { return (P->Size & 0x80000000) == 0; } int ResourceFile::ClearMark (ResourceIndex* P, void*) { P->Size &= ~0x80000000; return 0; } void ResourceFile::Pack () // Try to compress the resource file. When an object is deleted from the // reource file, the space is not reused. This means that by repeatedly // deleting and storing the same object, the resource file will grow. This // has no negative impacts on performance, but on the use of memory or disk // space. // // Packing is done by SwitchTo. To avoid unecessary copying of the resource // file, Pack checks if packing is really needed, that is, unused space exists // inside the resource file. // // Algorithm for doing that: // // 0. Current position is base position. // 1. Check if an object is stored at the current position. If no, goto 3, // if yes, goto 2. // 2. Mark the found object by setting bit 31 of the variable Size in the // index entry. Note: This limits the size of a single object to 2GB. // Add the size of the object (beware: the high bit is a flag!) to the // current position and continue with 1. // 3. Are all objects marked? If yes, goto 4, if no, goto 5. // 4. Store the current position into IndexPos (new objects will be added // at this position). Unmark all objects. Goto 7. // 5. Unmark all objects. // 6. Create a new stream and use SwitchTo to copy all data into the new // stream. Reverse this process and truncate the current stream at // IndexPos. Delete the temporary stream. Goto 7. // 7. Done. // { // Set up startiing position u32 CurPos = sizeof (ResFileHeader); // Now check all objects ResourceIndex* ObjWithPos; do { ObjWithPos = Index->Traverse (1, ObjHasPos, &CurPos); if (ObjWithPos != NULL) { // There is an object with this position, update CurPos and // mark the object CurPos += ObjWithPos->Size; ObjWithPos->Size |= 0x80000000; } } while (ObjWithPos != NULL); // The chain of continous objects in the file is broken. Check if all // objects are marked. if (Index->Traverse (1, NotMarked) == NULL) { // All objects are marked, no packing, unmark Index->Traverse (1, ClearMark); // New Index position is at CurPos + BasePos CurPos += BasePos; // If the new and old index positions are not equal, the // file has to be marked as modified. if (CurPos != IndexPos) { Dirty = 1; } // Now remember the new index position IndexPos = CurPos; } else { // File needs packing, clear marks Index->Traverse (1, ClearMark); // Pack the file u32 OldBasePos = BasePos; FileStream* NewStream = new FileStream; Stream* OldStream = SwitchTo (NewStream, 1); OldStream->Seek (OldBasePos); NewStream->Seek (0); delete SwitchTo (OldStream); // Truncate the stream at the current IndexPos S->Seek (IndexPos); S->Truncate (); } } estic-1.61.orig/spunk/resource.h0100644000176100001440000000743607031424704016163 0ustar debacleusers/*****************************************************************************/ /* */ /* RESOURCE.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __RESOURCE_H #define __RESOURCE_H #include "machine.h" #include "object.h" #include "strmable.h" #include "stream.h" #include "rescoll.h" // Error values for status (valid only after calling the constructor) const unsigned reOk = 0; // Status is ok const unsigned reStreamError = 1; // Stream error const unsigned reNoResource = 2; // No resource file const unsigned reNoIndex = 3; // No index present /*****************************************************************************/ /* class ResourceFile */ /*****************************************************************************/ class ResourceFile : public Object { friend class ResEditApp; // Resource editor is a friend private: // Iterator "action" functions static int ObjHasPos (ResourceIndex*, void*); static int NotMarked (ResourceIndex*, void*); static int ClearMark (ResourceIndex*, void*); protected: Stream* S; // Stream to store data in unsigned Status; // Status after init int Dirty; u32 BasePos; // Base position in stream u32 IndexPos; // Index position in the stream ResourceCollection* Index; // Stream index public: ResourceFile (Stream* aStream); // Create a new ResourceFile with the given stream. If there is a valid // signature at the beginning of the stream, an existing ResourceFile is // assumed, otherwise the ResourceFile is created using the given stream. virtual ~ResourceFile (); // Write out all dirty buffers, destruct the ResourceFile object int GetCount () const; // Get the count of stored objects void Delete (const String& Key); // Delete an object with the given key void Flush (); // Flush the ResourceFile (write the index) if it is dirty Streamable* Get (const String& Key); // Get a copy of a stored object by key Streamable* Get (int I); // Get a stored object by index ResourceCollection* GetIndex () const; // Return the resource index int IsDirty () const; // Return true if the ResourceFile has unwritten data const String& KeyAt (int I); // Return the key of the object at the given position int FindKey (const String& Key); // Try to find the resource with the given name and return the index. // Returns -1 if the key was not found. void Put (const Streamable* O, const String& Key); void Put (const Streamable& O, const String& Key); // Store an object into the resource deleting an already existing object // with the same name Stream* SwitchTo (Stream* aStream, int Pack = 0); // Switch to a new stream, eventually packing the resource void Pack (); // Pack the ResourceFile if needed const Stream& GetStream () const; // Get a reference to the stream used unsigned GetStatus () const; // Return the ResourceFile status }; inline int ResourceFile::GetCount () const { return Index->GetCount (); } inline ResourceCollection* ResourceFile::GetIndex () const { return Index; } inline void ResourceFile::Put (const Streamable& O, const String& Key) { Put (&O, Key); } inline int ResourceFile::IsDirty () const { return Dirty; } inline const Stream& ResourceFile::GetStream () const { return *S; } inline unsigned ResourceFile::GetStatus () const { return Status; } // End of RESOURCE.H #endif estic-1.61.orig/spunk/resprint.cc0100644000176100001440000000747407031424704016342 0ustar debacleusers/*****************************************************************************/ /* */ /* RESPRINT.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "resed.h" #include "strcvt.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ int ResEditApp::PrintOneItem (ListNode* Node, void* _F) // Print the data of one menue item { // Get a pointer to the window item WindowItem* I = Node->Contents (); // Create the string String Line (I->GetItemText ()); Line.Trunc (30); Line.Pad (String::Right, 31); String State ("Unknown"); if (I->IsSelected ()) { State = "Selected"; } else if (I->IsActive ()) { State = "Active"; } else if (I->IsGrayed ()) { State = "Grayed"; } Line += State.Pad (String::Right, 16) + I32Str (I->GetID ()).Pad (String::Left, 3) + " " + U32Str (I->GetAccelKey (), 16).Pad (String::Left, 4, '0'); fprintf ((FILE*) _F, "%s\n", Line.GetStr ()); return 0; } void ResEditApp::PrintMenue (FILE* F) // Print the item data into a file { // Cast the resource into type menue GenericMenue* M = (GenericMenue*) Res; // Build some sort of header String Header1 ("Resource: "); Header1 += ResName; String Header2 ("Text State ID Key"); String Header3 (75); Header3.Set (0, 75, '-'); fprintf (F, "%s\n\n", Header1.GetStr ()); fprintf (F, "%s\n", Header2.GetStr ()); fprintf (F, "%s\n", Header3.GetStr ()); // Traverse through the menue, printing data about all items M->Traverse (PrintOneItem, F); } int ResEditApp::PrintOneMsg (Msg* M, void* _F) // Print one message { // Get the line and convert control chars String S (::ShowControls (*M, ccHex | ccCStyle | ccSpunk)); // Convert the string to the current output character set S.OutputCvt (); // Print the line to print fprintf ((FILE*) _F, "%5u \"%s\"\n", M->GetNum (), S.GetStr ()); return 0; } void ResEditApp::PrintMsgCollection (FILE* F) // Print the contents of a message collection { ((MsgCollection*) Res)->Traverse (1, PrintOneMsg, F); } void ResEditApp::Print () { // Name of the output file static String OutFile ("PRN"); // Ask for the file name. The name may be a device like PRN int Abort; NamePrompt (" Output device ", OutFile, Abort); if (Abort) { return; } // Try to open the output file FILE* F = fopen (OutFile.GetStr (), "wt"); if (F == NULL) { ErrorMsg (FormatStr ("Error opening %s", OutFile.GetStr ())); return; } // Decide, what to print switch (ResID) { case ID_MsgCollection: PrintMsgCollection (F); break; case ID_Menue: PrintMenue (F); break; default: ErrorMsg ("Cannot print: Unknown resource type"); break; } // Close the output file (void) fclose (F); } estic-1.61.orig/spunk/resutil.cc0100644000176100001440000001466307031424704016161 0ustar debacleusers/*****************************************************************************/ /* */ /* RESUTIL.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "resed.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ void ResEditApp::DeleteRes () { delete Res; Res = 0; ResID = 0; ResChanged = 0; // Change menue entries MainMenue->GrayItem (miWindow); MainMenue->GrayItem (miItems); MainMenue->GrayItem (miEditActions); MainMenue->GrayItem (miPrint); MainMenue->GrayItem (miWrite); } void ResEditApp::AssignRes (Streamable *NewRes) { GenericMenue* M; // Delete the old resource, assign the new one DeleteRes (); Res = NewRes; ResID = NewRes->StreamableID (); // Change menue entries according to the resource type switch (ResID) { case ID_TopMenueBar: // Move the TopMenueBar into the visible area ((TopMenueBar*)Res)->MoveAbs (Point (0, 1)); case ID_Menue: M = (GenericMenue*) Res; MainMenue->SetToggleValue (miCanMove, M->CanMove ()); MainMenue->SetToggleValue (miCanResize, M->CanResize ()); MainMenue->SetToggleValue (miModal, M->IsModal ()); MainMenue->SetToggleValue (miLRLink, M->HasLRLink ()); MainMenue->SetToggleValue (miIgnoreAccept, M->IgnoreAccept ()); MainMenue->SetToggleValue (miVisible, M->SaveVisible ()); MainMenue->ActivateItem (miWindow); MainMenue->ActivateItem (miItems); MainMenue->ActivateItem (miPrint); if (ResFile) { MainMenue->ActivateItem (miWrite); } M->Show (); break; case ID_MsgCollection: MainMenue->ActivateItem (miEditActions); MainMenue->ActivateItem (miPrint); if (ResFile) { MainMenue->ActivateItem (miWrite); } break; default: DeleteRes (); ErrorMsg ("Unknown resource type, deleting"); break; } } void ResEditApp::NamePrompt (const String &Name, String &Val, int &Abort) { // Calculate the size of the window const Rect& Screen = Background->OuterBounds (); Rect Bounds; Bounds.A.X = 2; Bounds.A.Y = Screen.YSize () / 2; Bounds.B.X = Screen.XSize () - 2; Bounds.B.Y = Bounds.A.Y + 3; // Create a window with an edit item int Length = Name.Len (); EditLine* E = new EditLine (Name, 1, 1024, Bounds.XSize () - Length - 6, NULL); ItemWindow* Win = new ItemWindow (Bounds, wfFramed, paGray, 0, E); // Set the default E->SetValue (Val); // Edit the string E->Edit (Abort); if (!Abort) { Val = E->GetValue (); } // Delete the window including the edit item delete Win; } void ResEditApp::FloatPrompt (const String& Text, double& Val, double Min, double Max, int& Abort) { // Create a new edit item FloatEdit *F = new FloatEdit (Text, 1, 10, 3, NULL); // Calculate the size of the window Rect ScreenSize (Background->OuterBounds ()); Rect Bounds (0, 0, F->MinWidth () + 2, 3); Bounds.Center (ScreenSize, cfCenterAll); // Create a window and insert the edit item F->SetMinMax (Min, Max); ItemWindow *Win = new ItemWindow (Bounds, wfFramed, paGray, 0, F); // Set the default F->SetValue (Val); // Edit the string F->Edit (Abort); if (!Abort) { Val = F->GetValue (); } // Delete the window including the edit item delete Win; } void ResEditApp::LongPrompt (const String & Text, i32 &Val, i32 Min, i32 Max, int &Abort) { // Create a new edit item LongEdit *L = new LongEdit (Text, 1, 8, NULL); // Calculate the size of the window Rect ScreenSize (Background->OuterBounds ()); Rect Bounds (0, 0, L->MinWidth () + 2, 3); Bounds.Center (ScreenSize, cfCenterAll); // Create a window and insert the edit item L->SetMinMax (Min, Max); ItemWindow *Win = new ItemWindow (Bounds, wfFramed, paGray, 0, L); // Set the default L->SetValue (Val); // Edit the string L->Edit (Abort); if (!Abort) { Val = L->GetValue (); } // Delete the window including the edit item delete Win; } void ResEditApp::IDPrompt (i16& ID, int& Abort) { // Use a 32 bit int for temp val i32 ID32 = ID; // Get the id LongPrompt (" ID", ID32, 1, 32000, Abort); ID = (i16) ID32; } void ResEditApp::EditIDPrompt (i16 &ID, int &Abort) { // Use a 32 bit int for temp val i32 ID32 = ID; // Get the id LongPrompt (" Edit ID", ID32, 0, 32000, Abort); ID = (i16) ID32; } void ResEditApp::MinMaxPrompt (i32 &Min, i32 &Max, i32 MinVal, i32 MaxVal, int &Abort) { if (Min < MinVal) { Min = MinVal; } LongPrompt (" Minimum value", Min, MinVal, MaxVal, Abort); if (Abort) { return; } if (Max < Min) { Max = Min; } if (Max > MaxVal) { Max = MaxVal; } LongPrompt (" Maximum value", Max, Min, MaxVal, Abort); if (Abort) { return; } } void ResEditApp::FMinMaxPrompt (double& Min, double& Max, double MinVal, double MaxVal, int &Abort) { if (Min < MinVal) { Min = MinVal; } FloatPrompt (" Minimum value", Min, MinVal, MaxVal, Abort); if (Abort) { return; } if (Max < Min) { Max = Min; } if (Max > MaxVal) { Max = MaxVal; } FloatPrompt (" Maximum value", Max, Min, MaxVal, Abort); if (Abort) { return; } } void ResEditApp::TextIDPrompt (String &Text, i16 &ID, int &Abort) { // Choose the next possible ID ID = NextID (); // Edit the ID IDPrompt (ID, Abort); if (Abort) { return; } // Edit the text NamePrompt (" Text", Text, Abort); } int ResEditApp::SaveResource () // { if (Res && ResChanged) { switch (AskSaveChanges ()) { case 0: //Abort return 0; case 1: // No return 1; case 2: // Yes if (ResFile == NULL) { ErrorMsg ("^!!! No resource file !!!|^" "Choose ~No~ the next time,^" "or open a resource file first!|"); return 0; // Abort; } else { Write (); // Return true only if the save has been successful return (ResChanged == 0); } } } // No change, always successful return 1; } estic-1.61.orig/spunk/reswin.cc0100644000176100001440000001314707031424705015776 0ustar debacleusers/*****************************************************************************/ /* */ /* RESWIN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "resed.h" /*****************************************************************************/ /* class ResEditApp */ /*****************************************************************************/ void ResEditApp::Header () { // Create a pointer alias to the lowest object in the hierarchy that // has a header Window *W = (Window *) Res; int Abort; String Header (W->GetHeader ()); NamePrompt (" New header", Header, Abort); if (!Abort) { W->SetHeader (Header); ResChanged = 1; } } void ResEditApp::Footer () { // Create a pointer alias to the lowest object in the hierarchy that // has a footer Window *W = (Window *) Res; int Abort; String Footer (W->GetFooter ()); NamePrompt (" New footer ", Footer, Abort); if (!Abort) { W->SetFooter (Footer); ResChanged = 1; } } void ResEditApp::Size () { // Create a pointer alias to the lowest object in the hierarchy that // is sizeable Window *W = (Window*) Res; // Remember the old window flags u16 OldFlags = W->Flags; // Enable moving and resizing W->Flags |= wfCanMove | wfCanResize; // Go... W->MoveResize (); // Restore the old flags W->Flags = OldFlags; } void ResEditApp::Color () { // Cast the Resource to the lowest object in the hierarchy that is able // to change the palette Window *W = (Window *) Res; // Decide wich palette switch (SimpleMenue ("Choose palette", "@Blue\n@Gray\n@Cyan\n@Red\nBl@ack\n@Error")) { case 0: // Abort return; case 1: W->SetPalette (paBlue); break; case 2: W->SetPalette (paGray); break; case 3: W->SetPalette (paCyan); break; case 4: W->SetPalette (paRed); break; case 5: W->SetPalette (paBlack); break; case 6: W->SetPalette (paError); break; } // Resource is changed now ResChanged = 1; } void ResEditApp::BackgroundChar () { } void ResEditApp::Number () { } void ResEditApp::IgnoreAccept (int On) { ItemWindow * Win = (ItemWindow *) Res; if (On) { Win->Flags |= wfIgnoreAccept; } else { Win->Flags &= ~wfIgnoreAccept; } ResChanged = 1; } void ResEditApp::Modal (int On) { ItemWindow * Win = (ItemWindow *) Res; if (On) { Win->Flags |= wfModal; } else { Win->Flags &= ~wfModal; } ResChanged = 1; } void ResEditApp::LRLink (int On) { ItemWindow * Win = (ItemWindow *) Res; if (On) { Win->Flags |= wfLRLink; } else { Win->Flags &= ~wfLRLink; } ResChanged = 1; } void ResEditApp::Visible (int On) { ItemWindow* Win = (ItemWindow*) Res; if (On) { Win->Flags |= wfSaveVisible; } else { Win->Flags &= ~wfSaveVisible; } ResChanged = 1; } void ResEditApp::CenterX (int On) { Window *Win = (Window *) Res; if (On) { Win->SetOption (cfCenterX); } else { Win->ResetOption (cfCenterX); } ResChanged = 1; } void ResEditApp::CenterY (int On) { Window* Win = (Window*) Res; if (On) { Win->SetOption (cfCenterY); } else { Win->ResetOption (cfCenterY); } ResChanged = 1; } void ResEditApp::CanMove (int On) { Window* Win = (Window*) Res; if (On) { Win->Flags |= wfCanMove; } else { Win->Flags &= ~wfCanMove; } ResChanged = 1; } void ResEditApp::CanResize (int On) { Window* Win = (Window*) Res; if (On) { Win->Flags |= wfCanResize; } else { Win->Flags &= ~wfCanResize; } ResChanged = 1; } void ResEditApp::Test () { if (ResID == ID_Menue || ResID == ID_TopMenueBar) { // Some sort of Menue GenericMenue *M = (GenericMenue *) Res; // Set it active M->Activate (); // Show a status line StatusLine->Push (siEsc_Abort); // If there are items, work with the menue, else show it if (M->ItemCount > 0) { M->RegisterItemKeys (); while (M->GetChoice () != 0) ; M->UnregisterItemKeys (); } else { int Done = 0; while (!Done) { switch (KbdGet ()) { case vkAbort: case kbEsc: Done = 1; } } } // Deactivate the window, pop the statusline M->Deactivate (); StatusLine->Pop (); // Resource has changed ResChanged = 1; } else { // Wrong type of resource ErrorMsg ("Cannot test this type of resource"); } } estic-1.61.orig/spunk/rng.cc0100644000176100001440000000602507031424705015252 0ustar debacleusers/*****************************************************************************/ /* */ /* RNG.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Random number generator #include "check.h" #include "streamid.h" #include "stream.h" #include "rng.h" // Register the classes LINK (RNG, ID_RNG); /*****************************************************************************/ /* class BaseRNG */ /*****************************************************************************/ u32 BaseRNG::Get (u32 Range) // Get a random number in the range 0..Range-1 { PRECONDITION (Range <= GetRange ()); // Handle ranges < 2 correct if (Range <= 1) { return 0; } else { return GetUnscaled () % Range; } } double BaseRNG::Get () // Get a random number in the range [0.0 .. 1.0[ { return double (GetUnscaled ()) / double (GetRange ()); } /*****************************************************************************/ /* class RNG */ /*****************************************************************************/ RNG::RNG (u32 Seed): Front (1), Rear (0) // Create a random number generator with the given seed { Randomize (Seed); } RNG::RNG (StreamableInit) // Create an empty RNG { } void RNG::Randomize (u32 Seed) // Intialize the RNG for a specific random number stream { // Initialize the state array State [0] = Seed; for (unsigned I = 1; I < sizeof (State) / sizeof (State [0]); I++) { State [I] = 1103515245L * State [I - 1] + 12345; } Front = 1; Rear = 0; // Shuffle the state array for (unsigned J = 0; J < 10 * (sizeof (State) / sizeof (State [0])); J++) { (void) GetUnscaled (); } } u32 RNG::GetUnscaled () // Get an unscaled value from the RNG { // Create the next random number State [Front] += State [Rear]; u32 Val = State [Front]; if (++Front >= sizeof (State) / sizeof (State [0])) { Front = 0; Rear++; } else if (++Rear >= sizeof (State) / sizeof (State [0])) { Rear = 0; } return Val; } u32 RNG::GetRange () const // Return the range of different values, the random number generator // is able to return. { // Oh dear, this is incorrect! return 0xFFFFFFFF; } void RNG::Load (Stream& S) // Load the RNG from a stream { for (unsigned I = 0; I < sizeof (State) / sizeof (State [0]); I++) { S >> State [I]; } S >> Front >> Rear; } void RNG::Store (Stream& S) const // Store the RNG into a stream { for (unsigned I = 0; I < sizeof (State) / sizeof (State [0]); I++) { S << State [I]; } S << Front << Rear; } u16 RNG::StreamableID () const // Return the stream ID of the RNG class { return ID_RNG; } Streamable* RNG::Build () // Return an empty RNG object { return new RNG (Empty); } estic-1.61.orig/spunk/rng.h0100644000176100001440000000506207031424705015114 0ustar debacleusers/*****************************************************************************/ /* */ /* RNG.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Random number generator #ifndef _RNG_H #define _RNG_H #include "strmable.h" /*****************************************************************************/ /* class BaseRNG */ /*****************************************************************************/ // Class BaseRNG is an abstract base class, it defines an interface, not // an implementation class BaseRNG: public Streamable { protected: virtual u32 GetUnscaled () = 0; // Get an unscaled value from the RNG public: virtual void Randomize (u32 Seed) = 0; // Intialize the RNG for a specific random number stream u32 Get (u32 Range); // Get a random number in the range 0..Range-1. // Beware: Range must not be greater than the value returned by GetRange double Get (); // Get a random number in the range [0.0 .. 1.0[ virtual u32 GetRange () const = 0; // Return the range of different values, the random number generator // is able to return. }; /*****************************************************************************/ /* class RNG */ /*****************************************************************************/ // This is a default implementation for the RNG. It uses the polynom // X**63 + X + 1 for random number generation. class RNG: public BaseRNG { u32 State [63]; u16 Front; u16 Rear; protected: RNG (StreamableInit); // Create an empty RNG virtual u32 GetUnscaled (); // Get an unscaled value from the RNG public: RNG (u32 Seed = 0); // Create a random number generator with the given seed virtual void Randomize (u32 Seed); // Intialize the RNG for a specific random number stream virtual u32 GetRange () const; // Return the range of different values, the random number generator // is able to return. virtual void Load (Stream&); // Load the RNG from a stream virtual void Store (Stream&) const; // Store the RNG into a stream virtual u16 StreamableID () const; // Return the stream ID of the RNG class static Streamable* Build (); // Return an empty RNG object }; // End of RNG.H #endif estic-1.61.orig/spunk/screen.h0100644000176100001440000001105207031424705015601 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _SCREEN_H #define _SCREEN_H #include "machine.h" #include "object.h" #include "rect.h" #include "scrmodes.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) extern class Screen* TheScreen; /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ class Screen: public Object { private: u16 XSize; u16 YSize; u16 CurrentMode; // Current video mode int Color; // 1 if color mode, 0 if not int Console; // 1 if console screen, 0 if not int CP437; // 1 if CP437 should be used unsigned char* TransTable; // Translation table for output u16 StartupMode; // Mode before app was active u16 StartupCursor; // Cursor when app became active u16 CF_HiddenCursor; u16 CF_NormalCursor; u16 CF_FatCursor; void TCInit (); // Initialize the termcap system. Used for *nixen only. char* GetIS (char* IS); char* GetRS (char* RS); // Return a replacement for the init strings IS and RS. Used for *nixen // only. void SetModeData (); // Internally called after setting a new mode, sets cursor data etc. unsigned char Translate (unsigned char C); // Translate the char via the translation table u16* Translate (u16* Target, u16* Source, unsigned Len); // Translate a complete buffer via the translation table public: Screen (); ~Screen (); // Put a rectangular buffer region onto the screen void DisplayBuffer (const Rect& R, u16* Buf); // Video mode void SetMode (u16 Mode); u16 GetMode () const; int IsColor () const; int IsConsole () const; // Cursor void SetCursorOn (); void SetCursorOff (); void SetCursorFat (); void SetCursorPos (const Point& Pos); // Screen size u16 GetXSize () const; u16 GetYSize () const; Rect GetSize () const; unsigned TerminalSpeed (); // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. inline void SetTransTable (unsigned char* NewTable); // Set a new translation table. The old table is deleted. NewTable can // be NULL to clear the table. }; inline unsigned char Screen::Translate (unsigned char C) // Translate the char via the translation table { return TransTable? TransTable [C] : C; } inline u16 Screen::GetXSize () const { return XSize; } inline u16 Screen::GetYSize () const { return YSize; } inline Rect Screen::GetSize () const { return Rect (0, 0, XSize, YSize); } inline u16 Screen::GetMode () const { return CurrentMode; } inline int Screen::IsColor () const { return Color; } inline int Screen::IsConsole () const { return Console; } inline void Screen::SetTransTable (unsigned char* NewTable) // Set a new translation table. The old table is deleted. NewTable can be NULL // to clear the table. { delete [] TransTable; TransTable = NewTable; } // End of SCREEN.H #endif estic-1.61.orig/spunk/scrmodes.h0100644000176100001440000000414607031424705016147 0ustar debacleusers/*****************************************************************************/ /* */ /* SCRMODES.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __SCRMODES_H #define __SCRMODES_H #include "machine.h" /*****************************************************************************/ /* Video mode constants */ /*****************************************************************************/ static const u16 vmBW40 = 0x0000; static const u16 vmCO40 = 0x0001; static const u16 vmBW80 = 0x0002; static const u16 vmCO80 = 0x0003; static const u16 vmMono = 0x0007; // Extended modes static const u16 vmVGA_80x25 = vmCO80; static const u16 vmVGA_80x30 = 0x0101; static const u16 vmVGA_80x34 = 0x0102; static const u16 vmVGA_80x43 = 0x0103; static const u16 vmVGA_80x50 = 0x0104; static const u16 vmVGA_80x60 = 0x0105; static const u16 vmVGA_94x25 = 0x0110; static const u16 vmVGA_94x30 = 0x0111; static const u16 vmVGA_94x34 = 0x0112; static const u16 vmVGA_94x43 = 0x0113; static const u16 vmVGA_94x50 = 0x0114; static const u16 vmVGA_94x60 = 0x0115; // Card specific modes static const u16 vmET4_100x40 = 0x012A; // Ask the hardware for the current mode (*nix, X Window) static const u16 vmAsk = 0x0200; // The "don't know" video mode static const u16 vmInvalid = 0xFFFF; // End of SCRMODES.H #endif estic-1.61.orig/spunk/sema.h0100644000176100001440000000640607031424705015256 0ustar debacleusers/*****************************************************************************/ /* */ /* SEMA.H */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // This module defines an envelope class for a binary operating system // supported semaphore. Currently the class is implemented for OS/2 and NT. #ifndef _SEMA_H #define _SEMA_H #include "str.h" /*****************************************************************************/ /* class Semaphore */ /*****************************************************************************/ // Initial semaphore states const unsigned isUnowned = 0x00; const unsigned isOwned = 0x01; /*****************************************************************************/ /* class Semaphore */ /*****************************************************************************/ class SemHandle; class Semaphore: public Object { private: SemHandle* Handle; void Init (const String& Name, unsigned InitialState); // Does the real work for the constructors public: Semaphore (unsigned InitialState = isUnowned); // Create a new, unnamed semaphore with the given initial state Semaphore (const String& Name, unsigned InitialState = isUnowned); // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. Semaphore (const char* Name, unsigned InitialState = isUnowned); // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. virtual ~Semaphore (); // Cleanup semaphore resources void Up (); // Do an up on the semaphore (release it) int Down (i32 Timeout = -1); // Do a down on the semaphore (request it). The function returns 1 (true) // if the request was successful and a zero (false) otherwise. If the // timeout value is < 0 (the default), the wait will be indefinite and the // function will always return 1. }; // End of SEMA.H #endif estic-1.61.orig/spunk/sercom.h0100644000176100001440000002214107031424705015613 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library. // Beware: Some functions are no ops on some architectures, others do not // return exact values. You may assume a specific behaviour, but your // programs will not be portable then. #ifndef _SERCOM_H #define _SERCOM_H #include "strmable.h" #include "str.h" /*****************************************************************************/ /* Data and Types */ /*****************************************************************************/ // Constants for accessing the array of error counters const ceRXOverflow = 0; // Receive buffer overflow const ceTXOverflow = 1; // Transmit buffer overflow const ceOverrun = 2; // UART overrun const ceBreak = 3; // Break received const ceFrame = 4; // Framing error const ceParity = 5; // Parity error // Bitmask constants for evaluating the result of ModemStatus const csDeltaCTS = 0x01; // Delta CTS const csDeltaDSR = 0x02; // Delta DSR const csDeltaRI = 0x04; // Falling edge of RI const csDeltaCarrierDetect = 0x08; // Delta CD const csClearToSend = 0x10; // Clear To Send const csDataSetReady = 0x20; // Data Set Ready const csRingIndicator = 0x40; // Ring Indicator const csCarrierDetect = 0x80; // Carrier Detect const csCTS = csClearToSend; const csDSR = csDataSetReady; const csRI = csRingIndicator; const csCD = csCarrierDetect; const csDeltaCD = csDeltaCarrierDetect; // Type of an array with error counters typedef u16 ComErrorCounter [6]; /*****************************************************************************/ /* class ComPort */ /*****************************************************************************/ // All implementation dependant data is contained in a structure that is // defined in the CC file. Make a forward declaration here. struct _ComData; // ComPort class class ComPort: public Streamable { private: _ComData* ComData; // Pointer to implementation data // ComPort parameters String PortName; u32 Baudrate; char Databits; char Parity; char Stopbits; char Connection; char XonXoff; u16 RXBufSize; u16 TXBufSize; double RXTimeout; double TXTimeout; void Init (unsigned UARTBase = 0, unsigned IntNum = 0); // Initialization procedure, called from the constructors public: ComPort (const String& aPortName, u32 aBaudrate = 9600, char aDatabits = 8, // 5..8 char aParity = 'N', // one, dd, ven, ark, pace char aStopbits = 1, // 1, 2 char aConnection = 'M', // irect, odem char aXonXoff = 'D', // nabled, isabled unsigned UARTBase = 0, // I/O base address, DOS only unsigned IntNum = 0 // Number of interrupt used, DOS only ); // Create a ComPort object, use defaults for timeouts and buffer sizes virtual ~ComPort (); // Destruct a ComPort object void SetBufferSize (u16 aRXBufSize, u16 aTXBufSize); // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. unsigned Open (); // Open the port, return an error code or 0 on success void Close (); // Close the port int IsOpen () const; // Return a value != zero if the port is opened, return 0 otherwise void SetRXTimeout (double aRXTimeout); // Set the timeout value void SetTXTimeout (double aTXTimeout); // Set the timeout value double GetRXTimeout () const; // Get the timeout value double GetTXTimeout () const; // Get the timeout value void DTROn (); // Make the DTR line active void DTROff (); // Make the DTR line inactive void RTSOn (); // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem void RTSOff (); // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem unsigned RXCount () const; // Return the count of chars in the receive buffer, or just true 1 if the // exact amount of chars in the buffer cannot be determined and the value // is at least one. unsigned TXCount () const; // Return the count of chars in the transmit buffer. This function must // not exist, as it is impossible to determine the return value on some // operating systems. void RXClear (); // Clear the receive buffer. Maybe implemented as a no op function. void TXClear (); // Clear the transmit buffer. Maybe implemented as a no op function. unsigned TXFree () const; // Return the amount of free space in the transmit buffer. The function // may return the exact free space or just 1, if at least one character // can be placed into the send buffer (meaning, the Send function will // not block). int Receive (); // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. int Send (unsigned char B); // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. int TimedReceive (); // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. int TimedSend (unsigned char B); // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. void TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount); // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. void TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount); // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. void Break (double Duration); // Send a break with the given time in seconds ComErrorCounter& GetErrors (); // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. On some // architectures com errors are handled by the operating system, so // there is no way to get this information. If this is true, all counters // will always be zero. unsigned ModemStatus () const; // Return the state of the modem status lines const String& GetPortName () const; // Return the name of the port }; inline double ComPort::GetRXTimeout () const // Get the timeout value { return RXTimeout; } inline double ComPort::GetTXTimeout () const // Get the timeout value { return TXTimeout; } inline const String& ComPort::GetPortName () const // Return the name of the port { return PortName; } // End of SERCOM.H #endif estic-1.61.orig/spunk/serstrm.cc0100644000176100001440000001241707031424705016165 0ustar debacleusers/*****************************************************************************/ /* */ /* SERSTRM.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // A serial character stream using the sercom module. #include "serstrm.h" /*****************************************************************************/ /* class SerialStream */ /*****************************************************************************/ SerialStream::SerialStream (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned UARTBase, unsigned IntNum): Port (aPortName, aBaudrate, aDatabits, aParity, aStopbits, aConnection, aXonXoff, UARTBase, IntNum) // Create a SerialStream object, use defaults for timeouts and buffer sizes { // Set the buffer sizes to something big SetBufferSize (2048, 2048); // Open the port unsigned Result = Port.Open (); if (Result != 0) { Error (stInitError, Result); return; } // Activate the DTR line Port.DTROn (); } SerialStream::~SerialStream () // Close the port { // Beware: We may have had an error if (Port.IsOpen ()) { // Deactivate the DTR line Port.DTROff (); // Close the port Port.Close (); } } void SerialStream::SetBufferSize (unsigned aRXBufSize, unsigned aTXBufSize) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. { Port.SetBufferSize (aRXBufSize, aTXBufSize); } void SerialStream::SetReadTimeout (double T) // Set the read timeout for the stream. // A value of zero means no timeout (error if data not immidiately // available) a value less than zero means "indefinite wait". // Beware: The implementation of the timeout is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. { // Set the timeout and re-read it Port.SetRXTimeout (T); ReadTimeout = Port.GetRXTimeout (); } void SerialStream::SetWriteTimeout (double T) // Set the write timeout for the stream. // A value of zero means no timeout (error if data cannot be written // immidiately) a value less than zero means "indefinite wait". // Beware: The implementation of the timeouts is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. { // Set the timeout and re-read it Port.SetTXTimeout (T); ReadTimeout = Port.GetTXTimeout (); } size_t SerialStream::ReadCount () const // Return the amount of bytes that can be read without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be read without // blocking and 0 otherwise. { return Port.RXCount (); } size_t SerialStream::WriteCount () const // Return the amount of bytes that can be written without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be written without // blocking and 0 otherwise. { return Port.TXFree (); } void SerialStream::Read (void* Buf, size_t Count) // Read from the stream { // Ignore zero sized reads if (Count == 0) { return; } // Be shure to read only if the status is ok if (GetStatus () == stOk) { // Try to read the given amount of characters u32 ReadCount; Port.TimedReceiveBlock (Buf, Count, ReadCount); // If we did not get all characters, we have a timeout condition if (ReadCount != Count) { Error (stReadTimeout, ReadCount); } } } void SerialStream::Write (const void* Buf, size_t Count) // Write to the stream { // Ignore zero sized writes if (Count == 0) { return; } // Be shure to write only if the status of the stream is ok if (GetStatus () == stOk) { // Try to write the given amount of characters u32 WriteCount; Port.TimedSendBlock (Buf, Count, WriteCount); // If we could not write all characters, we have a timeout condition if (WriteCount != Count) { Error (stWriteTimeout, WriteCount); } } } estic-1.61.orig/spunk/serstrm.h0100644000176100001440000000762007031424705016027 0ustar debacleusers/*****************************************************************************/ /* */ /* SERSTRM.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // A serial character stream using the sercom module. #ifndef _SERSTRM_H #define _SERSTRM_H #include "sercom.h" #include "charstrm.h" /*****************************************************************************/ /* class SerialStream */ /*****************************************************************************/ class SerialStream: public CharacterStream { protected: ComPort Port; public: SerialStream (const String& aPortName, u32 aBaudrate = 9600, char aDatabits = 8, // 5..8 char aParity = 'N', // one, dd, ven, ark, pace char aStopbits = 1, // 1, 2 char aConnection = 'M', // irect, odem char aXonXoff = 'D', // nabled, isabled unsigned UARTBase = 0, // I/O base address, DOS only unsigned IntNum = 0 // Number of interrupt used, DOS only ); // Create a SerialStream object, use defaults for timeouts and buffer sizes virtual ~SerialStream (); // Close the port void SetBufferSize (unsigned aRXBufSize, unsigned aTXBufSize); // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. virtual void SetReadTimeout (double T); // Set the read timeout for the stream. // A value of zero means no timeout (error if data not immidiately // available) a value less than zero means "indefinite wait". // Beware: The implementation of the timeout is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. virtual void SetWriteTimeout (double T); // Set the write timeout for the stream. // A value of zero means no timeout (error if data cannot be written // immidiately) a value less than zero means "indefinite wait". // Beware: The implementation of the timeouts is device dependent! As an // example, there may be devices that cannot do timeouts less than one // second. virtual size_t ReadCount () const; // Return the amount of bytes that can be read without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be read without // blocking and 0 otherwise. virtual size_t WriteCount () const; // Return the amount of bytes that can be written without waiting. On many // devices it is impossible to tell the exact number, in these cases the // function returns a value of 1 if at least one byte can be written without // blocking and 0 otherwise. virtual void Read (void* Buf, size_t Count); // Read from the stream virtual void Write (const void* Buf, size_t Count); // Write to the stream }; // End of SERSTRM.H #endif estic-1.61.orig/spunk/settings.cc0100644000176100001440000001606607031424705016332 0ustar debacleusers/*****************************************************************************/ /* */ /* SETTINGS.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This module declares functions to work with program options (settings). // Settings are stored in a class derived from class ResourceFile that is // used internally. The external interface is a procedural one - this allows // the functions to check for a non existing or not open settings resource. // A not existing file is transparent to the programmer, the functions behave // as if the key did not exist (when calling OptGet...) and ignore the data // (when calling OptPut). #include "rect.h" #include "filepath.h" #include "memstrm.h" #include "resource.h" #include "settings.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Flag that says if we should flush the Settings file after every write // access. Safe but slow. static int FlushAlways; // Global pointer to the one and only settings database static class ResourceFile* Settings = NULL; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void StgFlushAlways () // Flush the file if the FlushAlways flag is set. This function is called // after every write { if (Settings && FlushAlways) { Settings->Flush (); } } unsigned StgOpen (const String& Filename, int MustFlush) // Filename is expanded (made absolute) and the function tries to open a // settings database with this name. If the database does not exist, a new // one is created. A ResourceFile error code is returned (which is zero if // no error occured). If there is an error, the database is deleted and all /// other functions just ignore the data as explained above. { // If there is already a settings object, something is wrong PRECONDITION (Settings == NULL); // Remember the flag FlushAlways = MustFlush; // Try to create the object Settings = new ResourceFile (new FileStream (MakeAbsolute (Filename))); // Check for errors unsigned Result = Settings->GetStatus (); if (Result != reOk) { // An error occurred delete Settings; Settings = NULL; } else { // In case we just created the file, flush it, so the file contents // are valid StgFlushAlways (); } // Ok, done return Result; } void StgClose () // Close the settings database { if (Settings) { // If the status is ok, pack the file if (Settings->GetStatus () == reOk) { Settings->Pack (); } // Delete the file delete Settings; Settings = NULL; } } int StgEmpty () // Return true if the settings file is empty, that is, it does not contain // any resources { return Settings == 0 || Settings->GetCount () == 0; } void StgFlush () // Flush the settings database to disk { if (Settings) { Settings->Flush (); } } Streamable* StgGet (const String& Name) // Read an object from the settings database, returns NULL if the key was not // found or the database does not exist. { if (Settings) { return Settings->Get (Name); } else { // No database return NULL; } } Point StgGetPoint (const String& Name, const Point& Default) // Return a point (position) or the default if there is no matching // key in the resource. { // As Point is not a Streamable object there is some work to read/write // a Point. The way to do it is to use a MemoryStream object that holds // the Point and read/write this MemoryStream object. MemoryStream* M = (MemoryStream*) StgGet (Name); if (M == NULL) { // No such key return Default; } else { // Found! Get the Point from the MemoryStream and delete it Point P; *M >> P; delete M; return P; } } Point StgGetPoint (const String& Name, int XDef, int YDef) // Return a point (position) or the default if there is no matching // key in the resource. { return StgGetPoint (Name, Point (XDef, YDef)); } Rect StgGetRect (const String& Name, const Rect& Default) // Return a rect or the default if there is no matching key // in the resource. { // As Rect is not a Streamable object there is some work to read/write // a Rect. The way to do it is to use a MemoryStream object that holds // the Rect and read/write this MemoryStream object. MemoryStream* M = (MemoryStream*) StgGet (Name); if (M == NULL) { // No such key return Default; } else { // Found! Get the Rect from the MemoryStream and delete it Rect R; *M >> R; delete M; return R; } } String StgGetString (const String& Name, const String& Default) // Return a String or the default if there is no matching key in the // resource. { String* S = (String*) StgGet (Name); if (S == NULL) { // Key not found return Default; } else { String T = *S; delete S; return T; } } void StgPut (const Streamable* Obj, const String& Name) // Put an object into the settings database { if (Settings) { Settings->Put (Obj, Name); StgFlushAlways (); } } void StgPutPoint (const Point& P, const String& Name) // Write a Point object into the settings database { if (Settings) { // As Point is not a Streamable object there is some work to read/write // a Point. The way to do it is to use a MemoryStream object that holds // the Point and read/write this MemoryStream object. MemoryStream M (sizeof (Point)); M << P; Settings->Put (M, Name); StgFlushAlways (); } } void StgPutRect (const Rect& R, const String& Name) // Write a Rect object into the settings database { if (Settings) { // As Rect is not a Streamable object there is some work to read/write // a Rect. The way to do it is to use a MemoryStream object that holds // the Rect and read/write this MemoryStream object. MemoryStream M (sizeof (Rect)); M << R; Settings->Put (M, Name); StgFlushAlways (); } } estic-1.61.orig/spunk/settings.h0100644000176100001440000000736207031424705016173 0ustar debacleusers/*****************************************************************************/ /* */ /* SETTINGS.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __SETTINGS_H #define __SETTINGS_H // This module declares functions to work with program options (settings). // Settings are stored in a class derived from class ResourceFile that is // used internally. The external interface is a procedural one - this allows // the functions to check for a non existing or not open settings resource. // A not existing file is transparent to the programmer, the functions behave // as if the key did not exist (when calling StgGet...) and ignore the data // (when calling StgPut). #include "rect.h" #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned StgOpen (const String& Filename, int FlushAlways = 1); // Filename is expanded (made absolute) and the function tries to open a // settings database with this name. If the database does not exist, a new // one is created. A ResourceFile error code is returned (which is zero if // no error occured). If there is an error, the database is deleted and all /// other functions just ignore the data as explained above. // If FlushAlways is set != zero, the settings file is flushed after every // write to prevent the file from becoming corrupted in case of a program // crash. void StgClose (); // Close the settings database int StgEmpty (); // Return true if the settings file is empty, that is, it does not contain // any resources void StgFlush (); // Flush the settings database to disk Streamable* StgGet (const String& Name); // Read an object from the settings database, returns NULL if the key was not // found or the database does not exist. Point StgGetPoint (const String& Name, const Point& Default); // Return a point (position) or the default if there is no matching // key in the resource. Point StgGetPoint (const String& Name, int XDef, int YDef); // Return a point (position) or the default if there is no matching // key in the resource. Rect StgGetRect (const String& Name, const Rect& Default); // Return a rect or the default if there is no matching key // in the resource. String StgGetString (const String& Name, const String& Default); // Return a String or the default if there is no matching key in the // resource. void StgPut (const Streamable* Obj, const String& Name); // Put an object into the settings database inline void StgPut (const Streamable& Obj, const String& Name) // Put an object into the settings database { StgPut (&Obj, Name); } void StgPutPoint (const Point& P, const String& Name); // Write a Point object into the settings database void StgPutRect (const Rect& R, const String& Name); // Write a Rect object into the settings database inline void StgPutString (const String& S, const String& Name) // Write a String object into the settings database { StgPut (S, Name); } // End of SETTINGS.H #endif estic-1.61.orig/spunk/sock.h0100644000176100001440000000147007031424705015264 0ustar debacleusers/*****************************************************************************/ /* */ /* MEMCHECK.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Class wrapper for TCP/IP sockets #ifndef _SOCK_H #define _SOCK_H #include "machine.h" /*****************************************************************************/ /* class Socket */ /*****************************************************************************/ class Socket: public Object { public: Socket ( // End of SOCK.H #endif estic-1.61.orig/spunk/splitmsg.cc0100644000176100001440000000752007031424705016327 0ustar debacleusers/*****************************************************************************/ /* */ /* SPLITMSG.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "splitmsg.h" /*****************************************************************************/ /* */ /*****************************************************************************/ ListNode* SplitLine (String Text, Rect &Bounds, unsigned MinLen) // Split the given string into a list of lines. MinLen is used if any of the // lines is requested to be centered. In this case, MinLen is the minimum // length of the centered line (used in windows with header strings). { String* S; // Check the parameters unsigned Len = Text.Len (); PRECONDITION (Len > 0); // Initialize bounds Bounds.A.X = Bounds.A.Y = 0; // Split the text into lots of lines remembering the longest line int Longest = MinLen; ListNode* Node = NULL; while (Len) { // Get the end of the line int Pos = Text.Pos ('\n'); // int L; if (Pos < 0) { // Last line S = new String (Text); L = Text.Len ("@~"); if (L > Longest) { Longest = L; } Len = 0; } else { // Cut the piece from the string, deleting the newline S = new String (Text.Cut (0, Pos)); Text.Del (0, Pos + 1); Len -= Pos + 1; // Get the length and compare to Longest L = S->Len ("@~\x01"); // Do not count caret/bar/center if (L > Longest) { Longest = L; } } // Create a new listnode ListNode* N = new ListNode (S); // Insert this node into the list if (Node) { N->InsertBefore (Node); } else { Node = N; } } // Now the length of the longest line is in Longest. Walk through // the line list, delete the center char and center lines if requested. // Count the nodes ListNode* N = Node; int Count = 0; do { // Get pointer to line String& S = *(N->Contents ()); Count++; // Check for center flag if string is not empty if (S.IsEmpty () == 0 && S [0] == '\x01') { // Delete the center flag S.Del (0, 1); // Center the string S.Pad (String::Center, Longest); } // Set next node N = N->Next (); } while (N != Node); // Set up the surrounding rectangle Bounds.B.X = (i16) Longest; Bounds.B.Y = (i16) Count; // Return the list return Node; } void ReleaseLines (ListNode *Node) // Release a line list build from SplitLine { ListNode *N = Node; while (!Node->IsEmpty ()) { // Get the next node and unlink it N = Node->Next (); N->Unlink (); // Delete the contents of the node and the node delete N->Contents (); delete N; } // Now delete the root node delete Node->Contents (); delete Node; } estic-1.61.orig/spunk/splitmsg.h0100644000176100001440000000310107031424705016160 0ustar debacleusers/*****************************************************************************/ /* */ /* SPLITMSG.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __SPLITMSG_H #define __SPLITMSG_H #include "listnode.h" #include "rect.h" #include "str.h" /*****************************************************************************/ /* */ /*****************************************************************************/ ListNode * SplitLine (String Text, Rect &Bounds, unsigned MinLen = 0); // Split the given string into a list of lines. MinLen is used if any of the // lines is requested to be centered. In this case, MinLen is the minimum // length of the centered line (used in windows with header strings). void ReleaseLines (ListNode *Node); // Release a line list build from SplitLine // End of SPLITMSG.H #endif estic-1.61.orig/spunk/spunk.chg0100644000176100001440000013664507031424706016015 0ustar debacleusers12.02.95: Changed identifiers "EntryCount" to "GetCount". This affects the collection classes and the ResourceFile class. Added a name member and a function to access it to class FileStream. It is now possible to retrieve the name of the associated file. Changed a lot of virtual template functions from inline to extern linkage. Added functionality to class FileViewer. 13.02.95: Added some more (Watcom specific) signal handling functions to class Thread. Changed the behavior of class Program when the resource file is not found. Added functionality to class FileViewer. Added dynamic left/right links to the window items in Menue::GetChoice. This is switchable through a flag defined in itemwin.h. Extended the resource editor to be able to set/reset this flag. Changed signal handling in class Thread: The signal handler is reinstalled before calling the signal specific virtual functions. If the signal handler is reinstalled after calling the handling function, the function cannot use longjmp to return from the handler. Changed the default handling of a few signals, including SIGBREAK. The new default is to reraise the signal without reinstalling the signal handler. This prevents the creation of "uninterruptible" programs by default. Changed the check for vkAbort in FileViewer::Browse to be done after the call to HandleKey. That way, HandleKey can change the key to vkAbort if desired. 20.02.95: Changed TEXTSTRM.CC, files containing a Ctrl-Z (OS/2 and MS-DOS) are now handled correctly. 21.02.95: New system dependent file filesys.h/filesys.cc. Some information contained in machine.h was moved to filesys, some identifiers changed. Lots of new functions in module filepath. Prepared a new target DOS4G. 22.02.95: Implemented a new target DOS4G (Watcom specific, DOS4G dos extender). Rewrote dossrc\kbd.cc, dossrc\screen.cc. Implemented lots of new (tweaked) video modes for DOS and some of them also for OS/2. Complete rewrite of the makefile. It is now possible to build all targets (excluding Linux) from DOS or OS/2. Extended and documented the string class. New module charset implementing class CharSet. Lots of changes in class BitSet (made parameters const if possible). Started to implement class FileSelector. 23.02.95: New module filecoll. New functions in module filepath: DelPathSep, FIsAbsolute. New file borstat.h. Prepared linuxsrc/filesys.cc Renamed the keyboard object to Kbd. Redesigned the KeyMapper object. Changed the target specific kbd.cc and screen.cc files. Removed the frame characters from the winattr.cc files and put them in a file for there own (frame.cc), because they are no longer system dependent. Removed the definition of the additional chars and made them constants in the .h file for the same reason. 24.02.95: Rewrote the linux specific files. Started port to linux. Some small changes to improve compatibilty and to overcome minor problems. Keyboard module and color output to console already working. 25.02.95: Did terminal support for linux. More termcap entries, monochrome support, keyboard support for terminals. Did many optimizations on screen output. Previously I assumed, that the actual output to the screen is cheaper than searching through the window stack. This changed when serial terminal support appeared. Sometimes there were 4 updates of the same screen area without any user input! 26.02.95: Lots of minor changes to adopt the bevavior to linux. Added the name of the help file to class Program. The existance of the help file is checked when the program is started. Added an additional parameter for Keyboard::GetMappedKey (default has not changed). Changed behavior of KeyBoard::Peek: The function will now return immediately with a return value of kbNoKey if no key is available. Changed the complete handling of key names. Key names are now loaded from the resource. Changed the handling of virtual/normal keys. There are more virtual keys now (any key that has a function in his name should be virtual to be remappable). Added code to the keyboard classes to handle that. Old code will work, as long as no kbXXXX constants are used that are now virtual keys (check keydef.h for that). Changed the function Collection::Load: Items loaded with GetItem are not longer inserted directly but via Insert. This handles the case, when the sort order of a sorted collection has changed while the collection has been on disk. A good example for that is a string collection that is sorted by national conventions and that is transfered to another country. The old code would break, the new one will resort the collection when loading. Changed the default string compare in module str and other places from strcmp to strcoll. Removed an error from String::Len (const char*) which caused an endless loop when the parameter has length 1. 27.02.95: Spitted module national into a target specific initialization file, nlsinit.cc and a generic module national.cc. Complete rewrite of the NLS system. There are now functions to set different countries and languages. Both resource files (english and german) combined. ResourceFile::Get now searches first for the language specific version of a resource, the tries to load a generic version. Fixed a bug in GetEnvNum. Fixed a bug in Container::LoadData. 28.02.95: Renamed Collection::Error to Collection::CollError to avoid confusion in programs that have a (global) function Error. Member functions of a class derived from Collection will call Collection::Error instead without any warnings by compiler or linker. Changed secondary mappings for many virtual keys to something more WordStar(tm) compatible. Changed StringParser::GetFloat not to use pow, so the math library is not needed to link classlib programs. Fixed a bug in Window::CWrite: The function did not account for '~' chars when clipping the length. More optimizations for display update speed. Made functions to change the state of a window item virtual. New functions WindowItem::DrawItemText, MenueItem::DrawItemText. 02.03.95: Fixed a bug in menue.cc: Menue::SetStringValue did not know about PasswordEdits. New function in module keydef: GetKeyName3(). Changed class TextStream to expand tab characters when reading in a line from a file. 03.03.95: New module progutil. Adapted all other modules to use progutil. New functions in class Program to support an application message base. Removed the constant MSGBASE_USER from msgid.h. Programs using this constant must be changed to use an application message base (this allows easier updating of resources since the message bases don't have to be merged when updating, merging the resources is sufficient). Added more error checking to Stream.Get/Stream.Put/Stream.Read. Added check for duplicate class ids to the constructor of StreamableClass (yes, I learned it the hard way :-). 04.03.95: Changed FileViewer::DrawLine to work with buggy gcc. Changed siEsc_Abort in FileViewer::Browse to siEsc_End. 10.03.95: Added the capability to lock the window system when using more than one thread (OS/2). 20.03.95 - 27.03.95: Some small changes. Added more virtual keys (vkOpen, vkQuit, etc.) so existing programs have to be changed again (I'm sorry, but this may happen again). Fixed a bug in Window::Activate, the window that should be activated has to be unlinked from the chain of active windows in case it's already in there. 28.03.95: Rewrote the Collection and ListNode template classes to use an underlying implementation class that has the complete functionality but uses void pointers. This should result in smaller programs (I hope). Because of overloading problems, the return type of Collection::GetItem changed from T* to void*. This may cause changes in application programs. 39.03.95 - 31.03.95: More rewrites to save some space. Added a few utility member functions to some classes: RootWindow::RedrawScreen, Program::RedrawScreen, etc. 01.04.95: Added support for a frame in a special color when the window is resizing. Added another virtual key, vkSave plus the mappings for this key in the keyboard layers. Added window flags wfCanMove and wfCanResize. This is a start to get the move & resize capability of windows into the library. 02.04.95: Wrote some code for the file selector 03.04.95: Documented the window module. Changed Window::MaxX and Window::MaxY to return the correct maximum X/Y coordinate. Until now, both functions returned the size of the inner window which is one more than the maximum allowed X/Y position because X/Y positions are 0/0 base. This may break application code in a few places. 05.04.95: Many small changes and additions to support moving and resizing of menues and windows. 07.04.95: Changed the ListBox constructor to accept an additional argument (the palette index of the selected entry when the listbox is not selected). You have to change your derived constructors. Fixed a bug in the linux keyboard handler: Switching to escape prefix mode did not work ("Thou shalt check return codes"). 10.04.95 - 12.04.95: SIGWINCH now works under Linux. Small changes and some more bug fixes in the Linux keyboard and screen handlers. Translation tables in module screen are now loaded from the resource file. Added a function Program::Idle that is currently called from the Linux keyboard handler (this is used to handle SIGWINCH). Program::Idle is currently not called in DOS & OS/2. 27.04.95: The library finally got a name; it is now called SPUNK after a (fantasy) desease created by Pippi Langstrumpf. Fixed a bug in the Linux keyboard handler that was not noticed by g++ 2.5.8: Class KeyMapper cannot inherit private from class SortedCollection. (Thanks to Thomas Faehnle, thomas.faehnle@student.uni-ulm.de). Wrote the first part of the documentation. 28.04.95: Fixed a bug in program.cc: The resource file should be opened for read access only. Thanks to Jim Ockers, ockers.umr.edu. 30.04.95: Made argc and argv required parameters to the constructor of class Program. They will be expanded if the program is running under OS/2 or DOS. Changed Program::Program to take notice of argc/argv. Moved Program::Idle to Thread::Idle. Started to write an X backend for SPUNK. 10.05.95: Changed the crc block functions in crcccitt.cc and crc16.cc to work with blocks of size zero. 11.05.95: Added a function FSize to module filepath. Added an additional parameter (with default value) to function SplitLine. 17.05.95: Changed the pack function of the resource editor (ResEdApp::Pack) to flush the index after packing the file. This way, the resource file is in a valid state and still usable if the editor crashes. Changed the minimum size of a framed window from 4 to 3. 19.05.95: Fixed a bug in FloatItem::MinWidth. The function did not account for the trailing digits. 21.05.95: Fixed a bug in Window::SetWindowNumber that caused the function not to set the given number as new window number. 22.05.95: Fixed two bugs. ItemWindow::Load now does a SetWidth on every item. This causes a reset of the entry text. OffOnItem::Load and NoYesItem::Load now do a reset of the current displayed value string. 23.05.95: Added overloaded search functions requiring char pointers instead of Strings to module inifile. This should make programs smaller. 29.05.95: Added a workaround for a bug that pops up when moving simple text windows: When aborting a move/resize command, Window::Resize has been used to restore the original position of the window. Since Window::Resize does destroy the window contents and a simple text window does not know how to redraw it's interior, this caused the window contents to vanish. MoveResize now uses Window::Move if the size of the window has not changed. 30.05.95: Added a new function Screen::TerminalSpeed(). Wrote another part of the file selector. New overloaded function FSplit in module filepath. The new function does not split name and extension. Made lots of member function of class FileInfo const. Added a new functions ListBox::At() and ListBox::GetSelection(). Added defintions for symbolic links and sockets to borstat.h and renamed it to statdef.h. Fixed a bug in FileEdit::CharIsOk(): The function did not accept a colon even if the file system supports drives. Added a field fsCurDir to the FileSysInfo struct in module filesys. Added a function CleanPath to module filepath. 31.05.95: Made the constants in module filesys external to avoid compiler warnings about unreachable code. Added functionality to modules filesys and filepath. 01.06.95: Worked on the file selector. Added functions to modules filesel/filesys/ filepath. Fixed some bugs in these modules. 02.06.95: Worked around a watcom bug in module filepath. Changed the german time separator from '.' to ':' ('.' is the "official" time separator, but no one uses it). Many more changes in filesel/filesys/filepath. Completed most work on the file selector. 03.06.95: Changes in statflag.h, statline.cc etc. 04-08.06.95: Did some tuning on the file selector and related functions. Changed the key names (Ctrl-X is now Ctrl+X, Esc+Esc is now Esc-Esc). Added some stuff to the statusline. Started to add context sensitive help to the library. 09.06.95: Fixed a serious design bug in class StringPool. Class StringPool should not hold any pointers to items contained in an object of class MemPool. Whenever the buffer memory of class MemPool is expanded, all those pointers are becoming invalid. 18.06.95/19.06.1995: Fixed some portability bugs: The resource file header has been read in binary form from the stream. This prevents byte swapping on big endian cpus. In module stream, the "old style" data type were used instead of the fixed size ones. Introduced conditional defines CPU_LITTLE_ENDIAN and CPU_BIG_ENDIAN (must be defined in machine.h). New module cpucvt that converts the basic data types to and from the external format. Changed the stream module to do those conversions on read and write of integer data types. 22.06.95: Fixed a bug in module itemwin: The ItemWindow member functions to change the state of a specific item should check SelectedItem after changing the state. StringItem had a wrong pad spec, the input should be displayed left, not right padded. Fixed a bug in the resource editor (module resitem): After changing the text of an item, the complete item string has to be rebuild, otherwise the new text is not displayed. 27.06.95-28.06.95: Started to implement a serial communication module for all platforms. This will be similar to the OS/2 user.cc module and will be named sercom. The user module will be rewritten as needed (only a few small changes). DOS support finished but not tested. 29.06.95: Added functionality to class CharSet. Changed implementation of class TextEdit. THIS WILL MAKE OLD RESOURCES CONTAINING TextEdit OBJECTS INCOMPATIBLE. Added a new item class RStringItem. Changed the resource editor to use the new class and to provide a more object orientated approach when editing window items. 30.06.95: Added a new member function ItemWindow::PlaceNear (const Point&). Fixed a bug in module filesel: If a default extension has been specified and the file did not exist, the default extension has been added to the file name without checking if there has been already a default extension. 01.07.95: Tested and debugged the DOS sercom module. Converted the old OS/2 user module to sercom and made the user module obsolete. 02.07.95: Ported the sercom module to 32-bit DOS (DOS4G) and to Linux. 03.07.95: Deleted a Clear() statement in Window::ScreenSizeChanged() that was not needed. Changed class IniFile to support hex constants when reading integers from the ini file (functions ReadInt and GetInt). Changed class StringParser in module strparse to allow hex and octal values. Added support for big endian IEEE doubles in modules cpucvt and stream. 04.07.95: Included string.h instead of mem.h/memory.h where possible, because including string.h does not need a #ifdef . Removed a conditional include of unistd.h where stdlib.h is sufficient. Removed the target specific assembler code from the crc modules. 05.07.95: Worked around a gcc bug (deletion of temporaries) in IniFile::SetupIndex. 11.07.95: Fixed two typos in module cpucvt that were not noticed because the code was not compiled on little endian cpus (thanks to Lutz Vieweg). 12.07.95: Created a memory checker module memcheck. This module overloads the global operators new & delete and checks for memory overwrites, duplicate calls to delete etc. 15.07.95: Added functionality to module memcheck. Enabling the memory checker and the log feature at termination is now possible via two environment variables. Made the block collection static thus enabling checking earlier in the startup phase. Added calls to FreeMsgBase() and FreeAppMsgBase() to Program::Cleanup(). After this change, the amount of allocated blocks on program termination dropped to 0. Fixed a memory leak in module inifile: The collection containing the starting offsets of the sections has not been freed in the destructor. Added a destructor to class Thread to delete the registered keys on program termination. 31.07.95: Fixed a bug in os2src/sercom: The code did not support com ports with 16450 chips (it assumed a 16550 on each port). 01.08.95: Changed the os2 and dos keyboard modules to regularily call App->Idle() when waiting for a key (the linux version already supports this as it is needed for handling SIGWINCH). 02.08.95: Added member functions named Replace() to class String. 03.08.95: Changed the waiting time for keys under linux to 100ms. 06.09.95: Added an additional parameter to the constructor of class StringParser. This parameter has a default value, so existing code does not break. 07.09.95: The linux screen module saves the current cursor position and restores it, after doing a screen update. Without this, the cursor will get lost if some background task does screen output while the program awaits user input with a visible cursor. 10.09.95: Added a new function GetToken() to class StringParser. Added a call to String::InputCvt() to class FileViewer, so input lines are correctly converted to the internally used character set. 13.09.95: In menue.cc: included stdlib.h instead of malloc.h as the latter is flagged obsolete under FreeBSD. 14.09.95: Fixed a bug in module stream: The destructor of class FileStream tried to close the file, even if the FILE* pointer was NULL. Linux, OS/2 and DOS accepted a call to fclose with a NULL pointer - FreeBSD crashed the program with a SIGSEGV. 15.09.95: Renamed the function parameter of the manipulator support function in module stream.cc since some of the header files of FreeBSD do strange #defines... In module memcheck: Casted the parameters to the fprintf call in MemLogBlocksInUse to avoid gcc warnings. #ifdef'ed out function FormatStr (const String&, ...) for FreeBSD (cannot be used with Watcom-C anyway, so maybe dropping the function will be better? 19.09.95: Created a generic *nix version. Some of the linux and bsd files now reside in the generic directory if they can probably be compiled under more than one *nix operating system. New #define GENERIC_UNIX, some changes on the sercom module (made the result of some functions explicitly operating system dependent). Makefile for generic unix (makefile.gen). 23.09.95: Dropped the virtual function _Collection::CollError since it did not fit into the error handling strategy (it never did that and has not been used anywhere). Replaced it by calls to FAIL in the appropriate places. Fixed a bug in modules dossrc/_sercom.asm and dos4gsrc/_sercom.asm: The TX FIFO size has been incorrectly set. There is another bug in this module, that is still unfixed: There is no hw handshaking for incoming chars, even if the code should use handshaking. This may cause buffer overruns if the receiver is not fast enough. I'll fix this in the near future. 01.10.95: Replaced includes of malloc.h in the linux sources with stdlib.h (the proper place for malloc & friends). Some minor changes in bsdsrc/screen.cc: Removed Linux remnants. Changes {bsd, linux, unix}src/screen.cc: When determining the character set used, first check CL_CTYPE, then (if the former does not exist), check LC_CTYPE. Added the missing hardware handshaking to the assembler sercom modules in dossrc and dos4gsrc. Not tested, I hope it works. 10.10.95: File errlog.h needed an additional "#include ". Allow information windows to be closed with enter (in addition to esc). Fixed a bug in module window.cc: Window::CWrite had a "one less" error, the rightmost char in a window was never drawn (when using CWrite). 14.10.95: Split the screen modules for the unix operating system in two parts, a generic one and an os specific one. Changed the names of the environment variables from CL_* to SPUNK_*. Changed Screen::IsColorMode to Screen:IsColor to match Screen::IsConsole. 15.10.95: Added a new option to MemCheck: MemFill will fill memory blocks before and after use (the latter is available only if MemCheck is also true). MemCheck now checks for out of memory conditions in any case. Added a new response reEnd to ResponseWindow. New option for class StringParser: Accept a '.' as a decimal point even if the local symbol is different. This option is used now in class IniFile, so any notations of floats in inifiles are accepted. 23.10.95: Fixed a bug in dos4gsrc\_sercom.asm and dossrc\_sercom.asm: The _TXClear did not work correctly. More minor changes in these modules. 26.10.95: As bsdsrc/sercom.cc has been pretty generic, added some debugging stuff and moved it to unixsrc/sercom.cc. Added also error checking to linuxsrc/sercom.cc. 10.11.95: Added explicit template instantiations #ifdef'ed out by the define EXPLICIT_TEMPLATES. This is a rather ugly hack that is needed for compatibility with the current versions of gcc. Thanks to Ralf W. Stephan (ralf@ark.franken.de) for working out the needed statements. 18.11.95: Added more explicit templates. Fixed a bug in module program.cc: the replacement of the Fail vector has been done too late, errors when creating the main menue or the statusline caused a program abort but no console and keyboard reset. Again, thanks to Ralph W. Stephan. 19.11.95: Ported spunk to djgpp. As there is now another DOS extender, renamed the #define DOS4G to DOS32 and added compiler specific code in a few (too many) places. Renamed the directory dos4gsrc according to the new name. 21.11.95: Cleaned up the sources and directories. Changed dossrc\filesys.cc, added two new functions (FileSysGetDisk and FileSysSetDisk) and rewrote the function CurrentDir to avoid lots of #ifdefs (djgpp needed a completely different code). There's still some work to do with the directory structure - maybe another time. 26.11.95: Fixed some typos in spunk.doc. 27.11.95: Fixed a bug in the OS/2 version of module filesys: Some functions did not work when called with a drive identifier of a drive with removeable media that was not ready. Worked around a bug in the watcom compiler library: The opendir does not set errno to a valid error code on failure. DOS and OS/2 modules still used CL_LANGUAGE and CL_COUNTRY instead of SPUNK_*. 28.11.95: Changed the buffer parameter in ComPort::TimedSendBlock and TimedReceivceBlock from a char pointer to void. 29.11.95: Added the ability to handle control characters in a special way to class TextFileStream. The default for this handling is to replace tabs by sequences of spaces (as before), but to ignore all other control chars. The problems when viewing binary files under Linux with the FileViewer should now be gone. Fixed the CHECKs in the linux sercom module to print the real error code when an error occurs (used ZCHECK instead of CHECK). Added some more explicit templates for GNU compatibility. 30.11.95: Fixed a buf in the resource editor, function items/order: When selecting an item twice, the editor crashed with an error message. Added another constructor to class CharSet. Added an general purpose empty string variable to module str. Added a new function GetString to class StrParser. 05.12.1995: Added a parameter for functions Time::TimeStr and Time::DateTimeStr. The (flag) parameter has a default value that results in the same behavior than the old function. By setting the flag to zero, the seconds ore omitted from the strings. 06.12.1995: Changed some data types (mostly signed int <--> unsigned int) to avoid warnings from gcc 2.7.x. Added an explicit cast from NULL to the return type of some functions for the same reason as above. This seems to be a gcc bug (gcc handles the literal 0 as (void*)0 and warn's about converting implicitly from void* to a typed value), but anyway, the casts do no harm. Removed the function "String FormatStr (const String&, ...), since calling va_start with a reference argument is not supported with most compilers. 11.12.1995: Added a cursor move to position 0/0 to the destructor of the screen object in module unixsrc/screen2.cc. Obviously some terminals do not move the cursor home when the terminal reset sequence is sent (this may also be caused by a bad termcap entry, but anyway, moving the cursor explicitly does no harm). 16.12.1995: Deleted function _Collection::operator []. Made most of the public member functions of class Collection virtual to allow overloading by derived classes. 20.12.1995: Reworked the resource module: Documented the member functions in the header file. Deleted the member function GetName() since it has th same function as KeyAt(). Changed the function ResourceFile::Get (const String&). Previously this function searched for a national version of the resource. This does not make sense, since it is up to the application to do this, the ResourceFile should implement just the basic services. If the ResourceFile class has too much specialized functionality (like searching for national version of data), it is much less usable for a broad range of tasks. Changed Program::LoadResource to do the search instead. New function ResourceFile::FindKey (const String&). Class MemoryStream is now itself streamable (this is the first class with multiple inheritance in the library). New string functions ShowControls and HideControls that recode a string, showing control characters by replacing it with the literals, or hiding the same string literals. 21.12.1995: Some changes in the new ShowControls and HideControls functions. Support for an internal used character sequence: '\c': Center the line in an window. Rewrote SplitMsg to take advantage of those changes. SplitMsg will no longer use the chars '|' and '^' to mark newlines and centered lines, it will use '\n' and '\c' instead. The old solution has lead to lots of trouble since the CHECK and PRECONDITION macros often tried to output C statements that contained '|' chars, leading to chaotic window contents... The new solution is much cleaner, but beware: THIS IS AN INCOMPATIBLE CHANGE! YOU HAVE TO CHANGE MESSAGES THAT USE THE '|' and '^' FEATURE. 23.12.1995: Worked on a X backend for spunk. 25.12.1995: Added a function GetProgName to module progutil. Splitted the screen mode constants from file screen.h and put it in a separate header file, scrmodes.h that is included by screen.h. Fixed a bug in the DOS & OS/2 versions of Screen::Translate(). More work on the X backend. Winattr is not longer a system specific module (all winattr modules, even the one for X have been identical). New header file wincolor.h that has the color constants formerly in winattr. 26.12.-29.12.95 Finished the X backend. Needs still some fine tuning, but works now. Added a new video mode vmAsk, added a new window item TextItem in it's own module, changed the file selector to use this item. Many more small changes to allow the user to resize the application window at almost any time (as needed for the X backend). 03.01.1996: Updated the makefiles and renamed them. The subdirectory is now named "make", the names are *.mak instead of makefile.*, so there are now 8 characters to describe the contents instead of three. 05.01.1996: The default action for a Window in case of a screen size change is, to move itself so that at least the upper left corner is inside the screen area. 06.01.1996: Input and output conversion for message collections got lost when adding the conversion of control chars. Added a virtual function CanClose to class ItemWindow. Changed the construction of some messages in msgcoll.cc and program.cc to avoid a gcc bug. TextItems are now inactive by default (they were active previously). Changed the initialization in Program::Program again to make shure, the terminal is not left in an undeterminate state when exiting because of an error while initializing. Made function Window::MoveResize virtual. Added a virtual function Browse to class ItemWindow. This function should display the window contents in a suitable manner. Changed class FileViewer to be a descendant of class ItemWindow instead of class Window. Changed the Browse function of the file viewer so that it matches the definition from its new base class. 12.01.1996: Added a new function Find() to class SortedCollection. 13.01.1996: Added a new class RegularTask (module regtask) plus some support routines in class Program. 14.01.1996: Minor changes in class _Collection: Functions GetItem and PutItem now assume that the object is derived from class Streamable and act accordingly instead of calling ABSTRACT. 15.01.1996: Moved function Browse completely into class ItemWindow. Added virtual functions HandleKey and GetStatusFlags. The former has already been in class FileViewer, the latter has also been in class FileViewer and has been called GetStatusString with different calling conventions. THIS IS AN INCOMPATIBLE CHANGE! Removed Browse from class FileViewer, changed FileViewer::HandleKey and FileViewer::GetStatusFlags. Changed dossrc/delay.cc to include progutil.h instead of program.h (use Idle() instead App->Idle()). 27.01.1996: Changed the CleanPath function in module filepath to accept the tilde as a synonym for the users home directory under the unix like operating systems. New function MakeAbsolute to make a filename absolute. 28.01.1996: Made the Streamable parameter in ResourceFile::Put const. Made the Streamable parameter in function GetSize (module nullstrm) const. 01.02.1996: Fixed a bug in dossrc/sercom.cc: The variables for TXBufSize and RXBufSize have been used uninitialized resulting in random buffer sizes between 64 and 4096 bytes after calling the constructor. In addition to that, SetBufferSize did not set the buffer sizes in the ComPort structs, resulting eventually in undefined behavior. The last one is also an error in dos32src/sercom.cc. Thanks to Juergen Schick for the hint. 03.02.1996: Added code to lock the interrupt handler in memory (module dos32src\sercom.cc) and used another way to set the interrupt vector in dos32src\_sercom.asm. This may improve stability under Windows. Changed the position of class MemoryStream and class Stream in the object hierarchy since g++ does not cope with the multiple inheritance used in class MemoryStream. Removed the MI from class MemoryStream and made class Stream a descendant of class Streamable. I'm not happy with this, but is was the simplest way to avoid the g++ bug. Changed the macro name for registering a class from __link to LINK since __link is a reserved name (all names having two underscores and all names beginning with an underscore and a small letter are reserved for the C library). Thanks to Heiko Eissfeldt (heiko@colossus.escape.de) for pointing this out. 09.02.1996: Rearranged some code in FSearch (module filepath). 02.03.1996: Added a function StreamableID to template class ListBox that calls ABSTRACT. Otherwise it is possible to store class ListBox into a stream but this will not work since the needed functionality (derived from class WindowItem) is not there. With the new function the program will no longer crash but display "Call to abstract function". Fixed a bug in the Load and Store functions of class ListBox: The inherited functions (those of class WindowItem) have not been called. Fixed a bug in ItemWindow::Browse: The selected item should be deselected after Browse. Added two function for enabling/disabling menue commands to class program and to module progutil. These functions are currently empty. 03.03.1996: Fixed a bug in module listbox: The variable ItemWidth has not been set correctly, leading to undefined behaviour after a load. 08.03.1996: Changed the working of ComPort::DTROn in both DOS modules. The function activated both, RTS and DTR and will now activate DTR and eventuelly RTS (if handshake == (M)odem). Fixed some oddities in the linux keyboard and screen drivers. The functions to determine the screen size and detect the console did not use the correct file despriptors (stdin instead of stdout), which lead to unwanted behaviour if standard input was not a console tty. Rewrote the memcheck module to be as independent as possible from other stuff. Memcheck does no longer use any static objects and can be used without clashes with other static objects now (it is also somewhat slower now, but its just a debugging tool...). 13.03.1996: Changed the bevavior of the DTROn and DTROff functions of class ComPort (again). They will now follow the behavior of the function for the other operating systems. That is: Calling Open() will activate the RTS (but not DTR) line if a modem connection (hardware handshake) is enabled. Otherwise the Open() will leave the RTS and DTR lines inactive. DTROn() and DTROff() will only change the state of the DTR line. There is now another pair of functions, RTSOn/RTSOff to change the state of the RTS line. Since the RTS line is needed for handshaking if hardware handshake is enabled, it is not allowed to call the functions in this case. Added the new functions also to the linux sercom module. Changed (after a look into the kernel sources) the DTROn and DTROff functions in the linux sercom module because they suffered from race conditions. Added the same modifications to the generic unix module. I cannot test this now, just hope it works... 24.03.1996: Implemented an event mechanism. Added files: event.h event.cc eventid.h. Removed EnabledCommand/DisabledCommand and the functions for handling regular tasks from class program since they are not needed in the presence of event handling. Deleted fifo.h as this module has been superseeded by circbuf.h. Added the winmgr module to the spunk library (has been in use in some applications until now). 25.03.1996: Made ItemWindow a descendant of class EventHandler. Added some more util functions to module progutil. Added Load/Store capability to class FileViewer. 28.03.1996: Fixed a bug in the memcheck module: The block array may not be freed in the exit function since the startup code may release memory blocks later. Fixed a bug in class EventHandler: The root node may not be a real node but must be a pointer. Otherwise we get problems since the root node must be initialized first and this conflicts with object of class EventHandler that are also static. 06.04.1996: Changed the order of base classes in class Program to work around a gcc bug. 11.04.1996: Added a new function GetFile to class FileStream (thanks to Ralf Stephan, ralf@ark.franken.de for the suggestion). 12.04.1996: Added a #define to module filecoll to avoid warnings because of unreachable code. 20.04.1996: Changed frame.cc to include the SimpleFrame that has already been used in a few other modules. Also put in there a replacement for the frame characters when the KOI-8r character set is active (thanks to Michael A. Rodiono, marod@piglet.cnit.nsk.su). Finished the COPYING.TXT file, spunk now has real copying conditions (whow!). Added a sample directory and Ralphs std application as a first sample. 21.04.1996: Made three utility function of class Window protected instead of private, otherwise it is very difficult to override the frame drawing functions. 24.04.1996: Made the handling of the values of SPUNK_CTYPE and LC_CTYPE somewhat relaxed, hopefully now all variants of "ISO-8859-1" are recognized. 26.04.1996: Function FileSysCurrentDir did not convert the directory to lower case. 01.05.1996: Removed the code to map a keyword into a number given by a list of keywords/ numbers as a string from module environ and put it into module str (the function is now called MatchKeyword). Added the capability to use wildcards inside the keyword list. Added functions to look for key values to module inifile. 03.05.1996: Module charset: Changed one constructor, added another one to initialize the CharSet from a string. Changed all unsigned char parameters to char. Fixed to range bugs. Module chartype: Changed the WhiteSpace CharSet to use the changed constructor. Module strparse: Changed the StringParser class to use class CharSet for all operations where a set of characters is needed instead of using a string. Added a second argument (with a default value) to GetToken, it is now possible to specify the characters that separate the tokens. Made the WhiteSpace variable a non-static member of class CharSet which is initialized from the global WhiteSpace in chartype. There is currently no way to change this variable, this may be added if needed. Module str: New member function Remove() to remove characters from a string. Deleted the superflous Set functions from the header file (they had no implementation anyway). 04.05.1996: Added a new module, wildargs, that is used in DOS and OS/2 only. It contains a function to expand the argument vector and is called from the constructor of class Program. So any spunk program accepts now wildcard arguments (they are automatically expanded) but currently the function under DOS and OS/2 is slightly different from the *nix operating systems (escaped wildcards are not accepted for example). As an addition, a response file (syntax "@FILE" may be used, it's contents are also placed into the argument vector. 08.05.1996: Added defines for DOSLIKE_OS and UNIXLIKE_OS in machine.h. Simplified and corrected some functions in filepath.cc. Extended the Match function in module str to accept a list of substrings as part of the pattern string (syntax is "{aaa,bbb,ccc}"). Extended the FHasWildcards function to handle the characters '{' and '}' as wildcards. Extended the FileEdit class to accept '{', '}' and ',' if wildcards are allowed. 09-16.03.1996: Many smaller changes. Fixed a bug in ItemWindow::PlaceNear(), detected that the Match function is broken and will need a rewrite. Worked on the item edit capability of the resource editor. 18.05.1996: The PMODE/W DOS extender does not support function 65h of int 21h (get extended country information). Because of this, the call returned invalid data and the country information could not get retrieved when running with PMODE/W under pure DOS. Rewrote the DOS32 specific module to simulate the real mode in via DPMI function 0x300 to remove this problem. One day: Added changes and makefile for NetBSD/Amiga. Thanks to Ralph-Thomas Aussem (1aussem@informatik.uni-hamburg.de) for the work. 16.06.1996: Fixed a bug in String::PSZ(char*, size_t): Since the function used strncpy, it was not guaranteed that the resulting string was zero terminated. 20.06.1996: Added the changes and the makefile for the Solaris/X Version. Thanks to Martin Helmling (mh@octogon.de). 23.06.1996: Fixed a bug in MatchKeyword (module str). 01.07.1996: Allow a NULL pointer for the initialization of SubMenueItem. This makes it possible for the resource editor to create "empty" SubMenueItems and assign the menu later. 22.07.1996: Added some changes from Dr.-Ing. A. Irmer (dc1p@risc1.rhein-main.de) to avoid warnings from gcc 2.7.2. Added support for a marked line in class FileViewer (suggestion and initial coding by Ralf W. Stephan, ralf@ark.franken.de). 04.08.96: Removed a bug from CleanPath (module filepath): The function did not return an absolute path in all cases on systems supporting drives. 17.08.1996: Fixed a bug in OffOnItem::Load and NoYesItem::Load. The load functions did reset the toggle string and value according to the new national conventions, but did not set the length correctly 18.08.1996: Added two additional functions Low() and High() to class BitSet. Removed an error from StringParser::GetToken: An empty string was not flagged as an error. Added a function to class Time to fetch a broken down time with one call. 19.08.1996: Removed a bug from String::Remove. If the rmTrailing flag has been set, sometimes one character more than needed has been deleted. 01.09.1996: Incorporated changes from Andreas Irmer (dc1p@risc1.rhein-main.de) to suppress some warnings when compiling with gcc 2.7.2. Modules changed: memcheck.cc, charset.cc, fviewer.cc, linuxsrc/kbd.cc and unixsrc/screen2.cc. 02.09.1996: Added the changes for the Microsoft NT port from Michael Peschel (mipe@ibb.schwaben.com). 27.09.1996: New classes for random number generation: BaseRNG and RNG, implemented in module rng. Added an #include in syserror.h to remove the need for including this file each time, syserror.h is included. This is error prone when porting, since many libraries define errno in stdlib.h, but some don't, so the source may compile on one system and not on another. 20.10.1996: Added functions to class Stream to read and write a stream as a stream of bits. 24.10.1996: Added a Clear function to class MemPool and class StringPool. Added a Use function to class MemPool and class StringPool which uses an existing buffer. Changes in module memcheck: Used a dummy class in addition to a Watcom specific pragma to assure that the initialization of the memory checker is executed as early as possible. This removes a problem with static objects that were initialized before the memory checker. Whenever those objects tried to release memory, it was flagged as a "never allocated block" by the memory checker, since it was allocated before the initialization of the memory checker executed. THIS IS A COMPILER SPECIFIC SOLUTION, but anyway, it helps a lot since this is just a debugging tool. Changed a statement in module datetime, where a statement was hidden inside the PRECONDITION macro and would not expand if the macro was changed to nothing. 28.10.1996: Moved some functions from the header files, where they were declared as inline to the corresponding .cc file removing the inline declaration. The inline caused the linker not to include the .obj file when maximum optimization was enabled, since no functions inside the module were referenced. 06.11.1996: New modules charstrm and serstrm. Fixed a bug in Program::Idle which caused multiple evSecondChange and evMinuteChange events to be delivered if the Idle function was called from inside an event handler again. Imported the whole stuff into CVS. 24.11.1996: Added a 32 bit CRC module. Some cosmetic changes on the 16 bit CRC module. Changed the CRCStream class to use the 32 bit CRC. Changed module syserror to use the ANSI compatible function strerror instead of the less portable sys_error. This removes also a compiler error on some architectures regarding the assignment of const to non-const. 29.11.1996: Make the parameter to GetCRC const. Create another function that does not take a pointer but a (const) reference. Do not use Put() to calculate the CRC but use operator << (which invokes Load()) instead. This extends the usability to objects that have a Store() method but aren't registered (do not have a stream id). Changed _Collection::Load: The build constructor will clear Items. So, when Load is called with Items not NULL, someone called Load with an already initialized object instance. To mimic the behaviour of the builtin types, delete all items and the items space before loading. This allows to call Load() with an existing object, the old data will be replaced by the data from the stream. 30.11.1996: Added "const T* operator [] const" to class Collection. 01.12.1996: Added a function Add() to class String. Changed the default pad type from Left to Right. 08.12.1996: Complete rewrite of the CircularBuffer class. It has now a second template argument (the size) and is much more streamlined than before. The Put() and Get() member functions are now thread safe, that is, as long as one thread uses Put() and another Get() there are no concurrency problems. 10.12.1996: Small cosmetic changes (I was searching for a bug that was no real bug but an alignment problem). 18.12.1996: Stream::Error will call FAIL on stGetError and stPutError if no user defined error function handler is installed. Fixed an error in str.h: The operators == and != used NLSCmpStr to compare two strings, but NLSCmpStr uses a collation table that maps lower case to upper case characters (this causes also an error in the operators >, < etc.!) Fixed the former functions by using strcmp instead of NLSCmpStr. 28.12.1996: Reset the cursor position to zero in Window::Clear(). 29.12.1996: Added a new flag elTruncate for class IniFile. 30.12.1996: Fixed a bug in the last change (class IniFile). 31.12.1996: Added function GetSize() to class Screen. Made some functions of class Screen const that do not change internal variables. Changed the handling of screen size changes from a call to a function of the root window to an event that is posted. The root window has an event handler thet calls the ScreenSizeChanged function. This will enable other parts of the application to react to size change events. Made the classes Point and Rect descendants of class Streamble to allow them to be used when delivering events and streamline the code (5 years ago, when spunk was created, it was a performance decision to make Point and Rect independent classes). The representation of the classes inside of stream data has *not* changed. 02.01.1997: Added a new module task that implements a class for a operating system supported thread. Currently there are implementations for OS/2 and NT. 03.01.1997: Added a semaphore module; current implementations are for OS/2 and NT. Fixed a bug in the task modules, the task handle structure was not freed. 25.01.1997: Fixed a bug in module menuitem that was caused by changing the default pad type (change from 01.12.96). 26.01.1997: Added a new method, MoveResizeAfterLoad to class Window. The TopMenueBar class will use this method to reposition itself after Load(). The resource editor will now support the creation of TopMenueBar objects, so they must no longer be constructed "manually" at runtime. Fixed a bug in module program: When the main menu was loaded from the resource, and the main menu contained the names of keys, the program message base was loaded in between, changing the stream file pointer. 29.01.1997: Added a check for kbNoKey in Thread::RegisterKey (yes, I'm learning from my errors :-) 30.01.1997: The "Custom charset" feature from "Edit item" in the resource editor seems to have vanished. Reimplemented it. 03.02.1997: New function DigitValue in module charset. 05.02.1997: Updated dutch program messages from Oliver Daudey (oliver@xs4all.nl). Thanks! 07.02.1997: Made the NT screen module work under Win95. Enabled the already existing workaround for '..' directories in module filecoll. NT apps should now work under Win95 as textmode applications. 18.02.1997: Added a new object derived from class EventHandler that enables temporary event rerouting to a user supplied function. All incoming events will be rerouted to a function given by the creator of this object, until the object is destroyed. Incorporated the diffs for SVR4 (Unixware) from Felix Blank (felix@tasha.muc.de) into spunk in some way or the other :-) 20.02.1997: Allow a length of 1024 for message strings (and other input) in the resource editor. 21.02.1997: Allow a newline separated format for toggle texts in the resource editor. This enables the editor to determine the toggle count from the text. Currently, the text in the displays is still in old format, but the new and old format are accepted on input. 27.02.1997: Some cleanups in the sercom modules for OS/2 and Win32 (NT). Added checks in several places if the port is really open before starting some actions. Removed a bug from the NT version: The Open() function should not call FAIL (resp. ComError) in case of errors, it should return an error code instead. estic-1.61.orig/spunk/stack.h0100644000176100001440000000766407031424706015446 0ustar debacleusers/*****************************************************************************/ /* */ /* STACK.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __STACK_H #define __STACK_H #include #include "machine.h" #include "object.h" #include "strmable.h" #include "stream.h" /*****************************************************************************/ /* template class Stack */ /*****************************************************************************/ template class Stack : public Streamable { protected: T *Data; u16 SP; u16 Limit; protected: virtual void PutItem (Stream &S, T Item) const; // Not defined virtual T GetItem (Stream &S); // Not defined virtual void FreeItem (T Item); public: Stack (u16 Size); Stack (StreamableInit); virtual ~Stack (); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; static Streamable* Build (); // New member functions int IsEmpty (); void Push (T); T Pop (); T Peek (); void Drop (); void Swap (); }; template Stack::Stack (u16 Size) : SP (0), Limit (Size) { // Allocate memory Data = new T [Limit]; } template inline Stack::Stack (StreamableInit) { } template Stack::~Stack () { // Free remaining items while (SP--) { FreeItem (Data [SP]); } // Free the array delete [] Data; } template void Stack::Load (Stream& S) { // Read data S >> SP >> Limit; // Allocate memory Data = new T [Limit]; // Now read the items u16 I = SP; while (I--) { Data [I] = GetItem (S); } } template void Stack::Store (Stream& S) const { // Store data S << SP << Limit; // Store the items u16 I = SP; while (I--) { PutItem (S, Data [I]); } } template T Stack::GetItem (Stream&) { ABSTRACT (); return * (T *) NULL; } template void Stack::PutItem (Stream&, T) const { ABSTRACT (); } template inline void Stack::FreeItem (T) { // Default is to do nothing } template inline Streamable * Stack::Build () { return new Stack (Empty); } template inline int Stack::IsEmpty () { return (SP == 0); } template void Stack::Push (T O) { // Check for overflow CHECK (SP < Limit); // Push the item Data [SP++] = O; } template T Stack::Pop () { // There must be at least one element CHECK (SP >= 1); // Pop an element return Data [--SP]; } template T Stack::Peek () { // There must be at least one element CHECK (SP >= 1); // Pop an element return Data [SP-1]; } template void Stack::Drop () { // There must be at least one element CHECK (SP >= 1); // Drop the last element FreeItem (Data [--SP]); } template void Stack::Swap () { // Swap needs two elements at least CHECK (SP >= 2); // Swap the elements T Tmp = Data [SP-1]; Data [SP-1] = Data [SP-2]; Data [SP-2] = Tmp; } // End of STACK.H #endif estic-1.61.orig/spunk/statdef.h0100644000176100001440000000566007031424706015765 0ustar debacleusers/*****************************************************************************/ /* */ /* STATDEF.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file adds some defines that are missing in the DOS & OS/2 compilers for // handling the fields of struct stat and return codes for access() #ifndef __STATDEF_H #define __STATDEF_H #include /*****************************************************************************/ /* Defines */ /*****************************************************************************/ #ifndef R_OK #define R_OK 4 #endif #ifndef W_OK #define W_OK 2 #endif #ifndef X_OK #define X_OK 1 #endif #ifndef F_OK #define F_OK 0 #endif #ifndef S_IRUSR #define S_IRUSR S_IREAD #endif #ifndef S_IWUSR #define S_IWUSR S_IWRITE #endif #ifndef S_IXUSR #define S_IXUSR S_IEXEC #endif #ifndef S_IRGRP #define S_IRGRP S_IRUSR #endif #ifndef S_IWGRP #define S_IWGRP S_IWUSR #endif #ifndef S_IXGRP #define S_IXGRP S_IXUSR #endif #ifndef S_IROTH #define S_IROTH S_IRUSR #endif #ifndef S_IWOTH #define S_IWOTH S_IWUSR #endif #ifndef S_IXOTH #define S_IXOTH S_IXUSR #endif #ifndef S_IRWXU #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) #endif #ifndef S_IRWXG #define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) #endif #ifndef S_IRWXO #define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) #endif #ifndef S_ISUID #define S_ISUID 0 #endif #ifndef S_ISGID #define S_ISGID 0 #endif #ifndef S_ISVTX #define S_ISVTX 0 #endif #ifndef S_ISBLK #define S_ISBLK(__mode) 0 #endif #ifndef S_ISFIFO #define S_ISFIFO(__mode) 0 #endif #ifndef S_ISSOCK #define S_ISSOCK(__mode) 0 #endif #ifndef S_ISLNK #define S_ISLNK(__mode) 0 #endif #ifndef S_ISCHR #define S_ISCHR(__mode) (((__mode) & S_IFMT) == S_IFCHR) #endif #ifndef S_ISDIR #define S_ISDIR(__mode) (((__mode) & S_IFMT) == S_IFDIR) #endif #ifndef S_ISREG #define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG) #endif // End of STATDEF.H #endif estic-1.61.orig/spunk/statflag.h0100644000176100001440000000557307031424706016143 0ustar debacleusers/*****************************************************************************/ /* */ /* STATFLAG.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Flags for use with CreateStatusLine/PushStatusLine #ifndef __STATFLAG_H #define __STATFLAG_H /*****************************************************************************/ /* Flags for creating standard status lines */ /*****************************************************************************/ // !!! Old names, do not use for future development !!! const u32 siF1_Help = 0x00000001; const u32 siEsc_Abort = 0x00000002; const u32 siEsc_End = 0x00000004; const u32 siEsc_Proceed = 0x00000008; const u32 siF10_Accept = 0x00000010; const u32 siCR_Accept = 0x00000020; const u32 siUpDn_Select = 0x00000040; const u32 siUpDnCR_Select = 0x00000080; const u32 siIns_Insert = 0x00000100; const u32 siDel_Delete = 0x00000200; const u32 siCR_Change = 0x00000400; const u32 siCtrlD_Print = 0x00000800; const u32 siCtrlG_Graphics = 0x00001000; const u32 siAltX_Exit = 0x00002000; const u32 siCR_Confirm = 0x00004000; const u32 siCursPgKeys_Move = 0x00008000; const u32 siF3_Open = 0x00010000; const u32 siAltF3_Close = 0x00020000; const u32 siF5_Zoom = 0x00040000; const u32 siCtrlF5_Resize = 0x00080000; const u32 siAltI_Login = 0x00100000; const u32 siAltO_Logout = 0x00200000; // New codes -> Example const u32 siHelp = 0x00000001; // F1 Help const u32 siAbort = 0x00000002; // ESC Abort const u32 siEnd = 0x00000004; // ESC Done const u32 siProceed = 0x00000008; // ESC Proceed const u32 siAccept = 0x00000010; // F10 Accept const u32 siEnter = 0x00000020; // <ÄŁ Accept const u32 siSelectKeys = 0x00000040; //  Select const u32 siSelectChooseKeys = 0x00000080; // <ÄŁ Select const u32 siInsert = 0x00000100; // Ins Insert const u32 siDelete = 0x00000200; // Del Delete const u32 siChange = 0x00000400; // <ÄŁ Change const u32 siPrint = 0x00000800; // Alt-D Print const u32 siGraphics = 0x00001000; // Alt-G Graphics const u32 siExit = 0x00002000; // Alt-X Exit const u32 siConfirm = 0x00004000; // Enter Confirm const u32 siPageKeys = 0x00008000; //  PgUp PgDn Move const u32 siOpen = 0x00010000; // F3 Open const u32 siSave = 0x00020000; // F2 Save const u32 siClose = 0x00040000; // Alt-F3 Close const u32 siZoom = 0x00080000; // F5 Zoom const u32 siResize = 0x00100000; // Ctrl-F5 Resize const u32 siLogin = 0x00200000; // Alt-I Login const u32 siLogout = 0x00400000; // Alt-O Logout const u32 siMoveKeys = 0x10000000; // <-> Move const u32 siResizeKeys = 0x20000000; // Shift-<-> Resize // End of STATFLAG.H #endif estic-1.61.orig/spunk/statline.cc0100644000176100001440000003061707031424706016314 0ustar debacleusers/*****************************************************************************/ /* */ /* STATLINE.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "msgid.h" #include "streamid.h" #include "keydef.h" #include "screen.h" #include "progutil.h" #include "statline.h" // Register class StatusLine LINK (StatusLine, ID_StatusLine); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msHelp = MSGBASE_STATLINE + 0; static const u16 msAccept = MSGBASE_STATLINE + 1; static const u16 msAbort = MSGBASE_STATLINE + 2; static const u16 msEnd = MSGBASE_STATLINE + 3; static const u16 msProceed = MSGBASE_STATLINE + 4; static const u16 msChange = MSGBASE_STATLINE + 5; static const u16 msPrint = MSGBASE_STATLINE + 6; static const u16 msGraphics = MSGBASE_STATLINE + 7; static const u16 msInsert = MSGBASE_STATLINE + 8; static const u16 msDelete = MSGBASE_STATLINE + 9; static const u16 msSelect = MSGBASE_STATLINE + 10; static const u16 msConfirm = MSGBASE_STATLINE + 11; static const u16 msMove = MSGBASE_STATLINE + 12; static const u16 msLogin = MSGBASE_STATLINE + 13; static const u16 msLogout = MSGBASE_STATLINE + 14; static const u16 msExit = MSGBASE_STATLINE + 15; static const u16 msZoom = MSGBASE_STATLINE + 16; static const u16 msClose = MSGBASE_STATLINE + 17; static const u16 msOpen = MSGBASE_STATLINE + 18; static const u16 msResize = MSGBASE_STATLINE + 19; static const u16 msSave = MSGBASE_STATLINE + 20; static const u16 msSelectKeys = MSGBASE_STATLINE + 21; static const u16 msSelectChooseKeys = MSGBASE_STATLINE + 22; static const u16 msPageKeys = MSGBASE_STATLINE + 23; static const u16 msMoveKeys = MSGBASE_STATLINE + 24; static const u16 msResizeKeys = MSGBASE_STATLINE + 25; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Stack; #endif /*****************************************************************************/ /* class StatusLine */ /*****************************************************************************/ StatusLine::StatusLine (const String& FirstLine): Window (Rect (1, 1, 2, 2), 0, paGray, 0, 1), Lines (50) { // Initialize the instance Init (FirstLine); } StatusLine::StatusLine (u32 StdFlags) : Window (Rect (1, 1, 2, 2), 0, paGray, 0, 1), Lines (50) { // Initialize the instance Init (CreateLine (StdFlags)); } void StatusLine::Init (const String& FirstLine) // Used from the constructors { // Create an empty line CurrentLine = new String (FirstLine); // Get the size of the screen Rect Bounds = Background->OuterBounds (); // Resize the window to the bottom of the screen. This will also draw the // statusline text Bounds.A.Y = Bounds.B.Y - 1; Resize (Bounds); Show (); Unlock (); } StatusLine::~StatusLine () { // Delete the current line delete CurrentLine; // Pop all remaining lines to avoid deletion problems in the destructor // of class Stack while (!Lines.IsEmpty ()) { delete Lines.Pop (); } } void StatusLine::Load (Stream& S) { // Load parent data Window::Load (S); // Load own data S >> Lines; CurrentLine = (String*) S.Get (); } void StatusLine::Store (Stream& S) const { // Store parent data Window::Store (S); // Store own data S << Lines; S.Put (CurrentLine); } u16 StatusLine::StreamableID () const { return ID_StatusLine; } Streamable* StatusLine::Build () { return new StatusLine (Empty); } void StatusLine::DrawInterior () // Redraw the interior of the statusline { // Lock the output Lock (); // Clear the window Clear (); // If a string exists, show it if (CurrentLine) { CWrite (0, 0, *CurrentLine); } // Now allow screen output Unlock (); } String StatusLine::CreateLine (u32 StdFlags) // Create and return a string made from StdFlags { String NewLine; // Create the new status line string for (u32 I = 1; I != 0; I <<= 1) { // Continue if the bit is not set if ((StdFlags & I) == 0) { continue; } // Look at the value switch (I) { case siHelp: NewLine += GetKeyName3 (vkHelp) + LoadMsg (msHelp); break; case siAbort: NewLine += GetKeyName3 (vkAbort) + LoadMsg (msAbort); break; case siEnd: NewLine += GetKeyName3 (vkAbort) + LoadMsg (msEnd); break; case siProceed: NewLine += GetKeyName3 (vkAbort) + LoadMsg (msProceed); break; case siAccept: NewLine += GetKeyName3 (vkAccept) + LoadMsg (msAccept); break; case siEnter: NewLine += GetKeyName3 (kbEnter) + LoadMsg (msAccept); break; case siSelectKeys: if (TheScreen->IsConsole ()) { // We cannot display the keys if not at the console NewLine += LoadMsg (msSelectKeys); } break; case siSelectChooseKeys: if (TheScreen->IsConsole ()) { // We cannot display the keys if not at the console NewLine += LoadMsg (msSelectChooseKeys); } break; case siInsert: NewLine += GetKeyName3 (vkIns) + LoadMsg (msInsert); break; case siDelete: NewLine += GetKeyName3 (vkDel) + LoadMsg (msDelete); break; case siChange: NewLine += GetKeyName3 (kbEnter) + LoadMsg (msChange); break; case siPrint: NewLine += GetKeyName3 (kbCtrlD) + LoadMsg (msPrint); break; case siGraphics: NewLine += GetKeyName3 (kbCtrlG) + LoadMsg (msGraphics); break; case siExit: NewLine += GetKeyName3 (vkQuit) + LoadMsg (msExit); break; case siConfirm: NewLine += GetKeyName3 (kbEnter) + LoadMsg (msConfirm); break; case siPageKeys: if (TheScreen->IsConsole ()) { // We cannot display the keys if not at the console NewLine += LoadMsg (msPageKeys); } break; case siLogin: NewLine += GetKeyName3 (kbMetaI) + LoadMsg (msLogin); break; case siLogout: NewLine += GetKeyName3 (kbMetaO) + LoadMsg (msLogout); break; case siZoom: NewLine += GetKeyName3 (vkZoom) + LoadMsg (msZoom); break; case siOpen: NewLine += GetKeyName3 (vkOpen) + LoadMsg (msOpen); break; case siSave: NewLine += GetKeyName3 (vkSave) + LoadMsg (msSave); break; case siClose: NewLine += GetKeyName3 (vkClose) + LoadMsg (msClose); break; case siResize: NewLine += GetKeyName3 (vkResize) + LoadMsg (msResize); break; case siMoveKeys: if (TheScreen->IsConsole ()) { // We cannot display the keys if not at the console NewLine += LoadMsg (msMoveKeys); } break; case siResizeKeys: if (TheScreen->IsConsole ()) { // We cannot display the keys if not at the console NewLine += LoadMsg (msResizeKeys); } break; } } return NewLine; } void StatusLine::Push (const String& NewLine) { // Remember the length of the current line int OldLen = CurrentLine->Len ("~"); // Push the current line onto the stack Lines.Push (CurrentLine); // Get a copy of the new statusline CurrentLine = new String (NewLine); // If the line is longer than the old one, just write it to the // screen. Otherwise get a copy, pad that copy to length and write // the copy. What makes it slightly complicated is the fact that // there are non-displayed characters in both strings.... int NewLen = CurrentLine->Len ("~"); if (NewLen >= OldLen) { CWrite (0, 0, *CurrentLine); } else { String S = *CurrentLine; S.Pad (String::Right, OldLen + S.Len () - NewLen); CWrite (0, 0, S); // ^ Adjust for non visible chars } } void StatusLine::Push (u32 StdFlags) { // Push the current line onto the stack Push (CreateLine (StdFlags)); } void StatusLine::Pop () { // Remember the length of the current line int OldLen = CurrentLine->Len ("~"); // Delete the current copy of the statusline delete CurrentLine; // Pop the last one CurrentLine = Lines.Pop (); // If the line is longer than the old one, just write it to the // screen. Otherwise get a copy, pad that copy to length and write // the copy. What makes it slightly complicated is the fact that // there are non-displayed characters in both strings.... int NewLen = CurrentLine->Len ("~"); if (NewLen >= OldLen) { CWrite (0, 0, *CurrentLine); } else { String S = *CurrentLine; S.Pad (String::Right, OldLen + S.Len () - NewLen); CWrite (0, 0, S); // ^ Adjust for non visible chars } } void StatusLine::Replace (const String& NewLine) { // Remember the length of the current line int OldLen = CurrentLine->Len ("~"); // Delete current line delete CurrentLine; // Get a copy of the new statusline CurrentLine = new String (NewLine); // If the line is longer than the old one, just write it to the // screen. Otherwise get a copy, pad that copy to length and write // the copy. What makes it slightly complicated is the fact that // there are non-displayed characters in both strings.... int NewLen = CurrentLine->Len ("~"); if (NewLen >= OldLen) { CWrite (0, 0, *CurrentLine); } else { String S = *CurrentLine; S.Pad (String::Right, OldLen + S.Len () - NewLen); CWrite (0, 0, S); // ^ Adjust for non visible chars } } void StatusLine::Replace (u32 StdFlags) { // Set the line Replace (CreateLine (StdFlags)); } /*****************************************************************************/ /* class BottomStatusLine */ /*****************************************************************************/ void BottomStatusLine::ScreenSizeChanged (const Rect& NewScreen) // Called when the screen got another resolution. NewScreen is the new // screen size. { // Expand the size of the bar from the left to the right screen border // at the bottom of the screen Rect NewSize (NewScreen); NewSize.A.Y = NewSize.B.Y - 1; Resize (NewSize); } estic-1.61.orig/spunk/statline.h0100644000176100001440000000646507031424706016162 0ustar debacleusers/*****************************************************************************/ /* */ /* STATLINE.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __STATLINE_H #define __STATLINE_H #include "machine.h" #include "object.h" #include "statflag.h" #include "listnode.h" #include "strmable.h" #include "stream.h" #include "rect.h" #include "stack.h" #include "window.h" /*****************************************************************************/ /* class StatusLine */ /*****************************************************************************/ class StatusLine : public Window { private: void Init (const String& FirstLine); // Used in the constructors protected: Stack Lines; String* CurrentLine; StatusLine (StreamableInit); // Build constructor public: StatusLine (const String& FirstLine = ""); StatusLine (u32 StdFlags); virtual ~StatusLine (); // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class Window virtual void DrawInterior (); // New member functions void Push (const String& NewLine); void Push (u32 StdFlags); void Pop (); void Replace (const String& NewLine); void Replace (u32 StdFlags); static String CreateLine (u32 StdFlags); // Create a statusline text according to the flags in StdFlags }; inline StatusLine::StatusLine (StreamableInit) : Window (Empty), Lines (Empty) { } /*****************************************************************************/ /* class BottomStatusLine */ /*****************************************************************************/ class BottomStatusLine: public StatusLine { protected: virtual void ScreenSizeChanged (const Rect& NewScreen); // Called when the screen got another resolution. NewScreen is the new // screen size. BottomStatusLine (StreamableInit); // Build constructor public: BottomStatusLine (const String& FirstLine); BottomStatusLine (u32 StdFlags); BottomStatusLine (); }; inline BottomStatusLine::BottomStatusLine (StreamableInit) : StatusLine (Empty) { } inline BottomStatusLine::BottomStatusLine (const String& FirstLine) : StatusLine (FirstLine) { } inline BottomStatusLine::BottomStatusLine (u32 StdFlags) : StatusLine (StdFlags) { } inline BottomStatusLine::BottomStatusLine () : StatusLine () { } // End of STATLINE.H #endif estic-1.61.orig/spunk/stdmenue.cc0100644000176100001440000001350007031424706016305 0ustar debacleusers/*****************************************************************************/ /* */ /* STDMENUE.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "listnode.h" #include "menuitem.h" #include "stdmenue.h" #include "splitmsg.h" #include "progutil.h" #include "msgid.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msAreYouShure = MSGBASE_STDMENUE + 0; static const u16 msReallyQuit = MSGBASE_STDMENUE + 1; static const u16 msDiscardChanges = MSGBASE_STDMENUE + 2; static const u16 msSaveChanges = MSGBASE_STDMENUE + 3; static const u16 msYesNo = MSGBASE_STDMENUE + 4; static const u16 msNoYes = MSGBASE_STDMENUE + 5; /*****************************************************************************/ /* */ /*****************************************************************************/ unsigned SimpleMenue (const String& Header, const String& MenueText) // Builds a menue from the given strings, shows that menue and returns the // users choice. The return value is 0 if the menue was aborted. // Use \n to separate ther entries, use \c to create a new item that is // centered. Use '@' to mark hotkeys (as usual). { Rect Bounds; ListNode* Node; ListNode* N; // Split up the text for the menue items Node = SplitLine (MenueText, Bounds); i16 ItemCount = Bounds.B.Y; // Add horizontal room for the border, check against the length of the // Header line Bounds.B.X += 4; int Len = Header.Len (); if ((Len + 2) > Bounds.B.X) { Bounds.B.X = Len + 2; } // Add vertical room for the border and for the header line (if one // exists) if (Len > 0) { Bounds.B.Y += 4; } else { Bounds.B.Y += 2; } // Traverse through the list and build the menue items MenueItem* Item = NULL; N = Node->Prev (); i16 ID = ItemCount; do { Item = new MenueItem (*(N->Contents ()), ID, Item); ID--; N = N->Prev (); } while (N != Node->Prev ()); // Delete the (not longer needed) string list ReleaseLines (Node); // Get the screen size and center the menue Rect ScreenSize (Background->OuterBounds ()); Bounds.Center (ScreenSize, cfCenterAll); // Set up the header item. If a header string is given, the list should // contain an inactive menue item with the header and a menue line as // the first two items if (Len > 0) { Item = new MenueItem (Header, 10000, new MenueLine (10001, Item)); } // Now create the menue Menue* M = new Menue (Bounds.A, "", Item); // Set the menue options so that the menue remains centered if the // screen resolution changes, but allow moving the menue M->SetOption (cfCenterAll); M->SetCanMove (); // The menue is invisible. Make the header line inactive (remember: the // item representing the header is the first item of the list) Item->Deactivate (); // Push a status line PushStatusLine (siAbort); // Time for the user to get active unsigned Choice = M->GetChoice (); // Pop the status line PopStatusLine (); // Destroy the menue delete M; // Return the result return Choice; } unsigned AskYesNo (const String& Header) // Pop up a menue with the given header and the entries "Yes" and "No", // "Yes" being the default entry. // Returns 0 = Abort, 1 = No, 2 = Yes { // We have to remap the return codes here switch (SimpleMenue (Header, LoadMsg (msYesNo))) { case 0: return 0; case 1: return 2; case 2: return 1; } FAIL ("AskYesNo: Unexpected result code"); return 0; } unsigned AskNoYes (const String& Header) // Pop up a menue with the given header and the entries "No" and "Yes", // "No" being the default entry. // Returns 0 = Abort, 1 = No, 2 = Yes { return SimpleMenue (Header, LoadMsg (msNoYes)); } unsigned AskReallyQuit () // Pops up a menue with the question "Really quit" and returns the result // 0 = Abort, 1 = No, 2 = Yes { return AskYesNo (LoadMsg (msReallyQuit)); } unsigned AskDiscardChanges () // Pops up a menue with the question "Discard changes?" and returns the result // 0 = Abort, 1 = No, 2 = Yes { return AskNoYes (LoadMsg (msDiscardChanges)); } unsigned AskSaveChanges () // Pops up a menue with the question "Save changes?" and returns the result // 0 = Abort, 1 = No, 2 = Yes { return AskYesNo (LoadMsg (msSaveChanges)); } unsigned AskAreYouShure () // Pops up a menue with the question "Are you shure?" and returns the result // 0 = Abort, 1 = No, 2 = Yes { return AskNoYes (LoadMsg (msAreYouShure)); } unsigned MenueChoice (const String& ResName) // Loads a menue with the name ResName from the resource file, gets the user // response and deletes the menue. { Menue* M = (Menue*) LoadResource (ResName); unsigned Choice = M->GetChoice (); delete M; return Choice; } estic-1.61.orig/spunk/stdmenue.h0100644000176100001440000000561307031424706016155 0ustar debacleusers/*****************************************************************************/ /* */ /* STDMENUE.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STDMENUE_H #define _STDMENUE_H #include "menue.h" /*****************************************************************************/ /* Result codes for the Abort/No/Yes menues */ /*****************************************************************************/ const unsigned arAbort = 0; const unsigned arNo = 1; const unsigned arYes = 2; /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned SimpleMenue (const String & Header, const String &MenueText); // Builds a menue from the given strings, shows that menue and returns the // users choice. The return value is 0 if the menue was aborted. // Use '|' to separate ther entries, use '^' to create a new item that is // centered. Use '@' to mark hotkeys (as usual). unsigned AskYesNo (const String & Header); // Pop up a menue with the given header and the entries "Yes" and "No", // "Yes" being the default entry. // Returns 0 = Abort, 1 = No, 2 = Yes unsigned AskNoYes (const String & Header); // Pop up a menue with the given header and the entries "No" and "Yes", // "No" being the default entry. // Returns 0 = Abort, 1 = No, 2 = Yes unsigned AskReallyQuit (); // Pops up a menue with the question "Really quit" and returns the result // 0 = Abort, 1 = No, 2 = Yes unsigned AskDiscardChanges (); // Pops up a menue with the question "Discard changes?" and returns the result // 0 = Abort, 1 = No, 2 = Yes unsigned AskSaveChanges (); // Pops up a menue with the question "Save changes?" and returns the result // 0 = Abort, 1 = No, 2 = Yes unsigned AskAreYouShure (); // Pops up a menue with the question "Are you shure?" and returns the result // 0 = Abort, 1 = No, 2 = Yes unsigned MenueChoice (const String& ResName); // Loads a menue with the name ResName from the resource file, gets the user // response and deletes the menue. // End of STDMENUE.H #endif estic-1.61.orig/spunk/stdmsg.cc0100644000176100001440000002066307031424706015772 0ustar debacleusers/*****************************************************************************/ /* */ /* STDMSG.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "msgid.h" #include "keydef.h" #include "splitmsg.h" #include "syserror.h" #include "progutil.h" #include "stdmsg.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ static const u16 msErrorHdr = MSGBASE_STDMSG + 0; static const u16 msInformationHdr = MSGBASE_STDMSG + 1; static const u16 msFatalErrorHdr = MSGBASE_STDMSG + 2; static const u16 msConfirm = MSGBASE_STDMSG + 10; static const u16 msAbort = MSGBASE_STDMSG + 11; static const u16 msIgnore = MSGBASE_STDMSG + 12; static const u16 msRetry = MSGBASE_STDMSG + 13; static const u16 msEnd = MSGBASE_STDMSG + 14; static const u16 msPleaseWait = MSGBASE_STDMSG + 15; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListNode; #endif /*****************************************************************************/ /* */ /*****************************************************************************/ Window* MsgWindow (const String& Msg, const String& Header, u16 Palette) // Create a window from the given data and return it. There are a few chars // in Msg that have a special meaning: // // ~ toggle the attribute between atTextNormal and atTextHigh // | begin a new line // ^ begin a new centered line // Note: The calling function has to free the returned window. { Rect Bounds; ListNode* Node; ListNode* N; // Get the length of the window header int HeaderLen = Header.Len (); // Split up the text for the lines Node = SplitLine (Msg, Bounds, HeaderLen); // Correct the size of the window if (Bounds.B.X < HeaderLen) { Bounds.B.X = HeaderLen; } Bounds.B.X += 4; // + Space + Frame Bounds.B.Y += 2; // + Frame // Center the message window inside the screen Rect ScreenSize (Background->OuterBounds ()); Bounds.Center (ScreenSize, cfCenterAll); // Open the window but keep it hidden Window* Win = new Window (Bounds, wfFramed | wfCanMove, Palette); // Set the window options so that the window will remain centered even // if the video mode changes Win->SetOption (cfCenterAll); // Write the Msg into the window N = Node; u16 Y = 0; do { Win->CWrite (1, Y, *(N->Contents ())); N = N->Next (); Y++; } while (N != Node); // Release the line list ReleaseLines (Node); // Set the window header and make it active (this will also show // the window) if (HeaderLen > 0) { Win->SetHeader (Header); } Win->Activate (); // Return the created window return Win; } Window* PleaseWaitWindow () // Pops up a centered, activated, cyan window with a message like // "Please wait..." in the current language // The caller must dispose the window. { return MsgWindow (LoadMsg (msPleaseWait), "", paCyan); } static String KeyMsg (Key K, unsigned MsgNum) // Return the name of key K surrounded by '~' and with the message with // number MsgNum added { return GetKeyName3 (K) + LoadMsg (MsgNum); } unsigned ResponseWindow (const String& Msg, const String& Header, u16 Palette, unsigned ResponseFlags) // Show a window via MsgWindow with the given Msg, Header, Palette. Ask // the user for a response. Allowed responses are coded in ResponseFlags. // The status line is updated to show the valid responses. { // ResponseFlags cannot be empty PRECONDITION (ResponseFlags != 0); // Build a statusline according to the flags set in ResponseFlags String StatusText; if (ResponseFlags & reConfirm) StatusText += KeyMsg (kbEnter, msConfirm); if (ResponseFlags & reAbort) StatusText += KeyMsg (vkAbort, msAbort); if (ResponseFlags & reIgnore) StatusText += KeyMsg (kbMetaI, msIgnore); if (ResponseFlags & reRetry) StatusText += KeyMsg (kbMetaR, msRetry); if (ResponseFlags & reEnd) StatusText += KeyMsg (vkAbort, msEnd); // Create the window Window* Win = MsgWindow (Msg, Header, Palette); // Show the new status line PushStatusLine (StatusText); // Now get the users response unsigned Result = 0; while (Result == 0) { Key K = KbdGet (); switch (K) { case kbEnter: case vkAccept: if (ResponseFlags & reConfirm) { Result = reConfirm; } else if (ResponseFlags & reEnd) { Result = reEnd; } break; case vkAbort: if (ResponseFlags & reAbort) { Result = reAbort; } else if (ResponseFlags & reEnd) { Result = reEnd; } break; case kbMetaI: if (ResponseFlags & reIgnore) { Result = reIgnore; } break; case kbMetaR: if (ResponseFlags & reRetry) { Result = reRetry; } break; case vkResize: Win->MoveResize (); break; } } // Delete the window and restore the old statusline delete Win; PopStatusLine (); return Result; } void ErrorMsg (const String& Msg) // Shows an error window. Returns when the window is closed (by vkAbort). { ResponseWindow (Msg, // Formatted message LoadMsg (msErrorHdr), // window header paRed, // palette reAbort); // valid responses } void ErrorMsg (u16 MsgNo, ...) // Shows an error window. Returns when the window is closed (by vkAbort). { va_list ap; va_start (ap, MsgNo); ResponseWindow (String (LoadMsg (MsgNo), ap), // Formatted message LoadMsg (msErrorHdr), // window header paRed, // palette reAbort); // valid responses va_end (ap); } void SysErrorMsg (int ErrorCode) // Display an appropriate error message for the system error code errno. Errno // _must_ be a valid error code from ::errno! { ErrorMsg (GetSysErrorMsg (ErrorCode)); } void InformationMsg (const String& Msg) // Shows an information window. Returns when the window is closed (by vkAbort). { ResponseWindow (Msg, // Formatted message LoadMsg (msInformationHdr), // window header paGray, // palette reEnd); // valid responses } void FatalErrorMsg (const String& Msg) // Shows an error window. Returns when the window is closed (by vkAbort). { ResponseWindow (Msg, // Formatted message LoadMsg (msFatalErrorHdr), // window header paError, // palette reAbort); // valid responses } estic-1.61.orig/spunk/stdmsg.h0100644000176100001440000000611707031424706015632 0ustar debacleusers/*****************************************************************************/ /* */ /* STDMSG.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __STDMSG_H #define __STDMSG_H #include "window.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ const unsigned reConfirm = 0x0001; const unsigned reAbort = 0x0002; const unsigned reIgnore = 0x0004; const unsigned reRetry = 0x0008; const unsigned reEnd = 0x0010; /*****************************************************************************/ /* Code */ /*****************************************************************************/ Window* MsgWindow (const String& Msg, const String& Header, u16 Palette); // Create a window from the given data and return it. There are a few chars // in Msg that have a special meaning: // // ~ toggle the attribute between atTextNormal and atTextHigh // | begin a new line // ^ begin a new centered line // Note: The calling function has to free the returned window. Window* PleaseWaitWindow (); // Pops up a centered, activated, cyan window with a message like // "Please wait..." in the current language // The caller must dispose the window. unsigned ResponseWindow (const String& Msg, const String& Header, u16 Palette, unsigned ResponseFlags); // Show a window via MsgWindow with the given Msg, Header, Palette. Ask // the user for a response. Allowed responses are coded in ResponseFlags. // The status line is updated to show the valid responses. void ErrorMsg (const String& Msg); // Shows an error window. Returns when the window is closed (by vkAbort). void ErrorMsg (u16 MsgNo, ...); // Shows an error window. Returns when the window is closed (by vkAbort). void SysErrorMsg (int Errno); // Display an appropriate error message for the system error code errno. Errno // _must_ be a valid error code from ::errno! void InformationMsg (const String& Msg); // Shows an information window. Returns when the window is closed (by vkAbort). void FatalErrorMsg (const String& Msg); // Shows an error window. Returns when the window is closed (by vkAbort). // End of STDMSG.H #endif estic-1.61.orig/spunk/str.cc0100644000176100001440000010113707031424706015275 0ustar debacleusers/*****************************************************************************/ /* */ /* STR.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "chartype.h" #include "charset.h" #include "str.h" #include "strcvt.h" #include "strparse.h" #include "stream.h" #include "streamid.h" // Register class String LINK (String, ID_String); /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Character used as escape char when calling Match unsigned char MatchEscChar = '\\'; // An empty string - for function returns and other stuff extern const String EmptyString (""); /*****************************************************************************/ /* class String */ /*****************************************************************************/ String::String (u16 Size) { Limit = Reblock (Size + 1); CHECK (Limit > 0); Str = new char [Limit]; *Str = '\0'; Length = 0; } void String::Init (const char* S, va_list ap) { if (S == NULL || *S == '\0') { // S is empty Length = 0; Limit = Reblock (Length + 1); Str = new char [Limit]; *Str = '\0'; } else { // S is not empty, format the string char Buf [1024]; Length = vsprintf (Buf, S, ap); CHECK (Length < sizeof (Buf)); Limit = Reblock (Length + 1); Str = (char *) memcpy (new char [Limit], Buf, Length + 1); } } String::String (const char* S) { if (S == NULL || *S == '\0') { // S is empty Length = 0; Limit = Reblock (Length + 1); Str = new char [Limit]; *Str = '\0'; } else { // S is not empty Length = strlen (S); Limit = Reblock (Length + 1); Str = (char *) memcpy (new char [Limit], S, Length + 1); } } String::String (const String& S) { Length = S.Length; Limit = S.Limit; Str = (char *) memcpy (new char [Limit], S.Str, Length + 1); } String::~String () { delete [] Str; } void String::Resize (u16 NewLimit) { NewLimit = Reblock (NewLimit); if (NewLimit == Limit) { // Nothing has changed... return; } char *P = new char [NewLimit]; if (Length < NewLimit) { // String fits, safe to copy memcpy (P, Str, Length + 1); } else { // New string is shorter memcpy (P, Str, NewLimit - 1); P [NewLimit] = '\0'; Length = NewLimit - 1; } Limit = NewLimit; delete [] Str; Str = P; } void String::Load (Stream &S) { S >> Length; delete [] Str; // Use this to mimic behaviour of builtin types Limit = Reblock (Length + 1); Str = new char [Limit]; S.Read (Str, Length + 1); } void String::Store (Stream& S) const { S << Length; S.Write (Str, Length + 1); } u16 String::StreamableID () const { return ID_String; } Streamable *String::Build () { return new String (Empty); } void String::Crypt () // crypt (make unreadable) by a simple XOR scheme { for (int I = 0; I < Length; I++) { Str [I] ^= I+10; } } void String::Decrypt () // Reverses the action done by Crypt { Crypt (); } u16 String::Len (const char *S) const // Return the length of the string not counting chars in S { unsigned Count = 0; char *P = Str; if (strlen (S) == 1) { // One char only char C = S [0]; while (*P != '\0') { if (*P != C) { Count++; } P++; } } else { unsigned Span; while (*P != '\0') { Span = strcspn (P, S); P += Span; Count += Span; while (*P != '\0') { if (strchr (S, *P)) { P++; // Char is in S, skip } else { break; // Char is not in S, break } } } } return Count; } int String::Pos (const char C) const // Return the first position of the char C in the string. If C is not // found, the function returns -1 { char *P = strchr (Str, C); return P ? P - Str : -1; } int String::Pos (const char *S) const // Return the first position of the string S in the string. If S is not // found, the function returns -1 { char *P = strstr (Str, S); return P ? P - Str : -1; } String& String::Remove (const CharSet& Chars, unsigned Flags) // Remove characters from a string according to Flags. { char C; unsigned Start = 0; // Initialize to make gcc happy unsigned Stop = 0; // Initialize to make gcc happy // Count the leading characters. This is only needed if we must delete // trailing or interword characters if (Flags & (rmLeading | rmInterWord)) { Start = 0; const char* S = Str; while ((C = *S++) != '\0' && Chars [C] != 0) { Start++; } // Remove leading characters if needed if (Flags & rmLeading) { // Do the delete Del (0, Start); // Reset the pointer to the first character not in chars Start = 0; } } // Count trailing characters. This is only needed if we must delete // trailing or interword characters. if (Flags & (rmTrailing | rmInterWord)) { Stop = Length; // Find the last char while (Stop > 0 && Chars [Str [Stop-1]] != 0) { Stop--; } // Remove trailing characters if needed if (Flags & rmTrailing) { Trunc (Stop); } } // Start now points to the first character that is not in Chars, Stop // holds the character *after* the last character not in Chars. The // next step is only needed if we must delete characters inside. if (Flags & rmInterWord) { // Run from Start to stop, deleting all the characters between while (Start < Stop) { if (Chars [Str [Start]] != 0) { // Got one to delete Del (Start); Stop--; } else { // Next one Start++; } } } // Return a reference to the string return *this; } String& String::Remove (const char* Chars, unsigned Flags) // Remove characters from a string according to Flags. { return Remove (CharSet (Chars), Flags); } String& String::Remove (const String& Chars, unsigned Flags) // Remove characters from a string according to Flags. { return Remove (CharSet (Chars), Flags); } void String::Replace (unsigned Start, char C) // Replace the character at index Start with C. The string is expanded // using spaces if needed. { // Things are simple if the string is long enough if (Start < Length) { Str [Start] = C; return; } // Must expand string Resize (Start + 2); memset (Str + Length, ' ', Start - Length); Str [Start] = C; Length = Start+1; Str [Length] = '\0'; } void String::Replace (unsigned Start, const char* S) // Replace the characters at index Start with S. The string is expanded // using spaces if needed. { // Get the length of the string to replace unsigned SLen = strlen (S); // Check if the string is long enough if (Length >= Start + SLen) { // Long enough, just copy memmove (Str + Start, S, SLen); return; } // Must expand string Resize (Start + SLen + 1); memset (Str + Length, ' ', Start - Length); memmove (Str + Start, S, SLen); Length = Start + SLen; Str [Length] = '\0'; } void String::Replace (unsigned Start, const String& S) // Replace the characters at index Start with S. The string is expanded // using spaces if needed. { // Check if the string is long enough if (Length >= Start + S.Length) { // Long enough, just copy memmove (Str + Start, S.Str, S.Length); return; } // Must expand string Resize (Start + S.Length + 1); memset (Str + Length, ' ', Start - Length); memmove (Str + Start, S.Str, S.Length); Length = Start + S.Length; Str [Length] = '\0'; } String& String::Add (const char* S, unsigned Len, PadType P) // Build lines of formatted text: If Len is zero, add S to the end of // this. If Len is non zero, use P to pad S to the given length, then // add it to the end of P. { return Add (String (S), Len, P); } String& String::Add (const String& S, unsigned Len, PadType P) // Build lines of formatted text: If Len is zero, add S to the end of // this. If Len is non zero, use P to pad S to the given length, then // add it to the end of P. { if (Len == 0) { return *this += S; } else { String F = S; return *this += F.Pad (P, Len); } } String String::Cut (unsigned Start, unsigned Count) const { // Bail out if count is zero if (Count == 0 || Start >= Length) { return String (); } // Calculate the character count to copy if ((Start + Count) > Length) { Count = Length - Start; } // Create a new empty string String S (Empty); S.Length = Count; S.Limit = Reblock (Count + 1); S.Str = new char [S.Limit]; // just copy the characters as the buffer is big enough memcpy (S.Str, &Str [Start], Count); // Add the trailing zero S.Str [Count] = '\0'; // That's it return S; } void String::ForceLen (int NewLen, PadType P) // Force the string to a new length. If the string is too long, it is // replaced with a string of '!'s of length NewLen. If the string is too // short, it is padded to the given length using the padtype P. { if (NewLen > Length) { // Needs padding Pad (P, NewLen); } else if (NewLen < Length) { // String too long Set (0, NewLen, '!'); Str [NewLen] = '\0'; } } void String::Del (unsigned Start, unsigned Count) { if (Start >= Length) { return; } if ((Start + Count) > Length) { Count = Length - Start; } if (Count == 0) { return; } // Now use memmove memmove (&Str [Start], &Str [Start+Count], Length - Start - Count + 1); // Length of the string has changed Length -= Count; } void String::Ins (unsigned Start, char C) // Insert a character into a string { Resize (Length + 2); memmove (&Str [Start+1], &Str [Start], Length - Start + 1); Str [Start] = C; Length += 1; } void String::Ins (unsigned Start, const char *S) { unsigned Count = strlen (S); Resize (Length + Count + 1); memmove (&Str [Start+Count], &Str [Start], Length - Start + 1); memcpy (&Str [Start], S, Count); Length += Count; } // Utility macro used in RMatch #define IncPattern() Pattern++; \ if (*Pattern == '\0') { \ return 0; \ } static int RealChar (const unsigned char* Pattern) // Return the next character from Pattern. If the next character is the // escape character, skip it and return the following. { if (*Pattern == MatchEscChar) { Pattern++; return (*Pattern == '\0') ? -1 : *Pattern; } else { return *Pattern; } } static int RMatch (const unsigned char* Source, const unsigned char* Pattern) // A recursive pattern matcher { CharSet CS; while (1) { if (*Pattern == '\0') { // Reached the end of Pattern, what about Source? return (*Source == '\0') ? 1 : 0; } else if (*Pattern == '*') { Pattern++; if (*Pattern == '\0') { // a trailing '*' is always a match return 1; } // Check the rest of the string while (*Source) { if (RMatch (Source++, Pattern)) { // match! return 1; } } // No match... return 0; } else if (*Source == '\0') { // End of Source reached, no match return 0; } else { // Check a single char. Build a set of all possible characters in // CS, then check if the current char of Source is contained in // there. CS.Clear (); // Clear the character set if (*Pattern == '?') { // All chars are allowed CS.SetAll (); Pattern++; // skip '?' } else if (*Pattern == MatchEscChar) { // use the next char without looking at it IncPattern (); CS += *Pattern; Pattern++; // skip the character } else if (*Pattern == '[') { // a set follows IncPattern (); int Invert = 0; if (*Pattern == '!') { IncPattern (); Invert = 1; } while (*Pattern != ']') { int C1; if ((C1 = RealChar (Pattern)) == -1) { return 0; } IncPattern (); if (*Pattern != '-') { CS += C1; } else { IncPattern (); int C2; if ((C2 = RealChar (Pattern)) == -1) { return 0; } IncPattern (); for (unsigned char C = C1; C <= C2; C++) { CS += C; } } } Pattern++; // skip ']' if (Invert) { CS.Reverse (); } } else { // Include the char in the charset CS += *Pattern; Pattern++; } if (CS [*Source] == 0) { // No match return 0; } Source++; } } } int Match (const char* Source, const char* Pattern) // Match the string in Source against Pattern. Pattern may contain the // wildcards '*', '?', '[abcd]' '[ab-d]', '[!abcd]', '[!ab-d]'. The // function returns a value of zero if Source does not match Pattern, // otherwise a non zero value is returned. If Pattern contains an invalid // wildcard pattern (e.g. 'A[x'), the function returns zero. { if (Pattern == NULL || *Pattern == '\0') { if (Source == NULL || *Source == '\0') { return 1; } else { return 0; } } // Do the real thing return RMatch ((unsigned char *) Source, (unsigned char *) Pattern); } int Match (const String& Source, const String& Pattern) { return Match (Source.Str, Pattern.Str); } int Match (const String& Source, const char* Pattern) { return Match (Source.Str, Pattern); } int Match (const char* Source, const String& Pattern) { return Match (Source, Pattern.Str); } static String GetStr (String& ValStr, char C) // Helper function for MatchKeyword. Extract from ValStr the string delimited // by C. Delete this string (including C) from ValStr and return it. // Call FAIL if ValStr is invalid { // Get the position of the delimiter and make shure, it's there int DelimPos = ValStr.Pos (C); CHECK (DelimPos > 0); // Get the partial string String Val = ValStr.Cut (0, DelimPos); // Delete the partial string ValStr.Del (0, DelimPos + 1); // Return the extracted string return Val; } static u32 GetNumber (String& ValStr) // Helper function for MatchKeyword. Extract the numeric value from ValStr and // delete this number including the following '^'. Call FAIL if ValStr is // invalid { // Get the number String Val = GetStr (ValStr, '^'); // Set up the string parser StringParser SP (Val, StringParser::UseAll | StringParser::PascalHex | StringParser::CHex); // Get the value u32 Value; CHECK (SP.GetU32 (Value) == 0); // return the value return Value; } u32 MatchKeyword (const String& ID, String Keywords) // Match the string ID against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { // Get the default value (this is the first number in Keywords) int HaveDefault = 0; u32 Default = 0; // Initialize to make gcc happy // If ID is empty, we are already done if (ID.IsEmpty ()) { // Return the default return GetNumber (Keywords); } // Repeat until Keywords is gone.. do { // Get the next numeric value u32 NumVal = GetNumber (Keywords); // Use this value as default value if we don't have one until now if (!HaveDefault) { HaveDefault = 1; Default = NumVal; } // Compare the next value if (Match (ID, GetStr (Keywords, '|'))) { // Found the value return NumVal; } } while (!Keywords.IsEmpty ()); // Not found return Default; } u32 String::MatchKeyword (const String& Keywords) const // Match the string against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { return ::MatchKeyword (*this, Keywords); } u32 String::MatchKeyword (const char* Keywords) const // Match the string against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { return ::MatchKeyword (*this, Keywords); } String& String::Pad (PadType P, u16 NewLen, char C) // Pad the string to the given length using the padding char C. If the // string is too long, it is simply cut of at the end. { if (Length > NewLen) { // String is too long, nothing to pad Trunc (NewLen); return *this; } else if (Length == NewLen) { // Nothing to do return *this; } // Allocate memory for the new string u16 NewLimit = Reblock (NewLen + 1); char *S = new char [NewLimit]; // Initialize the following variables to prevent gcc warnings u16 LeftPad = 0; u16 RightPad = 0; switch (P) { case Left: LeftPad = NewLen - Length; RightPad = 0; break; case Center: RightPad = NewLen - Length; LeftPad = RightPad / 2; RightPad -= LeftPad; break; case Right: LeftPad = 0; RightPad = NewLen - Length; break; } memset (S, C, LeftPad); memcpy (&S [LeftPad], Str, Length); memset (&S [LeftPad + Length], C, RightPad); S [NewLen] = '\0'; // Now delete the old string data end store the new delete [] Str; Str = S; Limit = NewLimit; Length += LeftPad + RightPad; // Return a reference to this return *this; } int String::ScanL (const char C) const // Return the last position of the char C in the string. If C is not // found, the function returns -1 { char *P = strrchr (Str, C); return P ? P - Str : -1; } int String::ScanL (const char* S) const // Return the last position of the string S in the string. If S is not // found, the function returns -1 { char *P = Str; int Pos = -1; // Some optimization would be nice here, but it works ... while (1) { P = strstr (P, S); if (P == NULL) { // Not found, return last occurence return Pos; } else { // Found, remember this occurence, skip one char Pos = P - Str; P++; } } } void String::Set (unsigned Start, unsigned Count, char C) // Beginning from index Start, set Count characters to C. The string // is expanded if needed { if ((Start + Count + 1) > Limit) { Resize (Start + Count + 1); } memset (&Str [Start], C, Count); if ((Start + Count) > Length) { // Length has changed, add trailing zero, correct length Str [Start+Count] = '\0'; Length = Start + Count; } } String& String::Trunc (unsigned Position) // Truncate the string at the given position. After calling Trunc, the // string length is less or equal to Position. { // Ignore the cut if the string is shorter if (Position < Length) { Str [Position] = '\0'; Length = Position; } return *this; } char* String::PSZ (char* Buf, size_t BufLen) const // Copy the string to the given buffer. { if (Length < BufLen) { return strcpy (Buf, Str); } else { // Must truncate memcpy (Buf, Str, BufLen-1); Buf [BufLen-1] = '\0'; return Buf; } } String& String::operator = (const char* S) { if (S && *S != '\0') { // S is not empty. Check if there is enough room to copy Length = strlen (S); if (Length+1 <= Limit) { // Room enough, just copy memcpy (Str, S, Length+1); } else { // Need more memory delete [] Str; Limit = Reblock (Length+1); Str = (char *) memcpy (new char [Limit], S, Length + 1); } } else { // S is empty, do it the simple way *Str = '\0'; } return *this; } String& String::operator = (const String& S) { if (&S != this) { // beware of S = S; delete [] Str; Limit = S.Limit; Length = S.Length; Str = (char *) memcpy (new char [Limit], S.Str, Length + 1); } return *this; } char& String::operator [] (unsigned Index) { // Make shure, Index is valid PRECONDITION (Index <= Length); return Str [Index]; } const char& String::operator [] (unsigned Index) const { // Check the index against the string length PRECONDITION (Index <= Length); return Str [Index]; } String& operator += (String& S, const char C) { S.Resize (S.Length + 2); S.Str [S.Length] = C; S.Length++; S.Str [S.Length] = '\0'; return S; } String& operator += (String& S, const char* P) { u16 PLen = strlen (P); S.Resize (S.Length + PLen + 1); memcpy (&S.Str [S.Length], P, PLen + 1); S.Length += PLen; return S; } String operator + (const String& S, const char C) { String Ret = S; Ret += C; return Ret; } String operator + (const String& S, const char* P) { // Create an emtpy string to avoid calling operator new String Res (Empty); // Build the combined string u16 PLen = strlen (P); Res.Length = S.Length + PLen; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, S.Str, S.Length); memcpy (&Res.Str [S.Length], P, PLen + 1); // ... and return it return Res; } String operator + (const String& S1, const String& S2) { // Create an emtpy string to avoid calling operator new String Res (Empty); // Build the combined string Res.Length = S1.Length + S2.Length; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, S1.Str, S1.Length); memcpy (&Res.Str [S1.Length], S2.Str, S2.Length + 1); // ... and return it return Res; } String operator + (const char* P, const String& S2) { // Create empty object to avoid call to operator new String Res (Empty); u16 PLen = strlen (P); Res.Length = PLen + S2.Length; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, P, PLen); memcpy (&Res.Str [PLen], S2.Str, S2.Length + 1); return Res; } String operator + (const char C, const String& S) { // Create empty object to avoid call to operator new String Res (Empty); Res.Length = S.Length + 1; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; Res.Str [0] = C; memcpy (&Res.Str [1], S.Str, S.Length + 1); return Res; } String ShowControls (const String& S, unsigned Style) // Recode the given string and replace every control character by it's // visible representation, e.g. "\n" instead of the character with code // code 13. { // Numeric codes in hex static const char HexCodes [32][5] = { "\\x00", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\x07", "\\x08", "\\x09", "\\x0A", "\\x0B", "\\x0C", "\\x0D", "\\x0E", "\\x0F", "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17", "\\x18", "\\x19", "\\x1A", "\\x1B", "\\x1C", "\\x1D", "\\x1E", "\\x1F" }; // Numeric codes in octal static const char OctCodes [32][5] = { "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007", "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017", "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027", "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037", }; // Create a new string with a length of 110% of the string to recode. // This is just an assumption of the probable string growth and // is thought to prevent too many string resizes (each one calls // operator new). String T ((S.Len () * 11) / 10); // When recoding, access S directly to avoid the range check code // that would slow things down and is not needed here char* Str = S.Str; while (*Str) { switch (*Str) { case 0x01: // This is the special spunk char '\c' if (Style & ccSpunk) { T += "\\c"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\\': if (Style & ccCStyle) { T += "\\\\"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\a': if (Style & ccCStyle) { T += "\\a"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\b': if (Style & ccCStyle) { T += "\\b"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\f': if (Style & ccCStyle) { T += "\\f"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\n': if (Style & ccCStyle) { T += "\\n"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\t': if (Style & ccCStyle) { T += "\\t"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\v': if (Style & ccCStyle) { T += "\\v"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; default: if (!IsCntrl (*Str)) { // No control char, just add the char itself T += *Str; } else { // Another control char T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; } // Next char Str++; } // Done, return the result return T; } static unsigned Num (char C) // Return the numeric representation of the character C (assumes ASCII) { if (C >= 'a') { return C - 'a' + 10; } else if (C >= 'A') { return C - 'A' + 10; } else { return C - '0'; } } String HideControls (const String& S) // Recode the given string and replace every visible control character // representation by the character itself, e.g. replace "\n" by the // character with code 13. { // Create the target string with the same length as the source string. // The string will definitely not grow when recoding, so there is no // further call to operator new needed. String T (S.Len ()); // Access the source string directly to avoid the range check code // that is not needed here. char* Str = S.Str; // Recode the string while (*Str) { if (*Str == '\\') { // A control char. Check it. Str++; switch (*Str) { case '\0': // Ohh help! The string ends with an open sequence - // just copy the start of the sequence. Then remember // to decrease S 1 char back to match the end condition. T += '\\'; Str--; break; case '\\': T += '\\'; break; case 'a': T += '\a'; break; case 'b': T += '\b'; break; case 'c': // This an invalid sequence in c but used as the spunk // "center string" mark. T += char (0x01); break; case 'f': T += '\f'; break; case 'n': T += '\n'; break; case 't': T += '\t'; break; case 'v': T += '\v'; break; case 'x': case 'X': // Character code in hex follows. Check if there is really // a character code. if (IsXDigit (Str [1]) && IsXDigit (Str [2])) { T += char (Num (Str [1]) * 16 + Num (Str [2])); Str += 2; } else { // Something is wrong. Copy the '\x', which is the // only part, we know it is correct, and let the // next round determine what to do with the remaining // chars; T += "\\x"; } break; default: // This is an unknown control char. Swallow it. break; } } else { // Some other char, just copy it T += *Str; } // Next char Str++; } // Done, return the result return T; } String FormatStr (const char* S, ...) // Return a via sprintf formatted string { va_list ap; va_start (ap, S); #if defined(DOS) || defined (DOS32) || defined (OS2) // Does not call va_end but works on DOS/OS2 and does not need an extra copy return String (S, ap); #else // Portable version String Res (S, ap); va_end (ap); return Res; #endif } estic-1.61.orig/spunk/str.h0100644000176100001440000005050707031424706015143 0ustar debacleusers/*****************************************************************************/ /* */ /* STR.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STR_H #define _STR_H #include #include #include "machine.h" #include "object.h" #include "strmable.h" #include "national.h" // Forwards class Stream; class CharSet; /*****************************************************************************/ /* Constants */ /*****************************************************************************/ // Bitmapped constants that describe the behaviour of the ShowControls // functions const unsigned ccHex = 0x0000; // Use hex character code - // this is the default const unsigned ccOct = 0x0001; // Use octal codes instead // of hex codes const unsigned ccSpunk = 0x0002; // Show the special spunk // characters (\c for example) // not as codes but as names const unsigned ccCStyle = 0x0004; // Use the C style character // codes like '\n', '\r' // instead of numerical ones const unsigned ccDefault = ccHex | ccCStyle; // Bitmapped constants that describe the behaviour of the Remove functions const unsigned rmLeading = 0x0001; // Remove leading chars const unsigned rmTrailing = 0x0002; // Remove trailing chars const unsigned rmInterWord = 0x0004; // Remove chars inside const unsigned rmAll = rmLeading | rmTrailing | rmInterWord; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Character used as escape char when calling Match extern unsigned char MatchEscChar; // An empty string - for function returns and other stuff extern const class String EmptyString; /*****************************************************************************/ /* class String */ /*****************************************************************************/ // Note: This string class may not work with strings greater than INT_MAX or // 0xFFFF, whichever is less class String : public Streamable { protected: char* Str; u16 Limit; u16 Length; // Internal used functions u16 Reblock (u16) const; void Resize (u16 NewLimit); void Init (const char* S, va_list ap); public: enum PadType { Left, Center, Right }; String (u16 Size = 0); String (const char* S); String (const String& S); String (const char* S, va_list ap); String (const String& S, va_list ap); String (StreamableInit); ~String (); // Derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); // New member functions String& Clear (); // Set length to zero, return this void Crypt (); // crypt (make unreadable) by a simple XOR scheme u16 Len () const; // Return the length of the string u16 Len (const char* S) const; // Return the length of the string not counting any chars contained in S u16 Len (const String& S) const; // Return the length of the string not counting any chars contained in S String& Add (const char* S, unsigned Len = 0, PadType P = Right); String& Add (const String& S, unsigned Len = 0, PadType P = Right); // Build lines of formatted text: If Len is zero, add S to the end of // this. If Len is non zero, use P to pad S to the given length, then // add it to the end of P. String Cut (unsigned Start, unsigned Count) const; // Return the part of the string beginning with index Start that is Count // chars long void Decrypt (); // Reverses the action done by Crypt void Del (unsigned Start, unsigned Count = 1); // Delete Count chars starting at index Start void ForceLen (int NewLen, PadType P = Right); // Force the string to a new length. If the string is too long, it is // replaced with a string of '!'s of length NewLen. If the string is too // short, it is padded to the given length using the padtype P. void Ins (unsigned Start, char C); // Insert a character into the string at position Start void Ins (unsigned Start, const char* S); // Insert a run of characters into the string at position Start void Ins (unsigned Start, const String &S); // Insert another string beginning with position Start int IsEmpty () const; // Return true if the string is empty (the length is zero) int NotEmpty () const; // Return true if the string is not empty (the length is greater than zero) int Match (const String& Pattern) const; int Match (const char* Pattern) const; // Match the string against Pattern. Pattern may contain the // wildcards '*', '?', '[abcd]' '[ab-d]', '[!abcd]', '[!ab-d]'. The // function returns a value of zero if Source does not match Pattern, // otherwise a non zero value is returned. If Pattern contains an invalid // wildcard pattern (e.g. 'A[x'), the function returns zero. u32 MatchKeyword (const String& Keywords) const; u32 MatchKeyword (const char* Keywords) const; // Match the string against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. String& Pad (PadType P, u16 Length, char C = ' '); // Pad the string to the given length using the padding char C. If the // string is too long, it is simply cut of at the end. int Pos (const char C) const; // Return the first position of the char C in the string. If C is not // found, the function returns -1 int Pos (const char* S) const; // Return the first position of the string S in the string. If S is not // found, the function returns -1 int Pos (const String& S) const; // Return the first position of the string S in the string. If S is not // found, the function returns -1 String& Remove (const CharSet& Chars, unsigned Flags); // Remove characters from a string according to Flags. String& Remove (const char* Chars, unsigned Flags); // Remove characters from a string according to Flags. String& Remove (const String& Chars, unsigned Flags); // Remove characters from a string according to Flags. void Replace (unsigned Start, char C); // Replace the character at index Start with C. The string is expanded // using spaces if needed. void Replace (unsigned Start, const char* S); // Replace the characters at index Start with S. The string is expanded // using spaces if needed. void Replace (unsigned Start, const String& S); // Replace the characters at index Start with S. The string is expanded // using spaces if needed. int ScanR (const char C) const; // Return the first position of the char C in the string. If C is not // found, the function returns -1 int ScanR (const char* S) const; // Return the first position of the string S in the string. If S is not // found, the function returns -1 int ScanR (const String& S) const; // Return the first position of the string S in the string. If S is not // found, the function returns -1 int ScanL (const char C) const; // Return the last position of the char C in the string. If C is not // found, the function returns -1 int ScanL (const char* S) const; // Return the last position of the string S in the string. If S is not // found, the function returns -1 int ScanL (const String& S) const; // Return the last position of the string S in the string. If S is not // found, the function returns -1 void Set (unsigned Start, unsigned Count, char C = ' '); // Beginning from index Start, set Count characters to C. The string // is expanded if needed void Settle (); // Adjust the memory buffer of the string to the actual string length String& ToUpper (); // Uppercase the string using NLSUpper String& ToLower (); // Lowercase the string using NLSLower String& InputCvt (); // Convert the string from external character representation to the // internal used representation using the global function InputCvt. String& OutputCvt (); // Convert the string from internal character representation to the // external used representation using the global function OutputCvt. String& Trunc (unsigned Position = 0); // Truncate the string at the given position. After calling Trunc, the // string length is less or equal to Position. const char* GetStr () const; // Return the string as a asciiz string char* PSZ (char* Buf) const; char* PSZ (char* Buf, size_t Len) const; // Copy the string to the given buffer. The first form assumes, Buf is // big enough String& operator = (char C); String& operator = (const char* S); String& operator = (const String& S); // Copy something to a string char& operator [] (unsigned Index); const char& operator [] (unsigned Index) const; // Return a char from the string String& ShowControls (unsigned Style = ccDefault); // Recode the given string and replace every control character by it's // visible representation, e.g. "\n" instead of the character with code // code 13. String& HideControls (); // Recode the given string and replace every visible control character // representation by the character itself, e.g. replace "\n" by the // character with code 13. friend String ShowControls (const String& S, unsigned Style = ccDefault); // Recode the given string and replace every control character by it's // visible representation, e.g. "\n" instead of the character with code // code 13. friend String HideControls (const String& S); // Recode the given string and replace every visible control character // representation by the character itself, e.g. replace "\n" by the // character with code 13. // Friends friend String& operator += (String&, const char); friend String& operator += (String&, const char*); friend inline String& operator += (String&, const String&); friend String operator + (const String&, const char); friend String operator + (const String&, const char*); friend String operator + (const String&, const String&); friend String operator + (const char, const String&); friend String operator + (const char*, const String&); friend inline int operator == (const String&, const String&); friend inline int operator != (const String&, const String&); friend inline int operator >= (const String&, const String&); friend inline int operator <= (const String&, const String&); friend inline int operator > (const String&, const String&); friend inline int operator < (const String&, const String&); friend inline int operator == (const char*, const String&); friend inline int operator != (const char*, const String&); friend inline int operator >= (const char*, const String&); friend inline int operator <= (const char*, const String&); friend inline int operator > (const char*, const String&); friend inline int operator < (const char*, const String&); friend inline int operator == (const String&, const char*); friend inline int operator != (const String&, const char*); friend inline int operator >= (const String&, const char*); friend inline int operator <= (const String&, const char*); friend inline int operator > (const String&, const char*); friend inline int operator < (const String&, const char*); friend inline int Compare (const String& S1, const String& S2); // Compares two strings alphabetically friend int Match (const char* Source, const char* Pattern); friend int Match (const String& Source, const String& Pattern); friend int Match (const String& Source, const char* Pattern); friend int Match (const char* Source, const String& Pattern); // Match the string in Source against Pattern. Pattern may contain the // wildcards '*', '?', '[abcd]' '[ab-d]', '[!abcd]', '[!ab-d]'. The // function returns a value of zero if Source does not match Pattern, // otherwise a non zero value is returned. If Pattern contains an invalid // wildcard pattern (e.g. 'A[x'), the function returns zero. // NOTE: Do not use this function for matching file names - use FMatch // (module filepath) instead! friend String FormatStr (const char* S, ...); }; // The Build-constructor has to clear Str, because Load will free an already // allocated String. This behaviour is different to that of most other // classes, but mimics better the builtin types. inline String::String (StreamableInit) : Str (NULL) { } inline String::String (const char* S, va_list ap) { Init (S, ap); } inline String::String (const String& S, va_list ap) { Init (S.Str, ap); } inline u16 String::Reblock (u16 Size) const // Re-Blocks the given size to achieve a granularity != 1 { return u16 ((Size + 0x000F) & 0xFFF0); } inline String& String::Clear () // Set length to zero { *Str = '\0'; Length = 0; return *this; } inline int String::IsEmpty () const // Return true if the string is empty (the length is zero) { return Length == 0; } inline int String::NotEmpty () const // Return true if the string is not empty (the length is greater than zero) { return Length != 0; } inline u16 String::Len () const // Return the length of the string { return Length; } inline u16 String::Len (const String& S) const // Return the length of the string not counting any chars in S { return Len (S.Str); } inline int String::Match (const String& Pattern) const { return ::Match (Str, Pattern.Str); } inline int String::Match (const char* Pattern) const { return ::Match (Str, Pattern); } inline int String::Pos (const String& S) const // Return the first position of the string S in the string. If S is not // found, the function returns -1 { return Pos (S.Str); } inline void String::Ins (unsigned Start, const String& S) { Ins (Start, S.Str); } inline int String::ScanR (const char C) const // Return the first position of the char C in the string. If C is not // found, the function returns -1 { return Pos (C); } inline int String::ScanR (const char* S) const // Return the first position of the string S in the string. If S is not // found, the function returns -1 { return Pos (S); } inline int String::ScanR (const String& S) const // Return the first position of the string S in the string. If S is not // found, the function returns -1 { return Pos (S); } inline int String::ScanL (const String& S) const { return ScanL (S.Str); } inline void String::Settle () // Adjust buffer size to the memory needed { Resize (Length + 1); } inline String& String::ToUpper () // Uppercase the string using NLSUpper { NLSUpStr (Str); return *this; } inline String& String::ToLower () // Lowercase the string using NLSLower { NLSLoStr (Str); return *this; } inline String& String::InputCvt () // Convert the string from external character representation to the // internal used representation using the global function InputCvt. { ::InputCvt (Str); return *this; } inline String& String::OutputCvt () // Convert the string from internal character representation to the // external used representation using the global function OutputCvt. { ::OutputCvt (Str); return *this; } inline const char* String::GetStr () const // Return the string as a asciiz string { return Str; } inline char* String::PSZ (char* Buf) const // Copy the string to the given buffer. { return strcpy (Buf, Str); } inline String& String::operator = (char C) // Copy a char as a string of length one to a string { // Str is at least 16 bytes long, so it's safe to copy Str [0] = C; Str [1] = '\0'; Length = 1; return *this; } inline String& String::ShowControls (unsigned Style) // Recode the given string and replace every control character by it's // visible representation, e.g. "\n" instead of the character with code // code 13. { return (*this = ::ShowControls (*this, Style)); } inline String& String::HideControls () // Recode the given string and replace every visible control character // representation by the character itself, e.g. replace "\n" by the // character with code 13. { return (*this = ::HideControls (*this)); } inline String & operator += (String& S1, const String& S2) { return (S1 += S2.Str); } inline int operator == (const String& S1, const String& S2) { return (strcmp (S1.Str, S2.Str) == 0); } inline int operator != (const String& S1, const String& S2) { return (strcmp (S1.Str, S2.Str) != 0); } inline int operator >= (const String& S1, const String& S2) { return (NLSCmpStr (S1.Str, S2.Str) >= 0); } inline int operator <= (const String& S1, const String& S2) { return (NLSCmpStr (S1.Str, S2.Str) <= 0); } inline int operator > (const String& S1, const String& S2) { return (NLSCmpStr (S1.Str, S2.Str) > 0); } inline int operator < (const String& S1, const String& S2) { return (NLSCmpStr (S1.Str, S2.Str) < 0); } inline int operator == (const char* S1, const String& S2) { return (strcmp (S1, S2.Str) == 0); } inline int operator != (const char* S1, const String& S2) { return (strcmp (S1, S2.Str) != 0); } inline int operator >= (const char* S1, const String& S2) { return (NLSCmpStr (S1, S2.Str) >= 0); } inline int operator <= (const char* S1, const String& S2) { return (NLSCmpStr (S1, S2.Str) <= 0); } inline int operator > (const char* S1, const String& S2) { return (NLSCmpStr (S1, S2.Str) > 0); } inline int operator < (const char* S1, const String& S2) { return (NLSCmpStr (S1, S2.Str) < 0); } inline int operator == (const String& S1, const char* S2) { return (strcmp (S1.Str, S2) == 0); } inline int operator != (const String& S1, const char* S2) { return (strcmp (S1.Str, S2) != 0); } inline int operator >= (const String& S1, const char* S2) { return (NLSCmpStr (S1.Str, S2) >= 0); } inline int operator <= (const String& S1, const char* S2) { return (NLSCmpStr (S1.Str, S2) <= 0); } inline int operator > (const String& S1, const char* S2) { return (NLSCmpStr (S1.Str, S2) > 0); } inline int operator < (const String& S1, const char* S2) { return (NLSCmpStr (S1.Str, S2) < 0); } inline int Compare (const String& S1, const String& S2) // Compares two strings alphabetically { return NLSCmpStr (S1.Str, S2.Str); } u32 MatchKeyword (const String& ID, String Keywords); // Match the string ID against a list of keywords given as a string. The // list of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. inline String ToUpper (String S) // Uppercase the string using NLSUpper { return S.ToUpper (); } inline String ToLower (String S) // Lowercase the string using NLSLower { return S.ToLower (); } // End of STR.H #endif estic-1.61.orig/spunk/str.new0100644000176100001440000007275207031424706015513 0ustar debacleusers/*****************************************************************************/ /* */ /* STR.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "chartype.h" #include "charset.h" #include "str.h" #include "strcvt.h" #include "strparse.h" #include "stream.h" #include "streamid.h" // Register class String LINK (String, ID_String); /*****************************************************************************/ /* Data & some types */ /*****************************************************************************/ // Character used as escape char when calling Match unsigned char MatchEscChar = '\\'; // An empty string - for function returns and other stuff extern const String EmptyString (""); // Types used in match typedef const unsigned char* PCONSTCHAR; // Constants for meta-characters in RMatch. All metacharacters *must* be // outside the 0..255 range const unsigned mcQuestionmark = 256; const unsigned mcStar = 257; const unsigned mcLeftSquareBracket = 258; const unsigned mcRightSquareBracket = 259; const unsigned mcLeftCurlyBrace = 260; const unsigned mcRightCurlyBrace = 261; /*****************************************************************************/ /* class String */ /*****************************************************************************/ String::String (u16 Size) { Limit = Reblock (Size + 1); CHECK (Limit > 0); Str = new char [Limit]; *Str = '\0'; Length = 0; } void String::Init (const char* S, va_list ap) { if (S == NULL || *S == '\0') { // S is empty Length = 0; Limit = Reblock (Length + 1); Str = new char [Limit]; *Str = '\0'; } else { // S is not empty, format the string char Buf [1024]; Length = vsprintf (Buf, S, ap); CHECK (Length < sizeof (Buf)); Limit = Reblock (Length + 1); Str = (char *) memcpy (new char [Limit], Buf, Length + 1); } } String::String (const char* S) { if (S == NULL || *S == '\0') { // S is empty Length = 0; Limit = Reblock (Length + 1); Str = new char [Limit]; *Str = '\0'; } else { // S is not empty Length = strlen (S); Limit = Reblock (Length + 1); Str = (char *) memcpy (new char [Limit], S, Length + 1); } } String::String (const String& S) { Length = S.Length; Limit = S.Limit; Str = (char *) memcpy (new char [Limit], S.Str, Length + 1); } String::~String () { delete [] Str; } void String::Resize (u16 NewLimit) { NewLimit = Reblock (NewLimit); if (NewLimit == Limit) { // Nothing has changed... return; } char *P = new char [NewLimit]; if (Length < NewLimit) { // String fits, safe to copy memcpy (P, Str, Length + 1); } else { // New string is shorter memcpy (P, Str, NewLimit - 1); P [NewLimit] = '\0'; Length = NewLimit - 1; } Limit = NewLimit; delete [] Str; Str = P; } void String::Load (Stream &S) { S >> Length; delete [] Str; // Use this to mimic behaviour of builtin types Limit = Reblock (Length + 1); Str = new char [Limit]; S.Read (Str, Length + 1); } void String::Store (Stream& S) const { S << Length; S.Write (Str, Length + 1); } u16 String::StreamableID () const { return ID_String; } Streamable *String::Build () { return new String (Empty); } void String::Crypt () // crypt (make unreadable) by a simple XOR scheme { for (int I = 0; I < Length; I++) { Str [I] ^= I+10; } } void String::Decrypt () // Reverses the action done by Crypt { Crypt (); } u16 String::Len (const char *S) const // Return the length of the string not counting chars in S { unsigned Count = 0; char *P = Str; if (strlen (S) == 1) { // One char only char C = S [0]; while (*P != '\0') { if (*P != C) { Count++; } P++; } } else { unsigned Span; while (*P != '\0') { Span = strcspn (P, S); P += Span; Count += Span; while (*P != '\0') { if (strchr (S, *P)) { P++; // Char is in S, skip } else { break; // Char is not in S, break } } } } return Count; } int String::Pos (const char C) const // Return the first position of the char C in the string. If C is not // found, the function returns -1 { char *P = strchr (Str, C); return P ? P - Str : -1; } int String::Pos (const char *S) const // Return the first position of the string S in the string. If S is not // found, the function returns -1 { char *P = strstr (Str, S); return P ? P - Str : -1; } String& String::Remove (const CharSet& Chars, unsigned Flags) // Remove characters from a string according to Flags. { char C; unsigned Start, Stop; // Count the leading characters. This is only needed if we must delete // trailing or interword characters if (Flags & (rmLeading | rmInterWord)) { Start = 0; const char* S = Str; while ((C = *S++) != '\0' && Chars [C] != 0) { Start++; } // Remove leading characters if needed if (Flags & rmLeading) { // Do the delete Del (0, Start); // Reset the pointer to the first character not in chars Start = 0; } } // Count trailing characters. This is only needed if we must delete // trailing or interword characters. if (Flags & (rmTrailing | rmInterWord)) { Stop = Length; // Find the last char while (Stop > 0 && Chars [Str [Stop-1]] != 0) { Stop--; } // Remove trailing characters if needed if (Flags & rmTrailing) { Trunc (Stop); } } // Start now points to the first character that is not in Chars, Stop // holds the character *after* the last character not in Chars. The // next step is only needed if we must delete characters inside. if (Flags & rmInterWord) { // Run from Start to stop, deleting all the characters between while (Start < Stop) { if (Chars [Str [Start]] != 0) { // Got one to delete Del (Start); Stop--; } else { // Next one Start++; } } } // Return a reference to the string return *this; } String& String::Remove (const char* Chars, unsigned Flags) // Remove characters from a string according to Flags. { return Remove (CharSet (Chars), Flags); } String& String::Remove (const String& Chars, unsigned Flags) // Remove characters from a string according to Flags. { return Remove (CharSet (Chars), Flags); } void String::Replace (unsigned Start, char C) // Replace the character at index Start with C. The string is expanded // using spaces if needed. { // Things are simple if the string is long enough if (Start < Length) { Str [Start] = C; return; } // Must expand string Resize (Start + 2); memset (Str + Length, ' ', Start - Length); Str [Start] = C; Length = Start+1; Str [Length] = '\0'; } void String::Replace (unsigned Start, const char* S) // Replace the characters at index Start with S. The string is expanded // using spaces if needed. { // Get the length of the string to replace unsigned SLen = strlen (S); // Check if the string is long enough if (Length >= Start + SLen) { // Long enough, just copy memmove (Str + Start, S, SLen); return; } // Must expand string Resize (Start + SLen + 1); memset (Str + Length, ' ', Start - Length); memmove (Str + Start, S, SLen); Length = Start + SLen; Str [Length] = '\0'; } void String::Replace (unsigned Start, const String& S) // Replace the characters at index Start with S. The string is expanded // using spaces if needed. { // Check if the string is long enough if (Length >= Start + S.Length) { // Long enough, just copy memmove (Str + Start, S.Str, S.Length); return; } // Must expand string Resize (Start + S.Length + 1); memset (Str + Length, ' ', Start - Length); memmove (Str + Start, S.Str, S.Length); Length = Start + S.Length; Str [Length] = '\0'; } String String::Cut (unsigned Start, unsigned Count) const { // Bail out if count is zero if (Count == 0 || Start >= Length) { return String (); } // Calculate the character count to copy if ((Start + Count) > Length) { Count = Length - Start; } // Create a new empty string String S (Empty); S.Length = Count; S.Limit = Reblock (Count + 1); S.Str = new char [S.Limit]; // just copy the characters as the buffer is big enough memcpy (S.Str, &Str [Start], Count); // Add the trailing zero S.Str [Count] = '\0'; // That's it return S; } void String::ForceLen (int NewLen, PadType P) // Force the string to a new length. If the string is too long, it is // replaced with a string of '!'s of length NewLen. If the string is too // short, it is padded to the given length using the padtype P. { if (NewLen > Length) { // Needs padding Pad (P, NewLen); } else if (NewLen < Length) { // String too long Set (0, NewLen, '!'); Str [NewLen] = '\0'; } } void String::Del (unsigned Start, unsigned Count) { if (Start >= Length) { return; } if ((Start + Count) > Length) { Count = Length - Start; } if (Count == 0) { return; } // Now use memmove memmove (&Str [Start], &Str [Start+Count], Length - Start - Count + 1); // Length of the string has changed Length -= Count; } void String::Ins (unsigned Start, char C) // Insert a character into a string { Resize (Length + 2); memmove (&Str [Start+1], &Str [Start], Length - Start + 1); Str [Start] = C; Length += 1; } void String::Ins (unsigned Start, const char *S) { unsigned Count = strlen (S); Resize (Length + Count + 1); memmove (&Str [Start+Count], &Str [Start], Length - Start + 1); memcpy (&Str [Start], S, Count); Length += Count; } // Utility macro used in RMatch #define IncPattern() Pattern++; \ if (*Pattern == '\0') { \ return 0; \ } static unsigned RealChar (PCONSTCHAR& Pattern) // Return the next character from Pattern. If the next character is the // escape character, skip it and return the following. { if (*Pattern == '\0') { // Do not advance over the trailer return 0; } else if (*Pattern == MatchEscChar) { // Skip the escape character Pattern++; // Check for meta characters unsigned char C = *Pattern++; switch (C) { case '*': return mcStar; case '?': return mcQuestionmark; case '[': return mcLeftSquareBracket; case ']': return mcRightSquareBracket; case '{': return mcLeftCurlyBrace; case '}': return mcRightCurlyBrace; case '\0': // Must be handled special Pattern--; // Set back to point to the trailer return 0; default: // No metacharacter, return the character itself return C; } else { // Just a simple character return *Pattern++; } } static int RMatch (const unsigned char* Source, const unsigned char* Pattern) // A recursive pattern matcher { CharSet CS; unsigned C, C1, C2; while (1) { // Get the next character from the pattern C = RealChar (Pattern); if (C == '\0') { // Reached the end of Pattern, what about Source? return (*Source == '\0') ? 1 : 0; } else if (C == '*') { if (*Pattern == '\0') { // a trailing '*' is always a match return 1; } // Check the rest of the string while (*Source) { if (RMatch (Source++, Pattern)) { // match! return 1; } } // No match... return 0; } else if (C == '{') { // Remember the current source pointer const unsigned char* OldSource = Source; // Compare one subpattern while ((C = RealChar (Pattern)) != ',' && C != '}' && C != '\0') { // Compare source and pattern. Since C is != '\0', this // catches also an end of source. if (C != *Source++) { // No match, skip pattern to end do { // Get the next character and check against zero. // Beware: Do not accept '\}' !! while (1) { C = *Pattern++; if (C == MatchEscChar) { IncPattern (); // Skip the escaped char continue; // and get the next one } else { // Got a non escaped char break; } } // If we have processed all substrings without a // match, or we have reached a terminating zero inside // the pattern, we have no match if (C == '}' || C == '\0') { // No match return 0; } } while (C != ','); // Reset the source pointer and continue with the next // subpattern Source = OldSource; } } // If there's a string end inside the pattern, there's no // match (an invalid pattern is never a match), otherwise we // had a match. if (C == '\0') { return 0; } // If we have a match, skip the pattern until the closing '}' while (C != '}') { // Get the next character and check against zero. Beware: // Do not accept '\}' !! while (1) { C = *Pattern++; if (C == MatchEscChar) { IncPattern (); // Skip the escaped char continue; // and get the next one } else { // Got a non escaped char, check against zero if (C == '\0') { // Invalid pattern return 0; } break; } } } } else if (*Source == '\0') { // End of Source reached, no match return 0; } else { // Check a single char. Build a set of all possible characters in // CS, then check if the current char of Source is contained in // there. CS.Clear (); // Clear the character set if (*Pattern == '?') { // All chars are allowed CS.SetAll (); Pattern++; // skip '?' } else if (*Pattern == MatchEscChar) { // use the next char without looking at it IncPattern (); CS += *Pattern; Pattern++; // skip the character } else if (*Pattern == '[') { // a set follows IncPattern (); int Invert = 0; if (*Pattern == '!') { IncPattern (); Invert = 1; } while (*Pattern != ']') { C1 = RealChar (Pattern); if (C1 == '\0') { return 0; } if (*Pattern != '-') { CS += C1; } else { Pattern++; C2 = RealChar (Pattern); if (C2 == '\0') { return 0; } for (C = C1; C <= C2; C++) { CS += C; } } } Pattern++; // skip ']' if (Invert) { CS.Reverse (); } } else { // Include the char in the charset CS += *Pattern; Pattern++; } if (CS [*Source] == 0) { // No match return 0; } Source++; } } } int Match (const char* Source, const char* Pattern) // Match the string in Source against Pattern. Pattern may contain the // wildcards '*', '?', '[abcd]' '[ab-d]', '[!abcd]', '[!ab-d]'. The // function returns a value of zero if Source does not match Pattern, // otherwise a non zero value is returned. If Pattern contains an invalid // wildcard pattern (e.g. 'A[x'), the function returns zero. { if (Pattern == NULL || *Pattern == '\0') { if (Source == NULL || *Source == '\0') { return 1; } else { return 0; } } // Do the real thing return RMatch ((unsigned char *) Source, (unsigned char *) Pattern); } int Match (const String& Source, const String& Pattern) { return Match (Source.Str, Pattern.Str); } int Match (const String& Source, const char* Pattern) { return Match (Source.Str, Pattern); } int Match (const char* Source, const String& Pattern) { return Match (Source, Pattern.Str); } static String GetStr (String& ValStr, char C) // Helper function for MatchKeyword. Extract from ValStr the string delimited // by C. Delete this string (including C) from ValStr and return it. // Call FAIL if ValStr is invalid { // Get the position of the delimiter and make shure, it's there int DelimPos = ValStr.Pos (C); CHECK (DelimPos > 0); // Get the partial string String Val = ValStr.Cut (0, DelimPos); // Delete the partial string ValStr.Del (0, DelimPos + 1); // Return the extracted string return Val; } static u32 GetNumber (String& ValStr) // Helper function for MatchKeyword. Extract the numeric value from ValStr and // delete this number including the following '^'. Call FAIL if ValStr is // invalid { // Get the number String Val = GetStr (ValStr, '^'); // Set up the string parser StringParser SP (Val, StringParser::UseAll | StringParser::PascalHex | StringParser::CHex); // Get the value u32 Value; CHECK (SP.GetU32 (Value) == 0); // return the value return Value; } u32 MatchKeyword (const String& ID, String Keywords) // Match the string ID against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { u32 Default; int HasDefault = 0; // If ID is empty, we are already done if (ID.IsEmpty ()) { return GetNumber (Keywords); } // Repeat until Keywords is gone.. do { // Get the next numeric value u32 NumVal = GetNumber (Keywords); // Compare the next value if (Match (ID, GetStr (Keywords, '|'))) { // Found the value return NumVal; } // If we don't have a default value until now, use the current one if (HasDefault == 0) { Default = NumVal; HasDefault = 1; } } while (!Keywords.IsEmpty ()); // Not found return Default; } u32 String::MatchKeyword (const String& Keywords) const // Match the string against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { return ::MatchKeyword (*this, Keywords); } u32 String::MatchKeyword (const char* Keywords) const // Match the string against a list of keywords given as a string. The list // of keywords looks like this: "1^ON|0^OFF|1^YES|0^NO|", meaning: // Return 1 if the value is "ON", return 0 if the value is "OFF" etc. // The match is case sensitive and each of the keywords may contain // wildcards as Match() is used to check for a match. { return ::MatchKeyword (*this, Keywords); } String& String::Pad (PadType P, u16 NewLen, char C) // Pad the string to the given length using the padding char C. If the // string is too long, it is simply cut of at the end. { if (Length > NewLen) { // String is too long, nothing to pad Trunc (NewLen); return *this; } else if (Length == NewLen) { // Nothing to do return *this; } // Allocate memory for the new string u16 NewLimit = Reblock (NewLen + 1); char *S = new char [NewLimit]; // Initialize the following variables to prevent gcc warnings u16 LeftPad = 0; u16 RightPad = 0; switch (P) { case Left: LeftPad = NewLen - Length; RightPad = 0; break; case Center: RightPad = NewLen - Length; LeftPad = RightPad / 2; RightPad -= LeftPad; break; case Right: LeftPad = 0; RightPad = NewLen - Length; break; } memset (S, C, LeftPad); memcpy (&S [LeftPad], Str, Length); memset (&S [LeftPad + Length], C, RightPad); S [NewLen] = '\0'; // Now delete the old string data end store the new delete [] Str; Str = S; Limit = NewLimit; Length += LeftPad + RightPad; // Return a reference to this return *this; } int String::ScanL (const char C) const // Return the last position of the char C in the string. If C is not // found, the function returns -1 { char *P = strrchr (Str, C); return P ? P - Str : -1; } int String::ScanL (const char* S) const // Return the last position of the string S in the string. If S is not // found, the function returns -1 { char *P = Str; int Pos = -1; // Some optimization would be nice here, but it works ... while (1) { P = strstr (P, S); if (P == NULL) { // Not found, return last occurence return Pos; } else { // Found, remember this occurence, skip one char Pos = P - Str; P++; } } } void String::Set (unsigned Start, unsigned Count, char C) // Beginning from index Start, set Count characters to C. The string // is expanded if needed { if ((Start + Count + 1) > Limit) { Resize (Start + Count + 1); } memset (&Str [Start], C, Count); if ((Start + Count) > Length) { // Length has changed, add trailing zero, correct length Str [Start+Count] = '\0'; Length = Start + Count; } } String& String::Trunc (unsigned Position) // Truncate the string at the given position. After calling Trunc, the // string length is less or equal to Position. { // Ignore the cut if the string is shorter if (Position < Length) { Str [Position] = '\0'; Length = Position; } return *this; } String& String::operator = (const char* S) { if (S && *S != '\0') { // S is not empty. Check if there is enough room to copy Length = strlen (S); if (Length+1 <= Limit) { // Room enough, just copy memcpy (Str, S, Length+1); } else { // Need more memory delete [] Str; Limit = Reblock (Length+1); Str = (char *) memcpy (new char [Limit], S, Length + 1); } } else { // S is empty, do it the simple way *Str = '\0'; } return *this; } String& String::operator = (const String& S) { if (&S != this) { // beware of S = S; delete [] Str; Limit = S.Limit; Length = S.Length; Str = (char *) memcpy (new char [Limit], S.Str, Length + 1); } return *this; } char& String::operator [] (unsigned Index) { // Make shure, Index is valid PRECONDITION (Index <= Length); return Str [Index]; } const char& String::operator [] (unsigned Index) const { // Check the index against the string length PRECONDITION (Index <= Length); return Str [Index]; } String& operator += (String& S, const char C) { S.Resize (S.Length + 2); S.Str [S.Length] = C; S.Length++; S.Str [S.Length] = '\0'; return S; } String& operator += (String& S, const char* P) { u16 PLen = strlen (P); S.Resize (S.Length + PLen + 1); memcpy (&S.Str [S.Length], P, PLen + 1); S.Length += PLen; return S; } String operator + (const String& S, const char C) { String Ret = S; Ret += C; return Ret; } String operator + (const String& S, const char* P) { // Create an emtpy string to avoid calling operator new String Res (Empty); // Build the combined string u16 PLen = strlen (P); Res.Length = S.Length + PLen; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, S.Str, S.Length); memcpy (&Res.Str [S.Length], P, PLen + 1); // ... and return it return Res; } String operator + (const String& S1, const String& S2) { // Create an emtpy string to avoid calling operator new String Res (Empty); // Build the combined string Res.Length = S1.Length + S2.Length; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, S1.Str, S1.Length); memcpy (&Res.Str [S1.Length], S2.Str, S2.Length + 1); // ... and return it return Res; } String operator + (const char* P, const String& S2) { // Create empty object to avoid call to operator new String Res (Empty); u16 PLen = strlen (P); Res.Length = PLen + S2.Length; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; memcpy (Res.Str, P, PLen); memcpy (&Res.Str [PLen], S2.Str, S2.Length + 1); return Res; } String operator + (const char C, const String& S) { // Create empty object to avoid call to operator new String Res (Empty); Res.Length = S.Length + 1; Res.Limit = Res.Reblock (Res.Length + 1); Res.Str = new char [Res.Limit]; Res.Str [0] = C; memcpy (&Res.Str [1], S.Str, S.Length + 1); return Res; } String ShowControls (const String& S, unsigned Style) // Recode the given string and replace every control character by it's // visible representation, e.g. "\n" instead of the character with code // code 13. { // Numeric codes in hex static const char HexCodes [32][5] = { "\\x00", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\x07", "\\x08", "\\x09", "\\x0A", "\\x0B", "\\x0C", "\\x0D", "\\x0E", "\\x0F", "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17", "\\x18", "\\x19", "\\x1A", "\\x1B", "\\x1C", "\\x1D", "\\x1E", "\\x1F" }; // Numeric codes in octal static const char OctCodes [32][5] = { "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007", "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017", "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027", "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037", }; // Create a new string with a length of 110% of the string to recode. // This is just an assumption of the probable string growth and // is thought to prevent too many string resizes (each one calls // operator new). String T ((S.Len () * 11) / 10); // When recoding, access S directly to avoid the range check code // that would slow things down and is not needed here char* Str = S.Str; while (*Str) { switch (*Str) { case 0x01: // This is the special spunk char '\c' if (Style & ccSpunk) { T += "\\c"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\\': if (Style & ccCStyle) { T += "\\\\"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\a': if (Style & ccCStyle) { T += "\\a"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\b': if (Style & ccCStyle) { T += "\\b"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\f': if (Style & ccCStyle) { T += "\\f"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\n': if (Style & ccCStyle) { T += "\\n"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\t': if (Style & ccCStyle) { T += "\\t"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; case '\v': if (Style & ccCStyle) { T += "\\v"; } else { T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; default: if (!IsCntrl (*Str)) { // No control char, just add the char itself T += *Str; } else { // Another control char T += (Style & ccOct)? OctCodes [*Str] : HexCodes [*Str]; } break; } // Next char Str++; } // Done, return the result return T; } static unsigned Num (char C) // Return the numeric representation of the character C (assumes ASCII) { if (C >= 'a') { return C - 'a' + 10; } else if (C >= 'A') { return C - 'A' + 10; } else { return C - '0'; } } String HideControls (const String& S) // Recode the given string and replace every visible control character // representation by the character itself, e.g. replace "\n" by the // character with code 13. { // Create the target string with the same length as the source string. // The string will definitely not grow when recoding, so there is no // further call to operator new needed. String T (S.Len ()); // Access the source string directly to avoid the range check code // that is not needed here. char* Str = S.Str; // Recode the string while (*Str) { if (*Str == '\\') { // A control char. Check it. Str++; switch (*Str) { case '\0': // Ohh help! The string ends with an open sequence - // just copy the start of the sequence. Then remember // to decrease S 1 char back to match the end condition. T += '\\'; Str--; break; case '\\': T += '\\'; break; case 'a': T += '\a'; break; case 'b': T += '\b'; break; case 'c': // This an invalid sequence in c but used as the spunk // "center string" mark. T += char (0x01); break; case 'f': T += '\f'; break; case 'n': T += '\n'; break; case 't': T += '\t'; break; case 'v': T += '\v'; break; case 'x': case 'X': // Character code in hex follows. Check if there is really // a character code. if (IsXDigit (Str [1]) && IsXDigit (Str [2])) { T += char (Num (Str [1]) * 16 + Num (Str [2])); Str += 2; } else { // Something is wrong. Copy the '\x', which is the // only part, we know it is correct, and let the // next round determine what to do with the remaining // chars; T += "\\x"; } break; default: // This is an unknown control char. Swallow it. break; } } else { // Some other char, just copy it T += *Str; } // Next char Str++; } // Done, return the result return T; } String FormatStr (const char* S, ...) // Return a via sprintf formatted string { va_list ap; va_start (ap, S); #if defined(DOS) || defined (DOS32) || defined (OS2) // Does not call va_end but works on DOS/OS2 and does not need an extra copy return String (S, ap); #else // Portable version String Res (S, ap); va_end (ap); return Res; #endif } estic-1.61.orig/spunk/strbox.cc0100644000176100001440000000421507031424706016005 0ustar debacleusers/*****************************************************************************/ /* */ /* STRBOX.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a listbox for a collection of strings #include "strbox.h" /*****************************************************************************/ /* class StrBox */ /*****************************************************************************/ void StringListBox::Print (int Index, int X, int Y, u16 Attr) // Display one of the listbox entries { String Line (Size.X); // Get the entry const String* S = Coll->At (Index); if (S == NULL) { // Entry is empty, clear it Line.Set (0, Size.X); } else { // Build the line Line += ' '; Line += *S; Line.Pad (String::Right, Size.X - 1); Line += ' '; } // Write it to the window Owner->Write (X, Y, Line, Attr); } StringListBox::StringListBox (const String& aItemText, i16 aID, const Point& aSize, u16 aNormAttr, u16 aSelAttr, u16 aHighAttr, WindowItem* NextItem): ListBox (aItemText, aID, aSize, aNormAttr, aSelAttr, aHighAttr, NextItem) { } StringListBox::StringListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem): ListBox (aItemText, aID, aSize, NextItem) { } estic-1.61.orig/spunk/strbox.h0100644000176100001440000000230207031424706015642 0ustar debacleusers/*****************************************************************************/ /* */ /* STRBOX.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a listbox for a collection of strings #ifndef __STRBOX_H #define __STRBOX_H #include "coll.h" #include "listbox.h" /*****************************************************************************/ /* class StrBox */ /*****************************************************************************/ class StringListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: StringListBox (const String& aItemText, i16 aID, const Point& aSize, u16 aNormAttr, u16 aSelAttr, u16 aHighAttr, WindowItem* NextItem); StringListBox (const String& aItemText, i16 aID, const Point& aSize, WindowItem* NextItem); }; // End of STRBOX.H #endif estic-1.61.orig/spunk/strcoll.cc0100644000176100001440000000402307031424707016144 0ustar debacleusers/*****************************************************************************/ /* */ /* STRCOLL.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "strcoll.h" #include "streamid.h" // Register class StringCollection if there are references in this module LINK(StringCollection, ID_StringCollection); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class StringCollection */ /*****************************************************************************/ Streamable* StringCollection::Build () { return new StringCollection (Empty); } void StringCollection::PutItem (Stream& S, void* Item) const { S.Put ((String*) Item); } void* StringCollection::GetItem (Stream& S) { return (void*) S.Get (); } u16 StringCollection::StreamableID () const { return ID_StringCollection; } int StringCollection::Compare (const String* Key1, const String* Key2) { return ::Compare (*Key1, *Key2); } estic-1.61.orig/spunk/strcoll.h0100644000176100001440000000307007031424707016007 0ustar debacleusers/*****************************************************************************/ /* */ /* STRCOLL.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __STRCOLL_H #define __STRCOLL_H #include "strmable.h" #include "coll.h" #include "stream.h" #include "str.h" /*****************************************************************************/ /* class StringCollection */ /*****************************************************************************/ class StringCollection : public SortedCollection { public: StringCollection (StreamableInit); StringCollection (int aLimit, int aDelta); // Derived from class Streamable static Streamable* Build (); virtual u16 StreamableID () const; protected: // Derived from class Collection virtual void* GetItem (Stream& S); virtual void PutItem (Stream& S, void* Item) const; // Derived from class SortedCollection virtual int Compare (const String* Key1, const String* Key2); }; inline StringCollection::StringCollection (StreamableInit) : SortedCollection (Empty) { } inline StringCollection::StringCollection (int aLimit, int aDelta) : SortedCollection (aLimit, aDelta) { ShouldDelete = 1; } // End of STRCOLL.H #endif estic-1.61.orig/spunk/strcvt.cc0100644000176100001440000000737407031424707016023 0ustar debacleusers/*****************************************************************************/ /* */ /* STRCVT.CC */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "check.h" #include "strcvt.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void IntCvt (u32 Val, unsigned Base, String& S) { unsigned C = Val % Base; if (Val /= Base) { IntCvt (Val, Base, S); } S += (C > 9) ? C - 10 + 'A' : C + '0'; // Assumes ASCII } String I32Str (i32 Val, unsigned Base) // Convert an integer into a string { String S; // Handle negative values if (Val < 0) { S += '-'; Val = -Val; } // Build the string IntCvt (Val, Base, S); // Return the result return S; } String U32Str (u32 Val, unsigned Base) // Convert an unsigned into a string { String S; // Build the string IntCvt (Val, Base, S); // Return the result return S; } String FloatStr (double Val, unsigned LDigits, unsigned TDigits) // Convert a double into a string. There is a difference between this function // and the converting functions for integers: The result definitely has not // more than the given width. { char Buf [256]; // Calculate width unsigned Width = TDigits + LDigits; if (TDigits > 0) { Width++; // Decimal separator } CHECK (Width < sizeof (Buf)); // Convert the float sprintf (Buf, "%.*f", (int) TDigits, Val); // Create the result string from the buffer String S (Buf); // Localize the decimal separator int SepPos = S.Pos ('.'); if (SepPos >= 0) { S [SepPos] = NLSData.DecSep; } // Assure the maximum length if (S.Len () > Width) { S.ForceLen (Width); } // Return the result return S; } String TimeStr (u32 TimeInSec) // Convert a time (given in seconds since midnight) into a string. { // Check the given parameter PRECONDITION (TimeInSec <= 23*3600 + 59*60 + 59); // Calculate hour/min/sec unsigned Sec = TimeInSec % 60; TimeInSec /= 60; unsigned Min = TimeInSec % 60; TimeInSec /= 60; unsigned Hour = TimeInSec; // Set up string according to local time format int PM = 0; switch (NLSData.Time) { case 0: // am/pm if (Hour >= 12) { Hour -= 12; PM = 1; } return FormatStr ("%02d%c%02d%c%02d %s", Hour, NLSData.TimeSep, Min, NLSData.TimeSep, Sec, PM ? "pm" : "am"); case 1: return FormatStr ("%02d%c%02d%c%02d", Hour, NLSData.TimeSep, Min, NLSData.TimeSep, Sec); default: FAIL ("Unknown value for NLSData.Time"); } // Never reached return String (); } estic-1.61.orig/spunk/strcvt.h0100644000176100001440000000322107031424707015650 0ustar debacleusers/*****************************************************************************/ /* */ /* STRCVT.H */ /* */ /* (C) 1993,94 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STRCVT_H #define _STRCVT_H #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String I32Str (i32 Val, unsigned Base = 10); // Convert an integer into a string String U32Str (u32 Val, unsigned Base = 10); // Convert an unsigned into a string String FloatStr (double Val, unsigned LDigits, unsigned TDigits); // Convert a double into a string. There is a difference between this function // and the converting functions for integers: The result definitely has not // more than the given width. String TimeStr (u32 TimeInSec); // Convert a time (given in seconds since midnight) into a string. // End of STRCVT.H #endif estic-1.61.orig/spunk/stream.cc0100644000176100001440000004435607031424707015772 0ustar debacleusers/*****************************************************************************/ /* */ /* STREAM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include #include #if defined (DOS) || defined (DOS32) || defined (OS2) # include #else # include #endif #include "cpucvt.h" #include "check.h" #include "stream.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; #endif /*****************************************************************************/ /* class StreamableClasses */ /*****************************************************************************/ class StreamableClasses : private SortedCollection { friend class StreamableClass; friend class Stream; public: // Constructor StreamableClasses (); virtual int Compare (const u16* Key1, const u16* Key2); virtual const u16* KeyOf (const StreamableClass* Item); StreamableClass* Lookup (u16 ID); }; // Database of all registered classes static StreamableClasses* ClassBase = NULL; StreamableClasses::StreamableClasses () : SortedCollection (50, 25) { } int StreamableClasses::Compare (const u16* Key1, const u16* Key2) { if (*Key1 > *Key2) { return 1; } else if (*Key1 < *Key2) { return -1; } else { return 0; } } StreamableClass* StreamableClasses::Lookup (u16 ID) { // This is not a virtual function so we can safely check "this" against // NULL. Return "Not found" (== NULL) in this case. if (this == NULL) { // The object does not exist return NULL; } // The object exists, search for the ID int Index; if (Search (&ID, Index)) { // Found, return pointer return At (Index); } else { // Not found return NULL; } } const u16* StreamableClasses::KeyOf (const StreamableClass* S) { return &S->ID; } /*****************************************************************************/ /* class StreamableClass */ /*****************************************************************************/ StreamableClass::StreamableClass (Streamable* (BuildFunc) (), u16 ClassID) : ID (ClassID), Builder (BuildFunc) { // Check if ClassBase already exists, if not, create it if (ClassBase == NULL) { // Create a ClassBase and insert the object ClassBase = new StreamableClasses; ClassBase->Insert (this); } else { // Check duplicates before inserting int Index; if (ClassBase->Search (&ClassID, Index)) { FAIL ("StreamableClass::StreamableClass: Duplicate class ID!"); } // Insert self into database ClassBase->Insert (this); } } /*****************************************************************************/ /* class Stream */ /*****************************************************************************/ Stream::Stream () : BitCount (0), BitBuf (0), Status (0), ErrorInfo (0), StreamError (NULL) { } void Stream::BitWrite (u32 Bits, unsigned Count) // Write the given bits to the stream, LSB first. Count may not be // greater than 32. { static const unsigned char Mask [8] = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF }; // Check the parameters PRECONDITION (Count <= CHAR_BIT * sizeof (Bits)); // Write the bits while (Count) { // Flush the buffer if needed if (BitCount == CHAR_BIT) { BitFlush (); } // Calculate the count of bits to write within this chunk unsigned Chunk = Count; if (Chunk > CHAR_BIT - BitCount) { Chunk = CHAR_BIT - BitCount; } Count -= Chunk; // Put the bits into the buffer BitBuf |= (Bits & Mask [Chunk-1]) << BitCount; BitCount += Chunk; Bits >>= Chunk; } } u32 Stream::BitRead (unsigned Count) // Read some bits from the stream. Count may not be greater than 32. { static const unsigned char Mask [8] = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF }; // Check the parameters PRECONDITION (Count <= CHAR_BIT * sizeof (u32)); // Read the bits unsigned Val = 0; unsigned BitsRead = 0; while (Count) { // Read a new byte if needed if (BitCount == 0) { Read (&BitBuf, sizeof (BitBuf)); BitCount = CHAR_BIT; } // Read B->Bits at max. unsigned Bits = Count; if (Bits > BitCount) { Bits = BitCount; } Count -= Bits; BitCount -= Bits; // Read the bits and put them into the result buffer Val |= (BitBuf & Mask [Bits-1]) << BitsRead; BitsRead += Bits; BitBuf >>= Bits; } // Return the bits read return Val; } void Stream::BitFlush () // Flush the bit buffer if needed. { if (BitCount) { Write (&BitBuf, sizeof (BitBuf)); BitBuf = 0; BitCount = 0; } } void Stream::Flush () { } u32 Stream::GetPos () { ABSTRACT (); return 0L; } u32 Stream::GetSize () { ABSTRACT (); return 0L; } void Stream::Reset () { Status = stOk; ErrorInfo = 0; } void Stream::Read (void*, size_t) { ABSTRACT (); } int Stream::Read () { ABSTRACT (); return 0; } void Stream::Seek (unsigned long) { ABSTRACT (); } void Stream::SeekToEnd () // Set the stream pointer to the end of the stream { Seek (GetSize ()); } Stream::ErrorFunc Stream::SetErrorFunc (ErrorFunc F) // Set a new StreamError function { ErrorFunc OldFunc = StreamError; StreamError = F; return OldFunc; } void Stream::Truncate () { ABSTRACT (); } void Stream::Write (const void*, size_t) { ABSTRACT (); } void Stream::CopyFrom (Stream& S, size_t Count) { static const BufSize = 4096; // Size of copy buffer // Check parameter PRECONDITION (Count > 0); // Check stream status if (Status != stOk) { return; } if (S.GetStatus () != stOk) { Error (stCopyError, S.GetStatus ()); return; } // Allocate buffer memory char *Buffer = new char [BufSize]; // Do the copy... size_t Bytes; while (Count) { Bytes = (Count > BufSize) ? BufSize : Count; S.Read (Buffer, Bytes); Write (Buffer, Bytes); Count -= Bytes; } // Free the allocated buffer delete [] Buffer; } Streamable* Stream::Get () { u16 ID; StreamableClass* C; // Check stream status if (Status != stOk) { return NULL; } // Read ID *this >> ID; // An ID of zero means a NULL object has been stored if (Status != stOk || ID == 0) { return NULL; } // Search the ID in the classbase if ((C = ClassBase->Lookup (ID)) == NULL) { // Error, class not registered Error (stGetError, ID); return NULL; } // Create a new (empty) instance Streamable* NewInstance = C->Builder (); // Read the instance data from stream *this >> *NewInstance; // Return the new instance return NewInstance; } void Stream::Put (const Streamable& O) { u16 ID; // Check stream status if (Status != stOk) { return; } // Write the object to the stream if (&O == NULL) { // Special handling for a NULL pointer: Write a ID of zero ID = 0; *this << ID; } else { // Get class ID ID = O.StreamableID (); // Find class in database CHECK (ClassBase->Lookup (ID) != NULL); // Write ID and instance data *this << ID << O; } } char* Stream::ReadStr () { u16 Len; // Check stream status if (Status != stOk) { return NULL; } // Read string length Read (&Len, sizeof (Len)); // If the string has size zero, return a NULL pointer if (Len == 0) { return NULL; } // Allocate memory for the string and read it char* S = new char [Len]; Read ((void*) S, Len); // return the allocated string return S; } void Stream::WriteStr (const char* S) { // Check stream status if (Status != stOk) { return; } // Check the length, allow NULL pointers for emtpy strings u16 Len = (u16) (S ? strlen (S) + 1 : 0); // Write the string length followed by the string itself Write (&Len, sizeof (Len)); if (Len) { Write (S, Len); } } void Stream::Error (int Code, int Info) { Status = Code; ErrorInfo = Info; // If an error function is defined, call this function. Otherwise handle // all errors that are considered fatal (which means that they are caused // by some sort of programming error). if (StreamError != NULL) { StreamError (*this); } else { char Buf [128]; switch (Code) { case stGetError: // Unregistered class found in call to Get sprintf (Buf, "Stream::Error: unregistered class with ID 0x%04X", Info); FAIL (Buf); break; case stPutError: // Unregistered class found in call to Put sprintf (Buf, "Stream::Error: unregistered class with ID 0x%04X", Info); FAIL (Buf); break; } } } Stream& operator >> (Stream& S, char* X) { // Read a copy of the string char* Y = S.ReadStr (); // Copy it to the destination strcpy (X, Y); // free the string delete [] Y; return S; } // Beware: Bug in BC++ for DOS - char and signed char are not distinct! #if !defined (DOS) || !defined (__BORLANDC__) Stream& operator << (Stream& S, char X) { S.Write (&X, sizeof (X)); return S; } #endif Stream& operator << (Stream& S, unsigned char X) { S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, signed char X) { S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, i16 X) { // Convert to little endian ToLittleEndian (X); // Write into the stream S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, u16 X) { // Convert to little endian ToLittleEndian (X); // Write into the stream S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, i32 X) { // Convert to little endian ToLittleEndian (X); // Write into the stream S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, u32 X) { // Convert to little endian ToLittleEndian (X); // Write into the stream S.Write (&X, sizeof (X)); return S; } Stream& operator << (Stream& S, float X) { // Write float as a double S << double (X); return S; } Stream& operator << (Stream& S, double X) { // Convert to little endian _double Y = { X }; ToLittleEndian (Y); S.Write (&Y.I, sizeof (Y.I)); return S; } Stream& operator << (Stream& S, char* X) { S.WriteStr (X); return S; } // Beware: Bug in BC++ for DOS - char and signed char are not distinct! #if !defined (DOS) || !defined (__BORLANDC__) Stream& operator >> (Stream& S, char & X) { S.Read (&X, sizeof (X)); return S; } #endif Stream& operator >> (Stream& S, unsigned char& X) { S.Read (&X, sizeof (X)); return S; } Stream& operator >> (Stream& S, signed char& X) { S.Read (&X, sizeof (X)); return S; } Stream& operator >> (Stream& S, i16& X) { // Read from the stream S.Read (&X, sizeof (X)); // Convert from little endian to native format FromLittleEndian (X); // Return the used stream return S; } Stream& operator >> (Stream& S, u16& X) { // Read from the stream S.Read (&X, sizeof (X)); // Convert from little endian to native format FromLittleEndian (X); // Return the used stream return S; } Stream& operator >> (Stream& S, i32& X) { // Read from the stream S.Read (&X, sizeof (X)); // Convert from little endian to native format FromLittleEndian (X); // Return the used stream return S; } Stream& operator >> (Stream& S, u32& X) { // Read from the stream S.Read (&X, sizeof (X)); // Convert from little endian to native format FromLittleEndian (X); // Return the used stream return S; } Stream& operator >> (Stream& S, float& X) { // Read a double from the stream double Y; S >> Y; X = Y; // Return the used stream return S; } Stream& operator >> (Stream& S, double& X) { // Read from the stream _double Y; S.Read (&Y.I, sizeof (Y.I)); // Convert from little endian to native format FromLittleEndian (Y); X = Y.F; // Return the used stream return S; } /*****************************************************************************/ /* Manipulators for class Stream */ /*****************************************************************************/ Stream& Flush (Stream& S) // Flush the stream { S.Flush (); return S; } /*****************************************************************************/ /* class FileStream */ /*****************************************************************************/ FileStream::FileStream (size_t BufSize): F (NULL) // Create a temporary file stream. The corresponding file will be deleted // when the stream is closed. You cannot get the name of a temporary file. { // Try to open the file if ((F = tmpfile ()) == NULL) { Error (stInitError, errno); return; } // Set the buffer SetBuf (BufSize); } FileStream::FileStream (const String& FileName, const String& Mode, size_t BufSize): F (NULL), Name (FileName) // Open a file stream using the given mode. { // Try to open the file if ((F = fopen (FileName.GetStr (), Mode.GetStr ())) == NULL) { Error (stInitError, errno); return; } // Set the buffer SetBuf (BufSize); } FileStream::FileStream (const String& FileName, size_t BufSize): F (NULL), Name (FileName) { // Try to open an existing file for r/w if ((F = fopen (FileName.GetStr (), "r+b")) == NULL) { // Error opening file. Try to create a new file if ((F = fopen (FileName.GetStr (), "w+b")) == NULL) { Error (stInitError, errno); return; } } // Set the buffer SetBuf (BufSize); } FileStream::~FileStream () { // If there is an open file, try to close it but ignore errors if (F) { (void) fclose (F); } } void FileStream::SetBuf (size_t BufSize) // Set the file buffer. For use in the constructors only! { // Set the buffer if (BufSize) { if (setvbuf (F, NULL, _IOFBF, BufSize) != 0) { Error (stInitError, 0); return; } } else { setvbuf (F, NULL, _IONBF, 0); } } void FileStream::Flush () { if (Status == stOk) { fflush (F); } } u32 FileStream::GetPos () { long Pos; if (Status == stOk) { if ((Pos = ftell (F)) == -1L) { Error (stSeekError, errno); return 0L; } return Pos; } return 0L; } u32 FileStream::GetSize () { if (Status == stOk) { // Remember current file position long CurPos = ftell (F); // Seek to the end fseek (F, 0L, SEEK_END); // Get file length long Length = ftell (F); // Seek back to the previous position fseek (F, CurPos, SEEK_SET); // Check for errors if (Length == -1L) { Error (stSeekError, errno); return 0L; } else { return Length; } } return 0L; } void FileStream::Read (void* Buf, size_t Count) { if (Status == stOk && Count > 0) { if (fread (Buf, 1, Count, F) != Count) { Error (stReadError, Count); } } } int FileStream::Read () { int C = EOF; if (Status == stOk) { if ((C = fgetc (F)) == EOF) { Error (stReadError, 0); } } return C; } void FileStream::Reset () { Stream::Reset (); clearerr (F); } void FileStream::Seek (unsigned long Pos) { if (Status == stOk) { if (fseek (F, Pos, SEEK_SET) != 0) { Error (stSeekError, 0); } } } void FileStream::SeekToEnd () // Set the stream pointer to the end of the stream { if (Status == stOk) { if (fseek (F, 0, SEEK_END) != 0) { Error (stSeekError, 0); } } } void FileStream::Truncate () { if (Status == stOk) { // Flush the stream Flush (); // Truncate the file #if defined(__WATCOMC__) || (defined(DOS) && defined(__BORLANDC__)) chsize (fileno (F), GetPos ()); #else ftruncate (fileno (F), GetPos ()); #endif } } void FileStream::Write (const void* Buf, size_t Count) { if (Status == stOk && Count > 0) { if (fwrite (Buf, 1, Count, F) != Count) { Error (stWriteError, 0); } } } estic-1.61.orig/spunk/stream.h0100644000176100001440000002334707031424707015631 0ustar debacleusers/*****************************************************************************/ /* */ /* STREAM.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Some words on the bit read and write functions for class Stream: // The functions // // BitWrite // BitRead // BitFlush // // depend on the normal Read and Write functions and may *not* be used // in a mixed fashion. BitWrite and BitRead manipulate byte sized buffers // that are written to / read from the stream using Read and Write when // needed. You *must* call BitFlush before calling any other non-"Bit" // function, or your data will get corrupted. BitWrite and BitRead use // the same buffer byte, so they may not be used together without calling // BitFlush first. #ifndef _STREAM_H #define _STREAM_H #include #include #include "strmable.h" #include "coll.h" #include "str.h" static const stOk = 0; // things are allright static const stInitError = 1; // error initializing the stream static const stReadError = 2; // error reading from the stream static const stWriteError = 3; // error writing to the stream static const stGetError = 4; // get found not registered class static const stPutError = 5; // put found not registered class static const stMemoryError = 6; // not enough memory static const stStoreError = 7; // Keine Store-Methode angegeben static const stLoadError = 8; // Keine Load-Methode oder Fehler bei Load static const stCopyError = 9; // CopyFrom: error of source stream static const stSeekError = 10; // error using Seek, GetPos etc. static const stReadTimeout = 11; // Timeout on read (CharacterStream only) static const stWriteTimeout = 12; // Timeout on write (CharcterStream only) // Register a class #define LINK(Class, ID) static StreamableClass __r##Class (Class::Build, ID) /*****************************************************************************/ /* class StreamableClass */ /*****************************************************************************/ // Object to keep track of registered streamable objects class StreamableClass : public Object { friend class StreamableClasses; friend class Stream; private: u16 ID; // ID of streamable class Streamable* (*Builder) (); // Pointer to Build member function public: StreamableClass (Streamable* (*BuildFunc) (), u16 ClassID); }; /*****************************************************************************/ /* class Stream */ /*****************************************************************************/ class Stream : public Streamable { public: typedef void (*ErrorFunc) (Stream&); // Type of function that is called from Error private: // Bit writing stuff unsigned BitCount; unsigned char BitBuf; protected: int Status; int ErrorInfo; ErrorFunc StreamError; // Function that is called in case of errors virtual void Error (int Code, int Info); // Sets the error and status codes and calls StreamError public: Stream (); void BitWrite (u32 Bits, unsigned Count); // Write the given bits to the stream, LSB first. Count may not be // greater than 32. u32 BitRead (unsigned Count); // Read some bits from the stream. Count may not be greater than 32. void BitFlush (); // Flush the bit write buffer if needed. void BitReset (); // Reset the bit buffer to empty without writing anything. This is needed // to reset to a byte boundary between two BitReads. void CopyFrom (Stream& S, size_t Count); // Copy data from another stream virtual void Flush (); // Flush associated buffers Streamable* Get (); // Read an object instance from the stream virtual u32 GetPos (); // Get the current value of the stream pointer virtual u32 GetSize (); // Return the size of the stream in bytes int GetStatus () const; // Return the stream status int GetErrorInfo () const; // Return the error information void Put (const Streamable&); void Put (const Streamable*); // Write an object instance into a stream virtual void Read (void* Buf, size_t Count); // Read from the stream virtual int Read (); // Read a character from the stream, return EOF in case of errors or // end of stream (need Reset to continue) char* ReadStr (); // Read a char* from the stream virtual void Reset (); // Reset the error codes virtual void Seek (unsigned long Pos); // Set the stream pointer to the specified position virtual void SeekToEnd (); // Set the stream pointer to the end of the stream ErrorFunc SetErrorFunc (ErrorFunc); // Set a new StreamError function virtual void Truncate (); // Truncate the stream at the current position virtual void Write (const void* Buf, size_t Count); // Write to the stream void WriteStr (const char* S); // Write a char* to the stream friend inline Stream& operator << (Stream&, Stream& (*F) (Stream&)); // Manipulator support function friend Stream& operator << (Stream&, char); friend Stream& operator << (Stream&, unsigned char); friend Stream& operator << (Stream&, signed char); friend Stream& operator << (Stream&, i16); friend Stream& operator << (Stream&, u16); friend Stream& operator << (Stream&, i32); friend Stream& operator << (Stream&, u32); friend Stream& operator << (Stream&, float); friend Stream& operator << (Stream&, double); friend Stream& operator << (Stream&, char*); friend Stream& operator >> (Stream&, char&); friend Stream& operator >> (Stream&, unsigned char&); friend Stream& operator >> (Stream&, signed char&); friend Stream& operator >> (Stream&, i16&); friend Stream& operator >> (Stream&, u16&); friend Stream& operator >> (Stream&, i32&); friend Stream& operator >> (Stream&, u32&); friend Stream& operator >> (Stream&, float&); friend Stream& operator >> (Stream&, double&); friend Stream& operator >> (Stream&, char*); }; inline void Stream::BitReset () // Reset the bit buffer to empty without writing anything. This is needed // to reset to a byte boundary between two BitReads. { BitCount = 0; BitBuf = 0; } inline int Stream::GetStatus () const { return Status; } inline int Stream::GetErrorInfo () const { return ErrorInfo; } inline void Stream::Put (const Streamable* X) { Put (*X); } inline Stream& operator << (Stream& S, Stream& (*Func) (Stream&)) // Manipulator support function { return Func (S); } /*****************************************************************************/ /* Manipulators for class Stream */ /*****************************************************************************/ Stream& Flush (Stream& S); // Flush the stream /*****************************************************************************/ /* class FileStream */ /*****************************************************************************/ class FileStream : public Stream { private: void SetBuf (size_t BufSize); // Set the file buffer. For use in the constructors only! protected: FILE *F; String Name; public: FileStream (const String& FileName, size_t BufSize = BUFSIZ); // Open a file stream. If the file with the given name does not exist, // it is created. FileStream (const String& FileName, const String& Mode, size_t BufSize = BUFSIZ); // Open a file stream using the given mode. FileStream (size_t BufSize = BUFSIZ); // Create a temporary file stream. The corresponding file will be deleted // when the stream is closed. You cannot get the name of a temporary file. virtual ~FileStream (); virtual void Flush (); // Flush associated buffers virtual u32 GetPos (); // Get the current value of the stream pointer virtual u32 GetSize (); // Return the size of the stream in bytes virtual void Read (void *Buf, size_t Count); // Read from the stream virtual int Read (); // Read a byte from the stream. Returns EOF if end of file is reached. // EOF is no error condition (as in all other reads) virtual void Reset (); virtual void Seek (unsigned long Pos); // Set the stream pointer to the given value void SeekToEnd (); // Set the stream pointer to the end of the stream virtual void Truncate (); // Truncate the stream at the current stream pointer position virtual void Write (const void *Buf, size_t Count); // Write data to the stream const String& GetName () const; // Return the filename const FILE* GetFile () const; // Return the file variable }; inline const String& FileStream::GetName () const { return Name; } inline const FILE* FileStream::GetFile () const { return F; } // End of STREAM.H #endif estic-1.61.orig/spunk/streamid.h0100644000176100001440000000555307031424707016145 0ustar debacleusers/*****************************************************************************/ /* */ /* STREAMID.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STREAMID_H #define _STREAMID_H #include "machine.h" /*****************************************************************************/ /* Streamable ID's */ /*****************************************************************************/ const u16 ID_Collection = 0x0010; const u16 ID_SortedCollection = 0x0011; const u16 ID_StringCollection = 0x0012; const u16 ID_MsgCollection = 0x0013; const u16 ID_Palette = 0x0014; const u16 ID_ResourceIndex = 0x0020; const u16 ID_ResourceCollection = 0x0021; const u16 ID_Window = 0x0030; const u16 ID_RootWindow = 0x0031; const u16 ID_StatusLine = 0x0032; const u16 ID_ItemWindow = 0x0033; const u16 ID_MenueBar = 0x0034; const u16 ID_TopMenueBar = 0x0035; const u16 ID_Menue = 0x0036; const u16 ID_FileViewer = 0x0037; const u16 ID_BitSet = 0x0040; const u16 ID_CharSet = 0x0041; const u16 ID_String = 0x0051; const u16 ID_Msg = 0x0052; const u16 ID_WindowItem = 0x0060; const u16 ID_ItemLabel = 0x0061; const u16 ID_TextItem = 0x0062; const u16 ID_MenueItem = 0x0070; const u16 ID_SubMenueItem = 0x0071; const u16 ID_MenueBarItem = 0x0072; const u16 ID_MenueLine = 0x0073; const u16 ID_LongItem = 0x0074; const u16 ID_StringItem = 0x0075; const u16 ID_HexItem = 0x0076; const u16 ID_ToggleItem = 0x0077; const u16 ID_OffOnItem = 0x0078; const u16 ID_NoYesItem = 0x0079; const u16 ID_FloatItem = 0x007A; const u16 ID_TimeItem = 0x007B; const u16 ID_DateItem = 0x007C; const u16 ID_RStringItem = 0x007D; const u16 ID_EditLine = 0x0090; const u16 ID_FloatEdit = 0x0091; const u16 ID_LongEdit = 0x0092; const u16 ID_HexEdit = 0x0093; const u16 ID_TextEdit = 0x0094; const u16 ID_TimeEdit = 0x0095; const u16 ID_DateEdit = 0x0096; const u16 ID_PasswordEdit = 0x0097; const u16 ID_FileEdit = 0x0098; const u16 ID_FileNameEdit = 0x0099; const u16 ID_Container = 0x00B0; const u16 ID_Time = 0x00C0; const u16 ID_TimeDiff = 0x00C1; const u16 ID_ComPort = 0x00D0; const u16 ID_PasswordEntry = 0x00E0; const u16 ID_PasswordColl = 0x00E1; const u16 ID_PWLogEntry = 0x00E2; const u16 ID_StringPool = 0x00F0; const u16 ID_FileInfo = 0x0100; const u16 ID_FileInfoColl = 0x0101; const u16 ID_MemoryStream = 0x0110; const u16 ID_WindowManager = 0x0120; const u16 ID_WinColl = 0x0121; const u16 ID_RNG = 0x0130; // First user ID const u16 ID_USER = 0x1000; // END of STREAMID.H #endif estic-1.61.orig/spunk/strmable.cc0100644000176100001440000000266707031424707016307 0ustar debacleusers/*****************************************************************************/ /* */ /* STRMABLE.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" #include "check.h" #include "object.h" #include "strmable.h" /*****************************************************************************/ /* class Streamable */ /*****************************************************************************/ void Streamable::Load (Stream&) { ABSTRACT (); } void Streamable::Store (Stream&) const { ABSTRACT (); } u16 Streamable::StreamableID () const { ABSTRACT (); return 0; } Streamable* Streamable::Build () { ABSTRACT (); return (Streamable*) NULL; } estic-1.61.orig/spunk/strmable.h0100644000176100001440000000417307031424707016143 0ustar debacleusers/*****************************************************************************/ /* */ /* STRMABLE.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STRMABLE_H #define _STRMABLE_H #include "machine.h" #include "object.h" // Dummy argument for build constructor enum StreamableInit { Empty }; /*****************************************************************************/ /* class Streamable */ /*****************************************************************************/ // Forwards class Stream; // Every streamable object must be derived from class Streamable class Streamable : public Object { public: virtual void Load (Stream&); virtual void Store (Stream&) const; virtual u16 StreamableID () const; static Streamable* Build (); friend inline Stream& operator << (Stream&, const Streamable&); friend inline Stream& operator >> (Stream&, Streamable&); friend inline Stream& operator << (Stream&, const Streamable*); friend inline Stream& operator >> (Stream&, Streamable*); }; inline Stream& operator << (Stream& S, const Streamable& O) { O.Store (S); return S; } inline Stream& operator >> (Stream& S, Streamable& O) { O.Load (S); return S; } inline Stream& operator << (Stream& S, const Streamable* O) { return S << *O; } inline Stream& operator >> (Stream& S, Streamable* O) { return S >> *O; } // End of STRMABLE.H #endif estic-1.61.orig/spunk/strparse.cc0100644000176100001440000003741507031424707016340 0ustar debacleusers/*****************************************************************************/ /* */ /* STRPARSE.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "chartype.h" #include "progutil.h" #include "msgid.h" #include "national.h" #include "charset.h" #include "strparse.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ static CharSet GetValidChars (int Base) { CharSet S; do { if (Base >= 10) { S += Base - 10 + 'A'; S += Base - 10 + 'a'; } else { S += Base + '0'; } Base--; } while (Base >= 0); return S; } /*****************************************************************************/ /* class StringParser */ /*****************************************************************************/ StringParser::StringParser (const String& X, u16 ParseFlags): P (0), S (X), Flags (ParseFlags), WhiteSpace (::WhiteSpace) { } void StringParser::SetPos (int NewPos) // Set a new position for parsing { u16 Len = S.Len (); P = (NewPos > Len) ? Len : NewPos; } void StringParser::Skip (const String& Chars) // Skip any chars contained in Chars { Skip (CharSet (Chars)); } void StringParser::Skip (const CharSet& Chars) // Skip any chars contained in Chars { char C; while ((C = S [P]) != '\0' && Chars [C] != 0) { P++; } } int StringParser::AllUsed () // Return true if UseAll is not set or if EOS is reached { return (Flags & UseAll) ? S [P] == '\0' : 1; } int StringParser::Num (char C) // Calculate the numeric value of the digit C (assumes ASCII!) { // C must be a digit or letter PRECONDITION (IsAlNum (C)); if (IsDigit (C)) { return (C & 0x0F); } else { return (NLSUpCase (C) - 'A' + 10); } } const String& StringParser::GetMsg (unsigned Res) // Return an apropriate error message for the result Res (!= 0) { PRECONDITION (Res > 0 && Res <= prMaxError); return LoadMsg (MSGBASE_STRPARSE - 1 + Res); } unsigned StringParser::GetI32 (i32& Val, unsigned Base) { // Check for a correct base value PRECONDITION (Base > 1 && Base <= 16); // save old position in case of errors int SavePos = P; // Skip white space if needed if (Flags & SkipWS) { SkipWhite (); } // Check for a minus sign int Sign = 1; if (S [P] == '-') { P++; Sign = -1; } else { // If pascal or C style hex constants are allowed, check for that. // Hex values are _not_ allowed if there is a preceeding minus sign. if (Base == 10 && (Flags & PascalHex) != 0) { if (S [P] == '$') { P++; Base = 16; } } if (Base == 10 && (Flags & CHex) != 0) { if (S [P] == '0' && S [P+1] == 'x') { P += 2; Base = 16; } } if (Base == 10 && (Flags & COct) != 0) { if (S [P] == '0') { P++; Base = 8; } } } // Get the valid chars according to base CharSet Chars = GetValidChars (Base); // Calculate the maximum value i32 MaxVal = 0x7FFFFFFF / Base; // Next char must be a digit if (Chars [S [P]] == 0) { P = SavePos; return prSyntax; } // Read the number Val = 0; while (Chars [S [P]] != 0) { if (Val > MaxVal) { // Value is getting to large P = SavePos; return prTooLarge; } Val = Val * Base + Num (S [P]); P++; } // make the value signed Val *= Sign; // Check if all chars are read if (AllUsed ()) { return 0; } else { P = SavePos; return prSyntax; } } unsigned StringParser::GetU32 (u32& Val, unsigned Base) { // Check for a correct base value PRECONDITION (Base > 1 && Base <= 16); // save old position in case of errors int SavePos = P; // Skip white space if needed if (Flags & SkipWS) { SkipWhite (); } // If pascal or C style hex constants are allowed, check for that. if (Base == 10 && (Flags & PascalHex) != 0) { if (S [P] == '$') { P++; Base = 16; } } if (Base == 10 && (Flags & CHex) != 0) { if (S [P] == '0' && S [P+1] == 'x') { P += 2; Base = 16; } } if (Base == 10 && (Flags & COct) != 0) { if (S [P] == '0') { P++; Base = 8; } } // Get the valid chars according to base CharSet Chars = GetValidChars (Base); // Calculate the maximum value u32 MaxVal = 0xFFFFFFFF / Base; // Next char must be a digit if (Chars [S [P]] == 0) { return prSyntax; } Val = 0; while (Chars [S [P]] != 0) { if (Val > MaxVal) { // Value is getting to large P = SavePos; return prTooLarge; } Val = Val * Base + Num (S [P]); P++; } // Check if all chars are read if (AllUsed ()) { return 0; } else { P = SavePos; return prSyntax; } } unsigned StringParser::GetFloat (double& Val) { Val = 0; // save old position in case of errors int SavePos = P; // Skip white space if needed if (Flags & SkipWS) { SkipWhite (); } // Check for leading minus int Sign = 1; switch (S [P]) { case '-': Sign = -1; P++; break; case '+': P++; break; } // Maybe there is a leading decimal separator int FracCnt; if (S [P] == NLSData.DecSep) { P++; FracCnt = 0; } else { FracCnt = -1; } // Next character must be a number if (!IsDigit (S [P])) { P = SavePos; return prSyntax; } while (1) { char C = S [P]; if (IsDigit (C)) { Val = Val * 10 + Num (C); if (FracCnt >= 0) { FracCnt++; } } else if (FracCnt < 0 && (C == NLSData.DecSep || ((Flags & AllowDP) && C == '.'))) { FracCnt++; } else { break; } P++; } // Correct for the fraction and the sign while (FracCnt > 0) { Val /= 10; FracCnt--; } Val *= Sign; // Check if all chars are read if (AllUsed ()) { return 0; } else { P = SavePos; return prSyntax; } } unsigned StringParser::GetToken (String& Tok, const CharSet& Chars) // Return a whitespace separated token from the string { // Clear the result string Tok.Clear (); // Remember the current position int SavePos = P; // Skip white space if needed if (Flags & SkipWS) { SkipWhite (); } // If the string is empty now, we have a syntax error if (S [P] == '\0') { P = SavePos; return prSyntax; } // Read characters until end of token is reached char C; while ((C = S [P]) != '\0' && Chars [C] == 0) { // Ok, end of string not reached and no whitespace. Add it. Tok += C; P++; } // Ok, done return 0; } unsigned StringParser::GetString (String& Str) // Return a string enclosed in double quotes { // Clear the result string Str.Clear (); // save old position in case of errors int SavePos = P; // Skip white space if needed if (Flags & SkipWS) { SkipWhite (); } // Next char must be a double quote if (S [P] != '"') { P = SavePos; return prSyntax; } P++; // Read characters until end of string is reached char C; while ((C = S [P]) != '\0' && C != '"') { Str += C; P++; } // Check if the ending double quote is missing else skip it if (C == '\0') { P = SavePos; return prSyntax; } P++; // Ok, done return 0; } unsigned StringParser::GetTime (Time& Val) { // save old position in case of errors int SavePos = P; // Skip white space if needed, then reset the skip and UseAll flags u16 SaveFlags = Flags; if (Flags & SkipWS) { SkipWhite (); } Flags &= ~(SkipWS | UseAll); // State machine u32 Hour, Min, Sec; unsigned Res = 0; enum { stStart, stSec, stMin, stHour, stError, stDone } State = stStart; while (State != stDone) { switch (State) { case stStart: State = stHour; break; case stHour: Res = GetU32 (Hour); if (Res != 0) { State = stError; } else if (Hour > 23) { Res = prTooLarge; State = stError; } else if (S [P] != NLSData.TimeSep) { Res = prSyntax; State = stError; } else { P++; State = stMin; } break; case stMin: Res = GetU32 (Min); if (Res != 0) { State = stError; } else if (Min > 59) { Res = prTooLarge; State = stError; } else if (S [P] != NLSData.TimeSep) { Sec = 0; State = stDone; } else { P++; State = stSec; } break; case stSec: Res = GetU32 (Sec); if (Res != 0) { State = stError; } else if (Sec > 59) { Res = prTooLarge; State = stError; } else { State = stDone; } break; case stError: P = SavePos; State = stDone; break; default: FAIL ("Illegal state machine value in StringParser::GetTime"); } // switch } // while // Restore original flags Flags = SaveFlags; // Set result if (Res == 0) { // Check if all chars are read if (AllUsed ()) { Val.SetTime (Hour, Min, Sec); return 0; } else { return prSyntax; } } else { return Res; } } unsigned StringParser::GetDate (Time& Val) { // save old position in case of errors int SavePos = P; // Skip white space if needed, then reset the skip and UseAll flags u16 SaveFlags = Flags; if (Flags & SkipWS) { SkipWhite (); } Flags &= ~(SkipWS | UseAll); // State machine u32 Year, Month, Day; unsigned Res = 0; enum { stStart, stDay, stDaySep, stMonth, stMonthSep, stYear, stYearSep, stError, stDone } State = stStart; while (State != stDone) { switch (State) { case stStart: switch (NLSData.Date) { case 0: State = stMonth; break; case 1: State = stDay; break; case 2: State = stYear; break; } break; case stYearSep: if (S [P] != NLSData.DateSep) { Res = prSyntax; State = stError; } else { P++; State = stYear; } break; case stYear: Res = GetU32 (Year); if (Res != 0) { State = stError; } else { if (Year >= 70 && Year < 100) { Year += 1900; } else if (Year <= 30) { Year += 2000; } if (Year < 1970) { Res = prTooSmall; State = stError; } else if (Year >= 2100) { Res = prTooLarge; State = stError; } else { switch (NLSData.Date) { case 0: State = stDone; break; case 1: State = stDone; break; case 2: State = stMonthSep; break; } } } break; case stMonthSep: if (S [P] != NLSData.DateSep) { Res = prSyntax; State = stError; } else { P++; State = stMonth; } break; case stMonth: Res = GetU32 (Month); if (Res != 0) { State = stError; } else if (Month > 12) { Res = prTooLarge; State = stError; } else if (Month == 0) { Res = prTooSmall; State = stError; } else { switch (NLSData.Date) { case 0: State = stDaySep; break; case 1: State = stYearSep; break; case 2: State = stDaySep; break; } } break; case stDaySep: if (S [P] != NLSData.DateSep) { Res = prSyntax; State = stError; } else { P++; State = stDay; } break; case stDay: Res = GetU32 (Day); if (Res != 0) { State = stError; } else if (Day > 31) { Res = prTooLarge; State = stError; } else if (Day == 0) { Res = prTooSmall; State = stError; } else { switch (NLSData.Date) { case 0: State = stYearSep; break; case 1: State = stMonthSep; break; case 2: State = stDone; break; } } break; case stError: P = SavePos; State = stDone; break; default: FAIL ("Illegal state machine value in StringParser::GetDate"); } // switch } // while // Restore original flags Flags = SaveFlags; // Set result if (Res == 0) { // Check if all chars are read if (AllUsed ()) { Val.SetDate (Year, Month, Day); return 0; } else { return prSyntax; } } else { return Res; } } estic-1.61.orig/spunk/strparse.h0100644000176100001440000000742207031424707016175 0ustar debacleusers/*****************************************************************************/ /* */ /* STRPARSE.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _STRPARSE_H #define _STRPARSE_H #include "chartype.h" #include "str.h" #include "charset.h" #include "datetime.h" /*****************************************************************************/ /* Constants for parsing results */ /*****************************************************************************/ const unsigned prOk = 0x0000; // Conversion done const unsigned prTooLarge = 0x0001; // Value too large for data type const unsigned prTooSmall = 0x0002; // Value to small for data type const unsigned prSyntax = 0x0003; // Syntax error const unsigned prMaxError = 0x0003; /*****************************************************************************/ /* class StringParser */ /*****************************************************************************/ class StringParser: public Object { public: enum { SkipWS = 0x0001, // Skip white space before parsing UseAll = 0x0002, // Error if no EOS is reached PascalHex = 0x0004, // Allow pascal style hex values CHex = 0x0008, // Allow C style hex values COct = 0x0010, // Allow C style octal digits AllowDP = 0x0020 // Allow real decimal point ('.') }; protected: int P; // Position in String const String& S; u16 Flags; // Parsing flags CharSet WhiteSpace; // White space characters private: int AllUsed (); // Return true if UseAll is not set or if EOS is reached static int Num (char C); // Calculate the numeric value of the digit C (assumes ASCII) public: StringParser (const String& X, u16 ParseFlags = StringParser::UseAll); void Reset (); // Reset position to 0 int GetPos () const; // Get current position in string void SetPos (int NewPos); // Set a new position for parsing void SkipWhite (); // Skip white space void Skip (const String& Chars); // Skip any chars contained in Chars void Skip (const CharSet& Chars); // Skip any chars contained in Chars int EOS () const; // Return 1 if the end of the string is reached const String& GetMsg (unsigned Res); // Return an apropriate error message for the result Res (!= 0) void SetFlags (u16 F); void ResetFlags (u16 F); u16 GetFlags (); // Handling the flags // Extracting data unsigned GetI32 (i32& Val, unsigned Base = 10); unsigned GetU32 (u32& Val, unsigned Base = 10); unsigned GetFloat (double& Val); unsigned GetTime (Time& Val); unsigned GetDate (Time& Val); unsigned GetToken (String& Tok, const CharSet& Chars = ::WhiteSpace); // Return token from the string that is separated by characters contained // in Chars unsigned GetString (String& S); // Return a string enclosed in double quotes }; inline void StringParser::Reset () // Reset position to 0 { P = 0; } inline int StringParser::GetPos () const // Get current position in string { return P; } inline int StringParser::EOS () const // Return 1 if the end of the string is reached { return S [P] == '\0'; } inline void StringParser::SkipWhite () // Skip white space { Skip (WhiteSpace); } inline void StringParser::SetFlags (u16 F) { Flags |= F; } inline void StringParser::ResetFlags (u16 F) { Flags &= ~F; } inline u16 StringParser::GetFlags () { return Flags; } // End of STRPARSE.H #endif estic-1.61.orig/spunk/strpool.cc0100644000176100001440000002322407031424707016170 0ustar debacleusers/*****************************************************************************/ /* */ /* STRPOOL.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "machine.h" #include "object.h" #include "streamid.h" #include "strmable.h" #include "coll.h" #include "national.h" #include "str.h" #include "mempool.h" #include "strpool.h" // Register class StringPool LINK(StringPool, ID_StringPool); /*****************************************************************************/ /* Types */ /*****************************************************************************/ struct Entry { u32 Str; // Character offset of the string u32 Num; // String number }; /*****************************************************************************/ /* class StringPoolEntryColl */ /*****************************************************************************/ // StringPoolEntryColl will set ShouldDelete to 1 and will therefore delete // all created Entry structs on deletion. class StringPoolEntryColl: public SortedCollection { private: MemPool const& Pool; protected: virtual int Compare (const char* Key1, const char* Key2); virtual const char* KeyOf (const Entry* Item); public: StringPoolEntryColl (MemPool const& aPool, int aLimit, int aDelta); }; StringPoolEntryColl::StringPoolEntryColl (MemPool const& aPool, int aLimit, int aDelta): SortedCollection (aLimit, aDelta, 1), Pool (aPool) { } int StringPoolEntryColl::Compare (const char* Key1, const char* Key2) { return NLSCmpStr (Key1, Key2); } const char* StringPoolEntryColl::KeyOf (const Entry* Item) { return Pool.Adr (Item->Str); } /*****************************************************************************/ /* class StringPoolStringColl */ /*****************************************************************************/ // StringPoolStringColl has ShouldDelete set to zero and will not touch the // Entry structs on deletion. class StringPoolStringColl: public Collection { protected: virtual void FreeItem (void*); virtual void* GetItem (Stream&); virtual void PutItem (Stream&, void*) const; public: StringPoolStringColl (int aLimit, int aDelta); }; StringPoolStringColl::StringPoolStringColl (int aLimit, int aDelta): Collection (aLimit, aDelta, 0) { } void StringPoolStringColl::FreeItem (void*) { // Cannot be called FAIL ("Call to StringPoolStringColl::FreeItem not allowed"); } void* StringPoolStringColl::GetItem (Stream&) { // Cannot be called FAIL ("Call to StringPoolStringColl::GetItem not allowed"); return NULL; } void StringPoolStringColl::PutItem (Stream&, void*) const { // Cannot be called FAIL ("Call to StringPoolStringColl::PutItem not allowed"); } /*****************************************************************************/ /* class StringPool */ /*****************************************************************************/ StringPool::StringPool (u32 BlockSize): Pool (BlockSize), EColl (new StringPoolEntryColl (Pool, BlockSize / 20, BlockSize / 20)), SColl (new StringPoolStringColl (BlockSize / 20, BlockSize / 20)), CurIndex (0) // Construct a StringPool { PRECONDITION (BlockSize > 0); } StringPool::StringPool (char* Buffer, u32 Size, u32 BlockSize): Pool (Buffer, Size, BlockSize) // Create a StringPool from the strings in Buffer. Size is the size of Buffer, // Buffer is assumed to be fully used. { PRECONDITION (Buffer != NULL && Size > 0 && BlockSize > 0); // Estimate Limit and Delta for the collections u32 Limit = Size / 20; // Estimated count of strings u32 Delta = Limit > 100? Limit / 10 : 10; // Create both collections EColl = new StringPoolEntryColl (Pool, Limit, Delta); SColl = new StringPoolStringColl (Limit, Delta); // Traverse the buffer memory, count the strings u32 Pos = 0; CurIndex = 0; while (Pos < Size) { // Create a new Entry for the current string Entry* E = new Entry; E->Str = Pos; E->Num = CurIndex; // Insert the Entry into both collections (only one of them is // responsible for deleting the entries) SColl->Insert (E); EColl->Insert (E); // Next string unsigned Len = strlen (Buffer) + 1; Pos += Len; Buffer += Len; CurIndex++; } } StringPool::StringPool (StreamableInit): Pool (Empty) { } StringPool::~StringPool () // Destruct a StringPool object { // One of the collections has ShouldDelete set to 1 and will delete all // the Entry structs delete SColl; delete EColl; } void StringPool::Load (Stream& S) { // Load the pool Pool.Load (S); // Read the index (the index is equal to the count of strings stored in // Pool) and recreate the index S >> CurIndex; // Create new collections EColl = new StringPoolEntryColl (Pool, CurIndex, CurIndex / 10); SColl = new StringPoolStringColl (CurIndex, CurIndex / 10); // Get a pointer to the first string in the pool. char* Str = Pool.Adr (0); // Traverse through all strings stored in the pool and construct the index u32 Pos = 0; for (u32 I = 0; I < CurIndex; I++) { // Create a new entry Entry* E = new Entry; E->Str = Pos; E->Num = I; // Insert the entry in both collections EColl->Insert (E); SColl->Insert (E); // Point to the next string unsigned Len = strlen (Str) + 1; Str += Len; Pos += Len; } } void StringPool::Store (Stream& S) const { // Store the pool Pool.Store (S); // Both index collections are not stored, they are created by Load S << CurIndex; } Streamable* StringPool::Build () { return new StringPool (Empty); } u16 StringPool::StreamableID () const { return ID_StringPool; } void StringPool::Clear () // Clear all entries in the pool { // Delete the entries of both collections, then delete the memory pool SColl->DeleteAll (); EColl->DeleteAll (); Pool.Clear (); CurIndex = 0; } void StringPool::Use (char* Buffer, u32 Size) // Throw the current data away and use the strings in the given buffer // instead. Size is the size of the buffer in characters, buffer must // be allocated on the heap, it will be deleted using delete[] if // necessary. { // Drop current data Clear (); // Tell the memory pool that we have new data Pool.Use (Buffer, Size); // Estimate Limit and Delta for the collections u32 Limit = Size / 20; // Estimated count of strings u32 Delta = Limit > 100? Limit / 10 : 10; // Create both collections EColl = new StringPoolEntryColl (Pool, Limit, Delta); SColl = new StringPoolStringColl (Limit, Delta); // Traverse the buffer memory, count the strings u32 Pos = 0; CurIndex = 0; while (Pos < Size) { // Create a new Entry for the current string Entry* E = new Entry; E->Str = Pos; E->Num = CurIndex; // Insert the Entry into both collections (only one of them is // responsible for deleting the entries) SColl->Insert (E); EColl->Insert (E); // Next string unsigned Len = strlen (Buffer) + 1; Pos += Len; Buffer += Len; CurIndex++; } } const char* StringPool::operator [] (u32 Index) const { return Pool.Adr (SColl->At (Index) -> Str); } const char* StringPool::At (u32 Index) const { return Pool.Adr (SColl->At (Index) -> Str); } u32 StringPool::Insert (const char* S) { // Try to find the string in the pool int Index; if (EColl->Search (S, Index)) { // Found! Return the string number return EColl->At (Index) -> Num; } else { // Not found - add the string to the pool // Calculate the string length unsigned Len = strlen (S); // Create a new entry and set the index number Entry* E = new Entry; E->Num = CurIndex++; // Allocate memory from the pool E->Str = Pool.Alloc (Len + 1); // Copy the string to the pool memcpy (Pool.Adr (E->Str), S, Len + 1); // Insert the pointers into both collections EColl->Insert (E); SColl->Insert (E); // Return the index of the stored string return CurIndex - 1; } } u32 StringPool::Find (const char* S) // Try to find the string in the pool, FAIL if the string is not found, // otherwise return the index { // Try to find the string in the pool int Index; int Result = EColl->Search (S, Index); CHECK (Result != 0); // Found! Return the string number return EColl->At (Index) -> Num; } estic-1.61.orig/spunk/strpool.h0100644000176100001440000000663307031424707016037 0ustar debacleusers/*****************************************************************************/ /* */ /* STRPOOL.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __STRPOOL_H #define __STRPOOL_H #include "machine.h" #include "object.h" #include "strmable.h" #include "coll.h" #include "str.h" #include "mempool.h" /*****************************************************************************/ /* class StringPool */ /*****************************************************************************/ // Forwards class StringPoolEntryColl; class StringPoolStringColl; class StringPool: public Streamable { private: MemPool Pool; // The buffer pool class StringPoolEntryColl* EColl; // cont: Entry, sorted by string class StringPoolStringColl* SColl; // cont: String, sorted by number u32 CurIndex; // Current index of string public: StringPool (u32 BlockSize = 1024); // Construct a StringPool StringPool (char* Buffer, u32 Size, u32 BlockSize = 1024); // Create a StringPool from the strings in Buffer. Size is the size of // Buffer, Buffer is assumed to be fully used. StringPool (StreamableInit); // Construct an empty and uninitialized StringPool virtual ~StringPool (); // Destruct a StringPool object // derived from class Streamable virtual void Load (Stream&); virtual void Store (Stream&) const; static Streamable* Build (); virtual u16 StreamableID () const; void Clear (); // Clear all entries in the pool void Use (char* Buffer, u32 Size); // Throw the current data away and use the strings in the given buffer // instead. Size is the size of the buffer in characters, buffer must // be allocated on the heap, it will be deleted using delete[] if // necessary. // Insert strings into the pool, return the index u32 Insert (const char*); u32 Insert (const String&); u32 Find (const char* S); // Try to find the string in the pool, FAIL if the string is not found, // otherwise return the index // Retrieve a string from the pool const char* operator [] (u32 Index) const; const char* At (u32 Index) const; // Return a pointer to the pool const char* GetPoolBuffer () const; // Return the size of the pool in chars u32 GetPoolSize () const; }; inline u32 StringPool::Insert (const String& S) { return Insert (S.GetStr ()); } inline const char* StringPool::GetPoolBuffer () const // Return a pointer to the pool { return Pool.Adr (0); } inline u32 StringPool::GetPoolSize () const // Return the size of the pool in chars { return Pool.GetCount (); } // End of STRPOOL.H #endif estic-1.61.orig/spunk/syserror.cc0100644000176100001440000001401707031424707016356 0ustar debacleusers/*****************************************************************************/ /* */ /* SYSERROR.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "msgid.h" #include "str.h" #include "progutil.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msDefault = MSGBASE_SYSERROR + 0; const u16 msNoError = MSGBASE_SYSERROR + 1; const u16 msNoSuchEntry = MSGBASE_SYSERROR + 2; const u16 msNoMem = MSGBASE_SYSERROR + 3; const u16 msAccessDenied = MSGBASE_SYSERROR + 4; const u16 msTooManyOpenFiles = MSGBASE_SYSERROR + 5; const u16 msNoSpaceOnDevice = MSGBASE_SYSERROR + 6; const u16 msAgain = MSGBASE_SYSERROR + 7; const u16 msBusy = MSGBASE_SYSERROR + 8; const u16 msFileTooLarge = MSGBASE_SYSERROR + 9; const u16 msIOError = MSGBASE_SYSERROR + 10; const u16 msIsADirectory = MSGBASE_SYSERROR + 11; const u16 msNotADirectory = MSGBASE_SYSERROR + 12; const u16 msTooManyLinks = MSGBASE_SYSERROR + 13; const u16 msBlockDevRequired = MSGBASE_SYSERROR + 14; const u16 msNotACharDev = MSGBASE_SYSERROR + 15; const u16 msNoSuchDev = MSGBASE_SYSERROR + 16; const u16 msNotOwner = MSGBASE_SYSERROR + 17; const u16 msBrokenPipe = MSGBASE_SYSERROR + 18; const u16 msReadOnlyFS = MSGBASE_SYSERROR + 19; const u16 msIllegalSeek = MSGBASE_SYSERROR + 20; const u16 msNoSuchProcess = MSGBASE_SYSERROR + 21; const u16 msTextFileBusy = MSGBASE_SYSERROR + 22; const u16 msNameTooLong = MSGBASE_SYSERROR + 23; const u16 msNoLocksAvailable = MSGBASE_SYSERROR + 24; const u16 msDirNotEmpty = MSGBASE_SYSERROR + 25; const u16 msFileNotFound = MSGBASE_SYSERROR + 26; const u16 msPathNotFound = MSGBASE_SYSERROR + 27; const u16 msInvalidDrive = MSGBASE_SYSERROR + 28; const u16 msCannotRemoveCurDir = MSGBASE_SYSERROR + 29; const u16 msFileExists = MSGBASE_SYSERROR + 30; const u16 msUnknown = MSGBASE_SYSERROR + 31; /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetSysErrorMsg (int Code) // This function tries to map a system error code to an error message in the // current language. This is not as easy as it seems, since the error codes // not only differ from operating system to operating system, but also from // compiler to compiler. If there is no predefined message, a default message // including the error number and the error string from sys_errlist (in // english) is returned. // Please note: The use of this function is not, to provide a verbose error // message for each and every error code, but to provide messages of the more // common errors. So, for example, EBADF ("bad file number") will _not_ get // mapped, since this error code denotes a program bug, but ENOENT _will_ // map to a verbose message, because this error may happen on a bad user input. { unsigned Msg; // Load a specific message for some well known error codes switch (Code) { #ifdef EZERO case EZERO: Msg = msNoError; break; #endif #if defined (ENOENT) && (!defined (ENOFILE) || ENOENT != ENOFILE) case ENOENT: Msg = msNoSuchEntry; break; #endif #ifdef ENOMEM case ENOMEM: Msg = msNoMem; break; #endif #ifdef EACCES case EACCES: Msg = msAccessDenied; break; #endif #ifdef EMFILE case EMFILE: Msg = msTooManyOpenFiles; break; #endif #ifdef ENOSPC case ENOSPC: Msg = msNoSpaceOnDevice; break; #endif #ifdef EAGAIN case EAGAIN: Msg = msAgain; break; #endif #ifdef EBUSY case EBUSY: Msg = msBusy; break; #endif #ifdef EFBIG case EFBIG: Msg = msFileTooLarge; break; #endif #ifdef EIO case EIO: Msg = msIOError; break; #endif #ifdef EISDIR case EISDIR: Msg = msIsADirectory; break; #endif #ifdef ENOTDIR case ENOTDIR: Msg = msNotADirectory; break; #endif #ifdef EMLINK case EMLINK: Msg = msTooManyLinks; break; #endif #ifdef ENOTBLK case ENOTBLK: Msg = msBlockDevRequired; break; #endif #ifdef ENOTTY case ENOTTY: Msg = msNotACharDev; break; #endif #ifdef ENXIO case ENXIO: Msg = msNoSuchDev; break; #endif #if defined (EPERM) && (!defined (EACCES) || EPERM != EACCES) case EPERM: Msg = msNotOwner; break; #endif #ifdef EPIPE case EPIPE: Msg = msBrokenPipe; break; #endif #ifdef EROFS case EROFS: Msg = msReadOnlyFS; break; #endif #ifdef ESPIPE case ESPIPE: Msg = msIllegalSeek; break; #endif #ifdef ESRCH case ESRCH: Msg = msNoSuchProcess; break; #endif #ifdef ETXTBSY case ETXTBSY: Msg = msTextFileBusy; break; #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: Msg = msNameTooLong; break; #endif #if defined (ENODEV) && (!defined (ENXIO) || ENODEV != ENXIO) case ENODEV: Msg = msNoSuchDev; break; #endif #ifdef ENOLCK case ENOLCK: Msg = msNoLocksAvailable; break; #endif #ifdef ENOTEMPTY case ENOTEMPTY: Msg = msDirNotEmpty; break; #endif #ifdef ENOFILE case ENOFILE: Msg = msFileNotFound; break; #endif #ifdef ENOPATH case ENOPATH: Msg = msPathNotFound; break; #endif #if defined (EINVDRV) && EINVDRV != ENODEV case EINVDRV: Msg = msInvalidDrive; break; #endif #ifdef ECURDIR case ECURDIR: Msg = msCannotRemoveCurDir; break; #endif #ifdef EEXIST case EEXIST: Msg = msFileExists; break; #endif default: // Unknown error code. Beware: Some compilers (Watcom for example) // give invalid error numbers, so check at least negative codes // here... if (Code < 0) { return FormatStr (LoadMsg (msUnknown).GetStr (), Code); } else { const char* Msg = strerror (Code); return FormatStr (LoadMsg (msDefault).GetStr (), Code, Msg); } } // If we get here, Msg contains a valid message number. return LoadMsg (Msg); } estic-1.61.orig/spunk/syserror.h0100644000176100001440000000303507031424707016216 0ustar debacleusers/*****************************************************************************/ /* */ /* SYSERROR.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _SYSERROR_H #define _SYSERROR_H #include #include "str.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ String GetSysErrorMsg (int Errno); // This function tries to map a system error code to an error message in the // current language. This is not as easy as it seems, since the error codes // not only differ from operating system to operating system, but also from // compiler to compiler. If there is no predefined message, a default message // including the error number and the error string from sys_errlist (in // english) is returned. // Please note: The use of this function is not, to provide a verbose error // message for each and every error code, but to provide messages of the more // common errors. So, for example, EBADF ("bad file number") will _not_ get // mapped, since this error code denotes a program bug, but ENOENT _will_ // map to a verbose message, because this error may happen on a bad user input. // End of SYSERROR.H #endif estic-1.61.orig/spunk/task.h0100644000176100001440000000763107031424707015276 0ustar debacleusers/*****************************************************************************/ /* */ /* TASK.H */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // Task (thread) object. Currently implemented for OS/2 and NT. There are some // quirks when working together with the rest of the spunk library, but the // object has shonw to be too useful to omit it. #ifndef _TASK_H #define _TASK_H #include "object.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Priority class values const unsigned PrioIdle = 0; // Run as idle thread const unsigned PrioRegular = 1; // Run with regular priority const unsigned PrioServer = 2; // Run as server thread const unsigned PrioTimeCritical = 3; // Run with time critical priority /*****************************************************************************/ /* class Task */ /*****************************************************************************/ class TaskHandle; class Task: public Object { protected: size_t StackSize; int Running; int RunDown; TaskHandle* Handle; private: static void CreateFunc (void*); // This function is started as a thread virtual void Init (); // This function is called before Run() virtual void Run () = 0; // This is the real "worker function" of the task virtual void Done (); // This function is called after Run() public: Task (size_t aStackSize = 0x8000); // Constructor. The Stacksize value may be honored or not. virtual ~Task (); // Destruktor virtual void Start (); // Start the task virtual void Stop (unsigned WaitTime = 2000); // Stop the task. WaitTime is the time, the routine waits for the thread // to terminate after the RunDown flag has been set. The Run() function // should poll this flag in regular intervalls. If the thread does not // recognize this flag, termination is forced. BEWARE: Forced termination // of a thread from outside is inherently dangerous, since the thread may // have no chance to cleanup resources. // The effects of this function differ from one supported operating // system to another, when the thread does not honor the RunDown flag and // must be killed: Under OS/2, the thread will catch the termination, // execute the Done() function and terminate itself. Under NT, the thread // will be killed immidiately without any chance for a cleanup. int IsRunning () const; // Return 1 if the task is currently running virtual void SetPriority (unsigned Priority, int Delta = 0); // Allows to set the priority of the task. BEWARE: Setting the priority // from outside the thread may not be possible from each supported // operating system. }; inline int Task::IsRunning () const // Return 1 if the task is currently running { return Running; } // End of TASK.H #endif estic-1.61.orig/spunk/textitem.cc0100644000176100001440000000524407031424707016333 0ustar debacleusers/*****************************************************************************/ /* */ /* TEXTITEM.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a special window item having the only purpose to display a row // of text in a given attribute in a window. It is not nthought to be active // or selected, so there are no special attributes for that. #include "streamid.h" #include "textitem.h" // Register the classes LINK (TextItem, ID_TextItem); /*****************************************************************************/ /* class WindowItem */ /*****************************************************************************/ TextItem::TextItem (const String& aItemText, i16 aID, u16 aAttr, WindowItem* NextItem): Attr (aAttr), WindowItem (aItemText, aID, NextItem) { // Make TextItems inactive by default Flags |= ifInactive; } TextItem::TextItem (StreamableInit): WindowItem (Empty) // Construct an empty TextItem { } void TextItem::Store (Stream& S) const // Store the item data into a stream { // Store WindowItem data WindowItem::Store (S); // Store additional data S << Attr; } void TextItem::Load (Stream& S) // Load the item data from a stream { // Load WindowItem data WindowItem::Load (S); // Load additional data S >> Attr; } u16 TextItem::StreamableID () const { return ID_TextItem; } Streamable* TextItem::Build () { return new TextItem (Empty); } u16 TextItem::MinWidth () { return 1; } void TextItem::Draw () { // Get the item text String S = ItemText; // Pad it to length S.Pad (String::Right, ItemWidth); // Lock the owner window Owner->Lock (); // Write out the item text Owner->Write (ItemX, ItemY, S, Attr); // Unlock the owner window Owner->Unlock (); } void TextItem::SetText (const String& aText) // Convenience function, identical to SetItemText { SetItemText (aText); } estic-1.61.orig/spunk/textitem.h0100644000176100001440000000410007031424707016163 0ustar debacleusers/*****************************************************************************/ /* */ /* TEXTITEM.H */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a special window item having the only purpose to display a row // of text in a given attribute in a window. It is not thought to be active // or selected, so there are no special attributes for that. #ifndef _TEXTITEM_H #define _TEXTITEM_H #include "itemwin.h" /*****************************************************************************/ /* class WindowItem */ /*****************************************************************************/ class TextItem : public WindowItem { friend class ResEditApp; // Resource editor is a friend protected: u16 Attr; // Text attribute public: TextItem (const String& aItemText, i16 aID, u16 aAttr, WindowItem* NextItem); // Construct a TextItem TextItem (StreamableInit); // Construct an empty TextItem // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); // Derived from class WindowItem virtual u16 MinWidth (); virtual void Draw (); void SetText (const String& aText); // Convenience function, identical to SetItemText }; // End of TEXTITEM.H #endif estic-1.61.orig/spunk/textstrm.cc0100644000176100001440000001466307031424707016367 0ustar debacleusers/*****************************************************************************/ /* */ /* TEXTSTRM.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "chartype.h" #include "textstrm.h" /*****************************************************************************/ /* class TextFileStream */ /*****************************************************************************/ TextFileStream::TextFileStream (const String& Name) : FileStream (Name, "rb"), Index (NULL), Limit (0), Count (0), Size (GetSize ()), TabSize (8), InOutFlags (tfDropCtrls | tfReplaceTabs), ReplaceChar (' ') // Open the stream in read-only mode. A non existant file is considered // an error. InOutFlags is set to DropCtrls | ReplaceTabs, ReplaceChar // is set to a blank { // Create the index for the beginning of all lines MakeLineIndex (); } TextFileStream::~TextFileStream () // Close the file, delete the line index { // Free the index delete [] Index; } void TextFileStream::MakeLineIndex (int LineLen) // Make a index into the file, storing the position of the beginning of // all lines. This speeds up seeking but consumes memory... // LineLen is the estimated length of a line in the file used for // estimating the size of the buffer. { static const Delta = 100; static const BufSize = 4096; // Estimate the count of lines if ((Limit = Size / LineLen) < 100) { Limit = 100; } // Release an eventually allocated old index delete [] Index; Index = NULL; Count = 0; // Allocate memory for new index u32* I = new u32 [Limit]; // Calculate line index if (Size > 0) { I [Count++] = 0; } // char* Buf = new char [BufSize]; int Fill = 0; u32 Bytes = Size; u32 BasePos = 0; while (Bytes) { // Buffer refill BasePos += Fill; Fill = (Bytes < BufSize) ? Bytes : BufSize; Bytes -= Fill; Read (Buf, Fill); #if defined (DOS) || defined (DOS32) || defined (OS2) // In case of DOS and OS/2, a Ctrl-Z terminates the file. Bytes is // invalid if this happens. Only the last CPM block (128 bytes) can // contain a Ctrl-Z. if (Bytes < 128) { // Read something from the last 128 bytes char* CtrlZPos = (char*) memchr (Buf, 0x1A, Fill); if (CtrlZPos != NULL) { // Found a Ctrl-Z Fill = CtrlZPos - Buf; Bytes = 0; } } #endif char* Pos = Buf; while (Pos && Pos < &Buf [Fill]) { Pos = (char*) memchr ((void*) Pos, '\n', Fill - (Pos - Buf)); if (Pos) { // Found another line begin, skip the lf Pos++; if (Count >= Limit) { // Index overflow Limit += Delta; u32* P = new u32 [Limit]; memcpy (P, I, Count*sizeof (u32)); delete [] I; I = P; } I [Count++] = BasePos + (Pos - Buf); } } } // Check if the last char in the buffer is a linefeed. If so, the last // index value points to EOF and is invalid. If Size is greater zero, // Fill will also be greater zero if (Size > 0 && Buf [Fill-1] == '\n') { Count--; } // Delete the buffer delete Buf; // Assign new index Index = I; } void TextFileStream::LineSeek (u32 Line) // Seek to a line absolute. The first line has the number 0. If the given // number is greater than the number of lines in the file, the seek // positions at end of file. { if (Line > Count) { Line = Count; } if (Line == Count) { Seek (Size); } else { Seek (Index [Line]); } } String TextFileStream::GetLine () // Read and return the next line from the file { // A char buffer with a fixed length is used for speed char Buf [512]; unsigned Count = 0; // Read char by char and stop at end of line register int C; while (1) { C = Read (); if (C == '\n' || C == '\r' || C == EOF) { break; } else if (C == '\t' && InOutFlags & tfReplaceTabs) { // Handle tabs unsigned Stop = ((Count + TabSize) / TabSize) * TabSize; if (Stop > sizeof (Buf) - 1) { Stop = sizeof (Buf) - 1; } while (Count < Stop) { Buf [Count++] = ' '; } } else { // Check if there is room left in the buffer if (Count < sizeof (Buf) - 1) { // Check for control chars if (IsCntrl (C)) { // Control char - maybe special handling switch (InOutFlags & tfHandleCtrls) { case tfReplaceCtrls: // Replace control char C = ReplaceChar; break; case tfDropCtrls: // Ignore this char continue; } } // Add the char to the buffer Buf [Count++] = C; } } } // Add the trailing zero Buf [Count] = '\0'; // Skip the rest of the line if (C == '\r') { // Skip until end of line do { C = Read (); } while (C != '\n' && C != EOF); } // Return the line return String (Buf); } void TextFileStream::SetTabSize (unsigned NewTabSize) // Set the new tabulator size (default is fixed 8 chars) { PRECONDITION (NewTabSize > 0 && NewTabSize <= 80); TabSize = NewTabSize; } estic-1.61.orig/spunk/textstrm.h0100644000176100001440000000543307031424707016224 0ustar debacleusers/*****************************************************************************/ /* */ /* TEXTSTRM.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __TEXTSTRM_H #define __TEXTSTRM_H #include "stream.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Constants for use in InOutFlags const unsigned tfHandleCtrls = 0x0003; // Mask for control handling const unsigned tfReplaceCtrls = 0x0001; // Replace control chars const unsigned tfDropCtrls = 0x0002; // Drop control chars const unsigned tfReplaceTabs = 0x0004; // Replace tabs by spaces /*****************************************************************************/ /* class TextFileStream */ /*****************************************************************************/ class TextFileStream: public FileStream { protected: u32* Index; // Line index u32 Limit; // Size of Index (in u32's) u32 Count; // Count of lines in the file u32 Size; // File size unsigned TabSize; // Size of tabs in files public: unsigned InOutFlags; // Bitmapped Flags char ReplaceChar; // Control chars are replaced by this char if // tfReplaceCtrls is set public: TextFileStream (const String& Name); // Open the stream in read-only mode. A non existent file is considered // as an error. InOutFlags is set to DropCtrls | ReplaceTabs, ReplaceChar // is set to a blank virtual ~TextFileStream (); // Close the file, delete the line index (if existant) void MakeLineIndex (int LineLen = 50); // Make a index into the file, storing the position of the beginning of // all lines. This speeds up seeking but consumes memory... // LineLen is the estimated length of a line in the file used for // estimating the size of the buffer. void LineSeek (u32 Line); // Seek to a line absolute. The first line has the number 0. If the given // number is greater than the number of lines in the file, the seek // positions at end of file. String GetLine (); // Read and return the next line from the file u32 LineCount () const; // Return the count of lines in the stream void SetTabSize (unsigned NewTabSize); // Set the new tabulator size (default is fixed 8 chars) }; inline u32 TextFileStream::LineCount () const // Return the count of lines in the stream { return Count; } // End of TEXTSTRM.H #endif estic-1.61.orig/spunk/thread.cc0100644000176100001440000001561007031424707015735 0ustar debacleusers/*****************************************************************************/ /* */ /* THREAD.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "screen.h" #include "kbd.h" #include "window.h" #include "thread.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class CircularBuffer; #endif /*****************************************************************************/ /* class Thread */ /*****************************************************************************/ // DJGPP has some weird declaration of the signal handler type so add a cast #ifdef __GO32__ #define SignalHandleFunc(__f) ((SignalHandler) __f) #else #define SignalHandleFunc(__f) __f #endif // Pointer to the current thread Thread* Thread::Current; Thread::Thread () : ANode (NULL), KeyList (NULL), Quit (0) { Current = this; // Try to catch all signals #ifdef SIGTERM signal (SIGTERM, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGBREAK signal (SIGBREAK, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGINT signal (SIGINT, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGILL signal (SIGILL, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGFPE signal (SIGFPE, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGSEGV signal (SIGSEGV, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGBUS signal (SIGBUS, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGABRT signal (SIGABRT, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGUSR1 signal (SIGUSR1, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGUSR2 signal (SIGUSR2, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGUSR3 signal (SIGUSR3, SignalHandleFunc (SIGHandler)); #endif #ifdef SIGWINCH signal (SIGWINCH, SignalHandleFunc (SIGHandler)); #endif } Thread::~Thread () { // Delete the list of registered keys while (KeyList) { RegKey* Key = KeyList->Next; delete KeyList; KeyList = Key; } } void Thread::GetEvent () { KeyBuf.Put (Kbd->Get ()); } void Thread::KbdPut (Key K) { KeyBuf.Put (K); } Key Thread::KbdGet () { while (KeyBuf.IsEmpty ()) { GetEvent (); } return KeyBuf.Get (); } Key Thread::KbdPeek () { if (!KeyBuf.IsEmpty ()) { return KeyBuf.Peek (); } else { return Kbd->Peek (); } } int Thread::KbdKeyAvail () { return (KeyBuf.IsEmpty () == 0 || Kbd->KeyAvail ()); } void Thread::SIGHandler (int Sig) { int Handled; // Re-Install the signal handler signal (Sig, SignalHandleFunc (SIGHandler)); // Call the signal specific function switch (Sig) { #ifdef SIGTERM case SIGTERM: Handled = CurThread () -> SigTerm (); break; #endif #ifdef SIGBREAK case SIGBREAK: Handled = CurThread () -> SigBreak (); break; #endif #ifdef SIGINT case SIGINT: Handled = CurThread () -> SigInt (); break; #endif #ifdef SIGILL case SIGILL: Handled = CurThread () -> SigIll (); break; #endif #ifdef SIGFPE case SIGFPE: Handled = CurThread () -> SigFPE (); break; #endif #ifdef SIGSEGV case SIGSEGV: Handled = CurThread () -> SigSegV (); break; #endif #ifdef SIGBUS case SIGBUS: Handled = CurThread () -> SigBus (); break; #endif #ifdef SIGABRT case SIGABRT: Handled = CurThread () -> SigAbrt (); break; #endif #ifdef SIGUSR1 case SIGUSR1: Handled = CurThread () -> SigUsr1 (); break; #endif #ifdef SIGUSR2 case SIGUSR2: Handled = CurThread () -> SigUsr2 (); break; #endif #ifdef SIGUSR3 case SIGUSR3: Handled = CurThread () -> SigUsr3 (); break; #endif #ifdef SIGWINCH case SIGWINCH: Handled = CurThread () -> SigWinCh (); break; #endif #ifdef SIGDIVZ case SIGDIVZ: Handled = CurThread () -> SigDivZ (); break; #endif #ifdef SIGOVF case SIGOVF: Handled = CurThread () -> SigOVF (); break; #endif default: Handled = 0; break; } // If the signal was not handled, install the default-handler and // re-raise the signal. if (!Handled) { #ifndef __GO32__ signal (Sig, SignalHandleFunc (SIG_DFL)); raise (Sig); #else // DJGPP is not able to raise a signal, so end the program FAIL ("Thread::SigHandler: Unhandled signal"); #endif } } int Thread::SigTerm () { // Don't ignore this one return 0; } int Thread::SigBreak () { // Don't ignore this one! return 0; } int Thread::SigInt () { // Don't ignore this one return 0; } int Thread::SigIll () { // OOPS - re-raise the signal return 0; } int Thread::SigFPE () { // OOPS - re-raise the signal FAIL ("Unexpected floating point exception"); return 0; } int Thread::SigSegV () { // OOPS - re-raise the signal FAIL ("Segmentation violation"); return 0; } int Thread::SigBus () { // OOPS - re-raise the signal return 0; } int Thread::SigAbrt () { // OOPS - re-raise the signal return 0; } int Thread::SigUsr1 () { // OOPS - re-raise the signal return 0; } int Thread::SigUsr2 () { // OOPS - re-raise the signal return 0; } int Thread::SigUsr3 () { // OOPS - re-raise the signal return 0; } int Thread::SigWinCh () { // Signal is handled return 1; } int Thread::SigDivZ () { // OOPS - re-raise the signal return 0; } int Thread::SigOVF () { // OOPS - re-raise the signal return 0; } void Thread::Idle () // This is the idle function of the thread class. Default is to // do nothing. This function may be called by anyone at anytime // but it's not guaranteed to be called regularly. { } void Thread::RegisterKey (Key K) // Register a key { // We cannot register a kbNoKey key if (K == kbNoKey) { FAIL ("Thread::RegisterKey: Trying to register kbNoKey"); } // Create a dynamic structure to store data RegKey* P = new RegKey; // Store data, insert new key in list P->K = K; P->Next = KeyList; KeyList = P; } void Thread::UnregisterKey (Key K) // Unregister a key { RegKey* P = KeyList; RegKey** Q = &KeyList; while (P != NULL) { if (P->K == K) { // Unlink node, delete registration record *Q = P->Next; delete P; return; } Q = &P->Next; P = P->Next; } FAIL ("Thread:KbdUnregister: Key not found"); } int Thread::KeyIsRegistered (Key K) // Check if a key is registered { RegKey* P = KeyList; while (P != NULL) { if (P->K == K) { // Found the key return 1; } P = P->Next; } return 0; } estic-1.61.orig/spunk/thread.h0100644000176100001440000000733207031424710015573 0ustar debacleusers/*****************************************************************************/ /* */ /* THREAD.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _THREAD_H #define _THREAD_H #include "machine.h" #include "object.h" #include "circbuf.h" #include "keydef.h" #include "window.h" /*****************************************************************************/ /* class Thread */ /*****************************************************************************/ class Thread: public Object { friend inline Thread* CurThread (); friend void Window::Activate (); friend void Window::Deactivate (); private: struct RegKey { RegKey* Next; Key K; }; static Thread* Current; ListNode ANode; RegKey* KeyList; protected: CircularBuffer KeyBuf; int Quit; // virtual void HandleEvent (Event &) virtual void GetEvent (); private: // Static signal handlers. This handler does nothing but calling // Current->Sig. To handle a signal, just override the virtual // Sig functions. If the virtual function returns zero, the // signal is re-raised, otherwise it is assumed that the function has // handled the signal. // Beware: On some architectures a few signals do not occur( e.g. DOS). // On other, some signals are only delivered to thread 1 (the application). // The default action of all Sig functions is to re-raise the // signal. Because the handling is set to SIG_DFLT before calling those // functions, the default handler will catch and handle the signal. static void SIGHandler (int); protected: // Functions called by SIGHandler virtual int SigTerm (); virtual int SigBreak (); virtual int SigInt (); virtual int SigIll (); virtual int SigFPE (); virtual int SigSegV (); virtual int SigBus (); virtual int SigAbrt (); virtual int SigUsr1 (); virtual int SigUsr2 (); virtual int SigUsr3 (); virtual int SigWinCh (); // Linux only virtual int SigDivZ (); // Watcom OS/2 only virtual int SigOVF (); // Watcom OS/2 only public: Thread (); ~Thread (); // The main execution function virtual int Run () = 0; // Checking the Quit Flag int Quitting (); virtual void Idle (); // This is the idle function of the thread class. Default is to // do nothing. This function may be called by anyone at anytime // but it's not guaranteed to be called regularly. // Handling Keyboard input virtual void KbdPut (Key K); virtual Key KbdGet (); virtual Key KbdPeek (); virtual int KbdKeyAvail (); // Registering keys void RegisterKey (Key K); void UnregisterKey (Key K); int KeyIsRegistered (Key K); }; inline Thread* CurThread () { return Thread::Current; } inline int Thread::Quitting () { return Quit; } // End of THREAD.H #endif estic-1.61.orig/spunk/todo.txt0100644000176100001440000000203107031424710015650 0ustar debacleusers - Refresh of windows under X11 does not work according to Nils Mueller, heino@psi.ozw.mayn.de - Change font detection from LC_TYPE. According to Thorsten Blum it is defined as ::= _. ::= based on ISO 639 ::= based on ISO 3166 (country code) ::= "EUC", "KOI8-R", ... but this clashes with most Linux systems. - More vga compatible X fonts. - Implementation of objects with only a single instance should be changed to reflect this. This suggestion is from Ralf Stephan, ralf@ark.franken.de, I'm currently thinking about a good general solution. - Support for KOI-8r character set. Michael Rodiono sent (incomplete) tables for the line drawing characters. This would best be coupled with the changed handling of LC_CTYPE. - Change spunk to support CP850 (multi national) on IBM compatibles as default, add code to support code page switching and translation tables for other code pages. - Docs, docs, docs... estic-1.61.orig/spunk/wildargs.cc0100644000176100001440000001026207031424710016272 0ustar debacleusers/*****************************************************************************/ /* */ /* WILDARGS.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a special module for DOS and OS/2. It is used to expand the // argument vector if any of the arguments has wildcards in it. #include #include "chartype.h" #include "filecoll.h" #include "filepath.h" #include "wildargs.h" /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; #endif /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void ExpandWildArg (const String& Arg, Collection& NewArgs) // Search for all files that match Arg and insert the names into NewArgs { // Separate path and filename String Dir, Name; FSplit (Arg, Dir, Name); // Read the files into a filename collection FileInfoColl Files; Files.ReadFiles (Dir, Name, 0xFFFF, 0x0000); // Now transfer the filenames. Beware: If the name does not expand to // anything insert just the name of the file. int Count = Files.GetCount (); if (Count == 0) { // Insert the original name NewArgs.Insert (new String (Arg)); } else { // Transfer all files for (int I = 0; I < Count; I++) { NewArgs.Insert (new String (Files [I]->Name)); } } } void ExpandArgs (int& ArgCount, _PPCHAR& ArgVec) // Expand the argument list { // Initialize ... char** OldArgs = ArgVec; Collection NewArgs (20, 20, 1); // Copy the first argument without looking at it, since this is the // name of the executable under DOS and OS/2 NewArgs.Insert (new String (*OldArgs++)); // Loop over all arguments, remember if we did an expand int DidExpand = 0; while (*OldArgs != NULL) { // Get the argument into a string String Arg = *OldArgs; // Here is a special convention: If an argument is preceeded by a // '@', it holds the name of a text file with one argument per // line. This is used to circumvent the 128 bytes command line // restriction of dos. FILE* F; if (Arg [0] == '@' && (F = fopen (&(*OldArgs) [1], "rt")) != NULL) { // We could open the file, read the lines char Buf [512]; while (fgets (Buf, sizeof (Buf), F) != NULL) { // Assign the line to the argument string Arg = Buf; // Remove leading and trailing white space Arg.Remove (WhiteSpace, rmLeading | rmTrailing); // Check if we have to expand the string if (Arg [0] != '-' && FHasWildcards (Arg)) { // Expand the argument ExpandWildArg (Arg, NewArgs); } else { // No wildcards, no switch: store a copy NewArgs.Insert (new String (Arg)); } // We expanded the file DidExpand = 1; } // Close the response file (void) fclose (F); } else if (Arg [0] != '-' && FHasWildcards (Arg)) { // Expand the argument ExpandWildArg (Arg, NewArgs); DidExpand = 1; } else { // No wildcards, no switch: store a copy NewArgs.Insert (new String (Arg)); } // Next argument OldArgs++; } // If we did not expand anything, we are done now, else copy the new // arguments if (DidExpand) { // Create a new char* argument vector. Don't forget the trailing NULL ArgVec = new char* [NewArgs.GetCount () + 1]; // Transfer the strings ArgCount = 0; for (ArgCount = 0; ArgCount < NewArgs.GetCount (); ArgCount++) { // Get the string argument String* Arg = NewArgs [ArgCount]; // Create a copy on the heap ArgVec [ArgCount] = new char [Arg->Len () + 1]; memcpy (ArgVec [ArgCount], Arg->GetStr (), Arg->Len () + 1); } // Add the trailing NULL ArgVec [ArgCount] = NULL; } } estic-1.61.orig/spunk/wildargs.h0100644000176100001440000000220307031424710016130 0ustar debacleusers/*****************************************************************************/ /* */ /* WILDARGS.H */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a special module for DOS and OS/2. It is used to expand the // argument vector if any of the arguments has wildcards in it. #ifndef __WILDARGS_H #define __WILDARGS_H #include "str.h" /*****************************************************************************/ /* Types */ /*****************************************************************************/ typedef char** _PPCHAR; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void ExpandArgs (int& ArgCount, _PPCHAR& ArgVec); // Expand the argument list // End of WILDARGS.H #endif estic-1.61.orig/spunk/winattr.cc0100644000176100001440000002400207031424710016143 0ustar debacleusers/*****************************************************************************/ /* */ /* WINATTR.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "wincolor.h" #include "palette.h" #include "winattr.h" /*****************************************************************************/ /* Palettes */ /*****************************************************************************/ // Two mono palettes static unsigned char plMono1 [] = { ((coBlack << 4) + coNormal ), // Frame: Passive ((coBlack << 4) + coNormal + coHigh ), // Active ((coBlack << 4) + coNormal + coHigh ), // Resizing ((coBlack << 4) + coNormal ), // Text: Normal ((coNormal << 4) + coBlack ), // Invers ((coBlack << 4) + coUnderline + coHigh ), // Selected ((coBlack << 4) + coUnderline + coHigh ), // High ((coNormal << 4) + coBlack ), // HighInv. ((coBlack << 4) + coNormal ), // Grayed ((coNormal << 4) + coBlack ), // GrayedInv ((coNormal << 4) + coBlack ), // Edit: Normal ((coNormal << 4) + coBlack ), // High ((coBlack << 4) + coNormal + coHigh ) // Bar }; static unsigned char plMono2 [] = { ((coNormal << 4) + coBlack ), // Frame: Passive ((coNormal << 4) + coBlack ), // Active ((coNormal << 4) + coBlack ), // Resizing ((coNormal << 4) + coBlack ), // Text: Normal ((coBlack << 4) + coNormal ), // Invers ((coNormal << 4) + coUnderline + coBlack ), // Selected ((coNormal << 4) + coUnderline + coBlack ), // High ((coBlack << 4) + coNormal + coHigh ), // HighInv. ((coNormal << 4) + coBlack ), // Grayed ((coBlack << 4) + coNormal ), // GrayedInv ((coBlack << 4) + coNormal ), // Edit: Normal ((coBlack << 4) + coNormal + coHigh ), // High ((coNormal << 4) + coBlack ) // Bar }; // Color palettes static unsigned char plBlue [] = { ((coBlue << 4) + coLightGray ), // Frame: Passive ((coBlue << 4) + coWhite ), // Active ((coBlue << 4) + coLightGreen), // Resizing ((coBlue << 4) + coLightGray ), // Text: Normal ((coLightGray << 4) + coBlue ), // Invers ((coBlue << 4) + coWhite ), // Selected ((coBlue << 4) + coYellow ), // High ((coLightGray << 4) + coRed ), // HighInv ((coBlue << 4) + coDarkGray ), // Grayed ((coLightGray << 4) + coDarkGray ), // GrayedInv ((coLightGray << 4) + coBlack ), // Edit: Normal ((coLightGray << 4) + coWhite ), // High ((coCyan << 4) + coBlack ) // Bar }; static unsigned char plCyan [] = { ((coCyan << 4) + coBlue ), // Frame: Passive ((coCyan << 4) + coWhite ), // Active ((coCyan << 4) + coLightGreen), // Resizing ((coCyan << 4) + coBlack ), // Text: Normal ((coGreen << 4) + coWhite ), // Invers ((coCyan << 4) + coWhite ), // Selected ((coCyan << 4) + coYellow ), // High ((coGreen << 4) + coRed ), // HighInv ((coCyan << 4) + coLightGray ), // Grayed ((coGreen << 4) + coDarkGray ), // GrayedInv ((coLightGray << 4) + coBlue ), // Edit: Normal ((coLightGray << 4) + coGreen ), // High ((coMagenta << 4) + coWhite ) // Bar }; static unsigned char plGray [] = { ((coLightGray << 4) + coBlack ), // Frame: Passive ((coLightGray << 4) + coWhite ), // Active ((coLightGray << 4) + coLightGreen), // Resizing ((coLightGray << 4) + coBlack ), // Text: Normal ((coGreen << 4) + coBlack ), // Invers ((coLightGray << 4) + coWhite ), // Selected ((coLightGray << 4) + coRed ), // High ((coGreen << 4) + coRed ), // HighInv ((coLightGray << 4) + coDarkGray ), // Grayed ((coGreen << 4) + coDarkGray ), // GrayedInv ((coBlue << 4) + coLightGray ), // Edit: Normal ((coBlue << 4) + coWhite ), // High ((coMagenta << 4) + coWhite ) // Bar }; static unsigned char plRed [] = { ((coRed << 4) + coYellow ), // Frame: Passive ((coRed << 4) + coWhite ), // Active ((coRed << 4) + coLightGreen), // Resizing ((coRed << 4) + coLightGray ), // Text: Normal ((coLightGray << 4) + coRed ), // Invers ((coRed << 4) + coWhite ), // Selected ((coRed << 4) + coYellow ), // High ((coLightGray << 4) + coYellow ), // HighInv ((coLightGray << 4) + coDarkGray ), // Grayed ((coLightGray << 4) + coDarkGray ), // GrayedInv ((coLightGray << 4) + coYellow ), // Edit: Normal ((coLightGray << 4) + coWhite ), // High ((coBlack << 4) + coWhite ) // Bar }; static unsigned char plBlack [] = { ((coBlack << 4) + coLightGray ), // Frame: Passive ((coBlack << 4) + coWhite ), // Active ((coBlack << 4) + coLightGreen), // Resizing ((coBlack << 4) + coLightGray ), // Text: Normal ((coLightGray << 4) + coBlack ), // Invers ((coBlack << 4) + coWhite ), // Selected ((coBlack << 4) + coYellow ), // High ((coLightGray << 4) + coYellow ), // HighInv ((coBlack << 4) + coDarkGray ), // Grayed ((coLightGray << 4) + coDarkGray ), // GrayedInv ((coLightGray << 4) + coBlack ), // Edit: Normal ((coLightGray << 4) + coWhite ), // High ((coMagenta << 4) + coBlack ) // Bar }; static unsigned char plEH [] = { ((coLightGray << 4) + coRed ), // Frame: Passive ((coLightGray << 4) + coRed ), // Active ((coLightGray << 4) + coLightGreen), // Resizing ((coLightGray << 4) + coBlack ), // Text: Normal ((coBlack << 4) + coLightGray ), // Invers ((coLightGray << 4) + coWhite ), // Selected ((coLightGray << 4) + coRed ), // High ((coGreen << 4) + coRed ), // HighInv ((coLightGray << 4) + coDarkGray ), // Grayed ((coGreen << 4) + coDarkGray ), // GrayedInv ((coBlue << 4) + coBlack ), // Edit: Normal ((coBlue << 4) + coWhite ), // High ((coMagenta << 4) + coWhite ) // Bar }; static unsigned char plRoot [] = { ((coBlack << 4) + coLightGray ), // Frame: Passive ((coBlack << 4) + coWhite ), // Active ((coBlack << 4) + coLightGreen), // Resizing ((coBlack << 4) + coLightGray ), // Text: Normal ((coLightGray << 4) + coBlack ), // Invers ((coBlack << 4) + coWhite ), // Selected ((coBlack << 4) + coLightGreen), // High ((coLightGray << 4) + coWhite ), // HighInv ((coBlack << 4) + coDarkGray ), // Grayed ((coLightGray << 4) + coDarkGray ), // GrayedInv ((coLightGray << 4) + coBlack ), // Edit: Normal ((coLightGray << 4) + coLightGreen), // High ((coMagenta << 4) + coWhite ) // Bar }; static unsigned char plHelp [] = { ((coLightGray << 4) + coBlack ), // Frame: Passive ((coLightGray << 4) + coWhite ), // Active ((coLightGray << 4) + coLightGreen), // Resizing ((coLightGray << 4) + coBlack ), // Text: Normal ((coBlack << 4) + coLightGray ), // Invers ((coLightGray << 4) + coWhite ), // Selected ((coLightGray << 4) + coLightBlue ), // High ((coGreen << 4) + coRed ), // HighInv ((coLightGray << 4) + coDarkGray ), // Grayed ((coGreen << 4) + coDarkGray ), // GrayedInv ((coBlue << 4) + coBlack ), // Edit: Normal ((coBlue << 4) + coWhite ), // High ((coMagenta << 4) + coWhite ) // Bar }; static unsigned char plFSel [] = { ((coLightGray << 4) + coBlack ), // Frame: Passive ((coLightGray << 4) + coWhite ), // Active ((coLightGray << 4) + coLightGreen), // Resizing ((coLightGray << 4) + coBlack ), // Text: Normal ((coBlue << 4) + coLightGray ), // Invers ((coLightGray << 4) + coWhite ), // Selected ((coLightGray << 4) + coYellow ), // High ((coBlue << 4) + coYellow ), // HighInv ((coLightGray << 4) + coDarkGray ), // Grayed ((coBlue << 4) + coLightGray ), // GrayedInv ((coBlue << 4) + coLightGray ), // Edit: Normal ((coBlue << 4) + coWhite ), // High ((coMagenta << 4) + coWhite ), // Balken im Fenster }; /*****************************************************************************/ /* Module initialization */ /*****************************************************************************/ void InitWinAttr () // Initialize window attributes { // Create a new palette Pal = new Palette; // Add palette entries Pal->Add (plMono1, plBlue); Pal->Add (plMono1, plGray); Pal->Add (plMono2, plCyan); Pal->Add (plMono2, plRed); Pal->Add (plMono1, plBlack); Pal->Add (plMono2, plEH); Pal->Add (plMono1, plRoot); Pal->Add (plMono1, plHelp); Pal->Add (plMono1, plFSel); } void DoneWinAttr () // Clean up after use { // Delete the used palette delete Pal; Pal = NULL; } estic-1.61.orig/spunk/winattr.h0100644000176100001440000000463507031424710016017 0ustar debacleusers/*****************************************************************************/ /* */ /* WINATTR.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __WINATTR_H #define __WINATTR_H #include "strmable.h" #include "coll.h" /*****************************************************************************/ /* Charset stuff */ /*****************************************************************************/ // Constants for use with the frame char arrays static const unsigned fcTopLeft = 0; static const unsigned fcTopRight = 1; static const unsigned fcBotLeft = 2; static const unsigned fcBotRight = 3; static const unsigned fcHorizontal = 4; static const unsigned fcVertical = 5; static const unsigned fcLeftTee = 6; static const unsigned fcRightTee = 7; static const unsigned fcTopTee = 8; static const unsigned fcBotTee = 9; static const unsigned fcCross = 10; // Characters for use in window frames etc. (these are in frame.cc and // initialized to CP850/CP437) extern unsigned char* ActiveFrame; extern unsigned char* InactiveFrame; // Other window frame arrays that may be used instead of the default ones // (these are also in frame.cc) extern unsigned char CP850_InactiveFrame []; extern unsigned char CP850_ActiveFrame []; extern unsigned char KOI8r_InactiveFrame []; extern unsigned char KOI8r_ActiveFrame []; extern unsigned char SimpleFrame []; // Some other useful characters. These must not be in the range 0x20..0x7F! const unsigned char LeftArrow = 0x1B; const unsigned char RightArrow = 0x1A; const unsigned char UpArrow = 0x18; const unsigned char DownArrow = 0x19; const unsigned char LeftTriangle = 0x11; const unsigned char RightTriangle = 0x10; const unsigned char UpTriangle = 0x1E; const unsigned char DownTriangle = 0x1F; /*****************************************************************************/ /* Module initialization */ /*****************************************************************************/ void InitWinAttr (); // Initialize window attributes void DoneWinAttr (); // Clean up after use // End of WINATTR.H #endif estic-1.61.orig/spunk/wincolor.h0100644000176100001440000000267507031424710016165 0ustar debacleusers/*****************************************************************************/ /* */ /* WINCOLOR.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __WINCOLOR_H #define __WINCOLOR_H /*****************************************************************************/ /* Color values */ /*****************************************************************************/ // Color values const unsigned coBlack = 0x00; const unsigned coBlue = 0x01; const unsigned coGreen = 0x02; const unsigned coCyan = 0x03; const unsigned coRed = 0x04; const unsigned coMagenta = 0x05; const unsigned coBrown = 0x06; const unsigned coLightGray = 0x07; const unsigned coDarkGray = 0x08; const unsigned coLightBlue = 0x09; const unsigned coLightGreen = 0x0A; const unsigned coLightCyan = 0x0B; const unsigned coLightRed = 0x0C; const unsigned coLightMagenta = 0x0D; const unsigned coYellow = 0x0E; const unsigned coWhite = 0x0F; const unsigned coCount = 0x10; // Monochrome values const unsigned coUnderline = 0x01; const unsigned coNormal = 0x07; const unsigned coHigh = 0x08; // Blink attribute const unsigned coBlink = 0x80; // End of WINCOLOR.H #endif estic-1.61.orig/spunk/window.cc0100644000176100001440000012676007031424710016000 0ustar debacleusers/*****************************************************************************/ /* */ /* WINDOW.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "eventid.h" #include "window.h" #include "winattr.h" #include "screen.h" #include "palette.h" #include "program.h" #include "streamid.h" // Register class Window LINK (Window, ID_Window); LINK (RootWindow, ID_RootWindow); /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class ListNode; #endif /*****************************************************************************/ /* Locking */ /*****************************************************************************/ // Default locking/unlocking functions are NOPs static void WinLockFunc () { } static void WinUnlockFunc () { } // Function vectors to lock/unlock the windows system void (*WinLock) () = WinLockFunc; void (*WinUnlock) () = WinUnlockFunc; /*****************************************************************************/ /* class RootWindow */ /*****************************************************************************/ // The root (background) window RootWindow* Background; RootWindow::RootWindow (): Window () // Create the background { // Assign to the variables ob the parent class. Because an (almost) // empty constructor of class window is used, they are not set before. Number = 0; Flags = wfVisible; LockCount = 0; OBounds = Rect (0, 0, TheScreen->GetXSize (), TheScreen->GetYSize ()); IBounds = OBounds; Cursor = csOff; CursorPos = Point (0, 0); Palette = paRoot; BGAttr = atTextNormal; BGChar = ' '; // Calculate the memory requirements VirtualScreenSize = OBounds.Chars (); // Allocate that memory VirtualScreen = new u16 [VirtualScreenSize]; // Set the module variable for the background window to "this" Background = this; // Clear the window Clear (); } u16 RootWindow::StreamableID () const { return ID_RootWindow; } Streamable* RootWindow::Build () { return new RootWindow (Empty); } void RootWindow::ScreenSizeChanged (const Rect& NewSize) // Called when the screen got another resolution. NewSize is the new // screen size. This functions calls ScreenSizeChanged of all other // windows on the screen. { // Lock the window system WinLock (); // Assign the new screen size OBounds = NewSize; IBounds = NewSize; // Delete the old virtual screen delete [] VirtualScreen; // Calculate the new memory requirements VirtualScreenSize = OBounds.Chars (); // Allocate that memory VirtualScreen = new u16 [VirtualScreenSize]; // Clear the window Clear (); // Unlock the window system WinUnlock (); } void RootWindow::RedrawScreen () // Redraw the complete screen in case it's garbled { UpdateScreen (OBounds); } void RootWindow::ChangeScreenSize (const Rect& NewSize) // Tell all windows about a changed screen size { // Lock the window system WinLock (); // Tell the windows about the changed size ListNode* N = &WNode; do { N->Contents () -> ScreenSizeChanged (NewSize); N = N->Next (); } while (N != &WNode); // Unlock the window system WinUnlock (); } Window* RootWindow::GetTopWindow () // Return the uppermost window. If there are no windows, return NULL { Window* PrevWindow = WNode.Prev () -> Contents (); return PrevWindow != this ? PrevWindow : (Window*) NULL; } Window* RootWindow::GetTopVisibleWindow () // Return the uppermost window that is visible. If there are no visible // windows, return NULL { ListNode* N = WNode.Prev (); while (N != &WNode) { Window* Win = N->Contents (); if (Win->IsVisible ()) { // Found the first visible window return Win; } N = N->Next (); } // Found no visible window return NULL; } Rect RootWindow::GetDesktop () const // Get the absolute coords of the desktop area { // Get the complete screen Rect Desktop = OBounds; // Now adjust for the status line and main menue if (App->StatusLine) { Desktop.B.Y--; } if (App->MainMenue) { Desktop.A.Y++; } // Return the result return Desktop; } void RootWindow::HandleEvent (Event& E) // Handle an incoming event. Default is to do nothing. { switch (E.What) { case evScreenSizeChange: ChangeScreenSize (* (const Rect*) E.Info.O); break; } } /*****************************************************************************/ /* class Window */ /*****************************************************************************/ Window::Window (const Rect& Bounds, u16 aState, u16 aPalette, u16 aNumber, int aLockCount): Number (aNumber), Flags (aState), Options (0), LockCount (aLockCount), OBounds (Bounds), Cursor (csOff), CursorPos (0, 0), Palette (aPalette), BGChar (' '), BGAttr (atTextNormal), VirtualScreen (NULL), VirtualScreenSize (0), WNode (this), ANode (this) { // Set inner window IBounds = OBounds; if (IsFramed ()) { IBounds.Grow (-1, -1); } CHECK (IBounds.Chars () > 0); // Calculate the memory requirements VirtualScreenSize = Bounds.Chars (); // Allocate that memory VirtualScreen = new u16 [VirtualScreenSize]; // Insert window as uppermost window WinLock (); WNode.InsertBefore (&Background->WNode); WinUnlock (); // Lock the window, so changes are accumulated Lock (); // Draw frame if window is framed DrawFrame (); // Clear the window Clear (); // Unlock window now Unlock (); } Window::~Window () // Delete a window { if (this != Background) { // If not already done, hide (and deactivate) the window Hide (); // Unlink the window from the window list if it's not the root window WinLock (); WNode.Unlink (); WinUnlock (); } // Now delete the allocated memory delete [] VirtualScreen; } u16 Window::StreamableID () const // Return the object ID { return ID_Window; } Streamable* Window::Build () // Build constructor { return new Window (Empty); } unsigned Window::MinXSize () const // Return the minimum X size of the window. Override this to limit resizing. { return IsFramed () ? 3 : 2; } unsigned Window::MinYSize () const // Return the minumim Y size of the window. Override this to limit resizing. { return IsFramed () ? 3 : 2; } void Window::SetPalette (u16 NewPalette) // Set a new window palette. NewPalette is the palette index of the new // palette. The window is redrawn to show the new palette. { if (NewPalette != Palette) { // Assign new palette Palette = NewPalette; // Redraw the frame and the interior Lock (); DrawFrame (); DrawInterior (); Unlock (); } } void Window::ScrollUp () // Scroll up the inner window by one line. The last line is cleared by // this function (BGAttr/BGChar) { Point ISize = IBounds.Size (); Point OSize = OBounds.Size (); // Calculate a pointer to the first row u16* Target = VirtualScreen; if (IsFramed ()) { Target += OSize.X + 1; } // Calculate a pointer to the second row u16* Source = Target + OSize.X; // Move memory for (int Y = ISize.Y - 1; Y > 0; Y--) { memmove (Target, Source, ISize.X * sizeof (u16)); Source += OSize.X; Target += OSize.X; } // Clear the last line u16 AttrChar = Pal->BuildAttr (Palette, BGAttr, BGChar); for (int X = ISize.X; X > 0; X--) { *Target++ = AttrChar; } // Update the window area Update (IBounds); } void Window::ScrollDown () // Scroll down the inner window by one line. The first line is cleared by // this function (BGAttr/BGChar) { Point ISize = IBounds.Size (); Point OSize = OBounds.Size (); // Calculate a pointer to the last row u16* Target = VirtualScreen + (OSize.Y - 1) * OSize.X; if (IsFramed ()) { Target -= OSize.X - 1; } // Calculate a pointer to the second last row u16* Source = Target - OSize.X; // Move memory for (int Y = ISize.Y - 1; Y > 0; Y--) { memmove (Target, Source, ISize.X * sizeof (u16)); Source -= OSize.X; Target -= OSize.X; } // Clear the first line u16 AttrChar = Pal->BuildAttr (Palette, BGAttr, BGChar); for (int X = ISize.X; X > 0; X--) { *Target++ = AttrChar; } // Update the window area Update (IBounds); } void Window::Clear () // Clear the inner window using the attribute BGAttr and the character // BGChar { u16* P; u16 AttrChar; int X, Y; Point ISize = IBounds.Size (); Point OSize = OBounds.Size (); Point Offs = IBounds.A - OBounds.A; P = VirtualScreen + Offs.X + Offs.Y * OSize.X; AttrChar = Pal->BuildAttr (Palette, BGAttr, BGChar); for (Y = 0; Y < ISize.Y; Y++, P += OSize.X) { for (X = 0; X < ISize.X; X++) { P [X] = AttrChar; } } // Reset the cursor position to zero CursorPos = Point (0, 0); // Update screen if not locked Update (OBounds); } void Window::DrawInterior () // Draw the interior of the window. You have to override this function // if your window contains something that has to be redrawn. The default // is to clear the inner window. { // Just clear the inner window here Clear (); } void Window::PutOnTop () // Put the given window on top of all other windows. { // Get pointer to node of root window ListNode* RootNode = &Background->WNode; // Check if any work if (WNode.Next () == RootNode) { // This window is the upper most window return; } // Unlink at current position and relink on top of all other windows WinLock (); WNode.Unlink (); WNode.InsertBefore (RootNode); WinUnlock (); // Redraw window hierarchy unconditionally Background->UpdateScreen (OBounds); } void Window::PutBeneath (Window& W) // Put a given window beneath another window. This second window cannot be // the root window (the root window must remain the last window in the // window hierarchy) { // Cannot put window beneath itself or beneath the root window PRECONDITION (&W != this && &W != Background); // Unlink at current position and link in before second window WinLock (); WNode.Unlink (); WNode.InsertBefore (&W.WNode); WinUnlock (); // Redraw window hierarchy unconditionally Background->UpdateScreen (OBounds); } Window* Window::UpperWindow () // Return the window in front of the this-window. If there is no upper // window, return NULL. { Window* Upper = WNode.Next () -> Contents (); return Upper != Background ? Upper : (Window*) NULL; } Window* Window::LowerWindow () // Return the window below the this-window. If there is no lower window, // return NULL. { Window* Lower = WNode.Prev () -> Contents (); return Lower != Background ? Lower : (Window*) NULL; } void Window::SetWindowNumber (u16 aNumber) // Set a new window number. If this makes the header line change, the // header is redrawn. { if (Number != aNumber) { // If the new number and old number is invisible, no need to redraw if ((Number == 0 || Number > 9) && (aNumber == 0 || aNumber > 9)) { // Just store the number Number = aNumber; } else { // Store the window number and redraw Number = aNumber; DrawHeader (); } } } inline unsigned char* Window::GetFrame () // Get a pointer to the frame char string according to the current // window state { // Use the active frame if the window is active or resizing, otherwise // use the passive frame return Flags & (wfActive | wfResizing) ? ActiveFrame : InactiveFrame; } unsigned Window::GetFrameAttr () // Return the palette index for the frame according to the current // window state { register unsigned Index; // Check out the correct index if (Flags & wfResizing) { // Resizing frame Index = atFrameResizing; } else if (Flags & wfActive) { // Active frame Index = atFrameActive; } else { // Inactive frame Index = atFrameInactive; } // Return the attribute char return Pal->BuildAttr (Palette, Index, ' '); } void Window::DrawHeader () // Draw the header line of the window frame. The function exits immidiately // if the window is not framed. { // Return immidiately if the window has no frame if (!IsFramed ()) { return; } // No output until Unlock Lock (); // Get needed frame characters and frame attribute unsigned char* F = GetFrame (); u16 AttrChar = GetFrameAttr (); // Get the attribute char for the horizontal lines u16 FrameAttr = Pal->BuildAttr (AttrChar, F [fcHorizontal]); // Calculate the header width unsigned Width = IBounds.XSize (); unsigned HeaderLen = Header.Len (); if (HeaderLen > Width) { HeaderLen = Width; } // Count of chars left and right of the header string unsigned LeftChars = (Width - HeaderLen) / 2; unsigned RightChars = Width - HeaderLen - LeftChars; // Starting X coord unsigned X = 1; unsigned I; // Draw the left part while (LeftChars--) { WriteChar (X++, 0, FrameAttr); } // Headerstring part I = 0; while (I < HeaderLen) { WriteChar (X++, 0, Pal->BuildAttr (AttrChar, Header [I])); I++; } // Draw the right part. This is special, because the windows number apears // here if (Number >= 1 && Number <= 9 && RightChars >= 3) { // There is a number and there's room for the number string. Calculate // the space left and right of the number string LeftChars = RightChars - 2; RightChars = RightChars - 1 - LeftChars; // Draw the left part while (LeftChars--) { WriteChar (X++, 0, FrameAttr); } // Draw the number WriteChar (X++, 0, Pal->BuildAttr (AttrChar, Number + '0')); // Draw the right part while (RightChars--) { WriteChar (X++, 0, FrameAttr); } } else { // No number or no room for the string while (RightChars--) { WriteChar (X++, 0, FrameAttr); } } // Unlock the window, update the screen Unlock (); } void Window::DrawFooter () // Draw the footer of the window frame. The function exits immidiately if // the window is not framed. // The footer is positioned at the lower right of the frame, there is exactly // one horizontal frame element to the right of the footer text. { // Return immidiately if the window has no frame if (!IsFramed ()) { return; } // No output until Unlock Lock (); // Get needed frame characters and frame attribute unsigned char* F = GetFrame (); u16 AttrChar = GetFrameAttr (); // Get the attribute char for the horizontal lines u16 FrameAttr = Pal->BuildAttr (AttrChar, F [fcHorizontal]); unsigned Width = IBounds.XSize (); if (Width == 0) { // No space for the footer Unlock (); return; } unsigned FooterLen = Footer.Len (); if (FooterLen >= Width) { FooterLen = Width - 1; } unsigned LeftChars = Width - FooterLen - 1; unsigned X = 1; unsigned Y = OBounds.YSize () - 1; // Write the horizontal characters to the left of the footer text while (LeftChars--) { WriteChar (X++, Y, FrameAttr); } // Write the footer text unsigned I = 0; while (I < FooterLen) { WriteChar (X++, Y, Pal->BuildAttr (AttrChar, Footer [I])); I++; } // Write the horizontal frame char to the right of the footer WriteChar (X, Y, FrameAttr); // Unlock the window, allow screen updates Unlock (); } void Window::DrawFrame () // Draw the window frame. This function is called if the state of the // window changes in a way that is shown in the frame. The function // exits immediately if the window has no frame. { // Bail out early if the window has no frame if (!IsFramed ()) { return; } // Get the window size int XMax = OBounds.XSize () - 1; int YMax = OBounds.YSize () - 1; // Get needed frame characters and frame attribute unsigned char* F = GetFrame (); u16 AttrChar = GetFrameAttr (); // Now draw top/bottom/left/right frame part, doing a lock/unlock pair // before and after each part. This will prevent redrawing the complete // window under linux (where terminal ouput may be slow). // Top part Lock (); WriteChar (0, 0, Pal->BuildAttr (AttrChar, F [fcTopLeft])); WriteChar (XMax, 0, Pal->BuildAttr (AttrChar, F [fcTopRight])); DrawHeader (); Unlock (); // Bottom part Lock (); WriteChar (0, YMax, Pal->BuildAttr (AttrChar, F [fcBotLeft])); WriteChar (XMax, YMax, Pal->BuildAttr (AttrChar, F [fcBotRight])); DrawFooter (); Unlock (); // Left part AttrChar = Pal->BuildAttr (AttrChar, F [fcVertical]); Lock (); int Y; for (Y = 1; Y < YMax; Y++) { WriteChar (0, Y, AttrChar); } Unlock (); // Right part Lock (); for (Y = 1; Y < YMax; Y++) { WriteChar (XMax, Y, AttrChar); } Unlock (); // Done } void Window::SetHeader (const String& NewHeader) // Set a new window header. The window header is visible only if the // window has a frame. In this case, it is centered in the top part of // the frame. This function redraws the top part of the frame. { Header = NewHeader; DrawHeader (); } void Window::SetFooter (const String& NewFooter) // Set a new window footer. The window footer is visible only if the // window has a frame. In this case, it is right justified in the bottom // part of the frame. This function redraws the bottom part of the frame. { Footer = NewFooter; DrawFooter (); } void Window::Absolute (Point& P) // Make a window relative point absolute (relative to the screen). The // given coordinates are (0/0) based relativ to the inner window { P += IBounds.A; } void Window::Relative (Point& P) // Make an absolute coordinate relative to the inner window { P -= IBounds.A; } void Window::Resize (const Rect& NewBounds) // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). // The function checks if the new size is applicable. If yes, the window // is resized and DrawInterior is called to redraw the windows contents. { // Lock the window system WinLock (); // Lock screen output Lock (); // Remember the old window bounds Rect OldBounds = OBounds; // Use the new bounds IBounds = OBounds = NewBounds; // Recalculate the inner window. Don't use Move, this can fail! if (IsFramed ()) { IBounds.Grow (-1, -1); } // Allocate memory for the new virtual screen u16 NewVirtualScreenSize = NewBounds.Chars (); u16* NewVirtualScreen = new u16 [NewVirtualScreenSize]; // Free the current virtual screen and use the new one delete [] VirtualScreen; VirtualScreen = NewVirtualScreen; VirtualScreenSize = NewVirtualScreenSize; // Draw the frame, then draw the interior DrawFrame (); DrawInterior (); // If the window is visible, update the union of the old and the // new window bounds. This will cause the dirty flag to be reset, // so the following unlock does nothing but reseting the lock counter if (IsVisible ()) { Background->UpdateScreen (Union (OldBounds, OBounds)); } // Allow screen output Unlock (); // Unlock the window system WinUnlock (); } void Window::MoveAbs (Point dP) // Move the window to an absolute position { MoveRel (dP - OBounds.A); } void Window::MoveRel (Point dP) // The window is moved by the given dX/dY { // Lock the window system WinLock (); if (IsVisible ()) { // Remember old coordinates Rect OldOBounds = OBounds; // Move window OBounds.Move (dP.X, dP.Y); IBounds.Move (dP.X, dP.Y); // If the window is moved not more than 4 units in combined // X and Y direction, redraw the union of both rectangles if ( (abs (dP.X) + abs (dP.Y)) > 4) { // Update old area, this resets a possibly set dirty flag Background->UpdateScreen (OldOBounds); // Update new area Background->UpdateScreen (OBounds); } else { // Update combined area Background->UpdateScreen (Union (OldOBounds, OBounds)); } } else { OBounds.Move (dP.X, dP.Y); IBounds.Move (dP.X, dP.Y); } // Unlock the window system WinUnlock (); } void Window::SetState (u16 State) // Set the state of the wfActive and wfVisible flags according to the // values contained in NewFlags. { switch (State & (wfActive | wfVisible)) { case wfActive | wfVisible: // Both flags should be set. To avoid redrawing the area twice, // just set the wfVisible Flag and call Activate. Activate will // call Show if the wfVisible flag is set, after redrawing the // frame, so the area is only output once Flags |= wfVisible; Activate (); break; case wfActive: // This one is simple... Activate (); break; case wfVisible: // This one is simple... Show (); break; case 0: // Hide the window. This will reset the wfActive flag Hide (); break; } } void Window::NewOptions (u16 NewOps) { u16 OldOps = Options; Options = NewOps; // Check if anything has changed if ((NewOps & cfCenterAll) != (OldOps & cfCenterAll)) { // Re-center the window Rect NewBounds (OBounds); NewBounds.Center (Background->OuterBounds (), Options); MoveAbs (NewBounds.A); } } void Window::MoveResizeAfterLoad (const Point& OldRes) // This function is called after a load when most of the window is // constructed. It is used to move the window to a new position if this is // needed. OldRes is the old screen resolution that was active, when the // window was stored. // The default is to recenter the window if the apropriate flags are set // and the screen resolution has changed. { // If the screen size has changed and some of the center options // are set, recenter the window. if (Background->OuterBounds ().Size () != OldRes && (Options & cfCenterAll) != 0) { // Screen size has changed Rect NewBounds (OBounds); NewBounds.Center (Background->OuterBounds (), Options); MoveAbs (NewBounds.A); } } void Window::Hide () // Hide the window. The window is no longer visible after calling this // function but any window output is still allowed. { if (IsVisible ()) { // Do not lock the window but reset the wfVisible flag before calling // (eventually) Deactivate. If the wfVisible flag is reset, there // will be no screen I/O anyway. Flags &= ~wfVisible; if (IsActive ()) { Deactivate (); } Background->UpdateScreen (OBounds); } } void Window::Show () // Show a previously hidden window. This does not put the window in front // of other windows, so the window may still be covered. { if (!IsVisible ()) { Flags |= wfVisible; Background->UpdateScreen (OBounds); } } void Window::StartResizing () // Set the wfResizing flag and redraw the frame to show the new window // state { // Set the flag bit Flags |= wfResizing; // Redraw the frame if there is one DrawFrame (); } void Window::EndResizing () // Reset the wfResizing flag and redraw the frame to show the new window // state { // Reset the flag bit Flags &= ~wfResizing; // Redraw the frame if there is one DrawFrame (); } void Window::RawActivate () // Activate the window without manipulating the active window stack { // If the window is already active, something is wrong PRECONDITION (!IsActive ()); // Lock the window, no screen output Lock (); // Remember that the window is active and draw the new frame Flags |= wfActive; DrawFrame (); // Lock the window system WinLock (); // Put window on top. Do not use PutOnTop for this, because PutOnTop // will unconditionally redraw the area covered by this window. This // is unneccessary and (under Linux) maybe slow. // Get pointer to node of root window ListNode* RootNode = &Background->WNode; // Check if any work if (WNode.Next () != RootNode) { // The window is not on top. Unlink it at the current position and // relink on top of all other windows WNode.Unlink (); WNode.InsertBefore (RootNode); // Because the window eventually has been covered, we have to redraw // the covered area now. Combine this with showing the window by // setting the wfVisible flag before updating the window area Flags |= wfVisible; Background->UpdateScreen (OBounds); } else { // The window has already been on top. If the window was invisible, // show it now, otherwise do nothing if (!IsVisible ()) { Show (); } } // Set the cursor form and position SetCursor (); // Unlock the window system WinUnlock (); // Unlock the window Unlock (); } void Window::Activate () // Set the window active flag, redraw the window frame to show the new // state, put the window in front of all other windows, then show it if // it has been hidden. This function deactivates an eventually active // window. { // Lock the window system WinLock (); // Activate the window if (!IsActive ()) { // Window is not active. Get a pointer to the current active // window in the thread. Make that window inactive but remember // the pointer. Thread* T = CurThread (); Window* OldActive = T->ANode.IsEmpty () ? (Window*) NULL : T->ANode.Prev () -> Contents (); // If there is a previous active window, lock it before making it // inactive. Maybe the window is completely covered by the new // active window, so redrawing the inactive frame will never get it // to the screen. if (OldActive) { // Some other active window, make it inactive OldActive->Lock (); OldActive->RawDeactivate (); } // Be careful here: The window that should become active could be // already in the list of active windows. So unlink it before doing // the real work ANode.Unlink (); // Make the current window active and set the pointer // to the current active window to "this". ANode.InsertBefore (&T->ANode); RawActivate (); // If there has been an old active window, unlock it now if (OldActive) { OldActive->Unlock (); } } // Unlock the window system WinUnlock (); } void Window::RawDeactivate () // Deactivate the window without manipulating the active window stack { // Window must be active or something is sincerely wrong PRECONDITION (IsActive ()); // Reset the flags and draw a new frame according to the new state Flags &= ~wfActive; DrawFrame (); } void Window::Deactivate () // Deactivates the window. This includes redrawing the frame and // re-activating a previuos active window. { // Lock the window system WinLock (); if (IsActive ()) { // The window is active. Deactivate the window. Get the pointer to // the last active window and activate this one. Store the pointer // to the last active window as currently active. Thread* T = CurThread (); ANode.Unlink (); RawDeactivate (); if (!T->ANode.IsEmpty ()) { T->ANode.Prev () -> Contents () -> RawActivate (); } } // Unlock the window system WinUnlock (); } void Window::Unlock () // Unlock the window. If there have been window changes while the window // was locked, the physical screen is updated in the area that contains // the changes. Lock/Unlock may be nested. { if (--LockCount == 0) { if (IsDirty () && IsVisible ()) { UpdateScreen (DirtyRect); } } } void Window::WriteChar (int X, int Y, u16 AttrChar) // Write a character to virtual and real screen. The coordinates are zero // based relative to the outer window. { // Calculate and check offset int Offset = OBounds.XSize () * Y + X; PRECONDITION (Offset < VirtualScreenSize); // Write char to virtual screen *(VirtualScreen + Offset) = AttrChar; // Update screen if not locked Update (Rect (OBounds.A.X + X, OBounds.A.Y + Y, OBounds.A.X + X + 1, OBounds.A.Y + Y + 1)); } void Window::WriteBuf (int X, int Y, u16* Buf, size_t Count) { // Check for a wrong Y coord PRECONDITION (Y < OBounds.YSize ()); // Get pointer to first mem location u16* Start = VirtualScreen + OBounds.XSize () * Y + X; // Don't wrap around the right border int Max = OBounds.XSize () - X; int C = (int (Count) > Max) ? Max : Count; // Cast to int if (C > 0) { // Now write the stuff to the virtual screen memcpy (Start, Buf, C * sizeof (u16)); // Update screen if not locked Update (Rect (OBounds.A.X + X, OBounds.A.Y + Y, OBounds.A.X + X + C, OBounds.A.Y + Y + 1)); } } void Window::CollectBuffer (const Rect& Bounds, u16* Buf) // "Collects" window data in a buffer. If a screen redraw must be done // because one of the windows in the hierarchy has changes, the window // allocates a buffer, fills it with the data from its virtual screen // and passes the buffer together with the window bounds to each one // of the windows in front. Each of those windows checks if the // rectangle overlaps with its own area and updates this area in the // buffer. // // +-------------+ // | | // | +------+------+ R1 = Bounds // | R1 | | | R2 = OBounds // | | R3 | | R3 = R // | | | | // +------+------+ | // | | // | R2 | // | | // | | // | | // +-------------+ // // { // If the window is not visible --> exit immidiately if (!IsVisible ()) { return; } // Get intersection of both rectangles Rect R = Intersection (Bounds, OBounds); // If the intersection is empty, nothing has to be done if (R.IsEmpty ()) { return; } // If the intersection contains the dirty rectangle, // the dirty flag can be reset, because the whole window will // be put in the buffer and the whole DirtyRect rectangle will // be updated on the real screen if (IsDirty () && R.Contains (DirtyRect)) { Flags &= ~wfDirty; } // Update the buffer int R1RowChars = Bounds.XSize (); int R2RowChars = OBounds.XSize (); int R3RowChars = R.XSize (); int R1RowOfs = R.A.X - Bounds.A.X; int R2RowOfs = R.A.X - OBounds.A.X; int R1YOfs = R.A.Y - Bounds.A.Y; int R2YOfs = R.A.Y - OBounds.A.Y; u16* Target = Buf + R1YOfs * R1RowChars + R1RowOfs; u16* Source = VirtualScreen + R2YOfs * R2RowChars + R2RowOfs; for (int Height = R.YSize (); Height > 0; Height--) { memmove (Target, Source, R3RowChars * sizeof (u16)); Target += R1RowChars; Source += R2RowChars; } } void Window::UpdateScreen (const Rect& Bounds) // Updates the real screen using the contents of the virtual screen. { // Intersect the given rectangle with the rectangle of the root window // clipping at all four borders. So no illegal coords are used. Rect B = Intersection (Background->OBounds, Bounds); // If the resulting intersection is empty, the rectangle is completely // oudside the screen. Ignore the call. if (B.IsEmpty ()) { return; } // Allocate buffer u16* Buf = new u16 [B.Chars ()]; // Lock the window system WinLock (); // Pass the buffer along to all windows in top of the current window, // with each window updating it's portion of the buffer // The buffer is passed at first to the current window, thus clearing // the dirty bit if the given rectangle is equal to the outer bounds // of the window. ListNode* RootNode = &Background->WNode; ListNode* NextNode = &WNode; do { NextNode->Contents ()->CollectBuffer (B, Buf); NextNode = NextNode->Next (); } while (NextNode != RootNode); // Now we have a complete screen image of the area, show it TheScreen->DisplayBuffer (B, Buf); // Unlock the window system WinUnlock (); // Free buffer delete [] Buf; } void Window::Update (const Rect& Bounds) // Update area or mark window as dirty if locked { // If the window is invisible, there's nothing to do if (IsVisible ()) { if (IsLocked ()) { // Output is locked, check if the window is already dirty if (IsDirty ()) { // Add the new region to the dirty region DirtyRect = Union (DirtyRect, Bounds); } else { // Not dirty until now DirtyRect = Bounds; Flags |= wfDirty; } } else { // Output is enabled, do the update UpdateScreen (Bounds); } } } void Window::Write (int X, int Y, const String& S, int Attr) // Write a string to the inner window. Note: Attr is an index, not a real // attribute ! { const BufSize = 256; u16 Buf [256]; // Check if the given string is empty int Len = S.Len (); if (Len == 0) { return; } // If the Y coord is outside the inner window, there is nothing to do if (Y >= IBounds.YSize ()) { return; } // Get the length of the string and clip to the right border of the // inner window if ((X + Len) > IBounds.XSize ()) { Len = IBounds.XSize () - X; } // Check against length of buffer if (Len > BufSize) { Len = BufSize; } // Get an empty attribute char u16 AttrChar = Pal->BuildAttr (Palette, Attr, ' '); // Fill the buffer for (int I = 0; I < Len; I++) { Buf [I] = Pal->BuildAttr (AttrChar, S [I]); } // Now write the buffer if (IsFramed ()) { X++; Y++; } WriteBuf (X, Y, Buf, Len); } void Window::Write (int X, int Y, char C, int Attr) // Write a char to the inner window. Note: Attr is an index, not a real // attribute { // Check if the coordinates are inside the inner window if (X >= 0 && X < IBounds.XSize () && Y >= 0 && Y < IBounds.YSize ()) { // Adjust coordinates if window is framed if (IsFramed ()) { X++; Y++; } WriteChar (X, Y, Pal->BuildAttr (Palette, Attr, C)); } } void Window::FWrite (const String& S, int Attr) // ## This function is a hack { String O (S.Len ()); int I; char C; // Lock output Lock (); // Examine given string I = 0; while (I < S.Len ()) { C = S [I++]; switch (C) { case '\x0D': case '\x0A': // Display collected buffer if (O.Len () > 0) { Write (CursorPos.X, CursorPos.Y, O, Attr); CursorPos.X += O.Len (); O.Clear (); } if (C == 0x0D) { // CR CursorPos.X = 0; } else if (C == 0x0A) { // LF if (++CursorPos.Y >= IBounds.YSize ()) { // Need scroll ScrollUp (); CursorPos.Y--; } } break; default: O += C; break; } } // Display collected buffer if (O.Len () > 0) { Write (CursorPos.X, CursorPos.Y, O, Attr); CursorPos.X += O.Len (); } // Unlock the window, allow screen output Unlock (); } void Window::CWrite (int X, int Y, const String& S) // Write a string to the inner window. Note: Attr is an index, not a real // attribute ! { const BufSize = 256; u16 Buf [BufSize]; // If the Y coord is outside the inner window, there is nothing to do if (Y >= IBounds.YSize ()) { return; } // We can not do any definite length checking because the string contains // meta chars ('~') to switch the attribute. Wait for that until we // translated it into the buffer. But if the string is empty, bail out here if (S.IsEmpty ()) { return; } // Set up starting attribute unsigned char Attr = atTextNormal; u16 AttrChar = Pal->BuildAttr (Palette, Attr, ' '); // Fill the buffer unsigned BufLen = 0; int CurX = X; int XEnd = IBounds.XSize (); int Len = S.Len (); const char* P = S.GetStr (); while (Len--) { if (*P == '~') { Attr = (Attr == atTextNormal) ? atTextHigh : atTextNormal; AttrChar = Pal->BuildAttr (Palette, Attr, ' '); } else { CurX++; if (CurX > XEnd || BufLen >= sizeof (Buf)) { // We are at the right border or have a buffer overflow - clip break; } Buf [BufLen++] = Pal->BuildAttr (AttrChar, *P); } P++; } // Now write the buffer if (IsFramed ()) { X++; Y++; } WriteBuf (X, Y, Buf, BufLen); } void Window::FCWrite (const String& S) // ## This function is a hack { String O (S.Len ()); int I; char C; unsigned char Attr = atTextNormal; // Lock output Lock (); // Examine given string I = 0; while (I < S.Len ()) { C = S [I++]; switch (C) { case '\x0D': case '\x0A': // Display collected buffer if (O.Len () > 0) { Write (CursorPos.X, CursorPos.Y, O, Attr); CursorPos.X += O.Len (); O.Clear (); } if (C == 0x0D) { // CR CursorPos.X = 0; } else if (C == 0x0A) { // LF if (++CursorPos.Y >= IBounds.YSize ()) { // Need scroll ScrollUp (); CursorPos.Y--; } } break; case '~': // Output string, switch attributes if (O.Len () > 0) { Write (CursorPos.X, CursorPos.Y, O, Attr); CursorPos.X += O.Len (); O.Clear (); } Attr = (Attr == atTextNormal) ? atTextHigh : atTextNormal; break; default: O += C; break; } } // Display collected buffer if (O.Len () > 0) { Write (CursorPos.X, CursorPos.Y, O, Attr); CursorPos.X += O.Len (); } // Unlock the window, allow screen output Unlock (); } void Window::ChangeAttr (int X, int Y, unsigned Count, unsigned Attr) // Change the attribute of the text starting at X, Y for Count chars { // Adjust for a frame if (IsFramed ()) { X++; Y++; } // Check for a wrong Y coord PRECONDITION (Y < OBounds.YSize ()); // Get pointer to first mem location u16* P = VirtualScreen + OBounds.XSize () * Y + X; // Don't wrap around the right border int Max = OBounds.XSize () - X; int C = (int (Count) > Max) ? Max : Count; // Cast to int if (C > 0) { // Get the attribute char u16 A = Pal->BuildAttr (Palette, Attr, '\0'); // Change the attribute Count = C; while (Count--) { *P = (*P & 0x00FF) | A; P++; } // Update screen if not locked Update (Rect (OBounds.A.X + X, OBounds.A.Y + Y, OBounds.A.X + X + C, OBounds.A.Y + Y + 1)); } } void Window::ScreenSizeChanged (const Rect& NewSize) // Called when the screen got another resolution. NewSize is the new // screen size. { // Lock the window system WinLock (); // Recenter if needed if (Options & cfCenterAll) { // Move the window Rect NewBounds (OBounds); NewBounds.Center (NewSize, Options); MoveAbs (NewBounds.A); // Set the cursor to the new position if the window is active SetCursor (); } // Check if the window is out of screen. If so, move it, so that the upper // left corner is still visible. Point MoveVec (0, 0); if (OBounds.A.X >= NewSize.B.X) { MoveVec.X = NewSize.B.X - OBounds.A.X - 1; } if (OBounds.A.Y >= NewSize.B.Y) { MoveVec.Y = NewSize.B.Y - OBounds.A.Y - 1; } if (MoveVec != Point (0, 0)) { // Move the window MoveRel (MoveVec); // Set the cursor to the new position if the window is active SetCursor (); } // Redraw the complete window in case of a mono/color change DrawFrame (); DrawInterior (); // Unlock the window system WinUnlock (); } void Window::Store (Stream& S) const // Store the window data into the given stream { // Set up a modified copy of the flags u16 SaveFlags = Flags & wfSaveFlags; if (SaveVisible ()) { // Save as visible SaveFlags |= wfVisible | wfSaveVisible; } // Store the current screen resolution. This value is used to resize/move // the window when loading S << Background->OuterBounds ().Size (); // Store instance data S << Number << SaveFlags << Options << LockCount << OBounds << IBounds << Header << Footer << (i16) Cursor << CursorPos << Palette << BGChar << BGAttr << u16 (VirtualScreenSize * sizeof (u16)); S.Write (VirtualScreen, VirtualScreenSize * sizeof (u16)); } void Window::Load (Stream& S) { i16 LoadCursor; // Load the screen resolution that was active, when the window was written // into the stream Point OldRes; S >> OldRes; // Load instance data S >> Number >> Flags >> Options >> LockCount >> OBounds >> IBounds >> Header >> Footer >> LoadCursor >> CursorPos >> Palette >> BGChar >> BGAttr >> VirtualScreenSize; Cursor = (CursorType) LoadCursor; // Compatibility fix: Calculate number of u16's from VirtualScreenSize VirtualScreenSize /= sizeof (u16); // Get memory for virtual screen VirtualScreen = new u16 [VirtualScreenSize]; // Load virtual screen S.Read (VirtualScreen, VirtualScreenSize * sizeof (u16)); // Remember the state of the wfActive and wfVisible bits in the flags, // then clear them. This means that all operations below are done with // an invisible window. u16 NewFlags = Flags & (wfVisible | wfActive); Flags &= ~(wfVisible | wfActive); // Lock the window system WinLock (); // Link into window list WNode.InsertBefore (&Background->WNode); // Allow the window to resize if needed MoveResizeAfterLoad (OldRes); // Now set the final window state, showing or activating the window if // needed SetState (NewFlags); // Unlock the window system WinUnlock (); } void Window::SetCursor () // If the window is active, set the screen (real) cursor to the position // and type of the window cursor { if (IsActive ()) { // Lock the window system WinLock (); // Set the real cursor to the window cursor position Point Pos = CursorPos; Absolute (Pos); TheScreen->SetCursorPos (Pos); // Switch the cursor according to the state switch (Cursor) { case csOff: // No cursor TheScreen->SetCursorOff (); break; case csOn: // Cursor on TheScreen->SetCursorOn (); break; case csFat: // Cursor fat TheScreen->SetCursorFat (); break; default: FAIL ("Window::SetCursor: Invalid cursortype"); break; } // Unlock the window system WinUnlock (); } } void Window::SetCursorPos (const Point& Pos) { // Remember cursor position CursorPos = Pos; // Lock the window system WinLock (); // If the window is active, use the new position if (IsActive ()) { Point NewPos = CursorPos; Absolute (NewPos); TheScreen->SetCursorPos (NewPos); } // Unlock the window system WinUnlock (); } void Window::SetCursorOff () { // Remember the new cursor form Cursor = csOff; // Lock the window system WinLock (); // If the window is active, use the new cursor if (IsActive ()) { TheScreen->SetCursorOff (); } // Unlock the window system WinUnlock (); } void Window::SetCursorOn () { // Remember the new cursor form Cursor = csOn; // Lock the window system WinLock (); // If the window is active, use the new cursor if (IsActive ()) { Point NewPos = CursorPos; Absolute (NewPos); TheScreen->SetCursorPos (NewPos); TheScreen->SetCursorOn (); } // Unlock the window system WinUnlock (); } void Window::SetCursorFat () { // Remember the new cursor form Cursor = csFat; // Lock the window system WinLock (); // If the window is active, use the new cursor if (IsActive ()) { Point NewPos = CursorPos; Absolute (NewPos); TheScreen->SetCursorPos (NewPos); TheScreen->SetCursorFat (); } // Unlock the window system WinUnlock (); } void Window::SetCursor (CursorType C) { switch (C) { case csOff: SetCursorOff (); break; case csOn: SetCursorOn (); break; case csFat: SetCursorFat (); break; } } estic-1.61.orig/spunk/window.h0100644000176100001440000005046607031424710015641 0ustar debacleusers/*****************************************************************************/ /* */ /* WINDOW.H */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _WINDOW_H #define _WINDOW_H #include "event.h" #include "listnode.h" #include "strmable.h" #include "stream.h" #include "rect.h" #include "str.h" #include "palette.h" #include "winflags.h" #include "winsize.h" /*****************************************************************************/ /* Locking */ /*****************************************************************************/ // Nested calling of the following functions from the same thread is explicitly // allowed! The following functions must _not_ block if the function is called // twice from one thread. // Anyway, the locking assumes, one window is handled by only one thread. If // you try to call window functions of one window by more than one thread, the // locking will fail. // Function vectors to lock/unlock the windows system extern void (*WinLock) (); extern void (*WinUnlock) (); /*****************************************************************************/ /* class Window */ /*****************************************************************************/ class Window : public Streamable { friend class ResEditApp; // Resource editor is a friend public: enum CursorType { csOff, csOn, csFat }; private: Rect DirtyRect; // Rectangle that is dirty protected: u16 Number; // window number u16 Flags; // Window state u16 Options; // grow options i16 LockCount; Rect OBounds; // Outer bounds of window Rect IBounds; // Inner bounds of window String Header; // Window header String Footer; // Window footer CursorType Cursor; Point CursorPos; // Position 0/0 based, inner window u16 Palette; // Number of palette used unsigned char BGChar; // Char used for background unsigned char BGAttr; // Number of attribute to use u16* VirtualScreen; // Pointer to virtual screen u16 VirtualScreenSize; // Size of this screen in bytes Window* LastActive; // Active window chain ListNode WNode; // List of all windows ListNode ANode; // List of active windows // --- "Raw" switching of the active window void RawActivate (); // Activate the window without manipulating the active window stack void RawDeactivate (); // Deactivate the window without manipulating the active window stack // --- Do something with the window contents unsigned char* GetFrame (); // Get a pointer to the frame char string according to the current // window state unsigned GetFrameAttr (); // Return the attribute for the frame according to the current // window state void SetCursor (); // If the window is active, set the screen (real) cursor to the position // and type of the window cursor virtual void DrawHeader (); // Draw the header line of the window frame. The function exits immidiately // if the window is not framed. virtual void DrawFooter (); // Draw the footer of the window frame. The function exits immidiately if // the window is not framed. // The footer is positioned at the lower right of the frame, there is // exactly one horizontal frame element to the right of the footer text. virtual void DrawFrame (); // Draw the window frame. This function is called if the state of the // window changes in a way that is shown in the frame. The function // exits immediately if the window has no frame. // Output void WriteChar (int X, int Y, u16 AttrChar); void WriteBuf (int X, int Y, u16* Buf, size_t Count); void CollectBuffer (const Rect& Bounds, u16* Buf); // Collect screen data into a buffer void UpdateScreen (const Rect& Bounds); // Update real screen from virtual screen void Update (const Rect& Bounds); // Update area or mark window as dirty if locked virtual void NewOptions (u16 NewOps); // Set new option flags virtual void MoveResizeAfterLoad (const Point& OldRes); // This function is called after a load when most of the window is // constructed. It is used to move the window to a new position if this is // needed. OldRes is the old screen resolution that was active, when the // window was stored. // The default is to recenter the window if the apropriate flags are set // and the screen resolution has changed. Window (); // "Do-nothing" constructor for use in derived classes Window (StreamableInit); // Build constructor public: Window (const Rect& Bounds, u16 aState = wfFramed, u16 aPalette = paGray, u16 Number = 0, int aLockCount = 0); // Create a new window virtual ~Window (); // Delete a window // Derived from class Streamable virtual void Store (Stream&) const; virtual void Load (Stream&); virtual u16 StreamableID () const; static Streamable* Build (); virtual void SetWindowNumber (u16 aNumber); // Set a new window number. If this makes the header line change, the // header is redrawn. u16 GetWindowNumber () const; // Return the window number const u16& GetWindowNumberRef () const; // Return a reference to the window number const Rect& OuterBounds () const; // Return the outer window rectangle including the frame const Rect& InnerBounds () const; // Return the inner window rectangle (without the frame) i16 MaxX () const; i16 MaxY () const; // Return the maximum allowed X/Y coordinate. Beware: This is one less // than the size of the inner window! unsigned IXSize (); unsigned IYSize (); // Return the size of the inner window unsigned OXSize (); unsigned OYSize (); // Return the size of the outer window virtual void Absolute (Point& P); // Make a window relative point absolute (relative to the screen). The // given coordinates are (0/0) based relativ to the inner window virtual void Relative (Point& P); // Make an absolute coordinate relative to the inner window // --- Handle frame and palette --- virtual void SetPalette (u16 NewPalette); // Set a new window palette. NewPalette is the palette index of the new // palette. The window is redrawn to show the new palette. virtual void SetHeader (const String& NewHeader); // Set a new window header. The window header is visible only if the // window has a frame. In this case, it is centered in the top part of // the frame. This function redraws the top part of the frame. virtual void SetFooter (const String& NewFooter); // Set a new window footer. The window footer is visible only if the // window has a frame. In this case, it is right justified in the bottom // part of the frame. This function redraws the bottom part of the frame. u16 GetPalette () const; // Return the current window palette const String& GetHeader () const; // Return the current window header string const String& GetFooter () const; // Return the current window footer string // --- Do something with the window contents virtual void ScrollUp (); // Scroll up the inner window by one line. The last line is cleared by // this function (BGAttr/BGChar) virtual void ScrollDown (); // Scroll down the inner window by one line. The first line is cleared by // this function (BGAttr/BGChar) virtual void Clear (); // Clear the inner window using the attribute BGAttr and the character // BGChar virtual void DrawInterior (); // Draw the interior of the window. You have to override this function // if your window contains something that has to be redrawn. The default // is to clear the inner window. // --- Moving & Resizing virtual unsigned MinXSize () const; // Return the minimum X size of the window. Override this to limit resizing. virtual unsigned MinYSize () const; // Return the minumim Y size of the window. Override this to limit resizing. virtual void Resize (const Rect& NewBounds); // Resize the window to the new bounds (this can also be used to move the // window but Move is faster if the window should not be resized). // This function does no checks! Call CanResize (NewBounds) if you don't // know if the new size is ok! virtual void MoveAbs (Point dP); // Move the window to an absolute position virtual void MoveRel (Point dP); // The window is moved by the given dX/dY. This function does no checks! // Call CanMove (dP) if you don't know if the new position is ok! virtual void PutOnTop (); // Put the given window on top of all other windows. virtual void PutBeneath (Window& W); // Put a given window beneath another window. This second window cannot be // the root window (the root window must remain the last window in the // window hierarchy) Window* UpperWindow (); // Return the window in front of the this-window. If there is no upper // window, return NULL. Window* LowerWindow (); // Return the window below the this-window. If there is no lower window, // return NULL. virtual void MoveResize (); // Allows interactive moving and resizing the window. This functions // calls ::MoveResize (this). // --- Set flag bits, take appropriate action virtual void Activate (); // Set the window active flag, redraw the window frame to show the new // state, put the window in front of all other windows, then show it if // it has been hidden. This function deactivates an eventually active // window. virtual void Deactivate (); // Deactivates the window. This includes redrawing the frame and // re-activating a previuos active window. virtual void Hide (); // Hide the window. The window is no longer visible after calling this // function but any window output is still allowed. virtual void Show (); // Show a previously hidden window. This does not put the window in front // of other windows, so the window may still be covered. virtual void StartResizing (); // Set the wfResizing flag and redraw the frame to show the new window // state virtual void EndResizing (); // Reset the wfResizing flag and redraw the frame to show the new window // state void SetSaveVisible (); // Set the "wfSaveVisible" flag. This causes future calls to Window::Store // to write out the Flags word with the wfVisible bit set. The default // is to clear this bit in the copy that goes to disk. void SetCanMove (); // Set the wfCanMove flag void SetCanResize (); // Set the wfCanResize flag void Lock (); // Lock the window. This causes screen changes to accumulate using the // wfDirty state and the DirtyRect rectangle. If the window is unlocked, // changes are written to the physical screen. Lock/Unlock may be nested. virtual void Unlock (); // Unlock the window. If there have been window changes while the window // was locked, the physical screen is updated in the area that contains // the changes. Lock/Unlock may be nested. // --- Check flag bits int IsFramed () const; // Return 1 if the window is framed, 0 otherwise int IsActive () const; // Return 1 if the window is active, 0 otherwise int IsVisible () const; // Return 1 if the window is visible, 0 otherwise int SaveVisible () const; // Return 1 if the wfSaveVisible flag is set, 0 otherwise int IsModal () const; // Return 1 if the wfModal flag is set, 0 otherwise. The wfModal flag // causes windows to ignore any reserved keys. int HasLRLink () const; // Return 1 if the wfLRLink flag is set, 0 otherwise. int IgnoreAccept () const; // Return 1 if the wfIgnoreAccept flag is set, 0 otherwise. int IsLocked () const; // Return 1 if the window output is locked, 0 otherwise. int IsDirty () const; // Return 1 if the window has changes that are not shown on the // physical screen, 0 otherwise. int IsResizing () const; // Return 1 if the wfResizing flag is set, 0 otherwise. int CanResize () const; // Return 1 if the wfCanResize flag is set, 0 otherwise. int CanMove () const; // Return 1 if the wfCanMove flag is set, 0 otherwise. // --- Get/Set the flags that describe the current window look u16 GetState (); // Return the state of the wfActive and wfVisible flags virtual void SetState (u16 NewFlags); // Set the state of the wfActive and wfVisible flags according to the // values contained in NewFlags. // --- Get/Set center options u16 GetOptions () const; void SetOption (u16 NewOptions); void ResetOption (u16 ResetOps); // --- Setting/getting cursor position and form const Point& GetCursorPos () const; void SetCursorPos (const Point& Pos); void SetCursorOff (); void SetCursorOn (); void SetCursorFat (); void SetCursor (CursorType C); CursorType GetCursor () const; // Write to the window (inner window, (0/0) based) virtual void Write (int X, int Y, const String& S, int Attr = atTextNormal); virtual void Write (int X, int Y, char C, int Attr = atTextNormal); virtual void FWrite (const String& S, int Attr = atTextNormal); virtual void CWrite (int X, int Y, const String& S); virtual void FCWrite (const String& S); virtual void ChangeAttr (int X, int Y, unsigned Count, unsigned Attr); // Change the attribute of the text starting at X, Y for Count chars // The following should be protected but there seems to be a bug in the // compiler - so leave it untouched! virtual void ScreenSizeChanged (const Rect& NewScreen); // Called when the screen got another resolution. NewScreen is the new // screen size. }; inline Window::Window () : Options (0), WNode (this), ANode (this) // "Do-nothing" constructor for use in derived classes { } inline Window::Window (StreamableInit) : Header (Empty), Footer (Empty), WNode (this), ANode (this) { } inline i16 Window::MaxX () const // Return the maximum allowed X coordinate. Beware: This is one less // than the size of the inner window! { return IBounds.XSize () - 1; } inline i16 Window::MaxY () const // Return the maximum allowed Y coordinate. Beware: This is one less // than the size of the inner window! { return IBounds.YSize () - 1; } inline unsigned Window::IXSize () // Return the size of the inner window { return IBounds.XSize (); } inline unsigned Window::IYSize () // Return the size of the inner window { return IBounds.YSize (); } inline unsigned Window::OXSize () // Return the size of the outer window { return OBounds.XSize (); } inline unsigned Window::OYSize () // Return the size of the outer window { return OBounds.YSize (); } inline void Window::SetSaveVisible () // Set the "wfSaveVisible" flag. This causes future calls to Window::Store // to write out the Flags word with the wfVisible bit set. The default // is to clear this bit in the copy that goes to disk. { Flags |= wfSaveVisible; } inline void Window::SetCanMove () // Set the wfCanMove flag { Flags |= wfCanMove; } inline void Window::SetCanResize () // Set the wfCanResize flag { Flags |= wfCanResize; } inline void Window::Lock () // Lock the window. This causes screen changes to accumulate using the // wfDirty state and the DirtyRect rectangle. If the window is unlocked, // changes are written to the physical screen. Lock/Unlock may be nested. { LockCount++; } inline int Window::IsFramed () const // Return 1 if the window is framed, 0 otherwise { return (Flags & wfFramed) != 0; } inline int Window::IsActive () const // Return 1 if the window is active, 0 otherwise { return (Flags & wfActive) != 0; } inline int Window::IsVisible () const // Return 1 if the window is visible, 0 otherwise { return (Flags & wfVisible) != 0; } inline int Window::SaveVisible () const // Return 1 if the wfSaveVisible flag is set, 0 otherwise { return (Flags & wfSaveVisible) != 0; } inline int Window::IsModal () const // Return 1 if the wfModal flag is set, 0 otherwise. The wfModal flag // causes windows to ignore any reserved keys. { return (Flags & wfModal) != 0; } inline int Window::HasLRLink () const // Return 1 if the wfLRLink flag is set, 0 otherwise. { return (Flags & wfLRLink) != 0; } inline int Window::IgnoreAccept () const // Return 1 if the wfIgnoreAccept flag is set, 0 otherwise. { return (Flags & wfIgnoreAccept) != 0; } inline int Window::IsLocked () const // Return 1 if the window output is locked, 0 otherwise. { return LockCount != 0; } inline int Window::IsDirty () const // Return 1 if the window has changes that are not reflected on the // physical screen, 0 otherwise. { return (Flags & wfDirty) != 0; } inline int Window::IsResizing () const // Return 1 if the wfResizing flag is set, 0 otherwise. { return (Flags & wfResizing) != 0; } inline int Window::CanResize () const // Return 1 if the wfCanResize flag is set, 0 otherwise. { return (Flags & wfCanResize) != 0; } inline int Window::CanMove () const // Return 1 if the wfCanMove flag is set, 0 otherwise. { return (Flags & wfCanMove) != 0; } inline u16 Window::GetState () // Return the state of the wfActive and wfVisible flags { return Flags & (wfActive | wfVisible); } inline u16 Window::GetOptions () const { return Options; } inline void Window::SetOption (u16 SetOps) { NewOptions ((u16) (Options | SetOps)); } inline void Window::ResetOption (u16 ResetOps) { NewOptions ((u16) (Options & ~ResetOps)); } inline const Point& Window::GetCursorPos () const { return CursorPos; } inline Window::CursorType Window::GetCursor () const { return Cursor; } inline u16 Window::GetWindowNumber () const { return Number; } inline const u16& Window::GetWindowNumberRef () const { return Number; } inline const Rect& Window::OuterBounds () const { return OBounds; } inline const Rect& Window::InnerBounds () const { return IBounds; } inline u16 Window::GetPalette () const { return Palette; } inline const String& Window::GetHeader () const { return Header; } inline const String& Window::GetFooter () const { return Footer; } inline void Window::MoveResize () // Allows interactive moving and resizing the window. This functions // calls ::MoveResize (this). { ::MoveResize (this); } /*****************************************************************************/ /* class RootWindow */ /*****************************************************************************/ class RootWindow: public Window, public EventHandler { friend class ResEditApp; // Resource editor is a friend protected: RootWindow (StreamableInit); // Build constructor public: RootWindow (); // Construct the root window // Derived from class Streamable virtual u16 StreamableID () const; static Streamable* Build (); Rect GetDesktop () const; // Get the absolute coords of the desktop area void RedrawScreen (); // Redraw the complete screen in case it's garbled void ChangeScreenSize (const Rect& NewSize); // Tell all windows about a changed screen size // The following should be protected but there seems to be a bug in the // compiler - so leave it untouched! virtual void ScreenSizeChanged (const Rect& NewScreen); // Called when the screen got another resolution. NewScreen is the new // screen size. This functions calls ScreenSizeChanged of all other // windows on the screen. Window* GetTopWindow (); // Return the uppermost window. If there are no windows, return NULL Window* GetTopVisibleWindow (); // Return the uppermost window that is visible. If there are no visible // windows, return NULL virtual void HandleEvent (Event& E); // Handle an incoming event. Default is to do nothing. }; // The background window extern RootWindow* Background; inline RootWindow::RootWindow (StreamableInit): Window (Empty) { } // End of WINDOW.H #endif estic-1.61.orig/spunk/winflags.h0100644000176100001440000000414307031424710016133 0ustar debacleusers/*****************************************************************************/ /* */ /* WINFLAGS.H */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _WINFLAGS_H #define _WINFLAGS_H #include "machine.h" // Flags const u16 wfFramed = 0x0001; // Window is framed const u16 wfActive = 0x0002; // Window is active const u16 wfVisible = 0x0004; // Window is visible const u16 wfSaveVisible = 0x0008; // Save visible flag const u16 wfModal = 0x0010; // Window ignores reserved keys const u16 wfIgnoreAccept = 0x0020; // Windows ignores accept key const u16 wfDirty = 0x0040; // Write occured since last lock const u16 wfLRLink = 0x0080; // Left/right cursor movement const u16 wfResizing = 0x0100; // Resizing in progress const u16 wfCanMove = 0x0200; // User is allowed to move const u16 wfCanResize = 0x0400; // User is allowed to resize // Mask for flags that are written out const u16 wfSaveFlags = wfFramed | wfSaveVisible | wfModal | wfIgnoreAccept | wfLRLink | wfCanMove | wfCanResize; // End of WINFLAGS.H #endif estic-1.61.orig/spunk/winmgr.cc0100644000176100001440000003643207031424710015770 0ustar debacleusers/*****************************************************************************/ /* */ /* WINMGR.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file contains some unnecessary global overrides (::) to work around // a gcc bug #include "msgid.h" #include "streamid.h" #include "eventid.h" #include "listbox.h" #include "stdmsg.h" #include "menue.h" #include "menuedit.h" #include "filesel.h" #include "progutil.h" #include "settings.h" #include "winmgr.h" // Register the classes LINK (WinColl, ID_WinColl); LINK (WindowManager, ID_WindowManager); /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msTooManyWindows = MSGBASE_WINMGR + 0; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Global accessible window manager instance WindowManager* WinMgr; /*****************************************************************************/ /* Explicit template instantiation */ /*****************************************************************************/ #ifdef EXPLICIT_TEMPLATES template class Collection; template class SortedCollection; template class ListBox; #endif /*****************************************************************************/ /* class WinColl */ /*****************************************************************************/ WinColl::WinColl (unsigned MaxWindows): SortedCollection (MaxWindows, 0, 1) { } WinColl::WinColl (StreamableInit): SortedCollection (Empty) { } u16 WinColl::StreamableID () const // Return the objects stream ID { return ID_WinColl; } Streamable* WinColl::Build () // Return an empty window { return new WinColl (Empty); } int WinColl::Compare (const u16* Key1, const u16* Key2) { if (*Key1 < *Key2) { return -1; } else if (*Key1 > *Key2) { return 1; } else { return 0; } } const u16* WinColl::KeyOf (const ItemWindow* Item) { return &Item->GetWindowNumberRef (); } int WinColl::FindWindow (u16 Num) // Return the index of the window with number Num { int Index; return Search (&Num, Index) ? Index : -1; } int WinColl::FindWindow (const Window* Win) // Return the index of the window Win { int Index; return Search (&Win->GetWindowNumberRef (), Index) ? Index : -1; } /*****************************************************************************/ /* class WinListBox */ /*****************************************************************************/ class WinListBox: public ListBox { protected: virtual void Print (int Index, int X, int Y, u16 Attr); // Display one of the listbox entries public: WinListBox (i16 aID, const Point& aSize, WindowItem* NextItem = NULL); }; WinListBox::WinListBox (i16 aID, const Point& aSize, WindowItem* NextItem): ListBox ("", aID, aSize, atEditNormal, atEditBar, atEditHigh, NextItem) { } void WinListBox::Print (int Index, int X, int Y, u16 Attr) { // Get the entry ItemWindow* Win = Coll->At (Index); // Get the filename and pad it String Line = FormatStr (" %2d %s", Win->GetWindowNumber (), Win->GetHeader ().GetStr ()); Line.Pad (String::Right, Size.X - 1); Line += ' '; // Print the name Owner->Write (X, Y, Line, Attr); } /*****************************************************************************/ /* class WinMgr */ /*****************************************************************************/ WindowManager::WindowManager (u16 aMaxWindows): Coll (new WinColl (aMaxWindows)), MaxWindows (aMaxWindows) // Construct a window manager { } WindowManager::WindowManager (StreamableInit): Coll (NULL) // Build constructor { } WindowManager::~WindowManager () // Delete the window manager instance { // Delete the window collection delete Coll; } void WindowManager::Load (Stream& S) // Load the object from a stream { // Read the maximum window count from the stream S >> MaxWindows ; // Create a new window collection Coll = new WinColl (MaxWindows); // Read the count of windows from the stream u16 Count; S >> Count; // Read the windows and insert them into the collection while (Count--) { AddWindow ((ItemWindow*) S.Get ()); } } void WindowManager::Store (Stream& S) const // Store the object into a stream { // Write the maximum window count to the stream S << MaxWindows; // Write the window count into the stream u16 Count = WindowCount (); S << Count; // Write all windows for (unsigned I = 0; I < Count; I++) { S.Put (Coll->At (I)); } } u16 WindowManager::StreamableID () const // Return the objects stream ID { return ID_WindowManager; } Streamable* WindowManager::Build () // Return an empty WindowManager object { return new WindowManager (Empty); } unsigned WindowManager::GetFreeWindowNumber () // Get the next free window number. If 9 windows are already open, print // an error message and return 0 { // Search for an empty slot for (unsigned I = 1; I <= MaxWindows; I++) { if (Coll->FindWindow (I) < 0) { return I; } } // No empty slot, there are already 9 windows ErrorMsg (::LoadMsg (msTooManyWindows)); return 0; } int WindowManager::CloseWindow (unsigned Index) // Close the window with the given Index. Return true if the window has been // closed, return false if the window refuses to get closed { // Parametercheck PRECONDITION (Index < (unsigned) Coll->GetCount ()); // Ask the window if it can be closed ItemWindow* Win = Coll->At (Index); if (Win->CanClose () == 0) { // Nope, window said no return 0; } // Unregister the window key UnregisterKey (GetWindowKey (Win)); // Delete the window Coll->AtDelete (Index); // If the count of windows is now one less than the maximum, post an // apropriate event if (Coll->GetCount () == MaxWindows - 1) { PostEvent (new Event (evWinMgrLastClose)); } // If the window count is zero, post an apropriate event if (Coll->GetCount () == 0) { PostEvent (new Event (evWinMgrNoWindows)); } // Success return 1; } Key WindowManager::GetWindowKey (const ItemWindow* W) // Return the hotkey for the given window { static const Key KeyTable [9] = { kbMeta1, kbMeta2, kbMeta3, kbMeta4, kbMeta5, kbMeta6, kbMeta7, kbMeta8, kbMeta9 }; // Get the window number unsigned Num = W->GetWindowNumber (); // Return the key if (Num >= 1 && Num <= 9) { return KeyTable [Num-1]; } else { return kbNoKey; } } void WindowManager::DeleteWindow (u16 Num) // Delete a window { // Try to find the window int I = Coll->FindWindow (Num); CHECK (I >= 0); // Close the window CloseWindow (I); } ItemWindow* WindowManager::AddWindow (ItemWindow* Win) // Add a window to the list. The window gets assigned an unused number. // If there are too many windows open, NULL is returned but the window // is _not_ deleted. If all is ok, the pointer to the window just // inserted is returned. { // Try to honor an already existing window number if possible u16 Num = Win->GetWindowNumber (); if (Num != 0) { // The window already has a number. If this number is unused, don't // change it, otherwise assign a new one if (Coll->FindWindow (Num) != -1) { // Number is already in use Num = 0; } } // If the window does not have a number or if the number is already in // use, assign a new one if (Num == 0) { // Get a free window number Num = GetFreeWindowNumber (); if (Num == 0) { // Too many windows already return NULL; } } // Assign the window number Win->SetWindowNumber (Num); // Insert the window Coll->Insert (Win); // Show the window Win->Show (); // If the window count is now 1, post an appropriate event if (Coll->GetCount () == 1) { PostEvent (new Event (evWinMgrFirstOpen)); } // If the window count has reached the maximum, post that if (Coll->GetCount () == MaxWindows) { PostEvent (new Event (evWinMgrMaxWindows)); } // Register the window key RegisterKey (GetWindowKey (Win)); // Return the created window return Win; } ItemWindow* WindowManager::ChooseWindow () // Choose a new active window { // Name of the position setting static const String StgName = "WindowManager.ChooseWindow.Position"; // Load the window Menue* Win = (Menue*) ::LoadResource ("WINMGR.ChooseWindow"); // If we have a stored window position, use it (moving is cheap now since // the window is invisible) Point Pos = StgGetPoint (StgName, Win->OuterBounds ().A); Win->MoveAbs (Pos); // Create a listbox inside the window Point Size; Size.X = Win->IXSize (); Size.Y = Win->IYSize (); WinListBox* Box = new WinListBox (1, Size); Box->SetColl (Coll); Win->AddItem (Box); Box->Select (); Box->Draw (); Win->Activate (); // New status line PushStatusLine (siAbort | siSelectChooseKeys); // Allow choosing an entry int Done = 0; ItemWindow* HW = NULL; while (!Done) { // Get keyboard input Key K = ::KbdGet (); // Let the box look for a useful key Box->HandleKey (K); // Look what's left int Selected; switch (K) { case vkResize: Win->MoveResize (); break; case kbEnter: Selected = Box->GetSelected (); if (Selected != -1) { HW = Coll->At (Selected); Done = 1; } break; case vkAbort: case vkClose: Done = 1; break; } } // Restore the status line PopStatusLine (); // Set a new collection for the listbox (otherwise the box would try to // delete the collection) Box->SetColl (NULL); // Store the current window position StgPutPoint (Win->OuterBounds ().A, StgName); // Delete the window delete Win; // Return the selected window return HW; } void WindowManager::Browse (ItemWindow* W) // Allow browsing the windows { // Allow browsing the given window while (W) { // browse... Key K = W->Browse (); // Check the abort key int I; switch (K) { case kbMeta1: W = FindWindow (1); break; case kbMeta2: W = FindWindow (2); break; case kbMeta3: W = FindWindow (3); break; case kbMeta4: W = FindWindow (4); break; case kbMeta5: W = FindWindow (5); break; case kbMeta6: W = FindWindow (6); break; case kbMeta7: W = FindWindow (7); break; case kbMeta8: W = FindWindow (8); break; case kbMeta9: W = FindWindow (9); break; case vkClose: I = Coll->FindWindow (W); if (CloseWindow (I)) { W = WinMgr->GetTopWindow (); } break; case vkAbort: W = NULL; break; default: // Key is handled by the main menue, quit browse func ::KbdPut (K); W = NULL; break; } } } ItemWindow* WindowManager::FindWindow (unsigned WindowNum) // Find a window by number { int I = Coll->FindWindow (WindowNum); return I >= 0 ? Coll->At (I) : 0; } ItemWindow* WindowManager::FindWindowWithKey (Key WindowKey) // Find a window by hotkey { // Cannot search for a non existing key PRECONDITION (WindowKey != kbNoKey); // Searching by keys is not supported by Coll, so use a linear search here for (int I = 0; I < Coll->GetCount (); I++) { ItemWindow* Win = Coll->At (I); if (WindowKey == GetWindowKey (Win)) { // Found return Win; } } // Not found return NULL; } void WindowManager::CloseAll () // Close all windows { unsigned I = Coll->GetCount (); while (I--) { CloseWindow (I); } } void WindowManager::VerticalTile (Rect Bounds, unsigned Start, unsigned End) // Tile the windows with indices Start to end vertically in the given // rectangle Bounds { // Calculate the window count unsigned Count = End - Start + 1; // Calculate the height of one window unsigned RemainingHeight = Bounds.YSize (); // Get the rectangle for the first window Rect WinBounds = Bounds; WinBounds.A.Y = 1; // Loop over all windows but the last for (unsigned I = Start; I < End; I++) { // Recalculate the height unsigned Height = RemainingHeight / Count; RemainingHeight -= Height; Count--; // Resize the rectangle WinBounds.B.Y = WinBounds.A.Y + Height; // Resize the window, the move the rectangle Coll->At (I)->Resize (WinBounds); // Set the next rectangle start point WinBounds.A.Y = WinBounds.B.Y; } // When drawing the last window, adjust for the accumulated error WinBounds.B.Y = Bounds.B.Y; Coll->At (End)->Resize (WinBounds); } void WindowManager::Tile () // Tile all windows on the screen { // Get the window count unsigned WindowCount = Coll->GetCount (); // Nothing to do if we have no windows if (WindowCount == 0) { return; } // Get the available background area Rect Screen = Background->OuterBounds (); Screen.Grow (0, -1); // Set up for the window rows if (WindowCount <= 3) { // This one is easy... VerticalTile (Screen, 0, WindowCount-1); } else if (WindowCount <= 8) { // Two rows of windows Rect Bounds = Screen; Bounds.B.X /= 2; unsigned FirstRowCount = WindowCount / 2; VerticalTile (Bounds, 0, FirstRowCount-1); Bounds.A.X = Bounds.B.X; Bounds.B.X = Screen.B.X; VerticalTile (Bounds, FirstRowCount, WindowCount-1); } else { // Three rows Rect Bounds = Screen; unsigned Width = Bounds.XSize () / 3; Bounds.B.X = Width; unsigned FirstRowCount = WindowCount / 3; VerticalTile (Bounds, 0, FirstRowCount-1); Bounds.Move (Width, 0); VerticalTile (Bounds, FirstRowCount, 2*FirstRowCount-1); Bounds.Move (Width, 0); Bounds.B.X = Screen.B.X; // Correct the errors VerticalTile (Bounds, 2*FirstRowCount, WindowCount-1); } } void WindowManager::Cascade () // Build a window cascade on the screen { // Get the desktop background Rect Bounds = Background->GetDesktop (); // Now loop over all windows for (int I = 0; I < Coll->GetCount (); I++) { ItemWindow* Win = Coll->At (I); Win->Resize (Bounds); Win->PutOnTop (); Bounds.A.X++; Bounds.A.Y++; } } ItemWindow* WindowManager::GetTopWindow () // Return the uppermost ItemWindow or NULL (if there are no windows) { // Return the topmost window Window* Win = Background->GetTopWindow (); // Now loop through the windows list and check if the given window is // in the list while (Win != NULL && Coll->FindWindow (Win) == -1) { // Get the next lower window Win = Win->LowerWindow (); } // Return the result return (ItemWindow*) Win; } int WindowManager::CanClose () // Return true if all windows answer yes to CanClose, false otherwise { for (int I = 0; I < Coll->GetCount (); I++) { if (Coll->At (I)->CanClose () == 0) { return 0; } } return 1; } estic-1.61.orig/spunk/winmgr.h0100644000176100001440000001056607031424710015632 0ustar debacleusers/*****************************************************************************/ /* */ /* WINMGR.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _WINMGR_H #define _WINMGR_H #include "keydef.h" #include "strmable.h" #include "coll.h" #include "itemwin.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ extern class WindowManager* WinMgr; /*****************************************************************************/ /* class WinColl */ /*****************************************************************************/ class WinColl: public SortedCollection { protected: virtual int Compare (const u16* Key1, const u16* Key2); virtual const u16* KeyOf (const ItemWindow* Item); public: WinColl (unsigned MaxWindows); // Construct a WinColl WinColl (StreamableInit); // Build constructor virtual u16 StreamableID () const; // Return the objects stream ID static Streamable* Build (); // Return an empty window int FindWindow (u16 Num); // Return the index of the window with number Num int FindWindow (const Window* Win); // Return the index of the window Win }; /*****************************************************************************/ /* class WindowManager */ /*****************************************************************************/ class WindowManager: public Streamable { protected: WinColl* Coll; u16 MaxWindows; void VerticalTile (Rect Bounds, unsigned Start, unsigned End); // Tile the windows with indices Start to end vertically in the given // rectangle Bounds int CloseWindow (unsigned Index); // Close the window with the given Index. Return true if the window has been // closed, return false if the window refuses to get closed Key GetWindowKey (const ItemWindow* W); // Return the hotkey for the given window public: WindowManager (u16 aMaxWindows = 9); // Construct a window manager WindowManager (StreamableInit); // Build constructor ~WindowManager (); // Delete the window manager instance virtual void Load (Stream& S); // Load the object from a stream virtual void Store (Stream& S) const; // Store the object into a stream virtual u16 StreamableID () const; // Return the objects stream ID static Streamable* Build (); // Return an empty WindowManager object unsigned GetFreeWindowNumber (); // Get the next free window number. If 9 windows are already open, print // an error message and return 0 void DeleteWindow (u16 Num); // Delete a window void DeleteWindow (ItemWindow* Win); // Delete a window ItemWindow* AddWindow (ItemWindow* Win); // Add a window to the list. The window gets assigned an unused number. // If there are too many windows open, NULL is returned but the window // is _not_ deleted. If all is ok, the pointer to the window just // inserted is returned. ItemWindow* FindWindow (unsigned WindowNum); // Find a window by number ItemWindow* FindWindowWithKey (Key WindowKey); // Find a window by hotkey ItemWindow* ChooseWindow (); // Choose a new active window void Browse (ItemWindow* W); // Allow browsing the windows void Tile (); // Tile all windows on the screen void Cascade (); // Build a window cascade on the screen void CloseAll (); // Close all windows unsigned WindowCount () const; // Return the count of windows ItemWindow* GetTopWindow (); // Return the uppermost window or NULL (if there are no windows) int CanClose (); // Return true if all windows answer yes to CanClose, false otherwise }; inline void WindowManager::DeleteWindow (ItemWindow* Win) // Delete a window { DeleteWindow (Win->GetWindowNumber ()); } inline unsigned WindowManager::WindowCount () const // Return the count of windows { return Coll->GetCount (); } // End of WINMGR.H #endif estic-1.61.orig/spunk/winsize.cc0100644000176100001440000001031307031424710016143 0ustar debacleusers/*****************************************************************************/ /* */ /* WINSIZE.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "msgid.h" #include "window.h" #include "progutil.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ const u16 msMove = MSGBASE_WINSIZE + 0; const u16 msResize = MSGBASE_WINSIZE + 1; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void MoveResize (class Window* Win) // Allow moving and resizing a window { // If moving/resizing is not allowed, return now if (Win->CanMove () == 0 && Win->CanResize () == 0) { return; } // Remember the current cursor and switch off the cursor Window::CursorType CT = Win->GetCursor (); Win->SetCursorOff (); // Tell the window what we are doing Win->StartResizing (); // New status line u32 StatusFlags = siAbort | siEnter; if (Win->CanMove ()) { StatusFlags |= siMoveKeys; } if (Win->CanResize ()) { StatusFlags |= siResizeKeys; } if (HelpAvail ()) { StatusFlags |= siHelp; } PushStatusLine (StatusFlags); // Calculate the desktop size Rect Desktop = Background->GetDesktop (); // Remember the window shape Rect OldBounds = Win->OuterBounds (); Rect NewBounds; // Now let's size/move... int Done = 0; while (!Done) { switch (KbdGet ()) { case vkHelp: // CallHelp ("MoveResize.Help"); break; case vkAbort: // Abort the operation. If the window size has been changed, // use Resize to restore the old size. Otherwise just use Move. // This prevents the text in simple text windows to vanish // when aborting a move/resize operation. if (int (Win->OXSize ()) != int (OldBounds.XSize ()) || int (Win->OYSize ()) != int (OldBounds.YSize ())) { // Size has changed, resize Win->Resize (OldBounds); } else { // Size hasn't changed, move the window Win->MoveAbs (OldBounds.A); } Done = 1; break; case vkAccept: case kbEnter: Done = 1; break; case vkUp: if (Win->CanMove ()) { NewBounds = Win->OuterBounds (); if (NewBounds.A.Y > Desktop.A.Y) { Win->MoveRel (Point (0, -1)); } } break; case vkDown: if (Win->CanMove ()) { NewBounds = Win->OuterBounds (); if (NewBounds.B.Y < Desktop.B.Y) { Win->MoveRel (Point (0, 1)); } } break; case vkLeft: if (Win->CanMove ()) { NewBounds = Win->OuterBounds (); if (NewBounds.A.X > Desktop.A.X) { Win->MoveRel (Point (-1, 0)); } } break; case vkRight: if (Win->CanMove ()) { NewBounds = Win->OuterBounds (); if (NewBounds.B.X < Desktop.B.X) { Win->MoveRel (Point (1, 0)); } } break; case vkCtrlUp: if (Win->CanResize ()) { if (Win->OYSize () > Win->MinYSize ()) { NewBounds = Win->OuterBounds (); NewBounds.B.Y--; Win->Resize (NewBounds); } } break; case vkCtrlLeft: if (Win->CanResize ()) { if (Win->OXSize () > Win->MinXSize ()) { NewBounds = Win->OuterBounds (); NewBounds.B.X--; Win->Resize (NewBounds); } } break; case vkCtrlDown: if (Win->CanResize ()) { NewBounds = Win->OuterBounds (); if (NewBounds.B.Y < Desktop.B.Y) { NewBounds.B.Y++; Win->Resize (NewBounds); } } break; case vkCtrlRight: if (Win->CanResize ()) { NewBounds = Win->OuterBounds (); if (NewBounds.B.X < Desktop.B.X) { NewBounds.B.X++; Win->Resize (NewBounds); } } break; } } // Restore the status line PopStatusLine (); // Stop the resizing Win->EndResizing (); // Set the old cursor type Win->SetCursor (CT); } estic-1.61.orig/spunk/winsize.h0100644000176100001440000000234307031424710016011 0ustar debacleusers/*****************************************************************************/ /* */ /* WINSIZE.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef __WINSIZE_H #define __WINSIZE_H /*****************************************************************************/ /* Code */ /*****************************************************************************/ // Forward class Window; void MoveResize (class Window* Win); // Allow moving and resizing a window // End of WINSIZE.H #endif estic-1.61.orig/spunk/bsdsrc/0040755000176100001440000000000007061535303015435 5ustar debacleusersestic-1.61.orig/spunk/bsdsrc/bsdterm.txt0100644000176100001440000000776107031424711017643 0ustar debacleusersFrom ibb.schwaben.com!wuschel.ibb.schwaben.com!seicom.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!news.sprintlink.net!in2.uu.net!news1.digital.com!nntp-hub2.barrnet.net!nntp-hub.barrnet.net!inet-nntp-gw-1.us.oracle.com!news.caldera.com!park.uvsc.edu!usenet Tue Oct 3 21:28:59 1995 Path: ibb.schwaben.com!wuschel.ibb.schwaben.com!seicom.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!news.sprintlink.net!in2.uu.net!news1.digital.com!nntp-hub2.barrnet.net!nntp-hub.barrnet.net!inet-nntp-gw-1.us.oracle.com!news.caldera.com!park.uvsc.edu!usenet From: Terry Lambert Newsgroups: comp.unix.bsd.freebsd.misc Subject: Re: Q: Writing to lower right of console Date: 2 Oct 1995 19:41:12 GMT Organization: Utah Valley State College, Orem, Utah Lines: 73 Message-ID: <44pf8o$ap@park.uvsc.edu> References: NNTP-Posting-Host: hecate.artisoft.com uz@wuschel.ibb.schwaben.com (Ullrich von Bassewitz) wrote: ] ] I'm trying to port a program from linux to freebsd. Until now there is only ] one problem: ] ] If I write to the last char of the screen (the char in the lower right ] corner), a scroll happens and my last line goes one line up, the first ] line vanishes. ] ] My program is screen oriented, it has a menu line as the first and a status ] line as the last line of the screen. You can imagine, what happens if the ] screen scrolls one line up when writing the status line... ] ] I know, that this is not really a freebsd problem, many terminals may have ] this too (the Linux console and xterm windows under X don't have it). ] With a special terminal, I can tell people, that my program will ] not support this terminal - but telling people that the console is not ] suppported would be a very unpopular approach :-) To support the terminals that do this: 1) look for the "xn" flag in the termcap entry using the tgetflag() routine. 2a) If the flag is set, use the current code. The "xnwrap" flag means that the cursor wraps BEFORE character 81 instead of AFTER character 80. This is also called "delayed wrap". 2b) If the flag is not set, then you will need to do the following to write the last character position (SCO Xenix and all Televideo sequence terminals -- like the Wyse-50, the most popular one of all time -- terminals do not have the xn flag set); i) Rememeber the second to last character. ii) write the last character in the second to last character position. iiia) use "insert character mode" to insert the second to last character in the correct position. This will force the last character to the right, and put it into the correct position as well. iiib) if the terminal does not support "insert character mode", but supports "inseert character" as an operation, then insert a character before the second to last character. This will force the correct character into the last postion. Then write the second to last character. iiic) if the terminal does not support either "insert character mode" or "insert character", then use "insert line" instead. iiid) if the terminal does not support any of "insert character mode", "insert character", or "insert line", then use a scroll region to implement insert line. iiie) if the terminal does not support any of "insert character mode", "insert character". "insert line", or scroll regions, then omit drawing the last character position entirely. Note that curses will implement these workarounds for you automatically: you should be using curses (I may be mistaken about curses knowing about using a scoll region to do an insert line; I seem to rememebr vi being stupid about this on real VT100's). All of the above are instances of a well known programming technique, the techinical name of which is "brute force". 8-). Terry Lambert terry@cs.weber.edu --- Any opinions in this posting are my own and not those of my present or previous employers. estic-1.61.orig/spunk/bsdsrc/kbd.cc0100644000176100001440000004642607031424711016512 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include #include #include #include #ifdef FREEBSD # include #endif #include "../machine.h" #include "../msgid.h" #include "../object.h" #include "../stack.h" #include "../charset.h" #include "../environ.h" #include "../keymap.h" #include "../program.h" #include "../kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // An instance of class KeyMapper to map char sequences to keys static KeyMapper Mapper; // A charset containing the available extended keys static CharSet AvailExtKeys; // An array for mapping extended to virtual keys const VirtualMapSize = 50; struct { Key EK; Key VK; } VirtualMap [VirtualMapSize]; static unsigned VirtualMapCount = 0; // Terminal settings at startup static termios StartupSettings; // Translation table for the ISO8859-1 charset to the IBM codepage 437 unsigned char TT_ISO_8859_1 [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 8 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 9 32,173,155,156, 32,157, 32, 32, 32, 32,166,174,170, 32, 32, 32, // A 248,241,253, 32, 32,230, 32,249, 32, 32,167,175,172, 32, 32,168, // B 32, 32, 32, 32,142,143,146,128, 32,144, 32, 32, 32, 32, 32, 32, // C 32,165, 32, 32, 32, 32,153, 32, 32, 32, 32, 32,154, 32, 32,225, // D 133,160,131, 32,132,134,145,135,138,130,136,137,141,161,140,139, // E 32,164,149,162,147, 32,148,246, 32,151,163, 32,129, 32,176,152 // F }; unsigned char TT_NOP [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int KbdIsConsole () // Return true if this is a console screen. { #ifdef FREEBSD // This is the console if we can request the state of the keyboard leds int Dummy; return ioctl (0, KDGETLED, &Dummy) == 0; #else return 0; #endif } static int KbdCharAvail () // Use select() to check for characters { // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // File descriptor is 0 (stdin) fd_set Desc; FD_ZERO (&Desc); FD_SET (0, &Desc); // Check input status return select (1, &Desc, NULL, NULL, &Timeout); } static void KbdInit () // Remember the current keyboard settings, then switch to raw mode { // Get current settings tcgetattr (0, &StartupSettings); // switch to raw mode termios Settings = StartupSettings; Settings.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IXANY | IXON | IXOFF | INPCK | ISTRIP); Settings.c_iflag |= (BRKINT | IGNPAR); Settings.c_oflag &= ~OPOST; Settings.c_lflag &= ~(ECHONL | NOFLSH | ICANON | ISIG | ECHO); Settings.c_cflag |= CREAD; Settings.c_cc[VTIME] = 1; // wait 100 ms for keys Settings.c_cc[VMIN] = 0; // return if timeout or keys available tcsetattr (0, TCSADRAIN, &Settings); } static void KbdExit () // Reset the keyboard to the startup state { // Reset keyboard settings tcsetattr (0, TCSADRAIN, &StartupSettings); } static char* KbdGetCap (const char* Cap) // Get a capability from the termcap file { static char CapBuf [128]; char* CapPtr = CapBuf; return tgetstr (Cap, &CapPtr); } static void KbdAddToMap (const char* S, Key K) // Add the given string to the mapper. If K is an extended key, add it to // the map of available extended keys. { Mapper.Add (S, K); if (S && IsExtendedKey (K)) { AvailExtKeys += (K & 0xFF); } } static void KbdAddCapToMap (const char* Cap, Key K) // Search the termcap entry for the capability Cap and add it to the Mapper // using the key K. { KbdAddToMap (KbdGetCap (Cap), K); } static int KbdHasKey (Key K) // Return true if the given extended(!) key is available on the keyboard { return AvailExtKeys [K & 0xFF] != 0; } static void KbdAddVMap (Key VK, Key EK) // Add the mapping to the virtual key map { // Check for overflow if (VirtualMapCount >= VirtualMapSize) { // Overflow! FAIL ("KbdAddVirtualMap: Buffer overflow!"); } // Add the mapping VirtualMap [VirtualMapCount].EK = EK; VirtualMap [VirtualMapCount].VK = VK; VirtualMapCount++; } static void KbdAddVMap (Key VK, Key MainKey, Key AltKey) // If MainKey is available on the keyboard, add a mapping MainKey --> VK. In // any case, add a mapping AltKey --> VK. Because the latter will be added // later, a search for a virtual key first finds MainKey as the equivalent // extended key. If there is no mapping for MainKey, AltKey is found. { // Conditionally add VK --> MainKey if (KbdHasKey (MainKey)) { // Key exists, add a mapping KbdAddVMap (VK, MainKey); } // Always add VK --> AltKey KbdAddVMap (VK, AltKey); } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Key Keyboard::RawKey () { // Not used return (Key) kbNoKey; } Keyboard::Keyboard (): Console (0), // Don't use special console code for now TransTable (new unsigned char [256]) { // Switch the keyboard into raw mode KbdInit (); // Check out the LC_CTYPE environment variable and assign the correct // translation table. There are only two possibilities until now, so // don't bother. switch (GetEnvVal ("LC_CTYPE", String ("0^NONE|1^ISO_8859_1|"))) { case 1: // ISO 8859-1 memcpy (TransTable, TT_ISO_8859_1, 256); break; default: // use a 1:1 mapping memcpy (TransTable, TT_NOP, 256); } // The termcap entry has been read before. Read in some key translations // and add them to the mapper // Function keys KbdAddCapToMap ("k1", kbF1); KbdAddCapToMap ("k2", kbF2); KbdAddCapToMap ("k3", kbF3); KbdAddCapToMap ("k4", kbF4); KbdAddCapToMap ("k5", kbF5); KbdAddCapToMap ("k6", kbF6); KbdAddCapToMap ("k7", kbF7); KbdAddCapToMap ("k8", kbF8); KbdAddCapToMap ("k9", kbF9); KbdAddCapToMap ("k0", kbF10); // Cursor keys needed KbdAddCapToMap ("kl", kbLeft); KbdAddCapToMap ("kr", kbRight); KbdAddCapToMap ("kd", kbDown); KbdAddCapToMap ("ku", kbUp); // Page up/down, home, end etc. KbdAddCapToMap ("kN", kbPgDn); KbdAddCapToMap ("kP", kbPgUp); KbdAddCapToMap ("kh", kbHome); KbdAddCapToMap ("kH", kbEnd); KbdAddCapToMap ("kD", kbDel); KbdAddCapToMap ("kI", kbIns); // Add the meta keys and other sequences to the mapper KbdAddToMap ("\033a", kbMetaA); KbdAddToMap ("\033b", kbMetaB); KbdAddToMap ("\033c", kbMetaC); KbdAddToMap ("\033d", kbMetaD); KbdAddToMap ("\033e", kbMetaE); KbdAddToMap ("\033f", kbMetaF); KbdAddToMap ("\033g", kbMetaG); KbdAddToMap ("\033h", kbMetaH); KbdAddToMap ("\033i", kbMetaI); KbdAddToMap ("\033j", kbMetaJ); KbdAddToMap ("\033k", kbMetaK); KbdAddToMap ("\033l", kbMetaL); KbdAddToMap ("\033m", kbMetaM); KbdAddToMap ("\033n", kbMetaN); KbdAddToMap ("\033o", kbMetaO); KbdAddToMap ("\033p", kbMetaP); KbdAddToMap ("\033q", kbMetaQ); KbdAddToMap ("\033r", kbMetaR); KbdAddToMap ("\033s", kbMetaS); KbdAddToMap ("\033t", kbMetaT); KbdAddToMap ("\033u", kbMetaU); KbdAddToMap ("\033v", kbMetaV); KbdAddToMap ("\033w", kbMetaW); KbdAddToMap ("\033x", kbMetaX); KbdAddToMap ("\033y", kbMetaY); KbdAddToMap ("\033z", kbMetaZ); KbdAddToMap ("\033""0", kbMeta0); KbdAddToMap ("\033""1", kbMeta1); KbdAddToMap ("\033""2", kbMeta2); KbdAddToMap ("\033""3", kbMeta3); KbdAddToMap ("\033""4", kbMeta4); KbdAddToMap ("\033""5", kbMeta5); KbdAddToMap ("\033""6", kbMeta6); KbdAddToMap ("\033""7", kbMeta7); KbdAddToMap ("\033""8", kbMeta8); KbdAddToMap ("\033""9", kbMeta9); KbdAddToMap ("\033\x01", kbEscCtrlA); KbdAddToMap ("\033\x02", kbEscCtrlB); KbdAddToMap ("\033\x03", kbEscCtrlC); KbdAddToMap ("\033\x04", kbEscCtrlD); KbdAddToMap ("\033\x05", kbEscCtrlE); KbdAddToMap ("\033\x06", kbEscCtrlF); KbdAddToMap ("\033\x07", kbEscCtrlG); KbdAddToMap ("\033\x08", kbEscCtrlH); KbdAddToMap ("\033\x09", kbEscCtrlI); KbdAddToMap ("\033\x0A", kbEscCtrlJ); KbdAddToMap ("\033\x0B", kbEscCtrlK); KbdAddToMap ("\033\x0C", kbEscCtrlL); KbdAddToMap ("\033\x0D", kbEscCtrlM); KbdAddToMap ("\033\x0E", kbEscCtrlN); KbdAddToMap ("\033\x0F", kbEscCtrlO); KbdAddToMap ("\033\x10", kbEscCtrlP); KbdAddToMap ("\033\x11", kbEscCtrlQ); KbdAddToMap ("\033\x12", kbEscCtrlR); KbdAddToMap ("\033\x13", kbEscCtrlS); KbdAddToMap ("\033\x14", kbEscCtrlT); KbdAddToMap ("\033\x15", kbEscCtrlU); KbdAddToMap ("\033\x16", kbEscCtrlV); KbdAddToMap ("\033\x17", kbEscCtrlW); KbdAddToMap ("\033\x18", kbEscCtrlX); KbdAddToMap ("\033\x19", kbEscCtrlY); KbdAddToMap ("\033\x1A", kbEscCtrlZ); KbdAddToMap ("\033\033", kbEscEsc); KbdAddToMap ("\x11\x13", kbCtrlQS); KbdAddToMap ("\x11""s", kbCtrlQS); KbdAddToMap ("\x11""S", kbCtrlQS); KbdAddToMap ("\x11\x04", kbCtrlQD); KbdAddToMap ("\x11""d", kbCtrlQD); KbdAddToMap ("\x11""D", kbCtrlQD); KbdAddToMap ("\x11\x12", kbCtrlQR); KbdAddToMap ("\x11""r", kbCtrlQR); KbdAddToMap ("\x11""E", kbCtrlQR); KbdAddToMap ("\x11\x03", kbCtrlQC); KbdAddToMap ("\x11""c", kbCtrlQC); KbdAddToMap ("\x11""C", kbCtrlQC); KbdAddToMap ("\x11\x05", kbCtrlQC); KbdAddToMap ("\x11""e", kbCtrlQC); KbdAddToMap ("\x11""E", kbCtrlQC); KbdAddToMap ("\x11\x18", kbCtrlQX); KbdAddToMap ("\x11""x", kbCtrlQX); KbdAddToMap ("\x11""X", kbCtrlQX); // Now create the mappings extended --> virtual (primary/secondary) KbdAddVMap (vkHelp, kbF1, kbEscCtrlH); KbdAddVMap (vkPgDn, kbPgDn, kbCtrlC); KbdAddVMap (vkPgUp, kbPgUp, kbCtrlR); KbdAddVMap (vkUp, kbUp, kbCtrlE); KbdAddVMap (vkDown, kbDown, kbCtrlX); KbdAddVMap (vkLeft, kbLeft, kbCtrlS); KbdAddVMap (vkRight, kbRight, kbCtrlD); KbdAddVMap (vkIns, kbIns, kbCtrlV); KbdAddVMap (vkDel, kbDel, kbCtrlG); KbdAddVMap (vkHome, kbHome, kbCtrlQS); KbdAddVMap (vkEnd, kbEnd, kbCtrlQD); KbdAddVMap (vkZoom, kbF5, kbEscCtrlZ); KbdAddVMap (vkClose, kbMetaF3, kbEscCtrlC); KbdAddVMap (vkOpen, kbF3, kbEscCtrlO); KbdAddVMap (vkSave, kbF2, kbEscCtrlS); KbdAddVMap (vkAccept, kbF10, kbEscCtrlA); // Keys that have no secondary form under linux KbdAddVMap (vkCtrlUp, kbCtrlW); KbdAddVMap (vkCtrlDown, kbCtrlZ); KbdAddVMap (vkCtrlLeft, kbCtrlA); KbdAddVMap (vkCtrlRight, kbCtrlF); KbdAddVMap (vkCtrlPgUp, kbCtrlQR); KbdAddVMap (vkCtrlPgDn, kbCtrlQC); KbdAddVMap (vkCtrlHome, kbCtrlQE); KbdAddVMap (vkCtrlEnd, kbCtrlQX); KbdAddVMap (vkResize, kbEscCtrlR); KbdAddVMap (vkQuit, kbMetaX); // Handle the abort key separate KbdAddVMap (vkAbort, IsConsole () ? kbEsc : kbEscEsc); // Map the character that c_cc[VERASE] sends to backspace (bug? // is c_cc signed?) if (StartupSettings.c_cc [VERASE] > 0 && StartupSettings.c_cc [VERASE] <= 256) { TransTable [StartupSettings.c_cc [VERASE]] = (unsigned char) kbBack; } else { // It seems that the setting is invalid, check the termcap database // for a kb entry. If the entry is only one char, translate it via // the translation table, otherwise use the mapper char* BS = KbdGetCap ("kb"); if (BS) { if (strlen (BS) == 1) { // Just one char TransTable [(unsigned char) (*BS)] = (unsigned char) kbBack; } else { // A sequence... KbdAddToMap (BS, kbBack); } } } } Keyboard::~Keyboard () { // Reset the keyboard state KbdExit (); // Delete the translation table delete [] TransTable; } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { static int BufFill = 0; static unsigned char Buf [64] = ""; // The handling is different, if we are on the console or not. On the // console, we can easily find a complete key sequence, because a // complete sequence is returned by read. This allows usage of the alt // keys. // On a terminal, we have to search for each sequence. if (IsConsole ()) { // This is the console. If we should not wait, first check if any // characters are available, if not, bail out if (Wait == 0 && KbdCharAvail () == 0) { // Nothing to do return; } // Now loop until we have a valid key while (1) { // Read in a complete sequence from the keyboard do { BufFill = read (0, Buf, sizeof (Buf)-1); if (BufFill == 0) { // Timeout waiting for a key, allow some idle processing App->Idle (); } } while (BufFill <= 0); Buf [BufFill] = '\0'; // If there is only one key in the buffer, read it directly, otherwise // ask the mapper. Key K; if (BufFill == 1) { // Remap the key K = KbdMapExtended (Translate (Buf [0])); // Put the mapped key into the buffer and return KeyBuf.Put (K); return; } else { // There is more than one char in the buffer. This must be a complete // key sequence. Try to find the mapping for that key, insert the // mapped key. If we do not find a mapping, this is a key sequence, // we don't know, so throw it away. int Index; if (Mapper.Search ((char*)Buf, Index)) { // Found! K = KbdMapExtended (Mapper [Index]->GetKey ()); KeyBuf.Put (K); return; } } } } else { // Not the console. If we have keys left in the buffer, try to find a // match. If we have a partial match, read more chars, until we get // a full or no match. char SBuf [sizeof (Buf)]; int SCount = 1; while (1) { while (SCount <= BufFill) { // Add the next char from Buf to SBuf, add the trailing zero SBuf [SCount-1] = Buf [SCount-1]; SBuf [SCount] = '\0'; // Now search for this portion of Buf int Index; Key K; switch (Mapper.Find (SBuf, Index)) { case 0: // No match. Return the translated equivalent of the // first char in Buf, then delete it from Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; case 1: // Partial match. Increase the length of the sequence, // we search for. If the length succeeds some arbitary // limit, handle it like no match. if (SCount < 16) { SCount++; } else { // Suspicious... Return the translated equivalent // of the first char in Buf, then delete it from // Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; } break; case 2: // Full match. Delete the sequence from the buffer. memmove (&Buf [0], &Buf [SCount], BufFill - SCount + 1); BufFill -= SCount; K = KbdMapExtended (Mapper [Index]->GetKey ()); KeyBuf.Put (K); return; } } // If we get here, the buffer is exhausted and we still have a // partial match (or the buffer has been empty on startup). // If we should read without a wait, check if there are characters // waiting. If not, don't do a blocking read but return without // doing anything. if (Wait == 0 && KbdCharAvail () == 0) { // No chars waiting return; } // Before trying to read more chars, check for a buffer overflow // (this should not happen, but who knows...) if (SCount >= sizeof (Buf)) { FAIL ("Keyboard::GetMappedKey: Buffer overflow"); } // Now read in a new chunk of chars. int Count; do { Count = read (0, &Buf [BufFill], sizeof (Buf) - BufFill - 1); if (Count == 0) { // Timeout waiting for a key, allow some idle processing App->Idle (); } } while (Count <= 0); BufFill += Count; Buf [BufFill] = '\0'; } } } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description if (IsConsole ()) { return App->LoadMsg (MSGBASE_KBD + K); } else { return App->LoadMsg (MSGBASE_KBD + 0x200 + K); } } estic-1.61.orig/spunk/bsdsrc/screen.cc0100644000176100001440000000371007031424711017216 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #ifdef FREEBSD # include #endif #include "../screen.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int ScrIsConsole () // Return true if this is a console screen { #ifdef FREEBSD // This is the console if we can request the keyboard leds int Dummy; return ioctl (0, KDGETLED, &Dummy) == 0; #else return 0; #endif } static int ScrHasColor () // Return true if this is a console that supports colors { #ifdef FREEBSD int Color; if (ioctl (0, GIO_COLOR, &Color) != 0) { // Error - this is not the console, assume no colors return 0; } // Return the value from the console driver return Color; #else // Assume no colors return 0; #endif } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): Color (ScrHasColor ()), Console (ScrIsConsole ()), CP437 (0), TransTable (NULL) { // Initialize the termcap system TCInit (); } char* Screen::GetIS (char* IS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { return IS; } char* Screen::GetRS (char* RS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { return RS; } estic-1.61.orig/spunk/djgppsrc/0040755000176100001440000000000007061535303015771 5ustar debacleusersestic-1.61.orig/spunk/djgppsrc/nlsinit.cc0100644000176100001440000002011507031424711017751 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Defines */ /*****************************************************************************/ // I've never seen such ugly names as in djgpp... #define TransferBuffer _go32_info_block.linear_address_of_transfer_buffer /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Target specific code */ /*****************************************************************************/ struct CountryInfo { char ID __attribute__ ((packed)); u16 Size __attribute__ ((packed)); u16 Country __attribute__ ((packed)); u16 CodePage __attribute__ ((packed)); u16 Date __attribute__ ((packed)); char CurrStr [5] __attribute__ ((packed)); char ThSep [2] __attribute__ ((packed)); char DecSep [2] __attribute__ ((packed)); char DateSep [2] __attribute__ ((packed)); char TimeSep [2] __attribute__ ((packed)); char Curr __attribute__ ((packed)); char CurrPlaces __attribute__ ((packed)); char Time __attribute__ ((packed)); u32 CaseMapFunc __attribute__ ((packed)); char DataSep [2] __attribute__ ((packed)); char Fill [10] __attribute__ ((packed)); }; static void GetCountryInfo (void* InfoStruct, unsigned InfoLen, unsigned char ID) { _go32_dpmi_registers Regs; // Clear out the registers memset (&Regs, 0, sizeof (Regs)); // Setup the registers Regs.x.ax = 0x6500 | ID; Regs.x.bx = 0xFFFF; Regs.x.cx = InfoLen; Regs.x.dx = 0xFFFF; Regs.x.di = TransferBuffer & 0x0F; Regs.x.es = (TransferBuffer >> 4) & 0xFFFF; // Now simulate the real mode interrupt _go32_dpmi_simulate_int (0x21, &Regs); // Transfer the data to the structure in user space movedata (_go32_conventional_mem_selector (), TransferBuffer & 0x000FFFFF, _go32_my_ds (), u32 (InfoStruct), InfoLen); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { CountryInfo Info; // Get country information GetCountryInfo (&Info, sizeof (Info), 0x01); // Try if there is an override for the country in the environment unsigned Country = GetEnvNum ("SPUNK_COUNTRY", Info.Country); // Set the country data NLSSetCountry (Country); // Try if there is an override for the language in the environment unsigned Language = GetEnvNum ("SPUNK_LANGUAGE", NLSGetDefaultLanguage (Country)); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/dos32src/0040755000176100001440000000000007061535304015620 5ustar debacleusersestic-1.61.orig/spunk/dos32src/_sercom.asm0100644000176100001440000015340407031424711017751 0ustar debacleusers; ***************************************************************************** ; * * ; * _SERCOM.ASM * ; * * ; * (C) 1991-96 Ullrich von Bassewitz * ; * Zwehrenbuehlstrasse 33 * ; * D-72070 Tuebingen * ; * EMail: uz@ibb.schwaben.com * ; * * ; ***************************************************************************** ; $Id$ ; ; $Log$ ; ; ; This is a simple module for serial communication under DOS based on a module ; called USER. The module supports up to four ports, 16550s and the "high" ; interrupts. DOS4G version. ; Comments are in german, sorry. ; *************************************************************************** IDEAL ; IDEAL-Modus von TASM einschalten JUMPS ; Sprungoptimierung LOCALS ; Lokale Symbole zulassen SMART ; "Schlauen" Modus einschalten P386 ; 80386 Protected Mode erlauben MODEL FLAT ; Im FLAT Modell bersetzen ; ------------------------------------------------------------------- ; ; Zeichen fr Flow-Control bei XON/XOFF ; XON = 11H ; XON XOFF = 13H ; XOFF ; ------------------------------------------------------------------- ; ; Struktur fr die Daten eines jeden seriellen Ports. Von diesen Strukturen ; ist fr jeden untersttzten Port eine vorhanden. ; STRUC PortDesc ; Allgemeine Einstellungen Baudrate dd ? ; Baudrate Connection db ? ; M)odem, D)irect Parity db ? ; N)one, O)dd, E)ven, S)pace, M)ark StopBits db ? ; 1, 2 DataBits db ? ; 5..8 XonXoff db ? ; E)nabled, D)isabled ALIGN 4 ; Fill auf gerade Adressen ; Ringpuffer fr Senden und Empfang incl Verwaltung RXBuf dd ? ; Zeiger auf Empfangspuffer TXBuf dd ? ; Zeiger auf Sendepuffer RXBufSize dd ? ; Gr”įe Empfangspuffer TXBufSize dd ? ; Gr”įe Sendepuffer RXStart dd 0 ; Ringpufferzeiger RXEnd dd 0 ; TXStart dd 0 TXEnd dd 0 RXCount dd 0 ; Anzahl Zeichen im Puffer TXCount dd 0 ; Anzahl Zeichen im Puffer ; Fehlerz„hler ERXOverflow dw 0 ; Pufferberlauf beim Empfang ETXOverflow dw 0 ; Pufferberlauf beim Senden EOvrRun dw 0 ; berlauf beim Empf„nger EBreak dw 0 ; Break EFrame dw 0 ; Framing Fehler EParity dw 0 ; Parity Fehler ErrorBlock EQU ERXOverFlow ; Interna Installed db 0 ; 1 wenn installiert IntNr db ? ; Interrupt-Nummer IC1Mask db ? ; Maske fr 8259A #1 NotIC1Mask db ? ; Komplement IC2Mask db ? ; Maske fr 8259A #2 NotIC2Mask db ? ; Komplement FIFOLen db ? ; Chunk-Size fr Sender-FIFO ParityMask db ? ; 7Fh wenn Parity, sonst 0FFh ALIGN 4 ; Make it even ; Adressen der Chip-Register DataReg dw ? ; data register DLL EQU DataReg ; divisor low latch IER dw ? ; interrupt enable register DLH EQU IER ; divisor high latch IIR dw ? ; interrupt id register (lesen) FCR EQU IIR ; FIFO control register (schreiben) LCR dw ? ; line control register MCR dw ? ; modem control register LSR dw ? ; line status register MSR dw ? ; modem status register ALIGN 4 IntHandler dd ? ; Offset des Interrupt-Handlers OldVecOffs dd ? ; Offset of old interrupt vector OldVecSeg dw ? ; Segment of old interrupt vector HostOff db 0 ; Host Xoff'ed (1=ja, 0 = nein) PCOff db 0 ; PC Xoff'ed (1=ja, 0=nein) MustSend db 0 ; Es _muį_ ein Byte gesendet werden DSR_CTS_Ok db ? ; DSR und CTS sind beide On ENDS PortDesc ; ; Steuerbits fr das FCR des NS16550A. ; FIFO_ENABLE = 001H ; FIFO einschalten FIFO_CLR_RX = 002H ; RX-FIFO l”schen FIFO_CLR_TX = 004H ; TX-FIFO l”schen FIFO_SZ_1 = 000H ; Warning level: 1 Bytes FIFO_SZ_4 = 040H ; Warning level: 4 Bytes FIFO_SZ_8 = 080H ; Warning level: 8 Bytes FIFO_SZ_14 = 0C0H ; Warning level: 14 Bytes FIFO_SZ_MASK = 0C0H ; Maske fr warning level ; ; FIFO Kommandos. In FIFO_INIT muį eingetragen werden, nach wievielen Bytes ; ein Interrupt erzeugt wird. Unter DOS sind normalerweise 14 Bytes ok, bei ; langsamen Rechnern (oder langsamen EMM) und hohen Zeichengeschwindigkeiten ; muį evtl. bereits nach 8 Zeichen ein Interrupt ausgel”st werden. ; Default ist Interrupt nach 8 Zeichen. ; FIFO_CLEAR = FIFO_CLR_RX OR FIFO_CLR_TX FIFO_INIT = FIFO_ENABLE OR FIFO_SZ_8 OR FIFO_CLR_RX OR FIFO_CLR_TX ; ; Sonstiges FIFO-Zeugs. ; FIFO_ENABLED = 0C0H ; Bitmuster wenn FIFO an ; ; Bits im Modem Control Register ; MCR_DTR = 00000001B MCR_RTS = 00000010B MCR_OUT2 = 00001000B ; ------------------------------------------------------------------- ; ; Externe Prozeduren, die das Programmiersprachenmodul zur Verfgung ; stellen muį. ; ; EXTRN PASCAL _COMWAIT : NEAR ; Warte-Prozedur EXTRN PASCAL _COMERROR : NEAR ; _ComError-Routine ; ------------------------------------------------------------------- ; ; Vom Assembler-Modul exportierte Routinen. ; PUBLIC _COMINSTALL PUBLIC _COMDEINSTALL PUBLIC _COMOPEN PUBLIC _COMCLOSE PUBLIC _COMISINSTALLED PUBLIC _COMISOPEN PUBLIC _COMDTROFF PUBLIC _COMDTRON PUBLIC _COMRTSOFF PUBLIC _COMRTSON PUBLIC _COMRXCOUNT PUBLIC _COMRXSIZE PUBLIC _COMRXCLEAR PUBLIC _COMTXCOUNT PUBLIC _COMTXSIZE PUBLIC _COMTXFREE PUBLIC _COMTXCLEAR PUBLIC _COMRECEIVE PUBLIC _COMSEND PUBLIC _COMBREAK PUBLIC _COMMODEMSTATUS ; Interrupt-Handler PUBLIC _INTCOM1 PUBLIC _INTCOM2 PUBLIC _INTCOM3 PUBLIC _INTCOM4 ; --------------------------------------------------------------------------- ; Datensegment ; DATASEG EXTRN C _ComPort1 : PortDesc EXTRN C _ComPort2 : PortDesc EXTRN C _ComPort3 : PortDesc EXTRN C _ComPort4 : PortDesc ; ------------------------------------------------------------------- ; ; Beginn Codesegment ; CODESEG ; ------------------------------------------------------------------------- ; ; _ComInstall ; ; Installiert einen Port mit der bergebenen Portnummer. Bei Erfolg wird das ; Handle (immer ein Wert <> 0) zurckgeliefert, ansonsten der Wert 0 als ; Handle. ; PROC PASCAL _ComInstall NEAR PortHandle: DWORD USES ESI, EDI mov esi, [PortHandle] ; Porthandle holen ; esi zeigt ab hier auf einen Record vom Typ PortDesc test [(PortDesc esi).Installed], 01h ; Bereits installiert jz @@L2 ; Nein: Ok ; Fehler, Port war bereits installiert @@L1: call _ComError jmp @@L3 ; Fehler, -1 als Handle liefern ; Port ist noch nicht installiert. Port-Adresse aus dem Default-Array holen ; und prfen, ob im entsprechenden BIOS-Bereich eine andere Adresse steht. ; Wenn Ja, dann diese andere Adresse bernehmen, wenn Nein, oder wenn diese ; andere Adresse eine 0 ist, den Default behalten. ; Dann prfen, ob diese Adresse _irgendwo_ im BIOS-Bereich als Adresse ; eingetragen ist. Fehler wenn nein. ; Der Sinn dieses ganzen Hin und Her ist es, auch etwas ungew”hnliche ; Installationen zu untersttzen, bei denen z.B. COM 3 fehlt aber COM 4 ; vorhanden ist. Das BIOS packt diese Adressen, so daį der Bereich von COM 4 ; leer ist und COM 3 die Adresse von COM 4 enth„lt. @@L2: mov ax, [(PortDesc esi).DataReg] ; Grundadresse holen mov edi, 0400h ; BIOS-Offset COM Bereich cld mov ecx, 4 repne scasw ; Adresse vorhanden ? je @@L4 ; Springe wenn Ja ; Fehler, die Adresse konnte nicht gefunden werden. -1 als Handle liefern. @@L3: mov eax, -1 ; Handle = -1 jmp @@L99 ; und Ende ; Adresse ist Ok, die gesamten Adressen in den Deskriptor-Record eintragen @@L4: lea edi, [(PortDesc esi).DataReg] ; Adresse erstes Register mov ecx, 7 ; 7 Register pro Chip @@L5: stosw ; Eintragen inc ax ; N„chste Adresse loop @@L5 ; Die Fehlerz„hler nullen xor ax, ax ; 0 nach ax lea edi, [(PortDesc esi).ErrorBlock]; Erster Z„hler mov ecx, 6 ; 6 Fehlerz„hler rep stosw ; l”schen ; Prfen ob der Port einen 16550A besitzt. Die Anzahl der Bytes die bei einem ; "Transmit-Register leer"-Interrupt geschrieben werden k”nnen vermerken. Diese ; Anzahl ist 1 ohne FIFO und bis zu 14 mit FIFO. mov dx, [(PortDesc esi).FCR] ; FIFO control register holen mov al, FIFO_INIT OR FIFO_ENABLED ; FIFO... out dx, al ; ... einschalten in al, dx ; Wert wieder holen and al, FIFO_ENABLED ; FIFO-Bits ausmaskieren mov ah, 1 ; annehmen, daį kein FIFO da cmp al, FIFO_ENABLED ; Ist es ein 16550A ? jne @@L6 ; Springe wenn keiner mov ah, 16 ; 16 Sendebytes wenn FIFO vorh. @@L6: mov [(PortDesc esi).FIFOLen], ah ; Wert merken ; FIFO (falls vorhanden) erstmal wieder ausschalten mov al, FIFO_CLEAR out dx, al ; Interrupt-Vektor retten und eigenen Vektor setzen push es mov ah, 35h mov al, [(PortDesc esi).IntNr] ; Nummer des Interrupts int 21h ; Vektor holen mov [(PortDesc esi).OldVecOffs], ebx mov [(PortDesc esi).OldVecSeg], es pop es push ds mov ah, 25h mov al, [(PortDesc esi).IntNr] ; Nummer des Interrupts mov edx, [(PortDesc esi).IntHandler]; push cs pop ds int 21h ; Vektor setzen pop ds ; Den Port als installiert markieren und das Handle in eax rckliefern mov [(PortDesc esi).Installed], 01h ; Bit 0 setzen mov eax, esi ; Handle nach eax ; Das wars: Funktionsausgang. @@L99: ret ENDP _ComInstall ; ------------------------------------------------------------------------- ; ; _ComDeInstall ; ; Deinstalliert den Port mit dem bergebenen Handle. ; PROC PASCAL _ComDeInstall NEAR PortHandle: DWORD USES ESI, EDI mov esi, [PortHandle] ; Deskriptor holen ; Prfen ob der Port installiert ist. Fehler wenn nicht. test [(PortDesc esi).Installed], 01h ; Installiert ? jnz @@L1 ; Springe wenn ja ; Fehler: Port ist nicht installiert call _ComError ; Fehler melden jmp @@L99 ; Und Ende ; Port ist installiert. Falls der Port auch gleichzeitig offen ist, zuerst ; schlieįen @@L1: test [(PortDesc esi).Installed], 02h ; Offen ? jz @@L2 ; Springe wenn Nein push esi ; PortHandle als Parameter call _ComClose ; Port schlieįen mov esi, [PortHandle] ; PortHandle neu laden ; Install-Merker rcksetzen @@L2: and [(PortDesc esi).Installed], NOT 01h ; Interrupt-Vektor rcksetzen. push ds mov ah, 25h mov al, [(PortDesc esi).IntNr] ; Nummer des belegten Interrupts mov edx, [(PortDesc esi).OldVecOffs] mov ds, [(PortDesc esi).OldVecSeg] int 21h ; Vektor rcksetzen pop ds ; Ende @@L99: ret ENDP _ComDeInstall ; ------------------------------------------------------------------------- ; ; _ComOpen ; ; Setzt Baudrate etc., l”scht die Puffer, gibt die Interrupts frei, kurz: ; Setzt den RS232-Betrieb in Gang. ; PROC PASCAL _ComOpen NEAR PortHandle: DWORD USES ESI, EDI ; Zeiger auf den Port-Deskriptor nach esi mov esi, [PortHandle] ; Prfen ob der Port installiert ist. Fehler wenn nicht. test [(PortDesc esi).Installed], 01h jnz @@L0 ; Springe wenn installiert call _ComError ; Fehler-Routine jmp @@L99 ; Prfen ob der Port bereits offen ist, wenn ja zuerst schlieįen @@L0: test [(PortDesc esi).Installed], 02h ; Offen ? jz @@L1 ; Nein: Springe push esi ; Parameter fr ComClose call _ComClose ; Schlieįen mov esi, [PortHandle] ; Handle neu laden ; Eine der Parit„t entsprechende AND-Maske setzen @@L1: mov al, 0FFh ; Maske fr kein Parity cmp [(PortDesc esi).Parity], 'N' ; Parity ? jz @@L2 ; Springe wenn Nein mov al, 07Fh ; Maske wenn Parity @@L2: mov [(PortDesc esi).ParityMask], al ; Maske merken ; Flow-Control rcksetzen sub eax, eax mov [(PortDesc esi).HostOff], al ; mov [(PortDesc esi).PCOff], al mov [(PortDesc esi).MustSend], al mov [(PortDesc esi).DSR_CTS_Ok], al ; Puffer rcksetzen mov [(PortDesc esi).TXStart], eax mov [(PortDesc esi).TXEnd], eax mov [(PortDesc esi).TXCount], eax mov [(PortDesc esi).RXStart], eax mov [(PortDesc esi).RXEnd], eax mov [(PortDesc esi).RXCount], eax ; UART initialisieren mov dx, [(PortDesc esi).MCR] ; modem control register mov al, 0 ; clr dtr, rts, out1, out2 & loopback out dx, al cmp [(PortDesc esi).Connection], 'D'; Direkte Verbindung ? jz @@L3 ; Springe wenn ja mov dx, [(PortDesc esi).MSR] ; modem status register in al, dx ; modem status lesen and al, 30h ; DSR, CTS maskieren cmp al, 30h ; DSR, CTS prfen jnz @@L4 ; Springe wenn nicht ok @@L3: mov [(PortDesc esi).DSR_CTS_Ok], 01h; Beide da, Ausgang Ok @@L4: mov dx, [(PortDesc esi).FCR] ; FIFO control register mov al, FIFO_CLEAR ; FIFO ausschalten out dx, al mov dx, [(PortDesc esi).LSR] ; line status register... in al, dx ; ...rcksetzen mov dx, [(PortDesc esi).DataReg] ; Datenregister in al, dx ; ...rcksetzen mov dx, [(PortDesc esi).MSR] ; modem status register... in al, dx ; ...rcksetzen ; Baudrate in Divisor umrechnen und setzen mov eax, 115200 sub edx, edx div [(PortDesc esi).Baudrate] mov ebx, eax ; Ergebnis nach ebx ; Baudrate am UART einstellen @@L6: mov dx, [(PortDesc esi).LCR] ; line control register mov al, 80h ; DLAB = 1 out dx, al mov ax, bx ; Divisor nach ax mov dx, [(PortDesc esi).DLL] ; divisor low out dx, al ; lsb ausgeben mov dx, [(PortDesc esi).DLH] ; divisor high xchg ah, al out dx, al ; msb ausgeben ; Parity und Anzahl Stop- und Daten-Bits setzen mov al, 00h ; Bits in al zusammenbauen mov ah, [(PortDesc esi).Parity] cmp ah, 'O' ; odd ? jne @@L7 or al, 0Ah ; odd ! jmp @@L9 @@L7: cmp ah, 'E' ; even ? jne @@L8 or al, 1Ah ; even ! jmp @@L9 @@L8: cmp ah, 'M' ; mark ? jne @@L9 or al, 2Ah ; mark ! @@L9: cmp [(PortDesc esi).StopBits], 2 ; 2 Stop-Bits ? jnz @@L10 or al, 04h @@L10: mov ah, [(PortDesc esi).DataBits] ; Anzahl Datenbits holen sub ah, 5 ; 5..8 --> 0..3 and ah, 3 ; maskieren or al, ah ; und reinodern mov dx, [(PortDesc esi).LCR] ; line control register out dx, al ; parity mode & DLAB = 0 ; FIFO's initalisieren (wird ignoriert wenn nicht 16550A) mov dx, [(PortDesc esi).FCR] ; FIFO control register mov al, FIFO_INIT out dx, al ; Interrupts freigeben cli ; Interrupts aus in al, 0A1h ; Int-Controller #2 and al, [(PortDesc esi).NotIC2Mask] ; Bit l”schen out 0A1h, al ; und wieder ausgeben in al, 021h ; Int-Controller #1 and al, [(PortDesc esi).NotIC1Mask] ; Bit l”schen out 021h, al ; und wieder ausgeben sti ; Interrupts an mov dx, [(PortDesc esi).IER] ; interrupt enable register mov al, 00001101B ; line & modem status, rec... out dx, al ; ...freigeben mov dx, [(PortDesc esi).MCR] ; modem control register mov al, MCR_OUT2 ; OUT2, kein RTS, kein DTR cmp [(PortDesc esi).Connection], 'M'; Modem connection? jne @@L11 ; Nein: Skip or al, MCR_RTS ; Ja: RTS aktiv setzen @@L11: out dx, al ; setzen ; Port als Open markieren. or [(PortDesc esi).Installed], 02h ; Ende @@L99: ret ENDP _ComOpen ; ------------------------------------------------------------------------- ; ; _ComClose ; ; Schlieįt einen Com-Port ; PROC PASCAL _ComClose NEAR PortHandle: DWORD ; Prfen ob der Port berhaupt offen ist mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Springe wenn Port nicht offen ; Interrupts an UART abklemmen, FIFO abschalten cli ; Keine Interrupts mov dx, [(PortDesc ebx).MCR] ; modem control register mov al, 0 ; Kein RTS, DTR, OUT2 out dx, al mov dx, [(PortDesc ebx).IER] ; interrupt enable register out dx, al ; Shut up ! mov dx, [(PortDesc ebx).FCR] mov al, FIFO_CLEAR out dx, al ; FIFO ausschalten ; Interrupt-Controller abschalten in al, 0A1h ; Int-Controller #2 or al, [(PortDesc ebx).IC2Mask] out 0A1h, al ; Interrupt sperren in al, 021h ; Int-Controller #1 or al, [(PortDesc ebx).IC1Mask] out 021h, al ; Interrupt sperren ; DTR und RTS l”schen mov dx, [(PortDesc ebx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT (MCR_DTR OR MCR_RTS) ; DTR l”schen... out dx, al ; ...und wieder setzen ; Vermerken, daį der Port nicht mehr offen ist und Ende and [(PortDesc ebx).Installed], NOT 02h sti ; Interrupts wieder zulassen @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComClose ; ---------------------------------------------------------------------- ; ; _ComDTROff ; ; Schaltet DTR auf off ; PROC PASCAL _ComDTROff NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Port ist offen, Aktion durchfhren mov dx, [(PortDesc ebx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT MCR_DTR ; DTR l”schen... out dx, al ; ...und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComDTROff ; ------------------------------------------------------------------------- ; ; _ComDTROn ; ; Schaltet DTR auf aktiv ; PROC PASCAL _ComDTROn NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Port nicht offen ; Port ist offen, DTR RTS setzen mov dx, [(PortDesc ebx).MCR] ; modem control register in al, dx ; Register lesen or al, MCR_DTR ; DTR aktiv... out dx, al ; und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComDTROn ; ---------------------------------------------------------------------- ; ; _ComRTSOff ; ; Schaltet RTS auf off ; PROC PASCAL _ComRTSOff NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error cmp [(PortDesc ebx).Connection], 'M'; Modem connection? je @@Error ; Dann Aufruf nicht erlaubt ; Port ist offen, RTS rcksetzen mov dx, [(PortDesc ebx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT MCR_RTS ; RTS l”schen... out dx, al ; ...und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComRTSOff ; ------------------------------------------------------------------------- ; ; _ComRTSOn ; ; Schaltet RTS auf aktiv ; PROC PASCAL _ComRTSOn NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Port nicht offen cmp [(PortDesc ebx).Connection], 'M'; Modem connection? je @@Error ; Dann Aufruf nicht erlaubt ; Port ist offen, RTS setzen mov dx, [(PortDesc ebx).MCR] ; modem control register in al, dx ; Register lesen or al, MCR_RTS ; RTS aktiv... out dx, al ; und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComRTSOn ; ------------------------------------------------------------------------- ; ; _ComIsInstalled ; ; Ergibt einen Wert != 0 wenn der Port installiert ist. ; PROC PASCAL _ComIsInstalled NEAR PortHandle: DWORD mov ebx, [PortHandle] mov bl, [(PortDesc ebx).Installed] sub eax, eax test bl, 01h ; Installiert ? jz @@L1 ; Springe wenn Nein inc eax ; Installiert ! @@L1: ret ENDP _ComIsInstalled ; ------------------------------------------------------------------------- ; ; _ComIsOpen ; ; Ergibt einen Wert != 0 wenn der Port ge”ffnet ist. ; PROC PASCAL _ComIsOpen NEAR PortHandle: DWORD mov ebx, [PortHandle] mov bl, [(PortDesc ebx).Installed] sub eax, eax test bl, 02h ; Offen ? jz @@L1 ; Springe wenn Nein inc eax ; Offen ! @@L1: ret ENDP _ComIsOpen ; ------------------------------------------------------------------------- ; ; _ComReceive ; ; Holt ein Zeichen aus dem Empfangspuffer. Warte bis ein Zeichen da ist. Bei ; Fehlern kommt -1 als Wert zurck. ; PROC PASCAL _ComReceive NEAR PortHandle: DWORD USES ESI, EDI mov esi, [PortHandle] test [(PortDesc esi).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Nein ; Port ist offen, prfen ob Zeichen da @@L1: cmp [(PortDesc esi).RXCount], 0 ; Zeichen da ? jnz @@L2 ; Abholen wenn ja ; Es ist kein Zeichen da - erstmal warten, dabei die _ComWait Routine ; aufrufen push 10 ; 10ms call _ComWait jmp @@L1 ; Zeichen ist da, holen. Da die Interrupt-Routinen nicht auf den ; RXStart-Zeiger zugreift, mssen die Interrupts nicht gesperrt ; werden. @@L2: mov ebx, [(PortDesc esi).RXStart] ; Ringpufferzeiger mov edi, [(PortDesc esi).RXBuf] ; Zeiger auf Pufferbereich mov al, [edi+ebx] ; Zeichen holen inc ebx ; Zeiger erh”hen movzx eax, al ; Zeichen nach DWORD wandeln push eax ; ...und auf den Stack cmp ebx, [(PortDesc esi).RXBufSize] ; Warp-Around ? jb @@L3 ; Springe wenn Nein sub ebx, ebx ; Ja, Ringpufferzeiger wird 0 @@L3: mov [(PortDesc esi).RXStart], ebx ; Zeiger rckschreiben dec [(PortDesc esi).RXCount] ; Ein Zeichen weniger... ; Flow-Control prfen. Zuerst Hardware (RTS/CTS), dann Software mov ebx, [(PortDesc esi).RXBufSize] ; Gr”įe Puffer nach ebx shr ebx, 2 ; Gr”įe/4 in ebx cmp [(PortDesc esi).RXCount], ebx ; Puffer fast leer ? jae @@L99 ; Ende wenn nicht cli ; Interrupts aus cmp [(PortDesc esi).Connection], 'M'; Modem connection? jne @@L4 ; Springe wenn nein mov dx, [(PortDesc esi).MCR] in al, dx ; MCR lesen or al, MCR_RTS ; RTS setzen (Freigabe) out dx, al ; Jetzt prfen ob XON/XOFF Flow-Control an-, und der Sender abgeschaltet wurde @@L4: cmp [(PortDesc esi).XonXoff], 'E' ; Flow-Control an ? jne @@L7 ; Ende wenn nicht cmp [(PortDesc esi).HostOff], 00h ; XOFF-Status ? jz @@L7 ; Ende wenn nicht ; Der Host ist gestoppt, der Puffer aber wieder leer genug. XON senden. @@L5: cmp [(PortDesc esi).MustSend], 00h ; Zeichen im Puffer ? je @@L6 ; Springe wenn Nein ; Es ist noch ein Steuerzeichen im Puffer. Warten bis es weg ist. sti ; Interrupts freigeben push 10 ; 10 ms call _ComWait ; Warteroutine aufrufen mov esi, [PortHandle] ; Handle neu laden cli ; Interrupts wieder aus jmp @@L5 ; und neu prfen... ; Das Kontrollzeichen kann ausgegeben werden @@L6: mov al, XON call SendII ; XON senden @@L7: sti ; Interrupts wieder freigeben ; Zeichen vom Stack und Ende pop eax @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError ; Fehler melden mov eax, -1 ; Returncode -1 jmp @@L99 ENDP _ComReceive ; ------------------------------------------------------------------------- ; ; _ComRXCount ; ; Liefert die Anzahl Bytes im Empfangspuffer. ; PROC PASCAL _ComRXCount NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Alles klar, Anzahl liefern und Ende mov eax, [(PortDesc ebx).RXCount] @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComRXCount ; ------------------------------------------------------------------------- ; ; _ComRXSize ; ; Liefert die Gr”įe des Empfangspuffers. ; PROC PASCAL _ComRXSize NEAR PortHandle: DWORD mov ebx, [PortHandle] mov eax, [(PortDesc ebx).RXBufSize] ret ENDP _ComRXSize ; ------------------------------------------------------------------------- ; ; _ComRXClear ; ; L”scht den kompletten Empfangspuffer. Der Port muį offen sein. ; PROC PASCAL _ComRXClear NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Alles klar, Port ist offen sub eax, eax cli ; Interrupts sperren mov [(PortDesc ebx).RXStart], eax mov [(PortDesc ebx).RXEnd], eax mov [(PortDesc ebx).RXCount], eax sti ; Interrupts freigeben @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComRXClear ; ------------------------------------------------------------------------- ; ; _ComTXCount ; ; Liefert die Anzahl belegter Bytes im Sendepuffer ; PROC PASCAL _ComTXCount NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Springe wenn nicht offen ; Port ist offen. Anzahl holen und Ende mov eax, [(PortDesc ebx).TXCount] @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError jmp @@L99 ENDP _ComTXCount ; ------------------------------------------------------------------------- ; ; _ComTXFree ; ; Liefert die Anzahl freier Bytes im Sendepuffer ; PROC PASCAL _ComTXFree NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Springe wenn nicht offen ; Port ist offen. Gr”įe - Belegte Bytes rechnen. ; VORSICHT: Dieser Wert kann negativ werden, da sich evtl. zus„tzliche ; Kontrollzeichen im Puffer befinden k”nnen. In einem solchen Fall ; einfach 0 liefern. mov eax, [(PortDesc ebx).TXBufSize] ; Gesamtgr”įe dec eax ; Maximale Gr”įe fr Benutzer sub eax, [(PortDesc ebx).TXCount] jnc @@L99 ; Springe wenn >= 0 sub eax, eax ; if (eax < 0) then eax := 0; @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError jmp @@L99 ENDP _ComTXFree ; ------------------------------------------------------------------------- ; ; _ComTXSize ; ; Liefert die Gr”įe des Sendepuffers. ; PROC PASCAL _ComTXSize NEAR PortHandle: DWORD mov ebx, [PortHandle] mov eax, [(PortDesc ebx).TXBufSize] ret ENDP _ComTXSize ; ------------------------------------------------------------------------- ; ; _ComTXClear ; ; L”scht den kompletten Sendespuffer. Der Port muį offen sein. ; ACHTUNG: Im Gegensatz zu ComRXClear k”nnen sich hier Steuerzeichen im Puffer ; befinden, deren L”schung fatal w„re. Falls sich ein Steuerzeichen im Puffer ; befindet ist es jedoch immer (!) das erste Zeichen im Puffer. PROC PASCAL _ComTXClear NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Alles klar, Port ist offen sub ecx, ecx cli ; Interrupts sperren mov eax, [(PortDesc ebx).TXEnd] cmp [(PortDesc ebx).MustSend], 00h ; Steuerzeichen im Puffer ? jz @@L2 ; Springe wenn Nein ; Ein Zeichen im Puffer lassen inc ecx ; Anzahl = 1 nach Clear or eax, eax ; Index schon 0? jnz @@L1 ; Springe wenn nein mov eax, [(PortDesc ebx).TXBufSize] ; Gr”įe laden @@L1: dec eax ; Puffer l”schen @@L2: mov [(PortDesc ebx).TXStart], eax mov [(PortDesc ebx).TXCount], ecx sti ; Interrupts wieder freigeben @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComTXClear ; ------------------------------------------------------------------------- ; ; _ComSend ; ; Abschicken eines Zeichens. ; PROC PASCAL _ComSend NEAR PortHandle: DWORD, C: BYTE:4 USES ESI, EDI mov esi, [PortHandle] test [(PortDesc esi).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn nein ; Port ist offen, prfen ob Platz im Puffer mov edx, [(PortDesc esi).TXBufSize] ; Gr”įe des Puffers nach edx cmp [(PortDesc esi).TXCount], edx ; noch Platz ? jae @@L4 ; Springe wenn Nein ; Es ist genug Platz. Zeichen schreiben. mov al, [C] ; Zeichen holen mov edi, [(PortDesc esi).TXBuf] ; Zeiger auf Puffer holen cli ; Keine Interrupts mov ebx, [(PortDesc esi).TXEnd] ; Pufferzeiger holen mov [edi+ebx], al ; Zeichen in Puffer schreiben inc ebx ; Pufferzeiger erh”hen cmp ebx, edx ; Wrap-Around ? jb @@L1 ; Springe wenn Nein sub ebx, ebx ; Ringpufferzeiger auf 0 wenn ja @@L1: mov [(PortDesc esi).TXEnd], ebx ; Pufferzeiger rckschreiben inc [(PortDesc esi).TXCount] ; Ein Zeichen mehr ; Wenn notwendig die Sende-Interrupts freischalten mov dx, [(PortDesc esi).IER] ; Interrupt enable register in al, dx ; ... lesen test al, 02h ; Interrupts frei ? jnz @@L2 ; Ja, alles klar cmp [(PortDesc esi).PCOff], 00h ; XOFF-Status ? jnz @@L2 ; Ja, nix unternehmen cmp [(PortDesc esi).DSR_CTS_Ok], 00h; Statusleitungen ok ? jz @@L2 ; Nein, nix unternehmen mov al, 00001111B ; out dx, al ; TX-Ints freischalten @@L2: sti ; Interrupts wieder frei movzx eax, [C] ; Zeichen nach eax ; Ende @@L99: ret ; Einsprung wenn Puffer voll @@L4: inc [(PortDesc esi).ETXOverFlow] ; Fehlerz„hler erh”hen mov eax, -1 ; Fehlerkennung jmp @@L99 ; Und Ende ; Einsprung wenn Port nicht offen @@Error:call _ComError ; Fehler melden jmp @@L99 ; Ende ENDP _ComSend ; ------------------------------------------------------------------------- ; ; Interne Routine. Wird aufgerufen von ComReceive und vom RX-Interrupthandler ; wenn Flow-Control Zeichen verschickt werden mssen. ; esi muį auf den Port-Deskriptor zeigen, Interrupts mssen gesperrt sein. ; al enth„lt das zu sendende Zeichen. ; PROC SENDII NEAR push ebx push edx ; Register werden ben”tigt push edi mov ebx, [(PortDesc esi).TXStart] ; Ringpufferzeiger holen mov edi, [(PortDesc esi).TXBuf] ; Zeiger auf Pufferbereich mov edx, [(PortDesc esi).TXBufSize] ; Puffergr”įe nach dx cmp [(PortDesc esi).TXCount], edx ; Puffer voll ? jb @@L2 ; Springe wenn Nein ; Im Puffer ist kein Platz mehr (obwohl das eigentlich immer gew„hrleistet ; werden sollte !). Das kann eigentlich nur passieren, wenn direkt ; hintereinander zwei Flow-Control Zeichen geschickt werden... mov [ebx+edi], al ; Zerst”rt erstes Zeichen inc [(PortDesc esi).ETXOverFlow] ; Fehlerz„hler erh”hen jmp @@L2 ; einfach weiter ; Im Puffer ist Platz, Zeichen an die erste Stelle schreiben dec ebx ; Ergibt 0FFFF wenn ebx = 0 jns @@L1 ; Springe wenn kein Wrap mov ebx, edx ; Sonst Gr”įe-1 nach ebx dec ebx @@L1: mov [ebx+edi], al ; Zeichen schreiben mov [(PortDesc esi).TXStart], ebx ; Zeiger rckschreiben inc [(PortDesc esi).TXCount] ; Ein Zeichen mehr ... ; Flag fr extra Zeichen setzen @@L2: mov [(PortDesc esi).MustSend], 01h ; Flag setzen ; Falls notwendig Interrupts enablen mov dx, [(PortDesc esi).IER] ; interrupt enable register in al, dx ; Wert holen test al, 02h ; TX-Ints frei ? jnz @@L99 ; Ja: Ende cmp [(PortDesc esi).DSR_CTS_Ok], 00h; Statusleitungen ok ? jz @@L99 ; Nein, Pech .. mov al, 00001111B ; modem & line status, rec, xmit out dx, al ; ... freigeben ; Fertig ! @@L99: pop edi pop edx pop ebx ret ENDP SendII ; ------------------------------------------------------------------------- ; ; _ComBreak ; ; Sendet ein Break-Signal mit variabler L„nge. ; PROC PASCAL _ComBreak NEAR PortHandle: DWORD, BreakLen: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h jz @@Error ; Springe wenn Port nicht offen ; Port ist offen, Break senden mov dx, [(PortDesc ebx).LCR] cli ; Interrupts off in al, dx ; get LCR or al, 40h ; break bit on out dx, al ; setzen sti ; Interrupts on ; Warte-Routine aufrufen push [BreakLen] call _ComWait ; Register sind futsch, neu laden mov ebx, [PortHandle] mov dx, [(PortDesc ebx).LCR] ; Und Break-Bit rcksetzen cli in al, dx and al, NOT 40h out dx, al sti ; Fertig @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError jmp @@L99 ENDP _ComBreak ; ------------------------------------------------------------------------- ; ; ComModemStatus ; ; Gibt den Status der Kontroll-Leitungen zurck. ; ; Portbelegung: ; 0x80: -CD (Carrier Detect, inverted) ; 0x40: -RI (Ring Indicator, inverted) ; 0x20: -DSR (Data Set Ready, inverted) ; 0x10: -CTS (Clear to Send, inverted) ; 0x08: Delta Carrier Detect (CD changed) ; 0x04: Trailing edge of RI (RI went OFF) ; 0x02: Delta DSR (DSR changed) ; 0x01: Delta CTS (CTS changed) ; PROC PASCAL _ComModemStatus NEAR PortHandle: DWORD mov ebx, [PortHandle] test [(PortDesc ebx).Installed], 02h ; Port Offen ? jz @@Error ; Springe wenn Nein mov dx, [(PortDesc ebx).MSR] ; Modem status register in al, dx ; Wert holen movzx eax, al ; Wert in eax @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComModemStatus ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM1 ; PROC PASCAL _IntCom1 FAR push esi ; Register retten mov esi, OFFSET _ComPort1 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom1 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM2 ; PROC PASCAL _IntCom2 FAR push esi ; Register retten mov esi, OFFSET _ComPort2 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom2 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM3 ; PROC PASCAL _IntCom3 FAR push esi ; Register retten mov esi, OFFSET _ComPort3 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom3 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM4 ; PROC PASCAL _IntCom4 FAR push esi ; Register retten mov esi, OFFSET _ComPort4 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom4 ; ------------------------------------------------------------------------- ; ; Gemeinsame Interrrupt-Routine fr alle Ports ; PROC IntCommon FAR pushad push ds ; Register retten mov ax, DGROUP mov ds, ax ; Datensegment setzen ; Rausfinden, was es fr ein Interrupt war und entsprechend verzweigen @@RePoll: mov dx, [(PortDesc esi).IIR] ; interrupt id register in al, dx test al, 01h ; "no interrupt present" ? jnz @@L98 ; Ja: Ende movzx ebx, al ; Wert nach ebx and ebx, 000Eh ; unerwnschte Bits ausmaskieren jmp [cs:@@IntDispatch+ebx*2] ; Behandlungsroutine LABEL @@IntDispatch DWORD dd @@MSInt ; 0: Modem status int dd @@TXInt ; 2: Transmitter int dd @@RXInt ; 4: Receiver int dd @@LSInt ; 6: Line status int dd @@RePoll ; 8: Reserviert dd @@RePoll ; A: Reserviert dd @@RXInt ; C: FIFO timeout, wie RXInt dd @@RePoll ; E: Reserviert ; Interrupt-Controller verst„ndigen. Problemlos m”glich, weil die Interrupts ; sowieso noch gesperrt sind. @@L98: mov dx, [(PortDesc esi).IER] ; Interrupt enable register in al, dx ; Wert lesen mov ah, al ; ... und nach ah retten xor al, al ; Interrupts disablen out dx, al mov al, 20h ; EOI cmp [(PortDesc esi).IC2Mask], 00 ; "Hoher" Interrupt ? jz @@L99 ; Springe wenn Nein out 0A0h, al ; EOI an Controller #2 @@L99: out 20h, al ; EOI an Controller #1 mov al, ah ; Alter IER-Wert out dx, al ; ... restaurieren pop ds popad pop esi iretd ; ------------------------------------------------------------------------- ; ; Line status interrupt ; @@LSInt:mov dx, [(PortDesc esi).LSR] ; line status register in al, dx ; lesen shr al, 1 ; Bit wird nicht ben”tigt sub bx, bx ; bx = 0 shr al, 1 ; overrun error prfen adc [(PortDesc esi).EOvrRun], bx ; Z„hler evtl. erh”hen shr al, 1 ; parity error prfen adc [(PortDesc esi).EParity], bx ; Z„hler evtl. erh”hen shr al, 1 ; framing error prfen adc [(PortDesc esi).EFrame], bx ; Z„hler evtl. erh”hen shr al, 1 ; break error prfen adc [(PortDesc esi).EBreak], bx ; Z„hler evtl. erh”hen jmp @@RePoll ; Und neu abfragen ; ------------------------------------------------------------------------- ; ; Modem status interrupt ; @@MSInt:mov dx, [(PortDesc esi).MSR] ; modem status register in al, dx ; lesen cmp [(PortDesc esi).Connection], 'D'; direkte Verbindung ? je @@B1 ; dann immer frei and al, 30h ; DSR/CTS maskieren cmp al, 30h ; beide da ? mov al, 00h ; Flag fr Nein jne @@B2 ; Springe wenn Nein @@B1: mov al, 01h ; Flag fr Ja @@B2: mov [(PortDesc esi).DSR_CTS_Ok], al ; Flag setzen ; Jetzt auf jeden Fall immer alle Interrupts freigeben. Falls keine Daten ; anliegen werden die Ints in der TXInt-Routine wieder gesperrt. mov dx, [(PortDesc esi).IER] ; interrupt enable register mov al, 00001111B out dx, al jmp @@RePoll ; und neu pollen ; ------------------------------------------------------------------------- ; ; Transmit interrupt ; @@TXInt:cmp [(PortDesc esi).DSR_CTS_Ok], 0 ; Hardware Ok ? je @@C5 ; Nein: Ints abklemmen und Ende mov ecx, 1 ; Anzahl Zeichen cmp [(PortDesc esi).MustSend], 00h ; Flow-Control Zeichen ? jnz @@C2 ; Ja, immer senden cmp [(PortDesc esi).PCOff], 00h ; Flow-Control ok ? jnz @@C5 ; Nein: Ints abklemmen und Ende mov cl, [(PortDesc esi).FIFOLen] ; Maximale Anzahl FIFO cmp ecx, [(PortDesc esi).TXCount] ; > Anzahl im Puffer ? jb @@C1 ; Springe wenn kleiner mov ecx, [(PortDesc esi).TXCount] ; Sonst Anzahl im Puffer nehmen @@C1: jecxz @@C5 ; Nichts zu senden @@C2: mov ebx, [(PortDesc esi).TXStart] ; Ringpufferzeiger mov edi, [(PortDesc esi).TXBuf] ; Zeiger auf Sendepuffer mov dx, [(PortDesc esi).DataReg] ; Datenregister sub [(PortDesc esi).TXCount], ecx ; Anzahl passend vermindern @@C3: mov al, [ebx+edi] ; Zeichen holen out dx, al ; und schreiben inc ebx ; Pufferzeiger erh”hen cmp ebx, [(PortDesc esi).TXBufSize] ; Wrap ? jb @@C4 sub ebx, ebx ; Wrap ! @@C4: loop @@C3 ; und n„chstes Zeichen mov [(PortDesc esi).TXStart], ebx ; Zeiger rckschreiben mov [(PortDesc esi).MustSend], 0 ; Flow-Control ist weg jmp @@RePoll ; Fertig ! ; Es gibt nichts zu senden, oder es darf nicht gesendet werden: ; TX-Interrupts abklemmen @@C5: mov dx, [(PortDesc esi).IER] ; interrupt enable register mov al, 00001101B ; line & modem status, rec. out dx, al jmp @@RePoll ; ------------------------------------------------------------------------- ; ; Receive interrupt ; @@RXInt:mov ebx, [(PortDesc esi).RXEnd] ; Ringpufferzeiger holen mov edi, [(PortDesc esi).RXBuf] ; Zeiger auf Pufferbereich holen mov ebp, [(PortDesc esi).RXBufSize] ; Puffergr”įe nach bp @@D1: mov dx, [(PortDesc esi).DataReg] ; Datenregister in al, dx ; lesen and al, [(PortDesc esi).ParityMask] ; Parity-Bit ausmaskieren cmp [(PortDesc esi).XonXoff], 'E' ; Flow Control ? jnz @@D4 ; Springe wenn Nein ; Flow-Control ist an, Ctrl-S und Ctrl-Q prfen cmp al, XOFF ; Ctrl-S ? jnz @@D2 ; Nein: Skip mov [(PortDesc esi).PCOff], 01h ; Ja: Stop ! mov al, 00001101B ; TX-Ints sperren jmp @@D3 ; Zeichen nicht speichern @@D2: cmp al, XON ; Ctrl-Q ? jnz @@D4 ; Nein: Skip mov [(PortDesc esi).PCOff], 00h ; Ja: Output freigeben mov al, 00001111B @@D3: mov dx, [(PortDesc esi).IER] out dx, al jmp @@D7 ; Zeichen nicht speichern ; Zeichen speichern @@D4: cmp [(PortDesc esi).RXCount], ebp ; Noch Platz ? jb @@D5 ; Springe wenn ja inc [(PortDesc esi).ERXOverflow] ; Fehlerz„hler erh”hen jmp @@D7 ; Und n„chstes Byte @@D5: mov [ebx+edi], al ; Zeichen speichern inc ebx ; Zeiger erh”hen cmp ebx, ebp ; Wrap-Araound ? jb @@D6 ; Springe wenn Nein sub ebx, ebx @@D6: inc [(PortDesc esi).RXCount] ; Anzahl im Puffer erh”hen ; Prfen, ob noch mehr Zeichen vorliegen (FIFO) @@D7: mov dx, [(PortDesc esi).LSR] ; line status register in al, dx ; ...lesen test al, 01h ; noch Zeichen da ? jne @@D1 ; Ja: N„chstes Zeichen lesen ; Es liegen keine Zeichen mehr vor. Pufferzeiger rckspeichern. mov [(PortDesc esi).RXEnd], ebx ; Jetzt noch prfen, ob der Sender gestoppt werden muį, wenn der Puffer ; zu voll wird. mov eax, [(PortDesc esi).RXBufSize] ; Puffergr”įe nach eax shr eax, 1 ; / 2 mov ebx, eax shr eax, 1 ; / 4 add eax, ebx ; 3/4 Gr”įe in eax cmp [(PortDesc esi).RXCount], eax ; Puffer 3/4 voll ? jb @@D99 ; Nein: Kein Grund fr HostOff ; Falls RTS/CTS verwendet wird, RTS abschalten cmp [(PortDesc esi).Connection], 'M'; HW Control? jne @@D8 ; Springe wenn nein mov dx, [(PortDesc esi).MCR] in al, dx ; Sonst MCR lesen... and al, NOT MCR_RTS ; ...RTS off... out dx, al ; ...und wieder schreiben ; Falls Software Flow Control verwendet wird, XOFF absenden @@D8: cmp [(PortDesc esi).XonXoff], 'E' ; Enabled ? jnz @@D99 ; Nein: Fertig cmp [(PortDesc esi).HostOff], 00h ; Schon XOFF gesandt ? jnz @@D99 ; Ja: Keins mehr senden mov al, XOFF call SendII ; Zeichen abschicken mov [(PortDesc esi).HostOff], 01h ; und merken... ; Fertig, neu pollen @@D99: jmp @@RePoll ENDP IntCommon END estic-1.61.orig/spunk/dos32src/delay.cc0100644000176100001440000000171407031424711017221 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System dependent function for waiting some time. // This file is exactly the same as in the dos version #include "dossrc\delay.cc" estic-1.61.orig/spunk/dos32src/filesys.cc0100644000176100001440000000101607031424712017575 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // // This file is exactly the same as in the dos version #include "dossrc\filesys.cc" estic-1.61.orig/spunk/dos32src/kbd.cc0100644000176100001440000000162107031424712016661 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file is exactly the same as in the dos version #include "dossrc\kbd.cc" estic-1.61.orig/spunk/dos32src/nlsinit.cc0100644000176100001440000001660107031424712017605 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // 32-bit (Watcom) version of nlsinit module. The code below is not compatible // with the 16-bit version since the pmode/w DOS extender does not support the // dos call used, so we have to work around it. #include #include #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Structure that holds the real mode registers in an simulated real mode int struct RealModeRegs { u32 edi; u32 esi; u32 ebp; u32 reserved_by_system; u32 ebx; u32 edx; u32 ecx; u32 eax; u16 flags; u16 es,ds,fs,gs,ip,cs,sp,ss; }; // Country info struct from DOS #pragma PACK(1) struct CountryInfo { char ID; u16 Size; u16 Country; u16 CodePage; u16 Date; char CurrStr [5]; char ThSep [2]; char DecSep [2]; char DateSep [2]; char TimeSep [2]; char Curr; char CurrPlaces; char Time; u32 CaseMapFunc; char DataSep [2]; char Fill [10]; }; #pragma PACK() // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void GetCountryInfo (void far* InfoStruct, u16 InfoLen, unsigned char ID) { REGS Regs; SREGS SRegs; RealModeRegs RMRegs; // Allocate a real mode memory block big enough Regs.w.ax = 0x0100; Regs.w.bx = (InfoLen + 15) / 16; // Memory in paras int386 (0x31, &Regs, &Regs); u16 Segment = Regs.w.ax; u16 Selector = Regs.w.dx; // Set up the registers for the simulated real mode interrupt memset (&RMRegs, 0, sizeof (RMRegs)); RMRegs.eax = 0x6500 | ID; RMRegs.ebx = (u32) -1; RMRegs.ecx = InfoLen; RMRegs.edx = (u32) -1; RMRegs.edi = 0; // Offset of low memory block RMRegs.es = Segment; // Segment of low memory block // Use the DPMI function 300h to simulate the real mode int memset (&SRegs, 0, sizeof (SRegs)); Regs.w.ax = 0x0300; Regs.w.bx = 0x0021; Regs.w.cx = 0x0000; SRegs.es = FP_SEG (&RMRegs); Regs.x.edi = FP_OFF (&RMRegs); int386x (0x31, &Regs, &Regs, &SRegs); // Copy the data from real mode memory _fmemcpy (InfoStruct, MK_FP (Selector, 0), InfoLen); // Free the real mode memory block Regs.w.ax = 0x101; Regs.w.dx = Selector; int386 (0x31, &Regs, &Regs); } void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { CountryInfo Info; // Get country information GetCountryInfo (&Info, sizeof (Info), 0x01); // Try if there is an override for the country in the environment unsigned Country = GetEnvNum ("SPUNK_COUNTRY", Info.Country); // Set the country data NLSSetCountry (Country); // Try if there is an override for the language in the environment unsigned Language = GetEnvNum ("SPUNK_LANGUAGE", NLSGetDefaultLanguage (Country)); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/dos32src/screen.cc0100644000176100001440000000162507031424712017404 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file is exactly the same as in the dos version #include "dossrc\screen.cc" estic-1.61.orig/spunk/dos32src/sercom.cc0100644000176100001440000006700107031424712017415 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // DOS32 version (DOS4G extender). // The DOS4G version of this module is just an OOP class that hides an older // assembler/C module for serial communication, that has been ported to // protected mode. Because of the history of this older module, comments // are in german, sorry. #include #include "check.h" #include "delay.h" #include "sercom.h" /******************************************************************************/ /* Function prototypes for the external assembler functions */ /******************************************************************************/ #ifdef __WATCOMC__ // For Watcom C specify new attributes for the pascal calling convention. // The routines in the assembler module expect the ds segment register to // contain the default data segment, so tell the compiler to reload ds // before calling a function specified as pascal #pragma aux __pascal "^" \ parm reverse routine [] \ value struct float struct caller [] \ modify [eax ebx ecx edx]; #endif // Type of a port handle typedef struct _ComData* HCOMPORT; extern "C" { HCOMPORT pascal _ComInstall (HCOMPORT Port); /* Installiert den COM-Port, ”ffnet ihn aber nicht. Zurck kommt ein Port- * Handle das $FFFF ist wenn ein Fehler aufgetreten ist (Port existiert nicht). * Dieses PortHandle muį bei der sp„teren Kommunikation mit den brigen Routinen * des Pakets angegeben werden. */ void pascal _ComDeinstall (HCOMPORT Port); /* Deinstalliert einen Port. Falls der Port noch offen ist wird er von der * Prozedur zuerst geschlossen. */ int pascal _ComIsInstalled (HCOMPORT Port); /* Ergibt den Wert 1 wenn der Port installiert ist, ansonsten 0. */ void pascal _ComOpen (HCOMPORT Port); /* ™ffnet den Port */ void pascal _ComClose (HCOMPORT Port); /* Schlieįt den Port */ int pascal _ComIsOpen (HCOMPORT Port); /* Ergibt den Wert 1 wenn der Port ge”ffnet ist, ansonsten 0. */ void pascal _ComDTROn (HCOMPORT Port); /* Macht die DTR-Leitung aktiv und gibt damit der Gegenstelle das Zeichen, daį * der Port aktiv ist. */ void pascal _ComDTROff (HCOMPORT Port); /* Macht die DTR-Leitung inaktiv und gibt damit der Gegenstelle zu erkennen, * daį der Port (bzw. der PC) inaktiv ist. */ void pascal _ComRTSOn (HCOMPORT Port); // Activate the RTS line. This is allowed only if the connection type of the // port is *not* 'M'odem. void pascal _ComRTSOff (HCOMPORT Port); // Deactivate the RTS line. This is allowed only if the connection type of the // port is *not* 'M'odem. unsigned pascal _ComRXSize (HCOMPORT Port); /* Gibt die Gr”įe des Empfangspuffers zurck */ unsigned pascal _ComRXCount (HCOMPORT Port); /* Gibt die Anzahl Zeichen im Empfangspuffer zurck */ void pascal _ComRXClear (HCOMPORT Port); /* L”scht den kompletten Sendepuffer */ unsigned pascal _ComTXSize (HCOMPORT Port); /* Gibt die Gr”įe des Sendepuffers zurck */ unsigned pascal _ComTXCount (HCOMPORT Port); /* Gibt die Anzahl der Zeichen im Sendepuffer zurck */ unsigned pascal _ComTXFree (HCOMPORT Port); /* Gibt die Anzahl freier Pl„tze im Sendepuffer zurck */ void pascal _ComTXClear (HCOMPORT Port); /* L”scht den kompletten Sendepuffer */ int pascal _ComReceive (HCOMPORT Port); /* Holt ein Zeichen aus dem Empfangspuffer fr den spezifizierten Port. Ist * der Puffer leer, so kommt -1 zurck. */ int pascal _ComSend (HCOMPORT Port, unsigned char B); /* Sendet ein Zeichen (legt es im Sendepuffer ab). Ist der Sendepuffer voll, * so wird der entsprechende Fehlerz„hler hochgez„hlt und das Zeichen wird * weggeworfen. */ void pascal _ComBreak (HCOMPORT Port, double Duration); /* Sendet ein Break mit der bergebenen Dauer (in Sekunden). Die Funktion * kehrt erst nach Ablauf dieser Zeit zurck. */ unsigned pascal _ComModemStatus (HCOMPORT Port); /* Gibt den Modemstatus (Status der Kontrolleitungen) fr den gewnschten Port * zurck. Die Bits k”nnen anhand der weiter oben definierten Konstanten aus- * gewertet werden. */ void pascal _IntCom1 (); void pascal _IntCom2 (); void pascal _IntCom3 (); void pascal _IntCom4 (); // Interrupt-Handlers for port 1..4 }; /*****************************************************************************/ /* struct _ComData */ /*****************************************************************************/ // All implementation dependant data is contained in a structure that is // defined in the CC file. struct _ComData { // Port-Definitione (duplicated) u32 Baudrate; char Connection; // irect, odem char Parity; // one, dd, ven, pace, ark char Stopbits; // 1, 2 char Databits; // 5..8 char XonXoff; // nabled, isabled char Fill1 [3]; // Make the offset even // Circular buffer void* RXBuf; void* TXBuf; u32 RXBufSize; u32 TXBufSize; u32 RXStart; u32 RXEnd; u32 TXStart; u32 TXEnd; u32 RXCount; u32 TXCount; // Error counters ComErrorCounter ErrorCounter; char Installed; // Don't use char IntNr; // Number of the interrupt used char IC1Mask; // Mask for interrupt controller #1 char NotIC1Mask; // Complement of the above mask char IC2Mask; // ... the same for IC #2 char NotIC2Mask; char FIFOLen; // Don't use char ParityMask; // Don't use u16 PortAddress; // UART-Address u16 Reserved [6]; char Fill2 [2]; void pascal (*IntHandler) (); void far* OldVector; char HostOff; char PCOff; char MustSend; char DSR_CTS_Ok; }; /*****************************************************************************/ /* Predefined _ComData structs, one for every port on the PC */ /*****************************************************************************/ // It seems that Watcom mangles variable names (is this standard?) extern "C" { // Descriptor for COM 1 _ComData _ComPort1 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) { 0, 0, 0 }, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0C, // * IntNr 0x10, // * IC1Mask 0xEF, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x3F8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 0 }, // Make the offset even _IntCom1, // Offset Interrupt-Handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // DSR_CTS_Ok }; // Descriptor for COM 2 _ComData _ComPort2 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) { 0, 0, 0 }, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Fehlerz„hler 0, // Installed 0x0B, // * IntNr 0x08, // * IC1Mask 0xF7, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x2F8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 0 }, // Make the offset even _IntCom2, // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // DSR_CTS_Ok }; // Descriptor for COM 3 _ComData _ComPort3 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) { 0, 0, 0 }, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0C, // * IntNr 0x10, // * IC1Mask 0xEF, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x3E8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 0 }, // Make the offset even _IntCom3, // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // DSR_CTS_Ok }; // Descriptor for COM 4 _ComData _ComPort4 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) { 0, 0, 0 }, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0B, // * IntNr 0x08, // * IC1Mask 0xF7, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x2E8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved { 0, 0 }, // Make the offset even _IntCom4, // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // DSR_CTS_Ok }; } // extern "C" /*****************************************************************************/ /* Code */ /*****************************************************************************/ extern "C" void pascal _ComError () // Error routine that is called on parameter errors from the assembler module { FAIL ("_ComError: Error in _SERCOM assembler module"); } extern "C" u32 pascal _ComWait (u32 ms) // Wait routine that is called from the assembler module. It returns the time // actually waited { delay (ms); return ms; } extern u32 CodeBase (); #pragma aux CodeBase = \ " mov bx, cs" \ " mov ax, 0006h" \ " int 31h" \ " rol ecx, 16" \ " mov cx, dx" \ modify [ebx eax edx] \ value [ecx] extern u32 DataBase (); #pragma aux DataBase = \ " mov bx, ds" \ " mov ax, 0006h" \ " int 31h" \ " rol ecx, 16" \ " mov cx, dx" \ modify [ebx eax edx] \ value [ecx] extern void LockLinearRegion (u32 Adr, u32 Size); #pragma aux LockLinearRegion = \ " mov ebx, ecx" \ " rol ebx, 16" \ " mov esi, edi" \ " rol esi, 16" \ " mov ax, 0600h" \ " int 31h" \ parm [ecx] [edi] \ modify [eax ebx ecx edx edi esi] extern void UnlockLinearRegion (u32 Adr, u32 Size); #pragma aux UnlockLinearRegion = \ " mov ebx, ecx" \ " rol ebx, 16" \ " mov esi, edi" \ " rol esi, 16" \ " mov ax, 0601h" \ " int 31h" \ parm [ecx] [edi] \ modify [eax ebx ecx edx edi esi] /*****************************************************************************/ /* class ComPort */ /*****************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned UARTBase, unsigned IntNum): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (512), TXBufSize (512), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { // Initialize the stuff Init (UARTBase, IntNum); // Lock the interrupt handler code and data in memory LockLinearRegion (CodeBase () + u32 (ComData->IntHandler), 4096); LockLinearRegion (DataBase () + u32 (ComData), sizeof (*ComData)); } ComPort::~ComPort () // Destruct a ComPort object { // If the port is installed, deinstall it (this will also close the port) if (_ComIsInstalled (ComData)) { _ComDeinstall (ComData); } // Free the buffers and reset the buffer pointers delete [] ComData->RXBuf; delete [] ComData->TXBuf; ComData->RXBuf = NULL; ComData->TXBuf = NULL; // Unlock the interrupt handler code and data in memory UnlockLinearRegion (CodeBase () + u32 (ComData->IntHandler), 4096); UnlockLinearRegion (DataBase () + u32 (ComData), sizeof (*ComData)); } void ComPort::Init (unsigned UARTBase, unsigned IntNum) // Initialization procedure, called from the constructors { static const u16 DefPortAddress [4] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }; static const unsigned char DefIntNr [4] = { 0x0C, 0x0B, 0x0C, 0x0B }; static _ComData* DefComData [4] = { &_ComPort1, &_ComPort2, &_ComPort3, &_ComPort4 }; // Assign one of the predefined ComData structures. To do this, the name // is examined, it must contain COMX where X is a number between 1 and 4. PortName.ToUpper (); if (PortName.Cut (0, 3) != "COM" && PortName.Len () != 4) { FAIL ("ComPort::Init: Invalid port name"); } // Check the last char unsigned Port; switch (PortName [3]) { case '1': Port = 0; break; case '2': Port = 1; break; case '3': Port = 2; break; case '4': Port = 3; break; default: FAIL ("ComPort::Init: Invalid port name"); break; } // Assign the ComData struct ComData = DefComData [Port]; // Transfer the parameters into the ComData struct ComData->Baudrate = Baudrate; ComData->Connection = Connection; ComData->Databits = Databits; ComData->Parity = Parity; ComData->Stopbits = Stopbits; ComData->XonXoff = XonXoff; ComData->RXBuf = NULL; ComData->TXBuf = NULL; // Assign the port address or use the default if zero if (UARTBase == 0) { UARTBase = DefPortAddress [Port]; } ComData->PortAddress = UARTBase; // Assign the interrupt number or use the default if zero. if (IntNum == 0) { IntNum = DefIntNr [Port]; } ComData->IntNr = IntNum; // Calculate the IC masks if (IntNum >= 0x08 && IntNum <= 0x0F) { // Low interrupt ComData->IC1Mask = 0x01 << (IntNum - 8); ComData->IC2Mask = 0x00; } else if (IntNum >= 0x70 && IntNum <= 0x77) { // High interrupt ComData->IC1Mask = 0x00; ComData->IC2Mask = 0x01 << (IntNum - 0x70); } else { FAIL ("ComPort::Init: Unsupported interrupt number"); } ComData->NotIC1Mask = ~ComData->IC1Mask; ComData->NotIC2Mask = ~ComData->IC2Mask; // Allocate the buffers SetBufferSize (RXBufSize, TXBufSize); // Install the port _ComInstall (ComData); } void ComPort::SetBufferSize (u16 aRXBufSize, u16 aTXBufSize) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Assure reasonable max and min values and remember them if (aRXBufSize < 64) { aRXBufSize = 64; } else if (aRXBufSize > 4096) { aRXBufSize = 4096; } RXBufSize = aRXBufSize; if (aTXBufSize < 64) { aTXBufSize = 64; } else if (aTXBufSize > 4096) { aTXBufSize = 4096; } TXBufSize = aTXBufSize; // Free the (possibly already existing) buffers delete [] ComData->RXBuf; delete [] ComData->TXBuf; // Allocate new buffers ComData->RXBuf = new char [RXBufSize]; ComData->TXBuf = new char [TXBufSize]; // Record the new sizes ComData->RXBufSize = RXBufSize; ComData->TXBufSize = TXBufSize; } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // All possible errors happen on _ComInstall, so check if the port // is installed if (_ComIsInstalled (ComData)) { // Error free, open the port and exit _ComOpen (ComData); return 0; } else { // Return a generic error code return 1; } } void ComPort::Close () // Close the port { _ComClose (ComData); } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return _ComIsOpen (ComData); } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { RXTimeout = aRXTimeout; } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { TXTimeout = aTXTimeout; } void ComPort::DTROn () // Make the DTR line active { _ComDTROn (ComData); } void ComPort::DTROff () // Make the DTR line inactive { _ComDTROff (ComData); } void ComPort::RTSOn () // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem { _ComRTSOn (ComData); } void ComPort::RTSOff () // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem { _ComRTSOff (ComData); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer { return _ComRXCount (ComData); } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { return _ComTXCount (ComData); } void ComPort::RXClear () // Clear the receive buffer { _ComRXClear (ComData); } void ComPort::TXClear () // Clear the transmit buffer { _ComTXClear (ComData); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer { return _ComTXFree (ComData); } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { return _ComReceive (ComData); } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { return _ComSend (ComData, B); } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { // Calculate the time to wait in ms u32 Wait = RXTimeout * 1000; // Wait until a character is available or timeout do { if (_ComRXCount (ComData)) { // A character is available, grab it return _ComReceive (ComData); } // Wait some time. u16 ActualWait = Wait > 10 ? 10 : Wait; ActualWait = _ComWait (ActualWait); // Reduce the time to wait if (ActualWait > Wait) { Wait = 0; } else { Wait -= ActualWait; } } while (Wait > 0); // Timeout return -1; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Calculate the time to wait in ms u32 Wait = TXTimeout * 1000; // Wait until the char can be put in the queue or timeout do { if (_ComTXFree (ComData)) { // There is a free position in the output queue return _ComSend (ComData, B); } // Wait some time. u16 ActualWait = Wait > 10 ? 10 : Wait; ActualWait = _ComWait (ActualWait); // Reduce the time to wait if (ActualWait > Wait) { Wait = 0; } else { Wait -= ActualWait; } } while (Wait > 0); // Timeout. Do an unconditional Send return _ComSend (ComData, B); } void ComPort::TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount) // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. { // Check the given parameters PRECONDITION (Count > 0); // Cast the buffer pointer unsigned char* Buf = (unsigned char*) Buffer; // No characters received until now ReadCount = 0; // Read all chars in a loop while (Count > 0) { // Try to receive a char int C = TimedReceive (); if (C == -1) { // Timeout return; } // Store the char Buf [ReadCount++] = (unsigned char) C; // One less Count--; } // Timeout return; } void ComPort::TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount) // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. { // Check the given parameters PRECONDITION (Count > 0); // Cast the buffer pointer const unsigned char* Buf = (const unsigned char*) Buffer; // No characters sent until now WriteCount = 0; // Write all chars in a loop while (Count > 0) { // Try to send the char if (TimedSend (Buf [WriteCount]) == -1) { // Timeout return; } // One more WriteCount++; Count--; } } void ComPort::Break (double Duration) // Send a break with the given time in seconds { _ComBreak (ComData, Duration * 1000.0); } ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { return _ComModemStatus (ComData); } estic-1.61.orig/spunk/dos32src/winattr.cc0100644000176100001440000000162607031424712017616 0ustar debacleusers/*****************************************************************************/ /* */ /* WINATTR.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file is exactly the same as in the dos version #include "dossrc\winattr.cc" estic-1.61.orig/spunk/dossrc/0040755000176100001440000000000007061535304015453 5ustar debacleusersestic-1.61.orig/spunk/dossrc/_sercom.asm0100644000176100001440000015474207031424712017613 0ustar debacleusers; ***************************************************************************** ; * * ; * _SERCOM.ASM * ; * * ; * (C) 1991-96 Ullrich von Bassewitz * ; * Zwehrenbuehlstrasse 33 * ; * D-72070 Tuebingen * ; * EMail: uz@ibb.schwaben.com * ; * * ; ***************************************************************************** ; $Id$ ; ; $Log$ ; ; ; This is a simple module for serial communication under DOS based on a module ; called USER. The module supports up to four ports, 16550s and the "high" ; interrupts. ; Comments are in german, sorry. ; *************************************************************************** IDEAL ; IDEAL-Modus von TASM einschalten JUMPS ; Sprungoptimierung LOCALS ; Lokale Symbole zulassen SMART ; "Schlauen" Modus einschalten MODEL LARGE ; Im LARGE Modell bersetzen ; ------------------------------------------------------------------- ; ; Zeichen fr Flow-Control bei XON/XOFF ; XON = 11H ; XON XOFF = 13H ; XOFF ; ------------------------------------------------------------------- ; ; Struktur fr die Daten eines jeden seriellen Ports. Von diesen Strukturen ; ist fr jeden untersttzten Port eine vorhanden. ; STRUC PortDesc ; Allgemeine Einstellungen Baudrate dd ? ; Baudrate Connection db ? ; M)odem, D)irect Parity db ? ; N)one, O)dd, E)ven, S)pace, M)ark StopBits db ? ; 1, 2 DataBits db ? ; 5..8 XonXoff db ? ; E)nabled, D)isabled db ? ; Fill auf gerade Adressen ; Ringpuffer fr Senden und Empfang incl Verwaltung RXBuf dd ? ; Zeiger auf Empfangspuffer TXBuf dd ? ; Zeiger auf Sendepuffer RXBufSize dw ? ; Gr”įe Empfangspuffer TXBufSize dw ? ; Gr”įe Sendepuffer RXStart dw 0 ; Ringpufferzeiger RXEnd dw 0 ; TXStart dw 0 TXEnd dw 0 RXCount dw 0 ; Anzahl Zeichen im Puffer TXCount dw 0 ; Anzahl Zeichen im Puffer ; Fehlerz„hler ERXOverflow dw 0 ; Pufferberlauf beim Empfang ETXOverflow dw 0 ; Pufferberlauf beim Senden EOvrRun dw 0 ; berlauf beim Empf„nger EBreak dw 0 ; Break EFrame dw 0 ; Framing Fehler EParity dw 0 ; Parity Fehler ErrorBlock EQU ERXOverFlow ; Interna Installed db 0 ; 1 wenn installiert IntNr db ? ; Interrupt-Nummer IC1Mask db ? ; Maske fr 8259A #1 NotIC1Mask db ? ; Komplement IC2Mask db ? ; Maske fr 8259A #2 NotIC2Mask db ? ; Komplement FIFOLen db ? ; Chunk-Size fr Sender-FIFO ParityMask db ? ; 7Fh wenn Parity, sonst 0FFh ; Adressen der Chip-Register DataReg dw ? ; data register DLL EQU DataReg ; divisor low latch IER dw ? ; interrupt enable register DLH EQU IER ; divisor high latch IIR dw ? ; interrupt id register (lesen) FCR EQU IIR ; FIFO control register (schreiben) LCR dw ? ; line control register MCR dw ? ; modem control register LSR dw ? ; line status register MSR dw ? ; modem status register IntHandler dw ? ; Offset des Interrupt-Handlers OldVector dd ? ; Alter Interrupt-Vektor HostOff db 0 ; Host Xoff'ed (1=ja, 0 = nein) PCOff db 0 ; PC Xoff'ed (1=ja, 0=nein) MustSend db 0 ; Es _muį_ ein Byte gesendet werden DSR_CTS_Ok db ? ; DSR und CTS sind beide On ENDS PortDesc ; ; Steuerbits fr das FCR des NS16550A. ; FIFO_ENABLE = 001H ; FIFO einschalten FIFO_CLR_RX = 002H ; RX-FIFO l”schen FIFO_CLR_TX = 004H ; TX-FIFO l”schen FIFO_SZ_1 = 000H ; Warning level: 1 Bytes FIFO_SZ_4 = 040H ; Warning level: 4 Bytes FIFO_SZ_8 = 080H ; Warning level: 8 Bytes FIFO_SZ_14 = 0C0H ; Warning level: 14 Bytes FIFO_SZ_MASK = 0C0H ; Maske fr warning level ; ; FIFO Kommandos. In FIFO_INIT muį eingetragen werden, nach wievielen Bytes ; ein Interrupt erzeugt wird. Unter DOS sind normalerweise 14 Bytes ok, bei ; langsamen Rechnern (oder langsamen EMM) und hohen Zeichengeschwindigkeiten ; muį evtl. bereits nach 8 Zeichen ein Interrupt ausgel”st werden. ; Default ist Interrupt nach 8 Zeichen. ; FIFO_CLEAR = FIFO_CLR_RX OR FIFO_CLR_TX FIFO_INIT = FIFO_ENABLE OR FIFO_SZ_8 OR FIFO_CLR_RX OR FIFO_CLR_TX ; ; Sonstiges FIFO-Zeugs. ; FIFO_ENABLED = 0C0H ; Bitmuster wenn FIFO an ; ; Bits im Modem Control Register ; MCR_DTR = 00000001B MCR_RTS = 00000010B MCR_OUT2 = 00001000B ; ------------------------------------------------------------------- ; ; Externe Prozeduren, die das Programmiersprachenmodul zur Verfgung ; stellen muį. ; ; EXTRN PASCAL _COMWAIT : FAR ; Warte-Prozedur EXTRN PASCAL _COMERROR : FAR ; _ComError-Routine ; ------------------------------------------------------------------- ; ; Vom Assembler-Modul exportierte Routinen. ; PUBLIC _COMINSTALL PUBLIC _COMDEINSTALL PUBLIC _COMOPEN PUBLIC _COMCLOSE PUBLIC _COMISINSTALLED PUBLIC _COMISOPEN PUBLIC _COMDTROFF PUBLIC _COMDTRON PUBLIC _COMRTSOFF PUBLIC _COMRTSON PUBLIC _COMRXCOUNT PUBLIC _COMRXSIZE PUBLIC _COMRXCLEAR PUBLIC _COMTXCOUNT PUBLIC _COMTXSIZE PUBLIC _COMTXFREE PUBLIC _COMTXCLEAR PUBLIC _COMRECEIVE PUBLIC _COMSEND PUBLIC _COMBREAK PUBLIC _COMMODEMSTATUS ; Interrupt-Handler PUBLIC _INTCOM1 PUBLIC _INTCOM2 PUBLIC _INTCOM3 PUBLIC _INTCOM4 ; --------------------------------------------------------------------------- ; Datensegment ; DATASEG EXTRN C _ComPort1 : PortDesc EXTRN C _ComPort2 : PortDesc EXTRN C _ComPort3 : PortDesc EXTRN C _ComPort4 : PortDesc ; ------------------------------------------------------------------- ; ; Beginn Codesegment ; CODESEG ; ------------------------------------------------------------------------- ; ; _ComInstall ; ; Installiert einen Port mit der bergebenen Portnummer. Bei Erfolg wird das ; Handle (immer ein Wert <> 0) zurckgeliefert, ansonsten der Wert 0 als ; Handle. ; PROC PASCAL _ComInstall FAR PortHandle: WORD USES SI, DI mov si, [PortHandle] ; Porthandle holen ; si zeigt ab hier auf einen Record vom Typ PortDesc test [(PortDesc si).Installed], 01h ; Bereits installiert jz @@L3 ; Nein: Ok ; Fehler, Port war bereits installiert @@L1: call _ComError mov ax, -1 ; -1 als Handle liefern jmp @@L99 ; Port ist noch nicht installiert. Port-Adresse aus dem Default-Array holen ; und prfen, ob im entsprechenden BIOS-Bereich eine andere Adresse steht. ; Wenn Ja, dann diese andere Adresse bernehmen, wenn Nein, oder wenn diese ; andere Adresse eine 0 ist, den Default behalten. ; Dann prfen, ob diese Adresse _irgendwo_ im BIOS-Bereich als Adresse ; eingetragen ist. Fehler wenn nein. ; Der Sinn dieses ganzen Hin und Her ist es, auch etwas ungew”hnliche ; Installationen zu untersttzen, bei denen z.B. COM 3 fehlt aber COM 4 ; vorhanden ist. Das BIOS packt diese Adressen, so daį der Bereich von COM 4 ; leer ist und COM 3 die Adresse von COM 4 enth„lt. ; bx enth„lt noch immer (PortAdresse-1)*2 @@L3: mov ax, [(PortDesc si).DataReg] ; Grundadresse holen mov di, 040h ; BIOS-Segment mov es, di xor di, di ; BIOS-Offset COM Bereich cld mov cx, 4 repne scasw ; Adresse vorhanden ? je @@L4 ; Springe wenn Ja ; Fehler, die Adresse konnte nicht gefunden werden. -1 als Handle liefern. mov ax, -1 ; Handle = -1 jmp @@L99 ; und Ende ; Adresse ist Ok, die gesamten Adressen in den Deskriptor-Record eintragen @@L4: push ds pop es lea di, [(PortDesc ds:si).DataReg] ; Adresse erstes Register mov cx, 7 ; 7 Register pro Chip @@L5: stosw ; Eintragen inc ax ; N„chste Adresse loop @@L5 ; Die Fehlerz„hler nullen xor ax, ax ; 0 nach ax lea di, [(PortDesc si).ErrorBlock] ; Erster Z„hler mov cx, 6 ; 6 Fehlerz„hler rep stosw ; l”schen ; Prfen ob der Port einen 16550A besitzt. Die Anzahl der Bytes die bei einem ; "Transmit-Register leer"-Interrupt geschrieben werden k”nnen vermerken. Diese ; Anzahl ist 1 ohne FIFO und bis zu 14 mit FIFO. mov dx, [(PortDesc si).FCR] ; FIFO control register holen mov al, FIFO_INIT OR FIFO_ENABLED ; FIFO... out dx, al ; ... einschalten in al, dx ; Wert wieder holen and al, FIFO_ENABLED ; FIFO-Bits ausmaskieren mov ah, 1 ; annehmen, daį kein FIFO da cmp al, FIFO_ENABLED ; Ist es ein 16550A ? jne @@L6 ; Springe wenn keiner mov ah, 16 ; 16 Sendebytes wenn FIFO vorh. @@L6: mov [(PortDesc si).FIFOLen], ah ; Wert merken ; FIFO (falls vorhanden) erstmal wieder ausschalten mov al, FIFO_CLEAR out dx, al ; Interrupt-Vektor retten und eigenen Vektor setzen mov ah, 35h mov al, [(PortDesc si).IntNr] ; Nummer des Interrupts int 21h ; Vektor holen mov [WORD LOW (PortDesc si).OldVector], bx mov [WORD HIGH (PortDesc si).OldVector], es push ds mov ah, 25h mov al, [(PortDesc si).IntNr] ; Nummer des Interrupts mov dx, [(PortDesc si).IntHandler] ; push cs pop ds int 21h ; Vektor setzen pop ds ; Den Port als installiert markieren und das Handle in ax rckliefern mov [(PortDesc si).Installed], 01h ; Bit 0 setzen mov ax, si ; Handle nach ax ; Das wars: Funktionsausgang. @@L99: ret ENDP _ComInstall ; ------------------------------------------------------------------------- ; ; _ComDeInstall ; ; Deinstalliert den Port mit dem bergebenen Handle. ; PROC PASCAL _ComDeInstall FAR PortHandle: WORD USES SI, DI mov si, [PortHandle] ; Deskriptor holen ; Prfen ob der Port installiert ist. Fehler wenn nicht. test [(PortDesc si).Installed], 01h ; Installiert ? jnz @@L1 ; Springe wenn ja ; Fehler: Port ist nicht installiert call _ComError ; Fehler melden jmp @@L99 ; Und Ende ; Port ist installiert. Falls der Port auch gleichzeitig offen ist, zuerst ; schlieįen @@L1: test [(PortDesc si).Installed], 02h ; Offen ? jz @@L2 ; Springe wenn Nein push si ; PortHandle als Parameter call _ComClose ; Port schlieįen mov si, [PortHandle] ; PortHandle neu laden ; Install-Merker rcksetzen @@L2: and [(PortDesc si).Installed], NOT 01h ; Interrupt-Vektor rcksetzen. push ds mov ah, 25h mov al, [(PortDesc si).IntNr] ; Nummer des belegten Interrupts mov dx, [WORD LOW (PortDesc si).OldVector] mov ds, [WORD HIGH (PortDesc si).OldVector] int 21h ; Vektor rcksetzen pop ds ; Ende @@L99: ret ENDP _ComDeInstall ; ------------------------------------------------------------------------- ; ; _ComOpen ; ; Setzt Baudrate etc., l”scht die Puffer, gibt die Interrupts frei, kurz: ; Setzt den RS232-Betrieb in Gang. ; PROC PASCAL _ComOpen FAR PortHandle: WORD USES SI, DI ; Zeiger auf den Port-Deskriptor nach si mov si, [PortHandle] ; Prfen ob der Port installiert ist. Fehler wenn nicht. test [(PortDesc si).Installed], 01h jnz @@L0 ; Springe wenn installiert call _ComError ; Fehler-Routine jmp @@L99 ; Prfen ob der Port bereits offen ist, wenn ja zuerst schlieįen @@L0: test [(PortDesc si).Installed], 02h ; Offen ? jz @@L1 ; Nein: Springe push si ; Parameter fr ComClose call _ComClose ; Schlieįen mov si, [PortHandle] ; Handle neu laden ; Eine der Parit„t entsprechende AND-Maske setzen @@L1: mov al, 0FFh ; Maske fr kein Parity cmp [(PortDesc si).Parity], 'N' ; Parity ? jz @@L2 ; Springe wenn Nein mov al, 07Fh ; Maske wenn Parity @@L2: mov [(PortDesc si).ParityMask], al ; Maske merken ; Flow-Control rcksetzen xor ax, ax mov [(PortDesc si).HostOff], al ; mov [(PortDesc si).PCOff], al mov [(PortDesc si).MustSend], al mov [(PortDesc si).DSR_CTS_Ok], al ; Puffer rcksetzen mov [(PortDesc si).TXStart], ax mov [(PortDesc si).TXEnd], ax mov [(PortDesc si).TXCount], ax mov [(PortDesc si).RXStart], ax mov [(PortDesc si).RXEnd], ax mov [(PortDesc si).RXCount], ax ; UART initialisieren mov dx, [(PortDesc si).MCR] ; modem control register mov al, 0 ; clr dtr, rts, out1, out2 & loopback out dx, al cmp [(PortDesc si).Connection], 'D' ; Direkte Verbindung ? jz @@L3 ; Springe wenn ja mov dx, [(PortDesc si).MSR] ; modem status register in al, dx ; modem status lesen and al, 30h ; DSR, CTS maskieren cmp al, 30h ; DSR, CTS prfen jnz @@L4 ; Springe wenn nicht ok @@L3: mov [(PortDesc si).DSR_CTS_Ok], 01h ; Beide da, Ausgang Ok @@L4: mov dx, [(PortDesc si).FCR] ; FIFO control register mov al, FIFO_CLEAR ; FIFO ausschalten out dx, al mov dx, [(PortDesc si).LSR] ; line status register... in al, dx ; ...rcksetzen mov dx, [(PortDesc si).DataReg] ; Datenregister in al, dx ; ...rcksetzen mov dx, [(PortDesc si).MSR] ; modem status register... in al, dx ; ...rcksetzen ; Baudrate in Divisor umrechnen und setzen cmp [WORD HIGH (PortDesc si).Baudrate], 0 jz @@L5 ; Baudrate < 65536 mov bx, 1 ; Divisor fr 115200 jmp @@L6 @@L5: mov ax, 0C200h ; 115200 MOD 10000h mov dx, 00001h ; 115200 DIV 10000h div [WORD LOW (PortDesc si).Baudrate] mov bx, ax ; Ergebnis nach bx ; Baudrate am UART einstellen @@L6: mov dx, [(PortDesc si).LCR] ; line control register mov al, 80h ; DLAB = 1 out dx, al xchg ax, bx ; Divisor nach ax mov dx, [(PortDesc si).DLL] ; divisor low out dx, al ; lsb ausgeben mov dx, [(PortDesc si).DLH] ; divisor high xchg ah, al out dx, al ; msb ausgeben ; Parity und Anzahl Stop- und Daten-Bits setzen mov al, 00h ; Bits in al zusammenbauen mov ah, [(PortDesc si).Parity] cmp ah, 'O' ; odd ? jne @@L7 or al, 0Ah ; odd ! jmp @@L9 @@L7: cmp ah, 'E' ; even ? jne @@L8 or al, 1Ah ; even ! jmp @@L9 @@L8: cmp ah, 'M' ; mark ? jne @@L9 or al, 2Ah ; mark ! @@L9: cmp [(PortDesc si).StopBits], 2 ; 2 Stop-Bits ? jnz @@L10 or al, 04h @@L10: mov ah, [(PortDesc si).DataBits] ; Anzahl Datenbits holen sub ah, 5 ; 5..8 --> 0..3 and ah, 3 ; maskieren or al, ah ; und reinodern mov dx, [(PortDesc si).LCR] ; line control register out dx, al ; parity mode & DLAB = 0 ; FIFO's initalisieren (wird ignoriert wenn nicht 16550A) mov dx, [(PortDesc si).FCR] ; FIFO control register mov al, FIFO_INIT out dx, al ; Interrupts freigeben cli ; Interrupts aus in al, 0A1h ; Int-Controller #2 and al, [(PortDesc si).NotIC2Mask] ; Bit l”schen out 0A1h, al ; und wieder ausgeben in al, 021h ; Int-Controller #1 and al, [(PortDesc si).NotIC1Mask] ; Bit l”schen out 021h, al ; und wieder ausgeben sti ; Interrupts an mov dx, [(PortDesc si).IER] ; interrupt enable register mov al, 00001101B ; line & modem status, rec... out dx, al ; ...freigeben mov dx, [(PortDesc si).MCR] ; modem control register mov al, MCR_OUT2 ; OUT2, kein RTS, kein DTR cmp [(PortDesc si).Connection], 'M' ; Modem connection? jne @@L11 ; Nein: Skip or al, MCR_RTS ; Ja: RTS aktiv setzen @@L11: out dx, al ; setzen ; Port als Open markieren. or [(PortDesc si).Installed], 02h ; Ende @@L99: ret ENDP _ComOpen ; ------------------------------------------------------------------------- ; ; _ComClose ; ; Schlieįt einen Com-Port ; PROC PASCAL _ComClose FAR PortHandle: WORD ; Prfen ob der Port berhaupt offen ist mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Springe wenn Port nicht offen ; Interrupts an UART abklemmen, FIFO abschalten cli ; Keine Interrupts mov dx, [(PortDesc bx).MCR] ; modem control register mov al, 0 ; Kein RTS, DTR, OUT2 out dx, al mov dx, [(PortDesc bx).IER] ; interrupt enable register out dx, al ; Shut up ! mov dx, [(PortDesc bx).FCR] mov al, FIFO_CLEAR out dx, al ; FIFO ausschalten ; Interrupt-Controller abschalten in al, 0A1h ; Int-Controller #2 or al, [(PortDesc bx).IC2Mask] out 0A1h, al ; Interrupt sperren in al, 021h ; Int-Controller #1 or al, [(PortDesc bx).IC1Mask] out 021h, al ; Interrupt sperren ; DTR und RTS l”schen mov dx, [(PortDesc bx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT (MCR_DTR OR MCR_RTS) ; DTR l”schen... out dx, al ; ...und wieder setzen ; Vermerken, daį der Port nicht mehr offen ist und Ende and [(PortDesc bx).Installed], NOT 02h sti ; Interrupts wieder zulassen @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComClose ; ---------------------------------------------------------------------- ; ; _ComDTROff ; ; Schaltet DTR auf off ; PROC PASCAL _ComDTROff FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Port ist offen, Aktion durchfhren mov dx, [(PortDesc bx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT MCR_DTR ; DTR l”schen... out dx, al ; ...und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComDTROff ; ------------------------------------------------------------------------- ; ; _ComDTROn ; ; Schaltet DTR auf aktiv ; PROC PASCAL _ComDTROn FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Port nicht offen ; Port ist offen, DTR setzen mov dx, [(PortDesc bx).MCR] ; modem control register in al, dx ; Register lesen or al, MCR_DTR ; DTR aktiv... out dx, al ; und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComDTROn ; ---------------------------------------------------------------------- ; ; _ComRTSOff ; ; Schaltet RTS auf off ; PROC PASCAL _ComRTSOff FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error cmp [(PortDesc bx).Connection], 'M' ; Modem connection? je @@Error ; Dann Aufruf nicht erlaubt ; Port ist offen, RTS rcksetzen mov dx, [(PortDesc bx).MCR] ; modem control register in al, dx ; Register lesen and al, NOT MCR_RTS ; RTS l”schen... out dx, al ; ...und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComRTSOff ; ------------------------------------------------------------------------- ; ; _ComRTSOn ; ; Schaltet RTS auf aktiv ; PROC PASCAL _ComRTSOn FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Port nicht offen cmp [(PortDesc bx).Connection], 'M' ; Modem connection? je @@Error ; Dann Aufruf nicht erlaubt ; Port ist offen, RTS setzen mov dx, [(PortDesc bx).MCR] ; modem control register in al, dx ; Register lesen or al, MCR_RTS ; RTS aktiv... out dx, al ; und wieder setzen ; Ende @@L99: ret ; Fehlereinsprung @@Error:call _ComError jmp @@L99 ENDP _ComRTSOn ; ------------------------------------------------------------------------- ; ; _ComIsInstalled ; ; Ergibt einen Wert != 0 wenn der Port installiert ist. ; PROC PASCAL _ComIsInstalled FAR PortHandle: WORD mov bx, [PortHandle] mov bl, [(PortDesc bx).Installed] xor ax, ax test bl, 01h ; Installiert ? jz @@L1 ; Springe wenn Nein inc ax ; Installiert ! @@L1: ret ENDP _ComIsInstalled ; ------------------------------------------------------------------------- ; ; _ComIsOpen ; ; Ergibt einen Wert != 0 wenn der Port ge”ffnet ist. ; PROC PASCAL _ComIsOpen FAR PortHandle: WORD mov bx, [PortHandle] mov bl, [(PortDesc bx).Installed] xor ax, ax test bl, 02h ; Offen ? jz @@L1 ; Springe wenn Nein inc ax ; Offen ! @@L1: ret ENDP _ComIsOpen ; ------------------------------------------------------------------------- ; ; _ComReceive ; ; Holt ein Zeichen aus dem Empfangspuffer. Warte bis ein Zeichen da ist. Bei ; Fehlern kommt -1 als Wert zurck. ; PROC PASCAL _ComReceive FAR PortHandle: WORD USES SI, DI mov si, [PortHandle] test [(PortDesc si).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn Nein ; Port ist offen, prfen ob Zeichen da @@L1: cmp [(PortDesc si).RXCount], 0 ; Zeichen da ? jnz @@L2 ; Abholen wenn ja ; Es ist kein Zeichen da - erstmal warten, dabei die _ComWait Routine ; aufrufen mov ax, 10 ; 10ms push ax call _ComWait jmp @@L1 ; Zeichen ist da, holen. Da die Interrupt-Routinen nicht auf den ; RXStart-Zeiger zugreift, mssen die Interrupts nicht gesperrt ; werden. @@L2: mov bx, [(PortDesc si).RXStart] ; Ringpufferzeiger les di, [(PortDesc si).RXBuf] ; Zeiger auf Pufferbereich mov al, [es:di+bx] ; Zeichen holen inc bx ; Zeiger erh”hen mov ah, 0 ; Zeichen nach WORD wandeln push ax ; ... und auf den Stack cmp bx, [(PortDesc si).RXBufSize] ; Warp-Around ? jb @@L3 ; Springe wenn Nein xor bx, bx ; Ja, Ringpufferzeiger wird 0 @@L3: mov [(PortDesc si).RXStart], bx ; Zeiger rckschreiben dec [(PortDesc si).RXCount] ; Ein Zeichen weniger... ; Flow-Control prfen. Zuerst Hardware (RTS/CTS), dann Software mov bx, [(PortDesc si).RXBufSize] ; Gr”įe Puffer nach bx shr bx, 1 shr bx, 1 ; Gr”įe/4 in bx cmp [(PortDesc si).RXCount], bx ; Puffer fast leer ? jae @@L99 ; Ende wenn nicht cli ; Interrupts aus cmp [(PortDesc si).Connection], 'M' ; Modem connection? jne @@L4 ; Springe wenn nein mov dx, [(PortDesc si).MCR] in al, dx ; MCR lesen or al, MCR_RTS ; RTS setzen (Freigabe) out dx, al ; Jetzt prfen ob XON/XOFF Flow-Control an-, und der Sender abgeschaltet wurde @@L4: cmp [(PortDesc si).XonXoff], 'E' ; Flow-Control an ? jne @@L7 ; Ende wenn nicht cmp [(PortDesc si).HostOff], 00h ; XOFF-Status ? jz @@L7 ; Ende wenn nicht mov bx, [(PortDesc si).RXBufSize] ; Gr”įe Puffer nach bx ; Der Host ist gestoppt, der Puffer aber wieder leer genug. XON senden. @@L5: cmp [(PortDesc si).MustSend], 00h ; Zeichen im Puffer ? je @@L6 ; Springe wenn Nein ; Es ist noch ein Steuerzeichen im Puffer. Warten bis es weg ist. sti ; Interrupts freigeben mov ax, 10 ; 10 ms push ax call _ComWait ; Warteroutine aufrufen mov si, [PortHandle] ; Handle neu laden cli ; Interrupts wieder aus jmp @@L5 ; und neu prfen... ; Das Kontrollzeichen kann ausgegeben werden @@L6: mov al, XON call SendII ; XON senden @@L7: sti ; Interrupts wieder freigeben ; Zeichen vom Stack und Ende @@L99: pop ax ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError ; Fehler melden mov ax, -1 ; Returncode -1 ret ENDP _ComReceive ; ------------------------------------------------------------------------- ; ; _ComRXCount ; ; Liefert die Anzahl Bytes im Empfangspuffer. ; PROC PASCAL _ComRXCount FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Alles klar, Anzahl liefern und Ende mov ax, [(PortDesc bx).RXCount] @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError ret ENDP _ComRXCount ; ------------------------------------------------------------------------- ; ; _ComRXSize ; ; Liefert die Gr”įe des Empfangspuffers. ; PROC PASCAL _ComRXSize FAR PortHandle: WORD mov bx, [PortHandle] mov ax, [(PortDesc bx).RXBufSize] ret ENDP _ComRXSize ; ------------------------------------------------------------------------- ; ; _ComRXClear ; ; L”scht den kompletten Empfangspuffer. Der Port muį offen sein. ; PROC PASCAL _ComRXClear FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Alles klar, Port ist offen xor ax, ax cli ; Interrupts sperren mov [(PortDesc bx).RXStart], ax mov [(PortDesc bx).RXEnd], ax mov [(PortDesc bx).RXCount], ax sti ; Interrupts freigeben @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError ret ENDP _ComRXClear ; ------------------------------------------------------------------------- ; ; _ComTXCount ; ; Liefert die Anzahl belegter Bytes im Sendepuffer ; PROC PASCAL _ComTXCount FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Springe wenn nicht offen ; Port ist offen. Anzahl holen und Ende mov ax, [(PortDesc bx).TXCount] @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError ret ENDP _ComTXCount ; ------------------------------------------------------------------------- ; ; _ComTXFree ; ; Liefert die Anzahl freier Bytes im Sendepuffer ; PROC PASCAL _ComTXFree FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Springe wenn nicht offen ; Port ist offen. Gr”įe - Belegte Bytes rechnen. ; VORSICHT: Dieser Wert kann negativ werden, da sich evtl. zus„tzliche ; Kontrollzeichen im Puffer befinden k”nnen. In einem solchen Fall ; einfach 0 liefern. mov ax, [(PortDesc bx).TXBufSize] ; Gesamtgr”įe dec ax ; Maximale Gr”įe fr Benutzer sub ax, [(PortDesc bx).TXCount] jnc @@L99 ; Springe wenn >= 0 xor ax, ax ; if (ax < 0) then ax := 0; @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError jmp @@L99 ENDP _ComTXFree ; ------------------------------------------------------------------------- ; ; _ComTXSize ; ; Liefert die Gr”įe des Sendepuffers. ; PROC PASCAL _ComTXSize FAR PortHandle: WORD mov bx, [PortHandle] mov ax, [(PortDesc bx).TXBufSize] ret ENDP _ComTXSize ; ------------------------------------------------------------------------- ; ; _ComTXClear ; ; L”scht den kompletten Sendespuffer. Der Port muį offen sein. ; ACHTUNG: Im Gegensatz zu ComRXClear k”nnen sich hier Steuerzeichen im Puffer ; befinden, deren L”schung fatal w„re. Falls sich ein Steuerzeichen im Puffer ; befindet ist es jedoch immer (!) das erste Zeichen im Puffer. PROC PASCAL _ComTXClear FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Alles klar, Port ist offen xor cx, cx ; Neue Anzahl Zeichen pushf ; I-Flag retten cli ; Interrupts sperren mov ax, [(PortDesc bx).TXEnd] cmp [(PortDesc bx).MustSend], 00h ; Steuerzeichen im Puffer ? jz @@L2 ; Springe wenn Nein ; Ein Zeichen im Puffer lassen inc cx ; Anzahl = 1 nach Clear or ax, ax ; Index schon 0? jnz @@L1 ; Springe wenn nein mov ax, [(PortDesc bx).TXBufSize] ; Gr”įe laden @@L1: dec ax ; - 1 ; Puffer l”schen @@L2: mov [(PortDesc bx).TXStart], ax mov [(PortDesc bx).TXCount], cx ; Neue Anzahl popf ; Altes I-Flag @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComTXClear ; ------------------------------------------------------------------------- ; ; _ComSend ; ; Abschicken eines Zeichens. ; PROC PASCAL _ComSend FAR PortHandle: WORD, C: BYTE USES SI, DI mov si, [PortHandle] test [(PortDesc si).Installed], 02h ; Port offen ? jz @@Error ; Springe wenn nein ; Port ist offen, prfen ob Platz im Puffer mov dx, [(PortDesc si).TXBufSize] ; Gr”įe des Puffers nach dx cmp [(PortDesc si).TXCount], dx ; noch Platz ? jae @@L4 ; Springe wenn Nein ; Es ist genug Platz. Zeichen schreiben. mov al, [C] ; Zeichen holen les di, [(PortDesc si).TXBuf] ; Zeiger auf Puffer holen cli ; Keine Interrupts mov bx, [(PortDesc si).TXEnd] ; Pufferzeiger holen mov [es:di+bx], al ; Zeichen in Puffer schreiben inc bx ; Pufferzeiger erh”hen cmp bx, dx ; Wrap-Around ? jb @@L1 ; Springe wenn Nein xor bx, bx ; Ringpufferzeiger auf 0 wenn ja @@L1: mov [(PortDesc si).TXEnd], bx ; Pufferzeiger rckschreiben inc [(PortDesc si).TXCount] ; Ein Zeichen mehr ; Wenn notwendig die Sende-Interrupts freischalten mov dx, [(PortDesc si).IER] ; Interrupt enable register in al, dx ; ... lesen test al, 02h ; Interrupts frei ? jnz @@L2 ; Ja, alles klar cmp [(PortDesc si).PCOff], 00h ; XOFF-Status ? jnz @@L2 ; Ja, nix unternehmen cmp [(PortDesc si).DSR_CTS_Ok], 00h ; Statusleitungen ok ? jz @@L2 ; Nein, nix unternehmen mov al, 00001111B ; out dx, al ; TX-Ints freischalten @@L2: sti ; Interrupts wieder frei mov al, [C] mov ah, 0 ; Zeichen nach ax ; Ende @@L99: ret ; Einsprung wenn Puffer voll @@L4: inc [(PortDesc si).ETXOverFlow] ; Fehlerz„hler erh”hen mov ax, -1 ; Fehlerkennung ret ; Und Ende ; Einsprung wenn Port nicht offen @@Error:call _ComError ; Fehler melden mov ax, -1 ; Fehlerkennung ret ; Ende ENDP _ComSend ; ------------------------------------------------------------------------- ; ; Interne Routine. Wird aufgerufen von ComReceive und vom RX-Interrupthandler ; wenn Flow-Control Zeichen verschickt werden mssen. ; si muį auf den Port-Deskriptor zeigen, Interrupts mssen gesperrt sein. ; al enth„lt das zu sendende Zeichen. ; PROC SENDII NEAR push bx push dx ; Register werden ben”tigt push di push es mov bx, [(PortDesc si).TXStart] ; Ringpufferzeiger holen les di, [(PortDesc si).TXBuf] ; Zeiger auf Pufferbereich mov dx, [(PortDesc si).TXBufSize] ; Puffergr”įe nach dx cmp [(PortDesc si).TXCount], dx ; Puffer voll ? jb @@L2 ; Springe wenn Nein ; Im Puffer ist kein Platz mehr (obwohl das eigentlich immer gew„hrleistet ; werden sollte !). Das kann eigentlich nur passieren, wenn direkt ; hintereinander zwei Flow-Control Zeichen geschickt werden... mov [es:bx+di], al ; Zerst”rt erstes Zeichen inc [(PortDesc si).ETXOverFlow] ; Fehlerz„hler erh”hen jmp @@L2 ; einfach weiter ; Im Puffer ist Platz, Zeichen an die erste Stelle schreiben dec bx ; Ergibt 0FFFF wenn bx = 0 jns @@L1 ; Springe wenn kein Wrap mov bx, dx ; Sonst Gr”įe-1 nach bx dec bx @@L1: mov [es:bx+di], al ; Zeichen schreiben mov [(PortDesc si).TXStart], bx ; Zeiger rckschreiben inc [(PortDesc si).TXCount] ; Ein Zeichen mehr ... ; Flag fr extra Zeichen setzen @@L2: mov [(PortDesc si).MustSend], 01h ; Flag setzen ; Falls notwendig Interrupts enablen mov dx, [(PortDesc si).IER] ; interrupt enable register in al, dx ; Wert holen test al, 02h ; TX-Ints frei ? jnz @@L99 ; Ja: Ende cmp [(PortDesc si).DSR_CTS_Ok], 00h ; Statusleitungen ok ? jz @@L99 ; Nein, Pech .. mov al, 00001111B ; modem & line status, rec, xmit out dx, al ; ... freigeben ; Fertig ! @@L99: pop es pop di pop dx pop bx ret ENDP SendII ; ------------------------------------------------------------------------- ; ; _ComBreak ; ; Sendet ein Break-Signal mit variabler L„nge. ; PROC PASCAL _ComBreak FAR PortHandle: WORD, BreakLen: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h jz @@Error ; Springe wenn Port nicht offen ; Port ist offen, Break senden mov dx, [(PortDesc bx).LCR] pushf ; I-Bit retten cli ; Interrupts off in al, dx ; get LCR or al, 40h ; break bit on out dx, al ; setzen popf ; Altes I-Bit ; Warte-Routine aufrufen push [BreakLen] call _ComWait ; Register sind futsch, neu laden mov bx, [PortHandle] mov dx, [(PortDesc bx).LCR] ; Und Break-Bit rcksetzen pushf cli in al, dx and al, NOT 40h out dx, al popf ; Fertig @@L99: ret ; Fehlereinsprung wenn Port ist nicht offen. @@Error:call _ComError jmp @@L99 ENDP _ComBreak ; ------------------------------------------------------------------------- ; ; ComModemStatus ; ; Gibt den Status der Kontroll-Leitungen zurck. ; ; Portbelegung: ; 0x80: -CD (Carrier Detect, inverted) ; 0x40: -RI (Ring Indicator, inverted) ; 0x20: -DSR (Data Set Ready, inverted) ; 0x10: -CTS (Clear to Send, inverted) ; 0x08: Delta Carrier Detect (CD changed) ; 0x04: Trailing edge of RI (RI went OFF) ; 0x02: Delta DSR (DSR changed) ; 0x01: Delta CTS (CTS changed) ; PROC PASCAL _ComModemStatus FAR PortHandle: WORD mov bx, [PortHandle] test [(PortDesc bx).Installed], 02h ; Port Offen ? jz @@Error ; Springe wenn Nein mov dx, [(PortDesc bx).MSR] ; Modem status register in al, dx ; Wert holen mov ah, 0 ; Wert in ax @@L99: ret ; Fehlereinsprung wenn Port nicht offen @@Error:call _ComError jmp @@L99 ENDP _ComModemStatus ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM1 ; PROC PASCAL _IntCom1 FAR push si ; Register retten mov si, OFFSET _ComPort1 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom1 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM2 ; PROC PASCAL _IntCom2 FAR push si ; Register retten mov si, OFFSET _ComPort2 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom2 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM3 ; PROC PASCAL _IntCom3 FAR push si ; Register retten mov si, OFFSET _ComPort3 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom3 ; ------------------------------------------------------------------------- ; ; Interrupt-Handler fr COM4 ; PROC PASCAL _IntCom4 FAR push si ; Register retten mov si, OFFSET _ComPort4 ; Deskriptor laden jmp SHORT IntCommon ; Gemeinsame Routine ENDP _IntCom4 ; ------------------------------------------------------------------------- ; ; Gemeinsame Interrrupt-Routine fr alle Ports ; PROC IntCommon FAR push ax push bx push cx push dx push di push bp push es push ds ; Register retten mov ax, DGROUP mov ds, ax ; Datensegment setzen ; Rausfinden, was es fr ein Interrupt war und entsprechend verzweigen @@RePoll: mov dx, [(PortDesc si).IIR] ; interrupt id register in al, dx test al, 01h ; "no interrupt present" ? jnz @@L98 ; Ja: Ende mov bl, al ; Wert nach bx and bx, 000Eh ; unerwnschte Bits ausmaskieren jmp [@@IntDispatch+bx] ; Behandlungsroutine LABEL @@IntDispatch WORD dw @@MSInt ; 0: Modem status int dw @@TXInt ; 2: Transmitter int dw @@RXInt ; 4: Receiver int dw @@LSInt ; 6: Line status int dw @@RePoll ; 8: Reserviert dw @@RePoll ; A: Reserviert dw @@RXInt ; C: FIFO timeout, wie RXInt dw @@RePoll ; E: Reserviert ; Interrupt-Controller verst„ndigen. Problemlos m”glich, weil die Interrupts ; sowieso noch gesperrt sind. @@L98: mov dx, [(PortDesc si).IER] ; Interrupt enable register in al, dx ; Wert lesen mov ah, al ; ... und nach ah retten xor al, al ; Interrupts disablen out dx, al mov al, 20h ; EOI cmp [(PortDesc si).IC2Mask], 00 ; "Hoher" Interrupt ? jz @@L99 ; Springe wenn Nein out 0A0h, al ; EOI an Controller #2 @@L99: out 20h, al ; EOI an Controller #1 mov al, ah ; Alter IER-Wert out dx, al ; ... restaurieren pop ds pop es pop bp pop di pop dx pop cx pop bx pop ax pop si iret ; ------------------------------------------------------------------------- ; ; Line status interrupt ; @@LSInt:mov dx, [(PortDesc si).LSR] ; line status register in al, dx ; lesen shr al, 1 ; Bit wird nicht ben”tigt xor bx, bx ; bx = 0 shr al, 1 ; overrun error prfen adc [(PortDesc si).EOvrRun], bx ; Z„hler evtl. erh”hen shr al, 1 ; parity error prfen adc [(PortDesc si).EParity], bx ; Z„hler evtl. erh”hen shr al, 1 ; framing error prfen adc [(PortDesc si).EFrame], bx ; Z„hler evtl. erh”hen shr al, 1 ; break error prfen adc [(PortDesc si).EBreak], bx ; Z„hler evtl. erh”hen jmp @@RePoll ; Und neu abfragen ; ------------------------------------------------------------------------- ; ; Modem status interrupt ; @@MSInt:mov dx, [(PortDesc si).MSR] ; modem status register in al, dx ; lesen cmp [(PortDesc si).Connection], 'D' ; direkte Verbindung ? je @@B1 ; dann immer frei and al, 30h ; DSR/CTS maskieren cmp al, 30h ; beide da ? mov al, 00h ; Flag fr Nein jne @@B2 ; Springe wenn Nein @@B1: mov al, 01h ; Flag fr Ja @@B2: mov [(PortDesc si).DSR_CTS_Ok], al ; Flag setzen ; Jetzt auf jeden Fall immer alle Interrupts freigeben. Falls keine Daten ; anliegen werden die Ints in der TXInt-Routine wieder gesperrt. mov dx, [(PortDesc si).IER] ; interrupt enable register mov al, 00001111B out dx, al jmp @@RePoll ; und neu pollen ; ------------------------------------------------------------------------- ; ; Transmit interrupt ; @@TXInt:cmp [(PortDesc si).DSR_CTS_Ok], 0 ; Hardware Ok ? je @@C5 ; Nein: Ints abklemmen und Ende mov cx, 1 ; Anzahl Flow-Control Zeichen cmp [(PortDesc si).MustSend], 00h ; Flow-Control Zeichen ? jnz @@C2 ; Ja, immer senden cmp [(PortDesc si).PCOff], 00h ; Flow-Control ok ? jnz @@C5 ; Nein: Ints abklemmen und Ende mov cl, [(PortDesc si).FIFOLen] ; Maximale Anzahl FIFO cmp cx, [(PortDesc si).TXCount] ; > Anzahl im Puffer ? jle @@C1 ; Springe wenn kleiner mov cx, [(PortDesc si).TXCount] ; Sonst Anzahl im Puffer nehmen @@C1: jcxz @@C5 ; Nichts zu senden @@C2: mov bx, [(PortDesc si).TXStart] ; Ringpufferzeiger les di, [(PortDesc si).TXBuf] ; Zeiger auf Sendepuffer mov dx, [(PortDesc si).DataReg] ; Datenregister sub [(PortDesc si).TXCount], cx ; Anzahl passend vermindern @@C3: mov al, [es:bx+di] ; Zeichen holen out dx, al ; und schreiben inc bx ; Pufferzeiger erh”hen cmp bx, [(PortDesc si).TXBufSize] ; Wrap ? jb @@C4 xor bx, bx ; Wrap ! @@C4: loop @@C3 ; und n„chstes Zeichen mov [(PortDesc si).TXStart], bx ; Zeiger rckschreiben mov [(PortDesc si).MustSend], 0 ; Flow-Control ist weg jmp @@RePoll ; Fertig ! ; Es gibt nichts zu senden, oder es darf nicht gesendet werden: ; TX-Interrupts abklemmen @@C5: mov dx, [(PortDesc si).IER] ; interrupt enable register mov al, 00001101B ; line & modem status, rec. out dx, al jmp @@RePoll ; ------------------------------------------------------------------------- ; ; Receive interrupt ; @@RXInt:mov bx, [(PortDesc si).RXEnd] ; Ringpufferzeiger holen les di, [(PortDesc si).RXBuf] ; Zeiger auf Pufferbereich holen mov bp, [(PortDesc si).RXBufSize] ; Puffergr”įe nach bp @@D1: mov dx, [(PortDesc si).DataReg] ; Datenregister in al, dx ; lesen and al, [(PortDesc si).ParityMask] ; Parity-Bit ausmaskieren cmp [(PortDesc si).XonXoff], 'E' ; Flow Control ? jnz @@D4 ; Springe wenn Nein ; Flow-Control ist an, Ctrl-S und Ctrl-Q prfen cmp al, XOFF ; Ctrl-S ? jnz @@D2 ; Nein: Skip mov [(PortDesc si).PCOff], 01h ; Ja: Stop ! mov al, 00001101B ; TX-Ints sperren jmp @@D3 ; Zeichen nicht speichern @@D2: cmp al, XON ; Ctrl-Q ? jnz @@D4 ; Nein: Skip mov [(PortDesc si).PCOff], 00h ; Ja: Output freigeben mov al, 00001111B @@D3: mov dx, [(PortDesc si).IER] out dx, al jmp @@D7 ; Zeichen nicht speichern ; Zeichen speichern @@D4: cmp [(PortDesc si).RXCount], bp ; Noch Platz ? jb @@D5 ; Springe wenn ja inc [(PortDesc si).ERXOverflow] ; Fehlerz„hler erh”hen jmp @@D7 ; Und n„chstes Byte @@D5: mov [es:bx+di], al ; Zeichen speichern inc bx ; Zeiger erh”hen cmp bx, bp ; Wrap-Araound ? jb @@D6 ; Springe wenn Nein xor bx, bx @@D6: inc [(PortDesc si).RXCount] ; Anzahl im Puffer erh”hen ; Prfen, ob noch mehr Zeichen vorliegen (FIFO) @@D7: mov dx, [(PortDesc si).LSR] ; line status register in al, dx ; ...lesen test al, 01h ; noch Zeichen da ? jne @@D1 ; Ja: N„chstes Zeichen lesen ; Es liegen keine Zeichen mehr vor. Pufferzeiger rckspeichern. mov [(PortDesc si).RXEnd], bx ; Jetzt noch prfen, ob der Sender gestoppt werden muį, wenn der Puffer ; zu voll wird. mov ax, [(PortDesc si).RXBufSize] ; Puffergr”įe nach ax shr ax, 1 ; / 2 mov bx, ax shr ax, 1 ; / 4 add ax, bx ; 3/4 Gr”įe in ax cmp [(PortDesc si).RXCount], ax ; Puffer 3/4 voll ? jb @@D99 ; Nein: Kein Grund zum Abschalten ; Falls RTS/CTS verwendet wird, RTS abschalten cmp [(PortDesc si).Connection], 'M' ; HW Control? jne @@D8 ; Springe wenn nein mov dx, [(PortDesc si).MCR] in al, dx ; Sonst MCR lesen... and al, NOT MCR_RTS ; ...RTS off... out dx, al ; ...und wieder schreiben ; Falls Software Flow Control verwendet wird, XOFF absenden @@D8: cmp [(PortDesc si).XonXoff], 'E' ; Enabled ? jnz @@D99 ; Nein: Fertig cmp [(PortDesc si).HostOff], 00h ; Schon XOFF gesandt ? jnz @@D99 ; Ja: Keins mehr senden mov al, XOFF call SendII ; Zeichen abschicken mov [(PortDesc si).HostOff], 01h ; und merken... ; Fertig, neu pollen @@D99: jmp @@RePoll ENDP IntCommon END estic-1.61.orig/spunk/dossrc/delay.cc0100644000176100001440000000465107031424712017060 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System dependent function for waiting some time. #include #ifdef __WATCOMC__ #include #endif #include "progutil.h" /*****************************************************************************/ /* Utility functions */ /*****************************************************************************/ static void GiveUpTimeslice () // Give up the remainder of the current timeslice. Multiplex interrupt works // under Windows and OS/2 { REGS Regs; #if defined (DOS32) && defined (__WATCOMC__) Regs.w.ax = 0x1680; int386 (0x2F, &Regs, &Regs); #else Regs.x.ax = 0x1680; int86 (0x2F, &Regs, &Regs); #endif } /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 Delay (u32 ms) // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // An argument of zero has a special meaning: The function tries to give up // the current time slice, calls App->Idle () and returns after that. // // The function returns the real time passed or just ms. { const ChunkSize = 256; // Check the argument... if (ms <= ChunkSize) { // Give up the time slice GiveUpTimeslice (); // Wait some time if (ms) { delay (ms); } // Call the applications idle function Idle (); } else { u32 Counter = ms; while (Counter) { unsigned TimeToWait = Counter >= ChunkSize ? ChunkSize : Counter; // Recursive call to Delay... u32 WaitTime = Delay (TimeToWait); if (WaitTime > Counter) { Counter = 0; } else { Counter -= WaitTime; } } } // Return the argument return ms; } estic-1.61.orig/spunk/dossrc/filesys.cc0100644000176100001440000001656307031424712017445 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // // This file is also used for the 32-bit version of the library. The define // DOS32 is used to control the compile target. The functions in the first // section (labeled "Target specific code") are the only ones that are // target specific. // Note: Because the Borland and Watcom compilers use different notations // when accessing the word registers in a REGS strcuture, all assignments // to those registers are splitted in two byte assignments. If you change // this, the module will no longer compatible with all supported compilers. #include #include #if defined (__BORLANDC__) #include #endif #if defined (__WATCOMC__) #include #endif #if defined (__GO32__) #include #include #endif #include "check.h" #include "str.h" #include "filepath.h" #include "filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '\\'; // Path separator extern const char FileSysListSep = ';'; // Path list separator extern const FileSysMaxPath = 79; // Maximum path length extern const FileSysMaxDir = 65; // Maximum directory length extern const FileSysMaxName = 8; // Maximum file name length extern const FileSysMaxExt = 4; // Maximum extension length (including the dot) /*****************************************************************************/ /* Target specific code */ /*****************************************************************************/ static char* CurDir (char* Buf, int Drive) // Store the current working directory of the given drive in Buf and return // Buf on success. If Drive is invalid, return NULL. Buf must be at least 65 // bytes large. { char PathBuf [65+2]; char* B; // Get the current disk int CurDrive = FileSysGetDrive (); // Check if we have to change the disk if (Drive != 0 && Drive != CurDrive) { // Must change the drive if (FileSysSetDrive (Drive) != 0) { // Cannot set drive return NULL; } B = getcwd (PathBuf, sizeof (PathBuf)); FileSysSetDrive (CurDrive); } else { // Drive is already ok or default drive B = getcwd (PathBuf, sizeof (PathBuf)); } if (B == NULL) { // An error occured return NULL; } // As the buffer contains the drive specifier, we have to copy the // path only strcpy (Buf, PathBuf + 2); #ifdef __GO32__ // The C library of gjgpp returns '/' as a path separator - convert it B = Buf; while (*B != '\0') { if (*B == '/') { *B = '\\'; } B++; } #endif // Return the result return Buf; } /*****************************************************************************/ /* Code */ /*****************************************************************************/ int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { // Set up for calling DOS function 19h REGS Regs; Regs.h.ah = 0x19; // Call DOS intdos (&Regs, &Regs); // Re-code the drive an return it return Regs.h.al + 1; } int FileSysSetDrive (unsigned Drive) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { // Check the parameter PRECONDITION (Drive != 0); // Set up for calling DOS function 0Eh REGS Regs; Regs.h.ah = 0x0E; Regs.h.dl = Drive - 1; // Call DOS intdos (&Regs, &Regs); // Unfortunately, there is no error code when using this function... return 0; } int FileSysExtractDrive (const String& Path) // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). { if (Path.Len () >= 2 && Path [1] == ':') { // Drive in first char int Drive = Path [0]; return (Drive >= 'a') ? Drive - 'a' + 1 : Drive - 'A' + 1; } else { // No drive spec return 0; } } void FileSysGetInfo (FileSysInfo& Info, int Drive) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // In DOS, there is no difference between file systems strcpy (Info.fsName, "FAT"); Info.fsMaxPath = FileSysMaxPath; Info.fsMaxDir = FileSysMaxDir; Info.fsMaxName = FileSysMaxName; Info.fsMaxExt = FileSysMaxExt; Info.fsPreservesCase = 0; Info.fsIgnoresCase = 1; CurDir (Info.fsCurDir, Drive); } int FileSysPreservesCase (int /*Drive*/ ) // Return 1 if the file system on the given drive preserves the case in // filenames { // DOS does not preserve case in file names return 0; } int FileSysIgnoresCase (int /*Drive*/ ) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { // DOS does ignore case in file names return 1; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. { // Invald chars in the fat file system static char InvalidChars [] = " <>|+=:;,\"/\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } // Check for other invalid chars return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int Drive) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { String Dir; // DOS file systems support drives, so check for IncludeDrive if (IncludeDrive) { // If the current drive should be included, get that if (Drive == 0) { Drive = FileSysGetDrive (); } // FAT is not case sensitive, so use lower case Dir += 'a' + Drive - 1; Dir += ':'; } // Now get the current working directory. Since FAT is not case sensitive, // convert the name to lower case. char Buf [80]; if (CurDir (Buf, Drive) == NULL) { // OOPS - unknown drive Dir.Clear (); } else { Dir += Buf; AddPathSep (Dir); Dir.ToLower (); } // Return the result return Dir; } estic-1.61.orig/spunk/dossrc/filetran.cc0100644000176100001440000001767007031424712017573 0ustar debacleusers/******************************************************************************/ /* */ /* Beispielprogramm zur Demonstration der Verwendung des Moduls U-SER. */ /* Verwendet zwei serielle Schnittstellen und bertr„gt eine als Parameter */ /* angegebene Text-Datei von einer Schnittstelle zur anderen und zeigt sie */ /* dann auf dem Bildschirm an. */ /* */ /* (C) 1993 by Ullrich von Bassewitz */ /* Zwehrenbhlstraįe 33 */ /* 7400 Tbingen */ /* */ /* */ /* ˇnderungen: */ /* */ /******************************************************************************/ #include #include #include #include "sercom.h" #define TEST #define HW_HANDSHAKE #ifndef TEST /* "Normale" Konfiguration */ #define COM1 "COM1" #define COM2 "COM2" #define BufSize 512 #define Baud 19200L /* H”chste Baudrate ohne FIFO */ #else /* Test-Konfiguration */ #define COM1 "COM2" #define COM2 "COM3" /* COM 3 auf INT 0x70 */ #define BufSize 512 #define Baud 9600L /* Nur mit FIFO ! */ #endif ComPort* SendPort = NULL; ComPort* RecPort = NULL; void Usage (void) { fprintf (stderr, "Syntax: FILETRAN \n"); #ifdef HW_HANDSHAKE fprintf (stderr, "Voraussetzung: COM1 und COM2 mssen vorhanden, und\n" "ber ein Nullmodem-Kabel verbunden sein.\n" "Das Programm verwendet RTS/CTS Handshake und sendet\n" "deshalb nicht, wenn das Kabel nicht korrekt verdrahtet\n" "ist. In diesem Fall sollte ein anderes Kabel oder ein\n" "anderer Handshake (XON/XOFF) verwendet werden...\n"); #else fprintf (stderr, "Voraussetzung: COM1 und COM2 mssen vorhanden, und\n" "ber ein Kabel verbunden sein, bei dem die Adern 2\n" "und 3 gekreuzt sind.\n" "Das Programm verwendet XON/XOFF Handshake und sendet\n" "deshalb auch dann, wenn das Kabel fehlt. In diesem\n" "Fall erfolgt keine Bildschirmausgabe...\n"); #endif exit (1); } void ExitFunc (void) /* Schlieįt offene Port wenn das Programm endet */ { delete RecPort; delete SendPort; } int main (int argc, char *argv []) { FILE *F; int C; int T; /* Parameter berprfen */ if (argc != 2) { Usage (); } /* Datei zur bertragung ”ffnen */ if ((F = fopen (argv [1], "rt")) == NULL) { fprintf (stderr, "Fehler beim ™ffnen von %s\n", argv [1]); exit (1); } /* Parameter der beiden Ports einstellen */ #ifdef HW_HANDSHAKE char Connection = 'M'; /* H/W Handshake */ char XonXoff = 'D'; /* kein XON/XOFF verwenden */ #else char Connection = 'D'; /* Kein H/W Handshake */ char XonXoff = 'E'; /* XON/XOFF verwenden */ #endif char Parity = 'N'; /* Keine Parit„t */ char StopBits = 1; /* 1 Stopbit */ char DataBits = 8; /* 8 Datenbits */ #ifdef TEST /* * Beispiel fr die Verwendung anderer Interrupts: Der hier verwendete * COM3 sitzt auf einer vierfach SIO-Karte und ist auf Interrupt 12 * gejumpert. Interrupt 12 entspricht der Interruptvektor 0x74. Da * diese Leitung am zweiten Interrupt-Controller sitzt, ist die Maske * fr den ersten Controller leer (0x00 bzw. 0xFF), die Maske fr den * zweiten Controller berechnet sich nach * * IC2Mask = 0x01 << (IntNr - 0x70); * NotIC2Mask = ~IC2Mask; * * Siehe dazu auch die Anmerkungen im Handbuch. * */ unsigned IntNr = 0x70; #else unsigned IntNr = 0x00; #endif /* Ports installieren */ SendPort = new ComPort (COM1, Baud, DataBits, Parity, StopBits, Connection, XonXoff, 0, 0); RecPort = new ComPort (COM2, Baud, DataBits, Parity, StopBits, Connection, XonXoff, 0, IntNr); if (SendPort->Open () != 0) { /* Port nicht verfgbar */ fprintf (stderr, "Keinen UART fr %s gefunden!\n", COM1); exit (1); } if (RecPort->Open () != 0) { /* Port nicht verfgbar */ fprintf (stderr, "Keinen UART fr %s gefunden!\n", COM2); exit (1); } /* Exit-Funktion installieren */ atexit (ExitFunc); /* Wenn Hardware-Handshake gew„hlt ist, mssen noch die Statusleitungen * der beiden Ports aktiv gemacht werden. Das ist bei Verwendung des * Software-Handshakes nicht notwendig. */ #ifdef HW_HANDSHAKE SendPort->DTROn (); RecPort->DTROn (); /* Warten bis die Statusleitungen des Empf„ngers ok sind */ for (T = 0; T < 30; T++) { unsigned Status = SendPort->ModemStatus (); const HandShake = csClearToSend | csDataSetReady; if ((Status & HandShake) == HandShake) { /* Status ist Ok */ break; } else { /* Nicht ok, warten */ delay (100); T++; } } /* Timeout prfen */ if (T == 30) { fprintf (stderr, "Statusleitungen nicht ok, Senden nicht m”glich.\n" "Ben”tigt wird: CTS aktiv und DSR aktiv,\n" "Status ist: CTS %s und DSR %s.\n", SendPort->ModemStatus () & csClearToSend ? "aktiv" : "inaktiv", SendPort->ModemStatus () & csDataSetReady ? "aktiv" : "inaktiv"); exit (1); } #endif /* Datei bertragen */ while ((C = getc (F)) != EOF) { /* Warten bis Platz im Ausgabepuffer ist. */ for (T = 0; T < 60; T++) { if (SendPort->TXFree () == 0) { /* Kein Platz, etwas warten */ delay (50); } else { /* Platz, senden */ break; } } /* Timeout prfen und Zeichen senden */ if (T == 60) { fprintf (stderr, "Timeout beim Senden\n"); fclose (F); exit (1); } SendPort->Send (C); /* Falls Zeichen im Empfangspuffer sind, abholen und auf dem * Bildschirm ausgeben. */ while (RecPort->RXCount () > 0) { /* Es sind welche da */ putchar (RecPort->Receive ()); } } /* Ganz wichtig ! Obwohl die Datei zu Ende ist, befinden sich evtl. (bzw. * eher mit Sicherheit) noch Zeichen in den Sende- und Empfangspuffern. * Es muį daher gewartet werden bis die Puffer beide geleert sind. * Nochmal ACHTUNG: Wird ein UART mit FIFO verwendet, so kann es * passieren, daį sowohl im Empfangs-, als auch im Sendepuffer keine * Zeichen mehr sind, die Datei aber trotzdem nicht vollst„ndig ber- * tragen wurde. Das liegt daran, daį der UART die Zeichen im FIFO erst * mit einer Verz”gerung herausgibt, die die Dauer von 4 Zeichen betr„gt. * Deshalb am besten immer etwas l„nger warten... */ delay (BufSize * (10000.0 / (double) Baud) + 100); while (RecPort->RXCount () > 0) { /* Es sind welche da */ putchar (RecPort->Receive ()); } /* Datei schlieįen */ fclose (F); /* Statusleitungen inaktiv */ #ifdef HW_HANDSHAKE SendPort->DTROff (); RecPort->DTROff (); #endif /* Ports werden ber ExitFunc geschlossen */ return 0; } estic-1.61.orig/spunk/dossrc/kbd.cc0100644000176100001440000001466407031424712016527 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file is also used for the 32-bit version of the library. The define // DOS32 is used to control the compile target. The functions in the first // section (labeled "Target specific code") are the only ones that are // target specific. // Note: Because the Borland and Watcom compilers use different notations // when accessing the word registers in a REGS strcuture, all assignments // to those registers are splitted in two byte assignments. If you change // this, the module will no longer compatible with all supported compilers. #if defined (__WATCOMC__) #include #include #elif defined (__BORLANDC__) || defined (__GO32__) #include #endif #include "msgid.h" #include "program.h" #include "kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // Mapper table from virtual to extended keys. This table is fixed for DOS/OS2 struct { Key EK; Key VK; } VirtualMap [] = { { kbEsc, vkAbort }, { kbF1, vkHelp }, { kbF10, vkAccept }, { kbPgUp, vkPgUp }, { kbPgDn, vkPgDn }, { kbCtrlPgUp, vkCtrlPgUp }, { kbCtrlPgDn, vkCtrlPgDn }, { kbUp, vkUp }, { kbDown, vkDown }, { kbLeft, vkLeft }, { kbRight, vkRight }, { kbIns, vkIns }, { kbDel, vkDel }, { kbHome, vkHome }, { kbEnd, vkEnd }, { kbCtrlUp, vkCtrlUp }, { kbCtrlDown, vkCtrlDown }, { kbCtrlLeft, vkCtrlLeft }, { kbCtrlRight, vkCtrlRight }, { kbCtrlIns, vkCtrlIns }, { kbCtrlDel, vkCtrlDel }, { kbCtrlHome, vkCtrlHome }, { kbCtrlEnd, vkCtrlEnd }, { kbF5, vkZoom }, { kbMetaF3, vkClose }, { kbF3, vkOpen }, { kbF2, vkSave }, { kbCtrlF5, vkResize }, { kbMetaX, vkQuit }, // Secondary mappings follow { kbCtrlR, vkPgUp }, { kbCtrlC, vkPgDn }, { kbCtrlE, vkUp }, { kbCtrlX, vkDown }, { kbCtrlS, vkLeft }, { kbCtrlD, vkRight }, { kbCtrlV, vkIns }, { kbCtrlG, vkDel }, { kbCtrlW, vkCtrlUp }, { kbCtrlZ, vkCtrlDown }, { kbCtrlA, vkCtrlLeft }, { kbCtrlF, vkCtrlRight }, }; /*****************************************************************************/ /* Target specific code */ /*****************************************************************************/ inline void KbdInt (REGS& Regs) // execute a software interrupt { #if defined (DOS32) && defined (__WATCOMC__) int386 (0x16, &Regs, &Regs); #else int86 (0x16, &Regs, &Regs); #endif } #ifdef __WATCOMC__ // Watcom-C does not allow to access the flags register via int86(), so use // inline assembly extern short KbdCharAvail (); // Return 1 if a key is available #pragma aux KbdCharAvail = \ " mov ah, 11h" \ " int 16h" \ " mov ax, 0" \ " jz L1" \ " inc ax" \ "L1:" \ value [ax] #else static int KbdCharAvail () // Return 1 if a key is available { REGS Regs; Regs.h.ah = 0x11; KbdInt (Regs); // A key is available if the zero flag is not set return (Regs.x.flags & 0x40) == 0; } #endif static void GiveUpTimeslice () // Give up the remainder of the current timeslice. Multiplex interrupt works // under Windows and OS/2 { REGS Regs; #if defined (DOS32) && defined (__WATCOMC__) Regs.w.ax = 0x1680; int386 (0x2F, &Regs, &Regs); #else Regs.x.ax = 0x1680; int86 (0x2F, &Regs, &Regs); #endif } /*****************************************************************************/ /* Code */ /*****************************************************************************/ static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Keyboard::Keyboard (): Console (1), TransTable (NULL) { } Keyboard::~Keyboard () { delete [] TransTable; } Key Keyboard::RawKey () // Get a raw (unmapped) key from the pc bios { REGS Regs; // Wait for a key calling App->Idle while (KbdCharAvail () == 0) { GiveUpTimeslice (); CurThread () -> Idle (); } // Retrieve the key Regs.h.ah = 0x10; KbdInt (Regs); // Remap some keys Key K = (unsigned (Regs.h.ah) << 8) | Regs.h.al; // Translate char/scancode to plain/extended key if ( (K & 0x00FF) == 0xE0 || (K & 0x00FF) == 0x00) { // Extended character return Key (0x0100 | (K >> 8)); } else { return Key (K & 0x00FF); } } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { // If waiting is not wanted, check if there are keys available before // grabbing them if (Wait == 0 && KbdCharAvail () == 0) { // No keys available, bail out return; } // Get a key, remap it and put it into the buffer KeyBuf.Put (KbdMapExtended (Translate (RawKey ()))); } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description return App->LoadMsg (MSGBASE_KBD + K); } estic-1.61.orig/spunk/dossrc/nlsinit.cc0100644000176100001440000001531007031424712017434 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // Note: Because the Borland and Watcom compilers use different notations // when accessing the word registers in a REGS strcuture, all assignments // to those registers are splitted in two byte assignments. If you change // this, the module will no longer compatible with all supported compilers. #if defined (__WATCOMC__) #include #include #elif defined (__BORLANDC__) #include #endif #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Country info struct from DOS #pragma PACK(1) struct CountryInfo { char ID; u16 Size; u16 Country; u16 CodePage; u16 Date; char CurrStr [5]; char ThSep [2]; char DecSep [2]; char DateSep [2]; char TimeSep [2]; char Curr; char CurrPlaces; char Time; u32 CaseMapFunc; char DataSep [2]; char Fill [10]; }; #pragma PACK() // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Target specific code */ /*****************************************************************************/ static void GetCountryInfo (void far* InfoStruct, u16 InfoLen, unsigned char ID) { REGS Regs; SREGS SRegs; // Clear out the segment registers memset (&SRegs, 0, sizeof (SRegs)); Regs.x.ax = 0x6500 | ID; Regs.x.bx = 0xFFFF; Regs.x.cx = InfoLen; Regs.x.dx = 0xFFFF; SRegs.es = FP_SEG (InfoStruct); Regs.x.di = FP_OFF (InfoStruct); int86x (0x21, &Regs, &Regs, &SRegs); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { CountryInfo Info; // Get country information GetCountryInfo (&Info, sizeof (Info), 0x01); // Try if there is an override for the country in the environment unsigned Country = GetEnvNum ("SPUNK_COUNTRY", Info.Country); // Set the country data NLSSetCountry (Country); // Try if there is an override for the language in the environment unsigned Language = GetEnvNum ("SPUNK_LANGUAGE", NLSGetDefaultLanguage (Country)); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/dossrc/os2win.txt0100644000176100001440000000023007031424713017423 0ustar debacleusersThis code detects if the dos session is running in an OS/2 window: int OS2Window () { return inp (0x3D6) == 0; } estic-1.61.orig/spunk/dossrc/screen.cc0100644000176100001440000004072307031424713017242 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This file is also used for the 32-bit version of the library. The define // DOS32 is used to control the compile target. The functions in the first // section (labeled "Target specific code") are the only ones that are // target specific. // Note: Because the Borland and Watcom compilers use different notations // when accessing the word registers in a REGS strcuture, all assignments // to those registers are splitted in two byte assignments. If you change // this, the module will no longer compatible with all supported compilers. #include #if defined (__WATCOMC__) #include #include #elif defined (__BORLANDC__) || defined (__GO32__) #include #else #error Unknown compiler! #endif #if defined (__GO32__) #include #include #endif #include "screen.h" // Instance of the screen class to handle screen output. Must be initialized // from outside (Application) Screen* TheScreen; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // These are defined as constants instead using the numerical value. If you // want to create a 16 bit dpmi version, change them to variables containing // the corresponding selectors. const u16 Seg0040 = 0x0040; const u16 SegB000 = 0xB000; const u16 SegB800 = 0xB800; // Constants for ScrGetCard static const u16 vcMono = 0x0000; static const u16 vcCGA = 0x0001; static const u16 vcEGA = 0x0002; static const u16 vcVGA = 0x0003; /*****************************************************************************/ /* Target specific code */ /*****************************************************************************/ #ifdef DOS #define PTR(__s,__o) MK_FP(__s,__o) #endif #ifdef DOS32 #define PTR(__s,__o) ((((u32)(u16)(__s)) << 4) + ((u16)(__o))) #endif #define BYTEPTR(__s,__o) ((unsigned char*) PTR (__s,__o)) #define WORDPTR(__s,__o) ((u16*) PTR (__s,__o)) #if defined (__GO32__) // Remapping of some djgpp function names #define _disable() disable () #define _enable() enable () #define outp(__a,__v) outportb (__a, __v) #define outpw(__a, __v) outportw (__a, __v) #define inp(__a) inportb (__a) #define inpw(__a) inportw (__a) // DJGPP specific stuff for accessing low memory #define DosSel _go32_conventional_mem_selector () #define PeekByte(__s, __o) _farpeekb (DosSel, PTR (__s, __o)) #define PeekWord(__s, __o) _farpeekw (DosSel, PTR (__s, __o)) #define PokeByte(__s, __o, __v) _farpokeb (DosSel, PTR (__s, __o), __v) #define PokeWord(__s, __o, __v) _farpokew (DosSel, PTR (__s, __o), __v) #else // Stuff for accessing low memory #define PeekByte(__s, __o) *BYTEPTR (__s, __o) #define PeekWord(__s, __o) *WORDPTR (__s, __o) #define PokeByte(__s, __o, __v) *BYTEPTR (__s, __o) = (__v) #define PokeWord(__s, __o, __v) *WORDPTR (__s, __o) = (__v) #endif /*****************************************************************************/ /* Code for tweaking vga registers */ /*****************************************************************************/ inline void VideoInt (REGS& Regs) // execute a software interrupt { #if defined (DOS32) && defined (__WATCOMC__) int386 (0x10, &Regs, &Regs); #else int86 (0x10, &Regs, &Regs); #endif } static void VGAOff () // Blank the vga display. Must be called with interrupts disabled! { outpw (0x3C4, 0x100); outp (0x3D4, 0x17); outp (0x3D5, inp (0x3D5) & 0x7F); outp (0x3D4, 0x11); outp (0x3D5, inp (0x3D5) & 0x7F); } static void VGAOn () // re-enable the vga display. { outp (0x3D4, 0x11); outp (0x3D5, inp (0x3D5) | 0x80); outp (0x3D4, 0x17); outp (0x3D5, inp (0x3D5) | 0x80); outpw (0x3C4, 0x300); } static void VGA94Cols () // Switch the vga hardware to handle 846 pixels horizontally { outp (0x3C2, (inp (0x3CC) & 0xF3) | 0x04); outp (0x3C4, 0x01); outp (0x3C5, inp (0x3C5) | 0x01); outpw (0x3D4, 0x6C00); outpw (0x3D4, 0x5D01); outpw (0x3D4, 0x5E02); outpw (0x3D4, 0x8F03); outpw (0x3D4, 0x6204); outpw (0x3D4, 0x8E05); outpw (0x3D4, 0x2F13); inp (0x3DA); outp (0x3C0, 0x13); outp (0x3C0, 0x00); outp (0x3C0, 0x20); outp (0x3C0, 0x20); } static void VGA480Scanlines () // Switch the vga to 480 lines { outp (0x3C2, inp (0x3CC) | 0xC0); outpw (0x3D4, 0x0B06); outpw (0x3D4, 0x3E07); outpw (0x3D4, 0x4F09); outpw (0x3D4, 0xEA10); outpw (0x3D4, 0x8C11); outpw (0x3D4, 0xDF12); outpw (0x3D4, 0xE715); outpw (0x3D4, 0x0416); } static void VGACharHeight (unsigned char H) // Set the character height in scan lines { // Set the bios value PokeByte (Seg0040, 0x0085, H); // program the vga outp (0x3D4, 0x09); outp (0x3D5, (inp (0x3D5) & 0xE0) + H - 1); outp (0x3D4, 0x0A); outp (0x3D5, H <= 12 ? H-2 : H-3); outp (0x3D4, 0x0B); outp (0x3D5, H <= 12 ? H-1 : H-2); } static void VGASetTweakedMode (unsigned Cols, unsigned Lines) // Set one of the tweaked VGA modes. A vga must be present if this function is // called! { REGS Regs; // Switch to 350 or 400 scanlines. If we need 480, switch to 400 here Regs.h.ah = 0x12; Regs.h.bl = 0x30; Regs.h.al = (Lines == 43) ? 0x01 : 0x02; VideoInt (Regs); // Setup 80 cols by switching to mode 3 (CO80) Regs.h.ah = 0x00; Regs.h.al = 0x03; VideoInt (Regs); // Load the font for the choosen resolution Regs.h.ah = 0x11; Regs.h.bl = 0x00; unsigned Height; switch (Lines) { case 25: case 30: Regs.h.al = 0x04; // 16x8 font Height = 16; break; case 34: Regs.h.al = 0x01; // 14x8 font Height = 14; break; default: Regs.h.al = 0x02; // 8x8 font Height = 8; break; } VideoInt (Regs); // Program the vga controller _disable (); VGAOff (); if (Cols == 94) { VGA94Cols (); } if (Lines == 30 || Lines == 34 || Lines == 60) { VGA480Scanlines (); } VGACharHeight (Height); VGAOn (); _enable (); // Set the BIOS variables for the selected screen size PokeByte (Seg0040, 0x004A, Cols); PokeByte (Seg0040, 0x0084, Lines-1); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ inline u16 ScrGetMode () // return the current video mode { return PeekByte (Seg0040, 0x0049); } inline u16 ScrGetCursor () // get the current cursor type { return PeekWord (Seg0040, 0x0060); } inline u16 ScrGetColsPerLine () // get the columns per line from the BIOS segment { return PeekByte (Seg0040, 0x004A); } static int ScrIsVGA () // Return 1 if the video card is VGA { REGS Regs; Regs.h.ah = 0x1A; Regs.h.al = 0x00; VideoInt (Regs); return Regs.h.al == 0x1A; } inline void ScrWriteBuf (u16* Buf, u16 X, u16 Y, unsigned Count) // write a row of char/attribute pairs to the screen { #if defined (__GO32__) // Get a pointer to the screen base and add row/col offset u32 ScrPtr = ScrGetMode () == 0x07 ? 0xB0000 : 0xB8000; ScrPtr += (Y * ScrGetColsPerLine () + X) * sizeof (u16); // Copy the buffer to the screen dosmemput (Buf, Count * sizeof (u16), ScrPtr); #else // Get a pointer to the screen base and add row/col offset u16* ScrPtr; if (ScrGetMode () == 0x07) { // mono ScrPtr = WORDPTR (SegB000, 0); } else { ScrPtr = WORDPTR (SegB800, 0); } ScrPtr += Y * ScrGetColsPerLine () + X; // Copy the buffer to the screen memcpy (ScrPtr, Buf, Count * sizeof (u16)); #endif } static void ScrSetCursorPos (unsigned char X, unsigned char Y) { REGS Regs; Regs.h.dh = Y; Regs.h.dl = X; Regs.h.bh = 0x00; // Display page Regs.h.ah = 0x02; // Function code VideoInt (Regs); } static void ScrSetMode (u16 Mode) // Set a video mode { REGS Regs; switch (Mode) { case vmBW40: case vmCO40: case vmBW80: case vmCO80: case vmMono: case vmET4_100x40: Regs.h.al = Mode & 0x00FF; Regs.h.ah = 0x00; VideoInt (Regs); break; case vmVGA_80x30: VGASetTweakedMode (80, 30); break; case vmVGA_80x34: VGASetTweakedMode (80, 34); break; case vmVGA_80x43: VGASetTweakedMode (80, 43); break; case vmVGA_80x50: VGASetTweakedMode (80, 50); break; case vmVGA_80x60: VGASetTweakedMode (80, 60); break; case vmVGA_94x25: VGASetTweakedMode (94, 25); break; case vmVGA_94x30: VGASetTweakedMode (94, 30); break; case vmVGA_94x34: VGASetTweakedMode (94, 34); break; case vmVGA_94x43: VGASetTweakedMode (94, 43); break; case vmVGA_94x50: VGASetTweakedMode (94, 50); break; case vmVGA_94x60: VGASetTweakedMode (94, 60); break; } } static void ScrSetCursor (u16 Cursor) // set a cursor { REGS Regs; Regs.h.ch = Cursor >> 8; Regs.h.cl = Cursor & 0x00FF; Regs.h.ah = 0x01; VideoInt (Regs); } static int ScrColorMode () // return 0 in mono mode, 1 in color mode { switch (ScrGetMode ()) { case 0: // BW40 case 2: // BW80 case 7: // Mono return 0; default: return 1; } } static void ScrScreenSize (u16& XSize, u16& YSize) // Get screen dimensions { REGS Regs; // Get the video mode and row count Regs.h.ah = 0x0F; VideoInt (Regs); XSize = Regs.h.ah; // Get line count Regs.h.ah = 0x11; Regs.h.al = 0x30; Regs.h.bh = 0x00; Regs.h.dl = 0x00; VideoInt (Regs); if (Regs.h.dl == 0x00) { // line count not set, assume 25 lines YSize = 25; } else { YSize = Regs.h.dl + 1; } } static u16 ScrGetCard () // Return the type of the video card installed. Used to set the // cursor type correctly { REGS Regs; if (ScrGetMode () == 0x07) { // Mono mode, check for a vga in monochrome mode return ScrIsVGA () ? vcVGA : vcMono; } else { // It is some sort of a color video card. // The following code is taken from the initialization part of // the crt unit as documented in Arne Schaepers, "Turbo Pascal 4.0" // The function call with ax = 1130h returns on EGA/VGA the number // of lines in dl, on a CGA dl is not changed. Regs.h.dl = 0x00; // Preset line count = 0 Regs.h.bh = 0x00; Regs.h.ah = 0x11; Regs.h.al = 0x30; VideoInt (Regs); if (Regs.h.dl == 0x00) { // CGA card returns no line count return vcCGA; } // Remainig cards are EGA and VGA return ScrIsVGA () ? vcVGA : vcEGA; } } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): Console (1), CP437 (1), TransTable (NULL) { // Remember old video mode and cursor form StartupMode = ScrGetMode (); StartupCursor = ScrGetCursor (); // Remember the current mode CurrentMode = ScrGetMode (); // Get size of screen ScrScreenSize (XSize, YSize); // Check if color mode Color = ScrColorMode (); // Switch cursor off SetCursorOff (); } Screen::~Screen () { // Reset old video mode and cursor SetMode (StartupMode); ScrSetCursor (StartupCursor); // Delete the translation table delete [] TransTable; } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table { if (TransTable) { unsigned char* S = (unsigned char*) Target; unsigned char* T = (unsigned char*) Source; while (Len--) { *T++ = TransTable [*S++]; // Translate character *T++ = *S++; // Copy attribute } return Target; } else { // No translation table, return the source buffer return Source; } } void Screen::SetMode (u16 Mode) { // Remember mode CurrentMode = Mode; // set mode ScrSetMode (Mode); // Get size of screen ScrScreenSize (XSize, YSize); // Check if color mode Color = ScrColorMode (); // Switch cursor off SetCursorOff (); } void Screen::SetCursorOn () { static u16 CursorTab [4] = { 0x0B0C, // Mono 0x0607, // CGA 0x0506, // EGA 0x0506 // VGA }; // Set the cursor according to the video card type ScrSetCursor (CursorTab [ScrGetCard ()]); } void Screen::SetCursorOff () { static u16 CursorTab [4] = { 0x1000, // Mono 0x8F8F, // CGA 0x8F8F, // EGA 0x2000 // VGA }; // Set the cursor according to the video card type ScrSetCursor (CursorTab [ScrGetCard ()]); } void Screen::SetCursorFat () { static u16 CursorTab [4] = { 0x020B, // Mono 0x040B, // CGA 0x0206, // EGA 0x0206 // VGA }; // Set the cursor according to the video card type ScrSetCursor (CursorTab [ScrGetCard ()]); } void Screen::SetCursorPos (const Point &Pos) { ScrSetCursorPos ((unsigned) Pos.X, (unsigned) Pos.Y); } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { int XtoDo, YtoDo; int XCount = R.XSize (); int YCount = R.YSize (); // Check if there is anything to do if (XCount == 0 || YCount == 0 || R.A.Y > YSize || R.A.X > XSize) { // Done return; } // Calculate the size of the output rectangle XtoDo = (R.B.X > XSize) ? XSize - R.A.X : XCount; YtoDo = (R.B.Y > YSize) ? YSize - R.A.Y : YCount; // If we have to translate the output, get buffer memory. This operation // is cheap, so do it, even if we don't need the buffer to avoid warnings u16* Buf2 = (u16*) alloca (XtoDo * sizeof (u16)); // Write the stuff to the screen int Y = R.A.Y; while (YtoDo--) { if (TransTable) { // Translate the buffer line and write it to the screen ScrWriteBuf (Translate (Buf2, Buf, XtoDo), R.A.X, Y, XtoDo); } else { // No translation, just write out the buffer ScrWriteBuf (Buf, R.A.X, Y, XtoDo); } Buf += XCount; Y++; } } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { // We have always direct access to the screen return 10; } estic-1.61.orig/spunk/dossrc/sercom.cc0100644000176100001440000006407707031424713017263 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // DOS version (no extender). // The DOS version of this module is just an OOP class that hides an older // assembler/C module for serial communication. Because of the history of this // older module, comments are in german, sorry. #include #include #include "check.h" #include "delay.h" #include "sercom.h" /******************************************************************************/ /* Function prototypes for the external assembler functions */ /******************************************************************************/ #ifdef __WATCOMC__ // For Watcom C specify new attributes for the pascal calling convention. // The routines in the assembler module expect the ds segment register to // contain the default data segment, so tell the compiler to reload ds // before calling a function specified as pascal #pragma aux __pascal "^" \ parm loadds reverse routine [] \ value struct float struct caller [] \ modify [ax bx cx dx es]; #endif // Type of a port handle typedef u16 HCOMPORT; extern "C" { HCOMPORT far pascal _ComInstall (HCOMPORT Port); /* Installiert den COM-Port, ”ffnet ihn aber nicht. Zurck kommt ein Port- * Handle das $FFFF ist wenn ein Fehler aufgetreten ist (Port existiert nicht). * Dieses PortHandle muį bei der sp„teren Kommunikation mit den brigen Routinen * des Pakets angegeben werden. */ void far pascal _ComDeinstall (HCOMPORT Port); /* Deinstalliert einen Port. Falls der Port noch offen ist wird er von der * Prozedur zuerst geschlossen. */ int far pascal _ComIsInstalled (HCOMPORT Port); /* Ergibt den Wert 1 wenn der Port installiert ist, ansonsten 0. */ void far pascal _ComOpen (HCOMPORT Port); /* ™ffnet den Port */ void far pascal _ComClose (HCOMPORT Port); /* Schlieįt den Port */ int far pascal _ComIsOpen (HCOMPORT Port); /* Ergibt den Wert 1 wenn der Port ge”ffnet ist, ansonsten 0. */ void far pascal _ComDTROn (HCOMPORT Port); /* Macht die DTR-Leitung aktiv und gibt damit der Gegenstelle das Zeichen, daį * der Port aktiv ist. */ void far pascal _ComDTROff (HCOMPORT Port); /* Macht die DTR-Leitung inaktiv und gibt damit der Gegenstelle zu erkennen, * daį der Port (bzw. der PC) inaktiv ist. */ void far pascal _ComRTSOn (HCOMPORT Port); // Activate the RTS line. This is allowed only if the connection type of the // port is *not* 'M'odem. void far pascal _ComRTSOff (HCOMPORT Port); // Deactivate the RTS line. This is allowed only if the connection type of the // port is *not* 'M'odem. unsigned far pascal _ComRXSize (HCOMPORT Port); /* Gibt die Gr”įe des Empfangspuffers zurck */ unsigned far pascal _ComRXCount (HCOMPORT Port); /* Gibt die Anzahl Zeichen im Empfangspuffer zurck */ void far pascal _ComRXClear (HCOMPORT Port); /* L”scht den kompletten Sendepuffer */ unsigned far pascal _ComTXSize (HCOMPORT Port); /* Gibt die Gr”įe des Sendepuffers zurck */ unsigned far pascal _ComTXCount (HCOMPORT Port); /* Gibt die Anzahl der Zeichen im Sendepuffer zurck */ unsigned far pascal _ComTXFree (HCOMPORT Port); /* Gibt die Anzahl freier Pl„tze im Sendepuffer zurck */ void far pascal _ComTXClear (HCOMPORT Port); /* L”scht den kompletten Sendepuffer */ int far pascal _ComReceive (HCOMPORT Port); /* Holt ein Zeichen aus dem Empfangspuffer fr den spezifizierten Port. Ist * der Puffer leer, so kommt -1 zurck. */ int far pascal _ComSend (HCOMPORT Port, unsigned char B); /* Sendet ein Zeichen (legt es im Sendepuffer ab). Ist der Sendepuffer voll, * so wird der entsprechende Fehlerz„hler hochgez„hlt und das Zeichen wird * weggeworfen. */ void far pascal _ComBreak (HCOMPORT Port, double Duration); /* Sendet ein Break mit der bergebenen Dauer (in Sekunden). Die Funktion * kehrt erst nach Ablauf dieser Zeit zurck. */ unsigned far pascal _ComModemStatus (HCOMPORT Port); /* Gibt den Modemstatus (Status der Kontrolleitungen) fr den gewnschten Port * zurck. Die Bits k”nnen anhand der weiter oben definierten Konstanten aus- * gewertet werden. */ void far pascal _IntCom1 (); void far pascal _IntCom2 (); void far pascal _IntCom3 (); void far pascal _IntCom4 (); // Interrupt-Handlers for port 1..4 }; /*****************************************************************************/ /* struct _ComData */ /*****************************************************************************/ // All implementation dependant data is contained in a structure that is // defined in the CC file. struct _ComData { // Port-Definitione (duplicated) u32 Baudrate; char Connection; // irect, odem char Parity; // one, dd, ven, pace, ark char Stopbits; // 1, 2 char Databits; // 5..8 char XonXoff; // nabled, isabled char Fill; // Make the offset even // Circular buffer void far* RXBuf; void far* TXBuf; u16 RXBufSize; u16 TXBufSize; u16 RXStart; u16 RXEnd; u16 TXStart; u16 TXEnd; u16 RXCount; u16 TXCount; // Error counters ComErrorCounter ErrorCounter; char Installed; // Don't use char IntNr; // Number of the interrupt used char IC1Mask; // Mask for interrupt controller #1 char NotIC1Mask; // Complement of the above mask char IC2Mask; // ... the same for IC #2 char NotIC2Mask; char FIFOLen; // Don't use char ParityMask; // Don't use u16 PortAddress; // UART-Address u16 Reserved [6]; u16 IntHandler; void far* OldVector; char HostOff; char PCOff; char MustSend; char RTS_CTS_Ok; }; /*****************************************************************************/ /* Predefined _ComData structs, one for every port on the PC */ /*****************************************************************************/ // It seems that Watcom mangles variable names (is this standard?) extern "C" { // Descriptor for COM 1 _ComData _ComPort1 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) 0, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0C, // * IntNr 0x10, // * IC1Mask 0xEF, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x3F8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved FP_OFF (_IntCom1), // Offset Interrupt-Handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // RTS_CTS_Ok }; // Descriptor for COM 2 _ComData _ComPort2 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) 0, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Fehlerz„hler 0, // Installed 0x0B, // * IntNr 0x08, // * IC1Mask 0xF7, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x2F8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved FP_OFF (_IntCom2), // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // RTS_CTS_Ok }; // Descriptor for COM 3 _ComData _ComPort3 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) 0, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0C, // * IntNr 0x10, // * IC1Mask 0xEF, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x3E8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved FP_OFF (_IntCom3), // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // RTS_CTS_Ok }; // Descriptor for COM 4 _ComData _ComPort4 = { 9600, // <-- Baudrate (9600) 'M', // <-- Connection (Modem) 'N', // <-- Parity (None) 1, // <-- StopBits (1) 8, // <-- DataBits (8) 'D', // <-- XonXoff (Disabled) 0, // Make the offset even NULL, // RXBuf NULL, // TXBuf 0, // RXBufSize 0, // TXBufSize 0, // RXStart 0, // RXEnd 0, // TXStart 0, // TXEnd 0, // RXCount 0, // TXCount { 0, 0, 0, 0, 0, 0 }, // Error counters 0, // Installed 0x0B, // * IntNr 0x08, // * IC1Mask 0xF7, // * NotIC1Mask 0x00, // * IC2Mask 0xFF, // * NotIC2Mask 14, // FIFOLen 0, // ParityMask 0x2E8, // * PortAddress { 0, 0, 0, 0, 0, 0 }, // Reserved FP_OFF (_IntCom4), // Offset of interrupt handler NULL, // OldVector 0, // HostOff 0, // PCOff 0, // MustSend 0 // RTS_CTS_Ok }; } // extern "C" /*****************************************************************************/ /* Code */ /*****************************************************************************/ extern "C" void far pascal _ComError () // Error routine that is called on parameter errors from the assembler module { FAIL ("_ComError: Error in _SERCOM assembler module"); } extern "C" u16 far pascal _ComWait (u16 ms) // Wait routine that is called from the assembler module. It returns the time // actually waited { delay (ms); return ms; } /*****************************************************************************/ /* class ComPort */ /*****************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned UARTBase, unsigned IntNum): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (512), TXBufSize (512), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (UARTBase, IntNum); } ComPort::~ComPort () // Destruct a ComPort object { // If the port is installed, deinstall it (this will also close the port) if (_ComIsInstalled (FP_OFF (ComData))) { _ComDeinstall (FP_OFF (ComData)); } // Free the buffers and reset the buffer pointers delete [] ComData->RXBuf; delete [] ComData->TXBuf; ComData->RXBuf = NULL; ComData->TXBuf = NULL; } void ComPort::Init (unsigned UARTBase, unsigned IntNum) // Initialization procedure, called from the constructors { static const u16 DefPortAddress [4] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }; static const unsigned char DefIntNr [4] = { 0x0C, 0x0B, 0x0C, 0x0B }; static _ComData* DefComData [4] = { &_ComPort1, &_ComPort2, &_ComPort3, &_ComPort4 }; // Assign one of the predefined ComData structures. To do this, the name // must contain just a number between 1 and 4 or it must be COMX, where // X is a number between 1 and 4. PortName.ToUpper (); char C; if (PortName.Cut (0, 3) == "COM" && PortName.Len () == 4) { C = PortName [3]; } else if (PortName.Len () == 1) { C = PortName [0]; } else { FAIL ("ComPort::Init: Invalid port name"); } // Check the last char unsigned Port; switch (C) { case '1': Port = 0; break; case '2': Port = 1; break; case '3': Port = 2; break; case '4': Port = 3; break; default: FAIL ("ComPort::Init: Invalid port name"); break; } // Assign the ComData struct ComData = DefComData [Port]; // Transfer the parameters into the ComData struct ComData->Baudrate = Baudrate; ComData->Connection = Connection; ComData->Databits = Databits; ComData->Parity = Parity; ComData->Stopbits = Stopbits; ComData->XonXoff = XonXoff; ComData->RXBuf = NULL; ComData->TXBuf = NULL; // Assign the port address or use the default if zero if (UARTBase == 0) { UARTBase = DefPortAddress [Port]; } ComData->PortAddress = UARTBase; // Assign the interrupt number or use the default if zero. if (IntNum == 0) { IntNum = DefIntNr [Port]; } ComData->IntNr = IntNum; // Calculate the IC masks if (IntNum >= 0x08 && IntNum <= 0x0F) { // Low interrupt ComData->IC1Mask = 0x01 << (IntNum - 8); ComData->IC2Mask = 0x00; } else if (IntNum >= 0x70 && IntNum <= 0x77) { // High interrupt ComData->IC1Mask = 0x00; ComData->IC2Mask = 0x01 << (IntNum - 0x70); } else { FAIL ("ComPort::Init: Unsupported interrupt number"); } ComData->NotIC1Mask = ~ComData->IC1Mask; ComData->NotIC2Mask = ~ComData->IC2Mask; // Allocate the buffers, setting the size variables SetBufferSize (RXBufSize, TXBufSize); // Install the port _ComInstall (FP_OFF (ComData)); } void ComPort::SetBufferSize (u16 aRXBufSize, u16 aTXBufSize) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Assure reasonable max and min values and remember them if (aRXBufSize < 64) { aRXBufSize = 64; } else if (aRXBufSize > 4096) { aRXBufSize = 4096; } RXBufSize = aRXBufSize; if (aTXBufSize < 64) { aTXBufSize = 64; } else if (aTXBufSize > 4096) { aTXBufSize = 4096; } TXBufSize = aTXBufSize; // Free the (possibly already existing) buffers delete [] ComData->RXBuf; delete [] ComData->TXBuf; // Allocate new buffers ComData->RXBuf = new char [RXBufSize]; ComData->TXBuf = new char [TXBufSize]; // Record the new sizes ComData->RXBufSize = RXBufSize; ComData->TXBufSize = TXBufSize; } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // All possible errors happen on _ComInstall, so check if the port // is installed if (_ComIsInstalled (FP_OFF (ComData))) { // Error free, open the port and exit _ComOpen (FP_OFF (ComData)); return 0; } else { // Return "NO DEVICE" return ENODEV; } } void ComPort::Close () // Close the port { _ComClose (FP_OFF (ComData)); } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return _ComIsOpen (FP_OFF (ComData)); } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { RXTimeout = aRXTimeout; } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { TXTimeout = aTXTimeout; } void ComPort::DTROn () // Make the DTR line active { _ComDTROn (FP_OFF (ComData)); } void ComPort::DTROff () // Make the DTR line inactive { _ComDTROff (FP_OFF (ComData)); } void ComPort::RTSOn () // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem { _ComRTSOn (FP_OFF (ComData)); } void ComPort::RTSOff () // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem { _ComRTSOff (FP_OFF (ComData)); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer, or just true 1 if the // exact amount of chars in the buffer cannot be determined and the value // is at least one. { return _ComRXCount (FP_OFF (ComData)); } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { return _ComTXCount (FP_OFF (ComData)); } void ComPort::RXClear () // Clear the receive buffer { _ComRXClear (FP_OFF (ComData)); } void ComPort::TXClear () // Clear the transmit buffer { _ComTXClear (FP_OFF (ComData)); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer. The function // may return the exact free space or just 1, if at least one character // can be placed into the send buffer (meaning, the Send function will // not block). { return _ComTXFree (FP_OFF (ComData)); } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { return _ComReceive (FP_OFF (ComData)); } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { return _ComSend (FP_OFF (ComData), B); } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { // Calculate the time to wait in ms u32 Wait = RXTimeout * 1000; // Wait until a character is available or timeout do { if (_ComRXCount (FP_OFF (ComData))) { // A character is available, grab it return _ComReceive (FP_OFF (ComData)); } // Wait some time. u16 ActualWait = Wait > 10 ? 10 : Wait; ActualWait = _ComWait (ActualWait); // Reduce the time to wait if (ActualWait > Wait) { Wait = 0; } else { Wait -= ActualWait; } } while (Wait > 0); // Timeout return -1; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Calculate the time to wait in ms u32 Wait = TXTimeout * 1000; // Wait until the char can be put in the queue or timeout do { if (_ComTXFree (FP_OFF (ComData))) { // There is a free position in the output queue return _ComSend (FP_OFF (ComData), B); } // Wait some time. u16 ActualWait = Wait > 10 ? 10 : Wait; ActualWait = _ComWait (ActualWait); // Reduce the time to wait if (ActualWait > Wait) { Wait = 0; } else { Wait -= ActualWait; } } while (Wait > 0); // Timeout. Do an unconditional Send return _ComSend (FP_OFF (ComData), B); } void ComPort::TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount) // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. { // Check the given parameters PRECONDITION (Count > 0); // Cast the buffer pointer unsigned char* Buf = (unsigned char*) Buffer; // No characters received until now ReadCount = 0; // Read all chars in a loop while (Count > 0) { // Try to receive a char int C = TimedReceive (); if (C == -1) { // Timeout return; } // Store the char Buf [ReadCount++] = (unsigned char) C; // One less Count--; } // Timeout return; } void ComPort::TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount) // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. { // Check the given parameters PRECONDITION (Count > 0); // Cast the buffer pointer const unsigned char* Buf = (const unsigned char*) Buffer; // No characters sent until now WriteCount = 0; // Write all chars in a loop while (Count > 0) { // Try to send the char if (TimedSend (Buf [WriteCount]) == -1) { // Timeout return; } // One more WriteCount++; Count--; } } void ComPort::Break (double Duration) // Send a break with the given time in seconds { _ComBreak (FP_OFF (ComData), Duration * 1000.0); } ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { return _ComModemStatus (FP_OFF (ComData)); } estic-1.61.orig/spunk/linuxsrc/0040755000176100001440000000000007061535304016025 5ustar debacleusersestic-1.61.orig/spunk/linuxsrc/filesys.cc0100644000176100001440000001152207031424714020007 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // #include #include #include "../check.h" #include "../str.h" #include "../filepath.h" #include "../filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '/'; // Path separator extern const char FileSysListSep = ':'; // Path list separator extern const FileSysMaxPath = 255; // Maximum path length extern const FileSysMaxDir = 255; // Maximum directory length extern const FileSysMaxName = 255; // Maximum file name length extern const FileSysMaxExt = 255; // Maximum extension length (including the dot) /*****************************************************************************/ /* Code */ /*****************************************************************************/ int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { FAIL ("Call to FileSysGetDrive on system without drives"); return 0; } int FileSysSetDrive (unsigned /*Drive*/) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { FAIL ("Call to FileSysSetDrive on system without drives"); return 0; } int FileSysExtractDrive (const String& /*Path*/) // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). { // Linux does not support drives return 0; } void FileSysGetInfo (FileSysInfo& Info, int /*Drive*/) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // Use a generic description, even if this is not correct... strcpy (Info.fsName, "EXT2"); Info.fsMaxPath = FileSysMaxPath; Info.fsMaxDir = FileSysMaxDir; Info.fsMaxName = FileSysMaxName; Info.fsMaxExt = FileSysMaxExt; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 0; getcwd (Info.fsCurDir, sizeof (Info.fsCurDir)); } int FileSysPreservesCase (int /*Drive*/) // Return 1 if the file system on the given drive preserves the case in // filenames { // Linux always(?) preserves the case of names return 1; } int FileSysIgnoresCase (int /*Drive*/) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { // Linux never(?) ignores case in file names return 0; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. { // Invald chars static char InvalidChars [] = " <>|=:\"\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int /* Drive */) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { // Linux does not support drives, so a request to include the drive // letter is invalid PRECONDITION (IncludeDrive == 0); // Return the current working directory char Buf [1024]; if (getcwd (Buf, sizeof (Buf)) == NULL) { // OOPS, working dir is not readable return ""; } else { String Dir (Buf); AddPathSep (Dir); return Dir; } } estic-1.61.orig/spunk/linuxsrc/kbd.cc0100644000176100001440000005702107031424714017075 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include #include #include #include #include #include "../machine.h" #include "../msgid.h" #include "../object.h" #include "../stack.h" #include "../charset.h" #include "../environ.h" #include "../keymap.h" #include "../program.h" #include "../kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // An instance of class KeyMapper to map char sequences to keys static KeyMapper Mapper; // A charset containing the available extended keys static CharSet AvailExtKeys; // An array for mapping extended to virtual keys const VirtualMapSize = 50; struct { Key EK; Key VK; } VirtualMap [VirtualMapSize]; static unsigned VirtualMapCount = 0; // Terminal settings at startup static termios StartupSettings; static int StartupMetaMode; // Translation table for the ISO8859-1 charset to the IBM codepage 437 unsigned char TT_ISO_8859_1 [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 8 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 9 32,173,155,156, 32,157, 32, 32, 32, 32,166,174,170, 32, 32, 32, // A 248,241,253, 32, 32,230, 32,249, 32, 32,167,175,172, 32, 32,168, // B 32, 32, 32, 32,142,143,146,128, 32,144, 32, 32, 32, 32, 32, 32, // C 32,165, 32, 32, 32, 32,153, 32, 32, 32, 32, 32,154, 32, 32,225, // D 133,160,131, 32,132,134,145,135,138,130,136,137,141,161,140,139, // E 32,164,149,162,147, 32,148,246, 32,151,163, 32,129, 32,176,152 // F }; unsigned char TT_NOP [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int KbdIsConsole () // Return true if this is a console screen { // This is the console if we can request the state of the keyboard leds int Dummy; return ioctl (STDIN_FILENO, KDGETLED, &Dummy) == 0; } static int KbdCharAvail () // Use select() to check for characters { // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // File descriptor is 0 (stdin) fd_set Desc; FD_ZERO (&Desc); FD_SET (STDIN_FILENO, &Desc); // Check input status return select (STDIN_FILENO+1, &Desc, NULL, NULL, &Timeout); } static void KbdInit () // Remember the current keyboard settings, then switch to raw mode { // Get current settings tcgetattr (STDIN_FILENO, &StartupSettings); // switch to raw mode termios Settings = StartupSettings; Settings.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | IXANY | IXON | IXOFF | INPCK | ISTRIP); Settings.c_iflag |= (BRKINT | IGNPAR); Settings.c_oflag &= ~OPOST; Settings.c_lflag &= ~(XCASE | ECHONL | NOFLSH | ICANON | ISIG | ECHO); Settings.c_cflag |= CREAD; Settings.c_cc[VTIME] = 1; // wait 100 ms for keys Settings.c_cc[VMIN] = 0; // return if timeout or keys available tcsetattr (STDIN_FILENO, TCSADRAIN, &Settings); // If this is the console, remember the old meta setting and switch it // to "prefix with escape" if (ioctl (STDIN_FILENO, KDGKBMETA, &StartupMetaMode) == 0) { // Successful - this is the console ioctl (STDIN_FILENO, KDSKBMETA, (void*) K_ESCPREFIX); } else { // Flag that there is no startup mode StartupMetaMode = -1; } } static void KbdExit () // Reset the keyboard to the startup state { // Reset keyboard settings tcsetattr (STDIN_FILENO, TCSADRAIN, &StartupSettings); // Reset meta mode handling if (StartupMetaMode != -1) { ioctl (STDIN_FILENO, KDSKBMETA, &StartupMetaMode); } } static char* KbdGetCap (const char* Cap) // Get a capability from the termcap file { static char CapBuf [128]; char* CapPtr = CapBuf; return tgetstr (Cap, &CapPtr); } static void KbdAddToMap (const char* S, Key K) // Add the given string to the mapper. If K is an extended key, add it to // the map of available extended keys. { Mapper.Add (S, K); if (S && IsExtendedKey (K)) { AvailExtKeys += (K & 0xFF); } } static void KbdAddCapToMap (const char* Cap, Key K) // Search the termcap entry for the capability Cap and add it to the Mapper // using the key K. { KbdAddToMap (KbdGetCap (Cap), K); } static int KbdHasKey (Key K) // Return true if the given extended(!) key is available on the keyboard { return AvailExtKeys [K & 0xFF] != 0; } static void KbdAddVMap (Key VK, Key EK) // Add the mapping to the virtual key map { // Check for overflow if (VirtualMapCount >= VirtualMapSize) { // Overflow! FAIL ("KbdAddVirtualMap: Buffer overflow!"); } // Add the mapping VirtualMap [VirtualMapCount].EK = EK; VirtualMap [VirtualMapCount].VK = VK; VirtualMapCount++; } static void KbdAddVMap (Key VK, Key MainKey, Key AltKey) // If MainKey is available on the keyboard, add a mapping MainKey --> VK. In // any case, add a mapping AltKey --> VK. Because the latter will be added // later, a search for a virtual key first finds MainKey as the equivalent // extended key. If there is no mapping for MainKey, AltKey is found. { // Conditionally add VK --> MainKey if (KbdHasKey (MainKey)) { // Key exists, add a mapping KbdAddVMap (VK, MainKey); } // Always add VK --> AltKey KbdAddVMap (VK, AltKey); } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (unsigned I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (unsigned I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Key Keyboard::RawKey () { // Not used return (Key) kbNoKey; } Keyboard::Keyboard (): Console (KbdIsConsole ()), TransTable (new unsigned char [256]) { // Switch the keyboard into raw mode KbdInit (); // Check out the LC_CTYPE environment variable and assign the correct // translation table. There are only two possibilities until now, so // don't bother. switch (GetEnvVal ("LC_CTYPE", String ("0^NONE|1^ISO_8859_1|"))) { case 1: // ISO 8859-1 memcpy (TransTable, TT_ISO_8859_1, 256); break; default: // use a 1:1 mapping memcpy (TransTable, TT_NOP, 256); } // The termcap entry has been read before. Read in some key translations // and add them to the mapper // Function keys KbdAddCapToMap ("k1", kbF1); KbdAddCapToMap ("k2", kbF2); KbdAddCapToMap ("k3", kbF3); KbdAddCapToMap ("k4", kbF4); KbdAddCapToMap ("k5", kbF5); KbdAddCapToMap ("k6", kbF6); KbdAddCapToMap ("k7", kbF7); KbdAddCapToMap ("k8", kbF8); KbdAddCapToMap ("k9", kbF9); KbdAddCapToMap ("k0", kbF10); KbdAddCapToMap ("k;", kbF10); // ncurses uses this one KbdAddCapToMap ("F1", kbShiftF1); KbdAddCapToMap ("F2", kbShiftF2); KbdAddCapToMap ("F3", kbShiftF3); KbdAddCapToMap ("F4", kbShiftF4); KbdAddCapToMap ("F5", kbShiftF5); KbdAddCapToMap ("F6", kbShiftF6); KbdAddCapToMap ("F7", kbShiftF7); KbdAddCapToMap ("F8", kbShiftF8); KbdAddCapToMap ("F9", kbShiftF9); KbdAddCapToMap ("FA", kbShiftF10); // Cursor keys needed KbdAddCapToMap ("kl", kbLeft); KbdAddCapToMap ("kr", kbRight); KbdAddCapToMap ("kd", kbDown); KbdAddCapToMap ("ku", kbUp); // Page up/down, home, end etc. KbdAddCapToMap ("kN", kbPgDn); KbdAddCapToMap ("kP", kbPgUp); KbdAddCapToMap ("kh", kbHome); KbdAddCapToMap ("kH", kbEnd); KbdAddCapToMap ("@7", kbEnd); // ncurses name KbdAddCapToMap ("kD", kbDel); KbdAddCapToMap ("kI", kbIns); // Add the meta keys and other sequences to the mapper KbdAddToMap ("\033a", kbMetaA); KbdAddToMap ("\033b", kbMetaB); KbdAddToMap ("\033c", kbMetaC); KbdAddToMap ("\033d", kbMetaD); KbdAddToMap ("\033e", kbMetaE); KbdAddToMap ("\033f", kbMetaF); KbdAddToMap ("\033g", kbMetaG); KbdAddToMap ("\033h", kbMetaH); KbdAddToMap ("\033i", kbMetaI); KbdAddToMap ("\033j", kbMetaJ); KbdAddToMap ("\033k", kbMetaK); KbdAddToMap ("\033l", kbMetaL); KbdAddToMap ("\033m", kbMetaM); KbdAddToMap ("\033n", kbMetaN); KbdAddToMap ("\033o", kbMetaO); KbdAddToMap ("\033p", kbMetaP); KbdAddToMap ("\033q", kbMetaQ); KbdAddToMap ("\033r", kbMetaR); KbdAddToMap ("\033s", kbMetaS); KbdAddToMap ("\033t", kbMetaT); KbdAddToMap ("\033u", kbMetaU); KbdAddToMap ("\033v", kbMetaV); KbdAddToMap ("\033w", kbMetaW); KbdAddToMap ("\033x", kbMetaX); KbdAddToMap ("\033y", kbMetaY); KbdAddToMap ("\033z", kbMetaZ); KbdAddToMap ("\033""0", kbMeta0); KbdAddToMap ("\033""1", kbMeta1); KbdAddToMap ("\033""2", kbMeta2); KbdAddToMap ("\033""3", kbMeta3); KbdAddToMap ("\033""4", kbMeta4); KbdAddToMap ("\033""5", kbMeta5); KbdAddToMap ("\033""6", kbMeta6); KbdAddToMap ("\033""7", kbMeta7); KbdAddToMap ("\033""8", kbMeta8); KbdAddToMap ("\033""9", kbMeta9); KbdAddToMap ("\033\x01", kbEscCtrlA); KbdAddToMap ("\033\x02", kbEscCtrlB); KbdAddToMap ("\033\x03", kbEscCtrlC); KbdAddToMap ("\033\x04", kbEscCtrlD); KbdAddToMap ("\033\x05", kbEscCtrlE); KbdAddToMap ("\033\x06", kbEscCtrlF); KbdAddToMap ("\033\x07", kbEscCtrlG); KbdAddToMap ("\033\x08", kbEscCtrlH); KbdAddToMap ("\033\x09", kbEscCtrlI); KbdAddToMap ("\033\x0A", kbEscCtrlJ); KbdAddToMap ("\033\x0B", kbEscCtrlK); KbdAddToMap ("\033\x0C", kbEscCtrlL); KbdAddToMap ("\033\x0D", kbEscCtrlM); KbdAddToMap ("\033\x0E", kbEscCtrlN); KbdAddToMap ("\033\x0F", kbEscCtrlO); KbdAddToMap ("\033\x10", kbEscCtrlP); KbdAddToMap ("\033\x11", kbEscCtrlQ); KbdAddToMap ("\033\x12", kbEscCtrlR); KbdAddToMap ("\033\x13", kbEscCtrlS); KbdAddToMap ("\033\x14", kbEscCtrlT); KbdAddToMap ("\033\x15", kbEscCtrlU); KbdAddToMap ("\033\x16", kbEscCtrlV); KbdAddToMap ("\033\x17", kbEscCtrlW); KbdAddToMap ("\033\x18", kbEscCtrlX); KbdAddToMap ("\033\x19", kbEscCtrlY); KbdAddToMap ("\033\x1A", kbEscCtrlZ); KbdAddToMap ("\033\033", kbEscEsc); KbdAddToMap ("\x11\x13", kbCtrlQS); KbdAddToMap ("\x11""s", kbCtrlQS); KbdAddToMap ("\x11""S", kbCtrlQS); KbdAddToMap ("\x11\x04", kbCtrlQD); KbdAddToMap ("\x11""d", kbCtrlQD); KbdAddToMap ("\x11""D", kbCtrlQD); KbdAddToMap ("\x11\x12", kbCtrlQR); KbdAddToMap ("\x11""r", kbCtrlQR); KbdAddToMap ("\x11""E", kbCtrlQR); KbdAddToMap ("\x11\x03", kbCtrlQC); KbdAddToMap ("\x11""c", kbCtrlQC); KbdAddToMap ("\x11""C", kbCtrlQC); KbdAddToMap ("\x11\x05", kbCtrlQC); KbdAddToMap ("\x11""e", kbCtrlQC); KbdAddToMap ("\x11""E", kbCtrlQC); KbdAddToMap ("\x11\x18", kbCtrlQX); KbdAddToMap ("\x11""x", kbCtrlQX); KbdAddToMap ("\x11""X", kbCtrlQX); // Now create the mappings extended --> virtual (primary/secondary) KbdAddVMap (vkHelp, kbF1, kbEscCtrlH); KbdAddVMap (vkPgDn, kbPgDn, kbCtrlC); KbdAddVMap (vkPgUp, kbPgUp, kbCtrlR); KbdAddVMap (vkUp, kbUp, kbCtrlE); KbdAddVMap (vkDown, kbDown, kbCtrlX); KbdAddVMap (vkLeft, kbLeft, kbCtrlS); KbdAddVMap (vkRight, kbRight, kbCtrlD); KbdAddVMap (vkIns, kbIns, kbCtrlV); KbdAddVMap (vkDel, kbDel, kbCtrlG); KbdAddVMap (vkHome, kbHome, kbCtrlQS); KbdAddVMap (vkEnd, kbEnd, kbCtrlQD); KbdAddVMap (vkZoom, kbF5, kbEscCtrlZ); KbdAddVMap (vkClose, kbMetaF3, kbEscCtrlC); KbdAddVMap (vkOpen, kbF3, kbEscCtrlO); KbdAddVMap (vkSave, kbF2, kbEscCtrlS); KbdAddVMap (vkAccept, kbF10, kbEscCtrlA); // Keys that have no secondary form under linux KbdAddVMap (vkCtrlUp, kbCtrlW); KbdAddVMap (vkCtrlDown, kbCtrlZ); KbdAddVMap (vkCtrlLeft, kbCtrlA); KbdAddVMap (vkCtrlRight, kbCtrlF); KbdAddVMap (vkCtrlPgUp, kbCtrlQR); KbdAddVMap (vkCtrlPgDn, kbCtrlQC); KbdAddVMap (vkCtrlHome, kbCtrlQE); KbdAddVMap (vkCtrlEnd, kbCtrlQX); KbdAddVMap (vkResize, kbEscCtrlR); KbdAddVMap (vkQuit, kbMetaX); // Handle the abort key separate KbdAddVMap (vkAbort, IsConsole () ? kbEsc : kbEscEsc); // Map the character that c_cc[VERASE] sends to backspace (bug? // is c_cc signed?) if (StartupSettings.c_cc [VERASE] > 0 && StartupSettings.c_cc [VERASE] <= 256) { TransTable [StartupSettings.c_cc [VERASE]] = (unsigned char) kbBack; } else { // It seems that the setting is invalid, check the termcap database // for a kb entry. If the entry is only one char, translate it via // the translation table, otherwise use the mapper char* BS = KbdGetCap ("kb"); if (BS) { if (strlen (BS) == 1) { // Just one char TransTable [(unsigned char) (*BS)] = (unsigned char) kbBack; } else { // A sequence... KbdAddToMap (BS, kbBack); } } } } Keyboard::~Keyboard () { // Reset the keyboard state KbdExit (); // Delete the translation table delete [] TransTable; } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { static int BufFill = 0; static unsigned char Buf [64] = ""; // The handling is different, if we are on the console or not. On the // console, we can easily find a complete key sequence, because a // complete sequence is returned by read. This allows usage of the alt // keys. // On a terminal, we have to search for each sequence. if (IsConsole ()) { // This is the console. If we should not wait, first check if any // characters are available, if not, bail out if (Wait == 0 && KbdCharAvail () == 0) { // Nothing to do return; } // Now loop until we have a valid key while (1) { // Read in a complete sequence from the keyboard do { BufFill = read (0, Buf, sizeof (Buf)-1); if (BufFill == 0) { // Timeout waiting for a key, allow some idle processing App->Idle (); } } while (BufFill <= 0); Buf [BufFill] = '\0'; // If there is only one key in the buffer, read it directly, otherwise // ask the mapper. Key K; if (BufFill == 1) { // Remap the key K = KbdMapExtended (Translate (Buf [0])); // Put the mapped key into the buffer and return KeyBuf.Put (K); return; } else { // There is more than one char in the buffer. This must be a complete // key sequence. Try to find the mapping for that key, insert the // mapped key. If we do not find a mapping, this is a key sequence, // we don't know, so throw it away. int Index; if (Mapper.Search ((char*) Buf, Index)) { // Found! K = KbdMapExtended (Mapper [Index]->GetKey ()); KeyBuf.Put (K); return; } } } } else { // Not the console. If we have keys left in the buffer, try to find a // match. If we have a partial match, read more chars, until we get // a full or no match. char SBuf [sizeof (Buf)]; int SCount = 1; while (1) { while (SCount <= BufFill) { // Add the next char from Buf to SBuf, add the trailing zero SBuf [SCount-1] = Buf [SCount-1]; SBuf [SCount] = '\0'; // Now search for this portion of Buf int Index; Key K; switch (Mapper.Find (SBuf, Index)) { case 0: // No match. Return the translated equivalent of the // first char in Buf, then delete it from Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; case 1: // Partial match. Increase the length of the sequence, // we search for. If the length succeeds some arbitary // limit, handle it like no match. if (SCount < 16) { SCount++; } else { // Suspicious... Return the translated equivalent // of the first char in Buf, then delete it from // Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; } break; case 2: // Full match. Delete the sequence from the buffer. memmove (&Buf [0], &Buf [SCount], BufFill - SCount + 1); BufFill -= SCount; K = KbdMapExtended (Mapper [Index]->GetKey ()); KeyBuf.Put (K); return; } } // If we get here, the buffer is exhausted and we still have a // partial match (or the buffer has been empty on startup). // If we should read without a wait, check if there are characters // waiting. If not, don't do a blocking read but return without // doing anything. if (Wait == 0 && KbdCharAvail () == 0) { // No chars waiting return; } // Before trying to read more chars, check for a buffer overflow // (this should not happen, but who knows...) if (SCount >= (int) sizeof (Buf)) { FAIL ("Keyboard::GetMappedKey: Buffer overflow"); } // Now read in a new chunk of chars. int Count; do { Count = read (0, &Buf [BufFill], sizeof (Buf) - BufFill - 1); if (Count == 0) { // Timeout waiting for a key, allow some idle processing App->Idle (); } } while (Count <= 0); BufFill += Count; Buf [BufFill] = '\0'; } } } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description if (IsConsole ()) { return App->LoadMsg (MSGBASE_KBD + K); } else { return App->LoadMsg (MSGBASE_KBD + 0x200 + K); } } estic-1.61.orig/spunk/linuxsrc/screen.cc0100644000176100001440000000461007031424714017610 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include #include "../screen.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int ScrIsConsole () // Return true if this is a console screen { // This is the console if we can request the keyboard meta mode int Dummy; return ioctl (STDOUT_FILENO, KDGETMODE, &Dummy) == 0; } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): Color (ScrIsConsole ()), // Default is to use color at the console Console (ScrIsConsole ()), CP437 (ScrIsConsole ()), // Default is to use CP437 at the console TransTable (NULL) { // Initialize the termcap system TCInit (); } char* Screen::GetIS (char* IS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { // We have a new string if we are on the console and are using CP437 return (Console && CP437)? "\033(U\033>\033[4;20l" : IS; } char* Screen::GetRS (char* RS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { // We have a new string if we are on the console and are using CP437 return (Console && CP437)? "\033(B\033>\033[4;20l\033[?25h" : RS; } estic-1.61.orig/spunk/linuxsrc/sercom.cc0100644000176100001440000004134607031424714017630 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // Linux version. #include #include #include #include #include #include #include #include #include "../check.h" #include "../sercom.h" #include "../filepath.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // internal used data struct _ComData { int Handle; // Port handle unsigned RXCount; // characters in receive queue unsigned TXCount; // characters in transmit queue termios StartupSettings;// Device settings on startup termios CurrentSettings;// Current device settings ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ static void SetReadTimeout (_ComData* ComData, int Min, int Time) { if (ComData->CurrentSettings.c_cc [VMIN] != Min || ComData->CurrentSettings.c_cc [VTIME] != Time) { // Need to set the new values ComData->CurrentSettings.c_cc [VMIN] = Min; ComData->CurrentSettings.c_cc [VTIME] = Time; ZCHECK (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings)); } } /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (4096), // Just some value... TXBufSize (4096), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen()) { Close(); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // Create an internally used data structure ComData = new _ComData; // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); // setting up ComData ComData->Handle = -1; // Port not open ComData->RXCount = 0; ComData->TXCount = 0; } void ComPort::SetBufferSize (u16 /*aRXBufSize*/, u16 /*aTXBufSize*/) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Otherwise this function is ignored under Linux as we could not set any // buffer sizes (no harm done anyway) } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // First, check if the port contains a directory. If not, add /dev String Dir, Name; FSplit (PortName, Dir, Name); if (Dir.IsEmpty ()) { PortName.Ins (0, "/dev/"); } // Open the port ComData->Handle = open (PortName.GetStr (), O_RDWR | O_NONBLOCK); if (ComData->Handle == -1) { // Got an error, return the error code return errno; } // Device must be a tty if (!isatty (ComData->Handle)) { // Error, close and exit Close (); return ENOTTY; } // Remember the current settings tcgetattr (ComData->Handle, &ComData->StartupSettings); // Set up the new settings ComData->CurrentSettings = ComData->StartupSettings; // Set up input flags tcflag_t iflag = IGNBRK | IGNPAR; if (Databits == 7) { iflag |= ISTRIP; // Strip bit 7 } if (XonXoff == 'E') { iflag |= IXON | IXOFF; // Enable XON/XOFF protocol } ComData->CurrentSettings.c_iflag = iflag; // Set up output flags tcflag_t oflag = 0; ComData->CurrentSettings.c_oflag = oflag; // Set up control flags tcflag_t cflag = CREAD | HUPCL; switch (Databits) { case 5: cflag |= CS5; break; case 6: cflag |= CS6; break; case 7: cflag |= CS7; break; case 8: cflag |= CS8; break; default: FAIL ("ComPort::Init: Unsupported databits value"); } switch (Parity) { case 'N': break; case 'E': cflag |= PARENB; break; case 'O': cflag |= PARENB | PARODD; break; default: FAIL ("ComPort::Init: Unsupported parity setting"); } switch (Stopbits) { case 1: break; case 2: cflag |= CSTOPB; break; default: FAIL ("ComPort::Init: Unsupported stopbits value"); } switch (Connection) { case 'M': cflag |= CRTSCTS; break; // not POSIX! case 'D': cflag |= CLOCAL; break; default: FAIL ("ComPort::Init: Unsupported connection setting"); } ComData->CurrentSettings.c_cflag = cflag; // Set up local flags tcflag_t lflag = 0; ComData->CurrentSettings.c_lflag = lflag; // Set XON/XOFF to Ctrl-S/Ctrl-Q ComData->CurrentSettings.c_cc [VSTART] = 0x11; ComData->CurrentSettings.c_cc [VSTOP] = 0x13; // Set the baudrate speed_t Baud = 0; switch (Baudrate) { case 50: Baud = B50; break; case 75: Baud = B75; break; case 110: Baud = B110; break; case 134: Baud = B134; break; case 150: Baud = B150; break; case 200: Baud = B200; break; case 300: Baud = B300; break; case 600: Baud = B600; break; case 1200: Baud = B1200; break; case 2400: Baud = B2400; break; case 4800: Baud = B4800; break; case 9600: Baud = B9600; break; case 19200: Baud = B19200; break; case 38400: Baud = B38400; break; case 57600: Baud = B57600; break; case 115200: Baud = B115200; break; case 230400: Baud = B230400; break; default: FAIL ("ComPort::Init: Unsupported baudrate value"); } ComData->CurrentSettings.c_cflag |= Baud; cfsetispeed (&ComData->CurrentSettings, Baud); cfsetospeed (&ComData->CurrentSettings, Baud); // Set timeouts ComData->CurrentSettings.c_cc [VMIN] = 1; ComData->CurrentSettings.c_cc [VTIME] = int (RXTimeout / 0.1); // Actually set up the device if (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings) < 0) { // Could not set int Result = errno; Close (); return Result; } // When we set cflags == CLOCAL on a direct connection, the RTS and DTR // lines will become active. This is not compatible to the other sercom // modules, so change it. Also make DTR low if hardware handshake is // enabled. int HandshakeLines = TIOCM_DTR; if (Connection == 'D') { HandshakeLines |= TIOCM_RTS; } ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &HandshakeLines)); // Reset nonblocking mode int Flags = fcntl (ComData->Handle, F_GETFL, 0); if (Flags < 0) { // Error int Result = errno; Close (); return Result; } Flags &= ~O_NONBLOCK; if (fcntl (ComData->Handle, F_SETFL, Flags) < 0) { // Error int Result = errno; Close (); return Result; } // Success return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open PRECONDITION (IsOpen ()); // Close the device close (ComData->Handle); // reset handle ComData->Handle = -1; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->Handle != -1; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout > 0 && aRXTimeout < 0.1) { aRXTimeout = 0.1; } // Remember the timeout RXTimeout = aRXTimeout; // Set the timeout SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; } void ComPort::DTROn () // Make the DTR line active { // Port must be open PRECONDITION (IsOpen ()); // Set DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::DTROff () // Make the DTR line inactive { // Port must be open PRECONDITION (IsOpen ()); // Clear DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } void ComPort::RTSOn () // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Set RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::RTSOff () // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Clear RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer { // Port must be open PRECONDITION (IsOpen ()); int Count; ZCHECK (ioctl (ComData->Handle, TIOCINQ, &Count)); return Count; } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); int Count; ZCHECK (ioctl (ComData->Handle, TIOCOUTQ, &Count)); return Count; } void ComPort::RXClear () // Clear the receive buffer { // Port must be open PRECONDITION (IsOpen ()); ZCHECK (tcflush (ComData->Handle, TCIFLUSH)); } void ComPort::TXClear () // Clear the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); ZCHECK (tcflush (ComData->Handle, TCOFLUSH)); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer. The function // may return the exact free space or just 1, if at least one character // can be placed into the send buffer (meaning, the Send function will // not block). { // Port must be open PRECONDITION (IsOpen ()); // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // Set the file descriptor to ComData->Handle fd_set Desc; FD_ZERO (&Desc); FD_SET (ComData->Handle, &Desc); // Check output status if (select (ComData->Handle+1, NULL, &Desc, NULL, &Timeout) > 0) { return 1; } else { return 0; } } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { // Port must be open PRECONDITION (IsOpen ()); // Set no timeout mode SetReadTimeout (ComData, 0, 0); // read one character unsigned char B; int ReadCount; do { ReadCount = read (ComData->Handle, &B, 1); } while (ReadCount != 1); // return character return B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { int WriteCount; do { WriteCount = write (ComData->Handle, &B, 1); } while (WriteCount != 1); return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { // Port must be open PRECONDITION (IsOpen ()); // Set up the device for timeout read SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); unsigned char B; int ReadCount = read (ComData->Handle, &B, 1); // Return the character read or -1 on timeout return ReadCount == 1 ? B : -1; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); // Use select to check if write is possible timeval Timeout; Timeout.tv_usec = u32 (TXTimeout * 1000000) % 1000000; Timeout.tv_sec = long (TXTimeout); fd_set Desc; FD_ZERO (&Desc); FD_SET (ComData->Handle, &Desc); if (select (ComData->Handle + 1, NULL, &Desc, NULL, &Timeout)) { // Descriptor is ready for writing write (ComData->Handle, &B, 1); return B; } else { // Timeout or signal. Return an timeout error code when a signal // occurs ComData->ErrorCounter [ceTXOverflow]++; return -1; } } void ComPort::Break (double /*Duration*/) // Send a break with the given time in seconds { // Port must be open PRECONDITION (IsOpen ()); // Ignore Duration as values != zero have undefined behavior ZCHECK (tcsendbreak (ComData->Handle, 0)); } #if 0 // gcc 2.5.8 is not able to compile this (bug using the typedef) // Leave it out and hope no one will notice... ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } #endif unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { // Port must be open PRECONDITION (IsOpen ()); // Get the modem lines int Lines; ZCHECK (ioctl (ComData->Handle, TIOCMGET, &Lines)); // Convert to sercom format, ignore the "delta" lines unsigned Status = 0; if (Lines & TIOCM_CTS) Status |= csCTS; if (Lines & TIOCM_DSR) Status |= csDSR; if (Lines & TIOCM_RNG) Status |= csRI; if (Lines & TIOCM_CAR) Status |= csCD; // Return the result return Status; } estic-1.61.orig/spunk/netwaresrc/0040755000176100001440000000000007061535304016333 5ustar debacleusersestic-1.61.orig/spunk/netwaresrc/delay.cc0100644000176100001440000000344707031424715017745 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System dependent function for waiting some time. #include #include "progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 Delay (u32 ms) // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // An argument of zero has a special meaning: The function tries to give up // the current time slice, calls App->Idle () and returns after that. // // The function returns the real time passed or just ms. { const ChunkSize = 100; // Check the argument... if (ms <= ChunkSize) { // Wait some time delay (ms); // Call the applications idle function Idle (); } else { u32 Counter = ms; while (Counter) { unsigned TimeToWait = Counter >= ChunkSize ? ChunkSize : Counter; // Recursive call to Delay... u32 WaitTime = Delay (TimeToWait); if (WaitTime > Counter) { Counter = 0; } else { Counter -= WaitTime; } } } // Return the argument return ms; } estic-1.61.orig/spunk/netwaresrc/filesys.cc0100644000176100001440000001211007031424715020310 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // #include #include #include #include "check.h" #include "str.h" #include "filepath.h" #include "filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '/'; // Path separator extern const char FileSysListSep = ';'; // Path list separator extern const FileSysMaxPath = 79; // Maximum path length extern const FileSysMaxDir = 65; // Maximum directory length extern const FileSysMaxName = 8; // Maximum file name length extern const FileSysMaxExt = 4; // Maximum extension length (including the dot) /*****************************************************************************/ /* Code */ /*****************************************************************************/ int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { FAIL ("Call to FileSysGetDrive on system without drives"); return 0; } int FileSysSetDrive (unsigned /*Drive*/) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { FAIL ("Call to FileSysSetDrive on system without drives"); return 0; } int FileSysExtractDrive (const String& /*Path*/) // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). { // Netware does not support drives return 0; } void FileSysGetInfo (FileSysInfo& Info, int /*Drive*/) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // Use a generic description, even if this is not correct... strcpy (Info.fsName, "NETWARE"); Info.fsMaxPath = FileSysMaxPath; Info.fsMaxDir = FileSysMaxDir; Info.fsMaxName = FileSysMaxName; Info.fsMaxExt = FileSysMaxExt; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 0; getcwd (Info.fsCurDir, sizeof (Info.fsCurDir)); } int FileSysPreservesCase (int /*Drive*/) // Return 1 if the file system on the given drive preserves the case in // filenames { // Filesystems do not preserve case return 0; } int FileSysIgnoresCase (int /*Drive*/ ) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { // Netware does ignore case in file names return 1; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. { // Invald chars static char InvalidChars [] = " <>|+=:;,\"/\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int /*Drive*/) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { String Dir; PRECONDITION (IncludeDrive == 0); // We don't have drives // Get the current working directory. Since FAT is not case sensitive, // convert the name to lower case. char Buf [256]; if (getcwd (Buf, sizeof (Buf)) == NULL) { // OOPS - unknown drive Dir.Clear (); } else { // Get the char* into a string Dir = Buf; // Remove the server spec from the name int P = Dir.Pos (FileSysPathSep); if (P >= 0) { Dir.Del (0, P + 1); } // Add a path separator AddPathSep (Dir); // Convert to lower case Dir.ToLower (); } // Return the result return Dir; } estic-1.61.orig/spunk/netwaresrc/kbd.cc0100644000176100001440000001074107031424715017402 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include "msgid.h" #include "program.h" #include "kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // Mapper table from virtual to extended keys. This table is fixed for DOS/OS2 static struct { Key EK; Key VK; } VirtualMap [] = { { kbEsc, vkAbort }, { kbF1, vkHelp }, { kbF10, vkAccept }, { kbPgUp, vkPgUp }, { kbPgDn, vkPgDn }, { kbCtrlPgUp, vkCtrlPgUp }, { kbCtrlPgDn, vkCtrlPgDn }, { kbUp, vkUp }, { kbDown, vkDown }, { kbLeft, vkLeft }, { kbRight, vkRight }, { kbIns, vkIns }, { kbDel, vkDel }, { kbHome, vkHome }, { kbEnd, vkEnd }, { kbCtrlUp, vkCtrlUp }, { kbCtrlDown, vkCtrlDown }, { kbCtrlLeft, vkCtrlLeft }, { kbCtrlRight, vkCtrlRight }, { kbCtrlIns, vkCtrlIns }, { kbCtrlDel, vkCtrlDel }, { kbCtrlHome, vkCtrlHome }, { kbCtrlEnd, vkCtrlEnd }, { kbF5, vkZoom }, { kbMetaF3, vkClose }, { kbF3, vkOpen }, { kbF2, vkSave }, { kbCtrlF5, vkResize }, { kbMetaX, vkQuit }, // Secondary mappings follow { kbCtrlR, vkPgUp }, { kbCtrlC, vkPgDn }, { kbCtrlE, vkUp }, { kbCtrlX, vkDown }, { kbCtrlS, vkLeft }, { kbCtrlD, vkRight }, { kbCtrlV, vkIns }, { kbCtrlG, vkDel }, { kbCtrlW, vkCtrlUp }, { kbCtrlZ, vkCtrlDown }, { kbCtrlA, vkCtrlLeft }, { kbCtrlF, vkCtrlRight }, }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int KbdCharAvail () // Return true if a char is available from the os { return kbhit (); } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Keyboard::Keyboard (): Console (1), TransTable (NULL) { } Keyboard::~Keyboard () { delete [] TransTable; } Key Keyboard::RawKey () // Get a raw (unmapped) key from the os { // Wait for a key calling repeatedly App->Idle () while (KbdCharAvail () == 0) { // Allow idle processing CurThread () -> Idle (); // Allow other threads to run ThreadSwitch (); } // Get the key Key K = getch (); if (K == 0) { // Extended key return (0x0100 | (Key) getch ()); } else { return (K & 0x00FF); } } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { // If waiting is not wanted, check if there are keys available before // grabbing them if (Wait == 0 && KbdCharAvail () == 0) { // No keys available, bail out return; } // Get a key, remap it and put it into the buffer KeyBuf.Put (KbdMapExtended (Translate (RawKey ()))); } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description return App->LoadMsg (MSGBASE_KBD + K); } estic-1.61.orig/spunk/netwaresrc/nlsinit.cc0100644000176100001440000001276707031424715020334 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { unsigned Country = DefaultCountry; unsigned Language = DefaultLanguage; // Get country information. Here I'm probably supposed to call // NWLLocaleconv, but I have no docs what the pointer given as argument is // for, so assume we don't have such a function. This may change later... // Try if there is an override for the country in the environment Country = GetEnvNum ("SPUNK_COUNTRY", Country); // Try if there is an override for the language in the environment Language = GetEnvNum ("SPUNK_LANGUAGE", Language); // Set the country data NLSSetCountry (Country); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/netwaresrc/screen.cc0100644000176100001440000001241307031424715020117 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include "screen.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) Screen * TheScreen; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static u16 ScrGetMode () // return the current video mode { if (IsColorMonitor ()) { return vmCO80; } else { return vmMono; } } static void ScrSetMode (u16 /*Mode*/) { // We cannot set the mode, at least I don't know how } static u16 ScrGetCursor () // get the current cursor type { BYTE Start, End; GetCursorShape (&Start, &End); return ( (((u16) Start) << 8) | (((u16) End) & 0x00FF) ); } static void ScrSetCursor (u16 Cursor) // set a cursor { SetCursorShape (Cursor >> 8, Cursor & 0x00FF); } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): CP437 (1), TransTable (NULL) { // Remember old video mode and cursor form StartupMode = ScrGetMode (); StartupCursor = ScrGetCursor (); // Use current screen mode CurrentMode = StartupMode; // Set the mode data for this mode SetModeData (); // Switch the cursor off SetCursorOff (); } Screen::~Screen () { // Reset old video mode and cursor SetMode (StartupMode); ScrSetCursor (StartupCursor); } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table { if (TransTable) { unsigned char* S = (unsigned char*) Target; unsigned char* T = (unsigned char*) Source; while (Len--) { *T++ = TransTable [*S++]; // Translate character *T++ = *S++; // Copy attribute } return Target; } else { // No translation table, return the source buffer return Source; } } void Screen::SetModeData () // Internally called after setting a new mode, sets cursor data etc. { // Get size of screen and the character cell height WORD Height, Width; GetSizeOfScreen (&Height, &Width); XSize = Width; YSize = Height; unsigned YCell = 16; // Calculate the cursor settings from the character cell height CF_HiddenCursor = 0; // is constant under OS/2 CF_FatCursor = 0x0100 + YCell - 1; CF_NormalCursor = ((YCell - 2) << 8) + (YCell - 1); // Check if color mode #if 0 Color = IsColorMonitor (); #endif Color = 1; } void Screen::SetMode (u16 Mode) { if (Mode == vmInvalid) { return; } // Remember mode CurrentMode = Mode; // set mode ScrSetMode (Mode); // Get mode data SetModeData (); // Switch cursor off SetCursorOff (); } void Screen::SetCursorOn () { DisplayInputCursor (); ScrSetCursor (CF_NormalCursor); } void Screen::SetCursorOff () { // ScrSetCursor (CF_HiddenCursor); HideInputCursor (); } void Screen::SetCursorFat () { DisplayInputCursor (); ScrSetCursor (CF_FatCursor); } void Screen::SetCursorPos (const Point& Pos) { gotoxy (Pos.X, Pos.Y); } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { int XtoDo, YtoDo; int XCount = R.XSize (); int YCount = R.YSize (); // Check if anything to do if (XCount == 0 || YCount == 0 || R.A.Y > YSize || R.A.X > XSize) { // Done return; } // Calculate the size of the output rectangle XtoDo = (R.B.X > XSize) ? XSize - R.A.X : XCount; YtoDo = (R.B.Y > YSize) ? YSize - R.A.Y : YCount; // If we have to translate the output, get buffer memory u16* Buf2; if (TransTable) { Buf2 = (u16*) alloca (XtoDo * sizeof (u16)); } int Y = R.A.Y; while (YtoDo--) { // Do a translation if neccessary if (TransTable) { // Translate and write to screen Translate (Buf2, Buf, XtoDo); CopyToScreenMemory (1, // Height XtoDo, // Width (BYTE*) Buf2, // Buffer R.A.X, // X position Y); // Y position } else { // No translation CopyToScreenMemory (1, // Height XtoDo, // Width (BYTE*) Buf, // Buffer R.A.X, // X position Y); // Y position } Buf += XCount; Y++; } } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { // We have always direct access to the screen return 10; } estic-1.61.orig/spunk/netwaresrc/sercom.cc0100644000176100001440000003344207031424715020135 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // Netware version. #include #include #include #include #include "check.h" #include "chartype.h" #include "delay.h" #include "sercom.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // internal used data struct _ComData { int Handle; // Port handle int AIOResult; // Result of last AIO operation int NewBufferSize; // Buffer size has been changed ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (512), // Just some value... TXBufSize (512), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen()) { Close(); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // If the name of the port is just a number, expand it by // inserting "COM". if (PortName.Len () == 1 && IsDigit (PortName [0])) { PortName.Ins (0, "COM"); } // Create an internally used data structure ComData = new _ComData; // Port is currently not open ComData->Handle = -1; // Reset flag for new buffer size ComData->NewBufferSize = 0; // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); } void ComPort::SetBufferSize (u16 aRXBufSize, u16 aTXBufSize) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Check the given parameters PRECONDITION (aRXBufSize >= 64 && aRXBufSize <= 16384); PRECONDITION (aTXBufSize >= 64 && aTXBufSize <= 16384); // Remember the new sizes RXBufSize = aRXBufSize; TXBufSize = aTXBufSize; // Set a flag for open ComData->NewBufferSize = 1; } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // Try to aquire the port int HardwareType = AIO_COMX_TYPE; int BoardNumber = AIO_BOARD_NUMBER_WILDCARD; int PortNumber = AIO_PORT_NUMBER_WILDCARD; ComData->AIOResult = AIOAcquirePort (&HardwareType, &BoardNumber, &PortNumber, &ComData->Handle); if (ComData->AIOResult != AIO_SUCCESS) { // Could not aquire port. ComData->Handle = -1; return EACCES; } // If the buffer sizes have been set, tell the OS to use the new sizes. // Otherwise read the current values and store them for later retrieval. if (ComData->NewBufferSize) { // Set the new sizes, errors are fatal CHECK (AIOSetReadBufferSize (ComData->Handle, RXBufSize) == AIO_SUCCESS); CHECK (AIOSetWriteBufferSize (ComData->Handle, TXBufSize) == AIO_SUCCESS); } else { // Get the buffer sizes and store them LONG ReadBufSize, WriteBufSize; CHECK (AIOGetReadBufferSize (ComData->Handle, &ReadBufSize) == AIO_SUCCESS); CHECK (AIOGetWriteBufferSize (ComData->Handle, &WriteBufSize) == AIO_SUCCESS); RXBufSize = (u16)ReadBufSize; TXBufSize = (u16)WriteBufSize; } // Set up the port configuration // --- Baudrate --- BYTE Bitrate; switch (Baudrate) { case 50: Bitrate = AIO_BAUD_50; break; case 75: Bitrate = AIO_BAUD_75; break; case 110: Bitrate = AIO_BAUD_110; break; case 150: Bitrate = AIO_BAUD_150; break; case 300: Bitrate = AIO_BAUD_300; break; case 600: Bitrate = AIO_BAUD_600; break; case 1200: Bitrate = AIO_BAUD_1200; break; case 1800: Bitrate = AIO_BAUD_1800; break; case 2000: Bitrate = AIO_BAUD_2000; break; case 2400: Bitrate = AIO_BAUD_2400; break; case 3600: Bitrate = AIO_BAUD_3600; break; case 4800: Bitrate = AIO_BAUD_4800; break; case 7200: Bitrate = AIO_BAUD_7200; break; case 9600: Bitrate = AIO_BAUD_9600; break; case 19200: Bitrate = AIO_BAUD_19200; break; case 38400: Bitrate = AIO_BAUD_38400; break; case 57600: Bitrate = AIO_BAUD_57600; break; case 115200: Bitrate = AIO_BAUD_115200; break; default: FAIL ("ComPort::Open: Unsupported value for Baudrate"); } // --- Number of data bits --- BYTE DatabitCount; switch (Databits) { case 5: DatabitCount = AIO_DATA_BITS_5; break; case 6: DatabitCount = AIO_DATA_BITS_6; break; case 7: DatabitCount = AIO_DATA_BITS_7; break; case 8: DatabitCount = AIO_DATA_BITS_8; break; default: FAIL ("ComPort::Open: Unsupported value for Databits"); } // --- Number of stop bits --- BYTE StopbitCount; switch (Stopbits) { case 1: StopbitCount = AIO_STOP_BITS_1; break; case 2: StopbitCount = AIO_STOP_BITS_2; break; default: FAIL ("ComPort::Open: Unsupported value for Stopbits"); } // --- parity mode --- BYTE ParityMode; switch (Parity) { case 'N': ParityMode = AIO_PARITY_NONE; break; case 'O': ParityMode = AIO_PARITY_ODD; break; case 'E': ParityMode = AIO_PARITY_EVEN; break; case 'M': ParityMode = AIO_PARITY_MARK; break; case 'S': ParityMode = AIO_PARITY_SPACE; break; default: FAIL ("ComPort::Open: Unsupported value for Parity"); } // --- flow control --- BYTE FlowControl = 0; switch (XonXoff) { case 'E': FlowControl |= AIO_SOFTWARE_FLOWCONTROL_ON; break; case 'D': FlowControl |= AIO_SOFTWARE_FLOWCONTROL_OFF; break; default: FAIL ("ComPort::Open: Unsupported value for XonXoff"); } switch (Connection) { case 'D': FlowControl |= AIO_HARDWARE_FLOWCONTROL_OFF; break; case 'M': FlowControl |= AIO_HARDWARE_FLOWCONTROL_ON; break; default: FAIL ("ComPort::Open: Unsupported value for Connection"); } // Try to configure the port ComData->AIOResult = AIOConfigurePort (ComData->Handle, Bitrate, DatabitCount, StopbitCount, ParityMode, FlowControl); // Check for errors if (ComData->AIOResult != AIO_SUCCESS) { // Some data is invalid return EINVAL; } return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open... PRECONDITION (IsOpen ()); // Close the port ComData->AIOResult = AIOReleasePort (ComData->Handle); // Invalidate the handle ComData->Handle = -1; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->Handle != -1; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout < 0.01) { aRXTimeout = 0.01; } // Remember the timeout RXTimeout = aRXTimeout; // Set the timeout // ## } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; // Set the timeout // ## } void ComPort::DTROn () // Make the DTR line active { // The port must be open PRECONDITION (IsOpen ()); } void ComPort::DTROff () // Make the DTR line inactive { // The port must be open PRECONDITION (IsOpen ()); } void ComPort::RTSOn () // Make the RTS line active { // The port must be open and a modem connection is not allowed PRECONDITION (IsOpen () && Connection != 'M'); } void ComPort::RTSOff () // Make the RTS line inactive { // The port must be open and a modem connection is not allowed PRECONDITION (IsOpen () && Connection != 'M'); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer { LONG Count; WORD State; CHECK (AIOReadStatus (ComData->Handle, &Count, &State) == AIO_SUCCESS); return Count; } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { LONG Count; WORD State; CHECK (AIOWriteStatus (ComData->Handle, &Count, &State) == AIO_SUCCESS); return Count; } void ComPort::RXClear () // Clear the receive buffer { CHECK (AIOFlushBuffers (ComData->Handle, AIO_FLUSH_READ_BUFFER) == AIO_SUCCESS); } void ComPort::TXClear () // Clear the transmit buffer { CHECK (AIOFlushBuffers (ComData->Handle, AIO_FLUSH_READ_BUFFER) == AIO_SUCCESS); } unsigned ComPort::TXFree () // Return the amount of free space in the transmit buffer { return TXBufSize - TXCount (); } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { char B; LONG BytesRead; do { CHECK (AIOReadData (ComData->Handle, &B, sizeof (B), &BytesRead) == AIO_SUCCESS); } while (BytesRead == 0); // return character return (int)(unsigned char)B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { char C = (char) B; LONG BytesWritten; CHECK (AIOWriteData (ComData->Handle, &C, sizeof (C), &BytesWritten) == AIO_SUCCESS); return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { return 0; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { return 0; } void ComPort::TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount) // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. { // Check params PRECONDITION (Count > 0); } void ComPort::TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount) // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. { // Check params PRECONDITION (Count > 0); } void ComPort::Break (double Duration) // Send a break with the given time in seconds { // BREAK ON CHECK (AIOSetExternalControl (ComData->Handle, AIO_BREAK_CONTROL, AIO_SET_BREAK_ON) == AIO_SUCCESS); // Wait... Delay (Duration * 1000); // BREAK OFF CHECK (AIOSetExternalControl (ComData->Handle, AIO_BREAK_CONTROL, AIO_SET_BREAK_OFF) == AIO_SUCCESS); } ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { LONG Status, Delta; CHECK (AIOGetExternalStatus (ComData->Handle, &Status, &Delta) == AIO_SUCCESS); // Convert to sercom format unsigned S = 0; if (Status & AIO_EXTSTA_CTS) S |= csCTS; if (Status & AIO_EXTSTA_DSR) S |= csDSR; if (Status & AIO_EXTSTA_RI) S |= csRI; if (Status & AIO_EXTSTA_DCD) S |= csCD; if (Delta & AIO_EXTSTA_CTS) S |= csDeltaCTS; if (Delta & AIO_EXTSTA_DSR) S |= csDeltaDSR; if (Delta & AIO_EXTSTA_RI) S |= csDeltaRI; if (Delta & AIO_EXTSTA_DCD) S |= csDeltaCD; // Return the result return S; } estic-1.61.orig/spunk/nls/0040755000176100001440000000000007061535304014752 5ustar debacleusersestic-1.61.orig/spunk/nls/049.dat0100644000176100001440000000144307031424715015757 0ustar debacleusersDM.,.:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙estic-1.61.orig/spunk/nls/ascii.dat0100644000176100001440000000040007031424715016523 0ustar debacleusers »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±> #include #include #define INCL_DOSNLS #include #include "machine.h" #include "nlsinfo.h" #include "national.h" #include "check.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void Error (const char* S, u32 RC, u32 Country) { fprintf (stderr, "Error reading %s, code = %d, country = %d\n", S, RC, Country); exit (1); } static void ReadCountry (u32 Country, u32 CodePage = 437) // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { _NLSInfo S; // Country code for the current country COUNTRYCODE CountryCode; CountryCode.country = Country; CountryCode.codepage = CodePage; COUNTRYINFO Info; ULONG DataLength; ULONG RC; // Get country information RC = DosQueryCtryInfo (sizeof (Info), &CountryCode, &Info, &DataLength); if (RC != 0) { fprintf (stderr, "Error reading DosQueryCtryInfo, code = %d, country = %d\n", RC, Country); return; } // Transfer data S.Data.Date = Info.fsDateFmt; S.Data.Time = Info.fsTimeFmt; S.Data.Curr = Info.fsCurrencyFmt; strcpy (S.Data.CurrStr, Info.szCurrency); S.Data.ThSep = Info.szThousandsSeparator [0]; S.Data.DecSep = Info.szDecimal [0]; S.Data.DateSep = Info.szDateSeparator [0]; S.Data.TimeSep = Info.szTimeSeparator [0]; S.Data.DataSep = Info.szDataSeparator [0]; unsigned I; for (I = 0; I < 256; I++) { S.UpCaseMap [I] = I; } // Get the current case map DosMapCase (sizeof (S.UpCaseMap), &CountryCode, S.UpCaseMap); if (RC != 0) { Error ("DosMapCase", RC, Country); } // Now create the lowercase table from the uppercase table memset (S.LoCaseMap, 0, 256); for (I = 0; I < 256; I++) { int Upper = S.UpCaseMap [I]; int Lower = I; if (Upper != Lower) { if (S.LoCaseMap [Upper] == 0) { S.LoCaseMap [Upper] = Lower; } } } for (I = 0; I < 256; I++) { if (S.LoCaseMap [I] == 0) { S.LoCaseMap [I] = I; } } // Retrieve the collating sequence table DosQueryCollate (sizeof (S.CollMap), &CountryCode, S.CollMap, &DataLength); if (RC != 0) { Error ("DosQueryCollate", RC, Country); } char Name [128]; sprintf (Name, "%03d.dat", Country); FILE* F = fopen (Name, "wb"); fwrite (&S, sizeof (S), 1, F); fclose (F); } int main () { ReadCountry ( 99, 437); ReadCountry ( 61, 437); ReadCountry ( 32, 437); ReadCountry ( 2, 437); ReadCountry ( 42, 437); ReadCountry ( 45, 437); ReadCountry (358, 437); ReadCountry ( 33, 437); ReadCountry ( 49, 437); ReadCountry ( 36, 437); ReadCountry (354, 437); ReadCountry ( 39, 437); ReadCountry ( 3, 437); ReadCountry ( 31, 437); ReadCountry ( 47, 437); ReadCountry ( 48, 437); ReadCountry (351, 437); ReadCountry ( 34, 437); ReadCountry ( 46, 437); ReadCountry ( 41, 437); ReadCountry ( 90, 437); ReadCountry ( 44, 437); ReadCountry ( 1, 437); ReadCountry ( 38, 437); return 0; } estic-1.61.orig/spunk/nls/iso8859.c0100644000176100001440000000253507031424715016250 0ustar debacleusers#include static unsigned char tab [256] = { /*0*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /*1*/ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /*2*/ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /*3*/ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /*4*/ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /*5*/ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /*6*/ 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /*7*/ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /*8*/ 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197, /*9*/ 201,230,198,244,246,242,252,249,255,214,220,162,163,165, 80,102, /*a*/ 225,237,243,250,241,209,170,186,191, 45,172,198,188,161,171,187, /*b*/ 254,254,254,124, 43, 43, 43, 43, 43, 43,124, 43, 43, 43, 43, 43, /*c*/ 43, 43, 43, 43, 45, 43, 43, 43, 43, 43, 43, 43, 43, 45, 43, 43, /*d*/ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,254,254,254,254,254, /*e*/ 97,223, 99,112, 90,115,181,116,112, 84, 79,100, 56, 48,101, 85, /*f*/ 61,177, 62, 60,102, 74,247,126,176,183,183, 47,110,178,254,255 }; int main (void) { FILE* F = fopen ("iso8859.dat", "wb"); fwrite (tab, 1, sizeof (tab), F); fclose (F); return 0; } estic-1.61.orig/spunk/nls/iso8859.dat0100644000176100001440000000040007031424715016563 0ustar debacleusers »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±> #include "progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 Delay (u32 ms) // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // An argument of zero has a special meaning: The function tries to give up // the current time slice, calls App->Idle () and returns after that. // // The function returns the real time passed or just ms. { const ChunkSize = 100; // Check the argument... if (ms <= ChunkSize) { // Wait some time Sleep (ms); // Call the applications idle function Idle (); } else { u32 Counter = ms; while (Counter) { unsigned TimeToWait = Counter >= ChunkSize ? ChunkSize : Counter; // Recursive call to Delay... u32 WaitTime = Delay (TimeToWait); if (WaitTime > Counter) { Counter = 0; } else { Counter -= WaitTime; } } } // Return the argument return ms; } estic-1.61.orig/spunk/ntsrc/filesys.cc0100644000176100001440000002254107031424715017275 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ #include #include #include #include "check.h" #include "str.h" #include "filepath.h" #include "filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '\\'; // Path separator extern const char FileSysListSep = ';'; // Path list separator extern const FileSysMaxPath = 259; // Maximum path length extern const FileSysMaxDir = 254; // Maximum directory length extern const FileSysMaxName = 254; // Maximum file name length extern const FileSysMaxExt = 254; // Maximum extension length (including the dot) /*****************************************************************************/ /* Code */ /*****************************************************************************/ static char* FSType (int Drive, char* Buf, unsigned BufSize, ULONG& Error) { char DriveSpec [5]; char VolumeNameBuffer [1024]; DWORD nVolumeNameSize = sizeof (VolumeNameBuffer); DWORD MaximumComponentLength; DWORD FileSystemFlags; char FileSystemNameBuffer [10]; DWORD nFileSystemNameSize = sizeof (FileSystemNameBuffer); // reset Error Error = 0; // Set up drive if (Drive == 0) { // No Path or no path in drive Drive = FileSysGetDrive (); } DriveSpec [0] = Drive + 'A' - 1; DriveSpec [1] = ':'; DriveSpec [2] = '\\'; DriveSpec [3] = '\0'; if (GetVolumeInformation (DriveSpec, VolumeNameBuffer, nVolumeNameSize, NULL, &MaximumComponentLength, &FileSystemFlags, FileSystemNameBuffer, nFileSystemNameSize) == 0) { // We had an error Error = 1; return NULL; } // Copy the returned name into the target buffer and return it strncpy (Buf, FileSystemNameBuffer, BufSize - 1); Buf [BufSize-1] = '\0'; return Buf; } int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { char Buf [FileSysMaxPath]; DWORD BufSize = sizeof (Buf); if (GetCurrentDirectory (BufSize, Buf) == 0) { // An error occured return -1; } else { // Completed without errors int Drive = Buf [0]; return (Drive >= 'a') ? Drive - 'a' + 1 : Drive - 'A' + 1; } } int FileSysSetDrive (unsigned Drive) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { char Buf [4] = " :."; // set drive name Buf [0] = 'A' + Drive - 1; return SetCurrentDirectory (Buf) ? 0 : -1; } int FileSysExtractDrive (const String& Path) // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). { if (Path.Len () >= 2 && Path [1] == ':') { // Drive in first char int Drive = Path [0]; return (Drive >= 'a') ? Drive - 'a' + 1 : Drive - 'A' + 1; } else { // No drive spec return 0; } } void FileSysGetInfo (FileSysInfo& Info, int Drive) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // Create the info ULONG Error; FSType (Drive, Info.fsName, sizeof (Info.fsName), Error); if (Error == 0 && strcmp (Info.fsName, "NTFS") == 0) { // NTFS file system Info.fsMaxPath = 259; Info.fsMaxDir = 254; Info.fsMaxName = 254; Info.fsMaxExt = 254; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 1; } else if (Error == 0 && strcmp (Info.fsName, "HPFS") == 0) { // HPFS file system Info.fsMaxPath = 259; Info.fsMaxDir = 254; Info.fsMaxName = 254; Info.fsMaxExt = 254; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 1; } else if (Error == 0 && strcmp (Info.fsName, "NFS") == 0) { // NFS file system Info.fsMaxPath = 259; Info.fsMaxDir = 254; Info.fsMaxName = 254; Info.fsMaxExt = 254; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 1; } else if (Error == 0 || Error == ERROR_NOT_READY) { // FAT or some other file system Info.fsMaxPath = 79; Info.fsMaxDir = 65; Info.fsMaxName = 8; Info.fsMaxExt = 4; Info.fsPreservesCase = 0; Info.fsIgnoresCase = 1; } else { FAIL ("FileSysGetInfo: Requesting info on a non existing drive"); } // Get the current directory. if (Error == 0) { String S = FileSysCurrentDir (0, Drive); strcpy (Info.fsCurDir, S.GetStr ()); } else { // We had a "drive not ready error" before, assume root dir strcpy (Info.fsCurDir, "\\"); } } int FileSysPreservesCase (int Drive) // Return 1 if the file system on the given drive preserves the case in // filenames { // Get the name of the file system. On errors, assume FAT ULONG Error; char Buf [128]; if (FSType (Drive, Buf, sizeof (Buf), Error) == NULL) { return 0; } // HPFS and NTFS is case preserving return (strcmp (Buf, "HPFS") == 0) || (strcmp (Buf, "NTFS") == 0); } int FileSysIgnoresCase (int /*Drive*/ ) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with NT's file systems). { // NT does ignore case in file names return 1; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. { // Invald chars static char InvalidChars [] = " <>|+=:;,\"/\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int Drive) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { String Dir; int CurrentDrive; char Buf [FileSysMaxPath]; DWORD BufLen = sizeof (Buf); // get current drive CurrentDrive = FileSysGetDrive (); // check for errors if (CurrentDrive < 0) { return Dir; } // If the current drive should be included, get that if (Drive == 0) { Drive = CurrentDrive; } // set drive if (FileSysSetDrive (Drive) < 0) { goto ExitPoint; } // get dir if (GetCurrentDirectory (BufLen, Buf) == 0) { goto ExitPoint; } // set Dir Dir += Buf; // check if this is the root directory, // if not append the trailing '\' if (Dir.Len () > 3) { Dir += '\\'; } // delete drive if not included if (!IncludeDrive) { Dir.Del (0, 2); } ExitPoint: // back to the actual drive FileSysSetDrive (CurrentDrive); // Return the result return Dir; } estic-1.61.orig/spunk/ntsrc/kbd.cc0100644000176100001440000003106607031424715016361 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ #include #include #include "msgid.h" #include "program.h" #include "kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // The keyboard handle static HANDLE KbdHandle; // Mapper table from virtual to extended keys. This table is fixed for DOS/OS2 static struct { Key EK; Key VK; } VirtualMap [] = { { kbEsc, vkAbort }, { kbF1, vkHelp }, { kbF10, vkAccept }, { kbPgUp, vkPgUp }, { kbPgDn, vkPgDn }, { kbCtrlPgUp, vkCtrlPgUp }, { kbCtrlPgDn, vkCtrlPgDn }, { kbUp, vkUp }, { kbDown, vkDown }, { kbLeft, vkLeft }, { kbRight, vkRight }, { kbIns, vkIns }, { kbDel, vkDel }, { kbHome, vkHome }, { kbEnd, vkEnd }, { kbCtrlUp, vkCtrlUp }, { kbCtrlDown, vkCtrlDown }, { kbCtrlLeft, vkCtrlLeft }, { kbCtrlRight, vkCtrlRight }, { kbCtrlIns, vkCtrlIns }, { kbCtrlDel, vkCtrlDel }, { kbCtrlHome, vkCtrlHome }, { kbCtrlEnd, vkCtrlEnd }, { kbF5, vkZoom }, { kbMetaF3, vkClose }, { kbF3, vkOpen }, { kbF2, vkSave }, { kbCtrlF5, vkResize }, { kbMetaX, vkQuit }, // Secondary mappings follow { kbCtrlR, vkPgUp }, { kbCtrlC, vkPgDn }, { kbCtrlE, vkUp }, { kbCtrlX, vkDown }, { kbCtrlS, vkLeft }, { kbCtrlD, vkRight }, { kbCtrlV, vkIns }, { kbCtrlG, vkDel }, { kbCtrlW, vkCtrlUp }, { kbCtrlZ, vkCtrlDown }, { kbCtrlA, vkCtrlLeft }, { kbCtrlF, vkCtrlRight }, }; // Tables to map the virtual keys // keys with ALT-modifier static const u16 MetaVKeyTab [0x80] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, kbMetaTab, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, kbMetaEsc, 0, 0, 0, 0, // 0x10 - 0x1F kbMetaSpace, kbMetaPgUp, kbMetaPgDn, kbMetaEnd, // 0x20 - 0x2F kbMetaHome, kbMetaLeft, kbMetaUp, kbMetaRight, kbMetaDown, 0, 0, 0, 0, kbMetaIns, kbMetaDel, 0, kbMeta0, kbMeta1, kbMeta2, kbMeta3, // 0x30 - 0x3F kbMeta4, kbMeta5, kbMeta6, kbMeta7, kbMeta8, kbMeta9, 0, 0, 0, 0, 0, 0, 0, kbMetaA, kbMetaB, kbMetaC, // 0x40 - 0x4F kbMetaD, kbMetaE, kbMetaF, kbMetaG, kbMetaH, kbMetaI, kbMetaJ, kbMetaK, kbMetaL, kbMetaM, kbMetaN, kbMetaO, kbMetaP, kbMetaQ, kbMetaR, kbMetaS, // 0x60 - 0x5F kbMetaT, kbMetaU, kbMetaV, kbMetaW, kbMetaX, kbMetaY, kbMetaZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x6F kbMetaF1, kbMetaF2, kbMetaF3, kbMetaF4, // 0x70 - 0x7F kbMetaF5, kbMetaF6, kbMetaF7, kbMetaF8, kbMetaF9, kbMetaF10, kbMetaF11, kbMetaF12, 0, 0, 0, 0, }; // keys with Ctrl-modifier static const u16 CtrlVKeyTab [0x80] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, kbCtrlTab, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F 0, kbCtrlPgUp, kbCtrlPgDn, kbCtrlEnd, // 0x20 - 0x2F kbCtrlHome, kbCtrlLeft, kbCtrlUp, kbCtrlRight, kbCtrlDown, 0, 0, 0, 0, kbCtrlIns, kbCtrlDel, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x6F kbCtrlF1, kbCtrlF2, kbCtrlF3, kbCtrlF4, // 0x70 - 0x7F kbCtrlF5, kbCtrlF6, kbCtrlF7, kbCtrlF8, kbCtrlF9, kbCtrlF10, kbCtrlF11, kbCtrlF12, 0, 0, 0, 0, }; // keys with Shift-modifier static const u16 ShiftVKeyTab [0x80] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, kbShiftTab, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, kbShiftIns, kbShiftDel, 0, // 0x20 - 0x2F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x6F kbShiftF1, kbShiftF2, kbShiftF3, kbShiftF4, // 0x70 - 0x7F kbShiftF5, kbShiftF6, kbShiftF7, kbShiftF8, kbShiftF9, kbShiftF10, kbShiftF11, kbShiftF12, 0, 0, 0, 0, }; // normal keys static const u16 NormalVKeyTab [0x80] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, kbTab, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F 0, kbPgUp, kbPgDn, kbEnd, // 0x20 - 0x2F kbHome, kbLeft, kbUp, kbRight, kbDown, 0, 0, 0, 0, kbIns, kbDel, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x6F kbF1, kbF2, kbF3, kbF4, // 0x70 - 0x7F kbF5, kbF6, kbF7, kbF8, kbF9, kbF10, kbF11, kbF12, 0, 0, 0, 0, }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static inline int IsMetaKey (u32 Flags) { return (Flags & LEFT_ALT_PRESSED) != 0; } static inline int IsCtrlKey (u32 Flags) { return ((Flags & LEFT_CTRL_PRESSED) || (Flags & RIGHT_CTRL_PRESSED)); } static inline int IsShiftKey (u32 Flags) { return (Flags & SHIFT_PRESSED) != 0; } u16 TranslateVKey (u16 Key, u32 Flags) { // only keys below 0x80 are supported if (Key > 0x7f) { return 0; } if (IsMetaKey (Flags)) { return MetaVKeyTab [Key]; } if (IsCtrlKey (Flags)) { return CtrlVKeyTab [Key]; } if (IsShiftKey (Flags)) { return ShiftVKeyTab [Key]; } return NormalVKeyTab [Key]; } static int IsSpecialKey (u16 Code) // returns true if the specified key has a special meaning { return ((Code >= VK_F1) && (Code <= VK_F12)) || // function keys ((Code >= VK_PRIOR) && (Code <= VK_DOWN)) || // cursor keys (Code == VK_INSERT) || (Code == VK_DELETE) || (Code == VK_TAB); } // the nect available key static u16 InKey = 0; static int KbdCharAvail () // Return true if a char is available from the os { // if there is a key currently not read, return immediatly if (InKey != 0) { return 1; } // examine input queue, until a key is available or the queue is empty while (InKey == 0) { // check input queue DWORD NumRead; INPUT_RECORD Info; PeekConsoleInput (KbdHandle, &Info, 1, &NumRead); // queue is empty if (NumRead == 0) { break; } // get event ReadConsoleInput (KbdHandle, &Info, 1, &NumRead); // first check if screen resizing if (Info.EventType == WINDOW_BUFFER_SIZE_EVENT) { // raise signal raise (SIGUSR3); continue; } if (Info.EventType != KEY_EVENT) { continue; } // check if key is released if (!Info.Event.KeyEvent.bKeyDown) { continue; } // get the flags u32 Flags = Info.Event.KeyEvent.dwControlKeyState; // convert key code if (IsMetaKey (Flags)) { InKey = TranslateVKey (Info.Event.KeyEvent.wVirtualKeyCode, Flags); } else if (IsSpecialKey (Info.Event.KeyEvent.wVirtualKeyCode)) { InKey = TranslateVKey (Info.Event.KeyEvent.wVirtualKeyCode, Flags); } else if (Info.Event.KeyEvent.uChar.AsciiChar != 0) { InKey = Info.Event.KeyEvent.uChar.AsciiChar; } } return (InKey != 0); } static Key KbdGetKey () // return the next available key and set this key to 0 (NoKey) { Key K = InKey; InKey = 0; return K; } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Keyboard::Keyboard (): Console (1), TransTable (NULL) { KbdHandle = GetStdHandle (STD_INPUT_HANDLE); CHECK (KbdHandle != INVALID_HANDLE_VALUE); CHECK (SetConsoleMode (KbdHandle, ENABLE_WINDOW_INPUT) != 0); } Keyboard::~Keyboard () { delete [] TransTable; } Key Keyboard::RawKey () // Get a raw (unmapped) key from the os { // Wait for a key calling repeatedly App->Idle () int I = 0; while (KbdCharAvail () == 0) { Sleep (20); if (I == 0) { CurThread () -> Idle (); } if (++I == 5) { I = 0; } } // Get the key return KbdGetKey (); } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { // If waiting is not wanted, check if there are keys available before // grabbing them if (Wait == 0 && KbdCharAvail () == 0) { // No keys available, bail out return; } // Get a key, remap it and put it into the buffer KeyBuf.Put (KbdMapExtended (Translate (RawKey ()))); } String Keyboard::GetKeyName (Key K) // Return a string describing the given key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description return App->LoadMsg (MSGBASE_KBD + K); } estic-1.61.orig/spunk/ntsrc/nlsinit.cc0100644000176100001440000001446307031424715017303 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ #include #include #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { // set default values unsigned Country = DefaultCountry; unsigned Language = DefaultLanguage; // Country code string returned bye GetLocaleInfo char CountryCodeStr [6]; // get country information if (GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ICOUNTRY, CountryCodeStr, sizeof (CountryCodeStr)) > 0) { // set country and language Country = atoi (CountryCodeStr); Language = NLSGetDefaultLanguage (Country); } // Try if there is an override for the country in the environment Country = GetEnvNum ("SPUNK_COUNTRY", Country); // Try if there is an override for the language in the environment Language = GetEnvNum ("SPUNK_LANGUAGE", Language); // Set the country data NLSSetCountry (Country); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/ntsrc/screen.cc0100644000176100001440000002524207031424715017077 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ #include #include #include #include "screen.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) Screen* TheScreen; // the original handle static HANDLE OriginalScrHandle; // the screen handle static HANDLE ScrHandle; // actual screen dimensions static unsigned ScreenHeight; static unsigned ScreenWidth; // max. window dimensions static unsigned MaxWidth; static unsigned MaxHeight; // min. window dimensions static const unsigned MinWidth = 40; static const unsigned MinHeight = 25; // Screen is using a color mode static int ScreenColor = 1; // actual Mode static unsigned ScreenMode; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void ScrOpen () // open a new screen buffer { // save the original handle OriginalScrHandle = GetStdHandle (STD_OUTPUT_HANDLE); // check handle CHECK (OriginalScrHandle != INVALID_HANDLE_VALUE); // get a new handle ScrHandle = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE, 0, // not shared NULL, // no security attr. CONSOLE_TEXTMODE_BUFFER, NULL); // check handle CHECK (ScrHandle != INVALID_HANDLE_VALUE); // activate the new screen buffer CHECK (SetConsoleActiveScreenBuffer (ScrHandle)); // Request the max. current window COORD Size = GetLargestConsoleWindowSize (ScrHandle); // Set data MaxWidth = Size.X; MaxHeight = Size.Y; } static void ScrClose () // restore the original screen buffer { // activate the new screen buffer SetConsoleActiveScreenBuffer (OriginalScrHandle); } static void ScrSetMode (u16 Mode) { unsigned XSize, YSize; // Request the max. possible window size COORD MaxSize = GetLargestConsoleWindowSize (ScrHandle); // Set global data MaxWidth = MaxSize.X; MaxHeight = MaxSize.Y; // Check the new dimensions switch (Mode) { case vmAsk: // request the current window size. CONSOLE_SCREEN_BUFFER_INFO Info; CHECK (GetConsoleScreenBufferInfo (ScrHandle, &Info) != 0); // Set data XSize = Info.dwMaximumWindowSize.X; YSize = Info.dwMaximumWindowSize.Y; // don't change color settings break; case vmBW40: XSize = 40; YSize = 25; ScreenColor = 0; break; case vmMono: case vmBW80: XSize = 80; YSize = 25; ScreenColor = 0; break; case vmCO40: XSize = 40; YSize = 25; ScreenColor = 1; break; case vmCO80: XSize = 80; YSize = 25; ScreenColor = 1; break; case vmVGA_80x30: XSize = 80; YSize = 30; ScreenColor = 1; break; case vmVGA_80x34: XSize = 80; YSize = 34; ScreenColor = 1; break; case vmVGA_80x43: XSize = 80; YSize = 43; ScreenColor = 1; break; case vmVGA_80x50: XSize = 80; YSize = 50; ScreenColor = 1; break; case vmVGA_80x60: XSize = 80; YSize = 60; ScreenColor = 1; break; case vmVGA_94x25: XSize = 94; YSize = 25; ScreenColor = 1; break; case vmVGA_94x30: XSize = 94; YSize = 30; ScreenColor = 1; break; case vmVGA_94x34: XSize = 94; YSize = 34; ScreenColor = 1; break; case vmVGA_94x43: XSize = 94; YSize = 43; ScreenColor = 1; break; case vmVGA_94x50: XSize = 94; YSize = 50; ScreenColor = 1; break; case vmVGA_94x60: XSize = 94; YSize = 60; ScreenColor = 1; break; case vmET4_100x40: XSize = 100; YSize = 40; ScreenColor = 1; break; default: // Ignore modes we do not know return; } // Check if we can resize the screen, bail out if not if (XSize > MaxWidth || YSize > MaxHeight) { return; } // set minimum size XSize = max (XSize, MinWidth); YSize = max (YSize, MinHeight); // if the new screen is larger set screen buffer before window-size // else window-size before screen buffer COORD Size = { XSize, YSize }; SMALL_RECT Rect = { 0, 0, XSize-1, YSize -1 }; if ((ScreenWidth * ScreenHeight) <= (XSize * YSize)) { SetConsoleScreenBufferSize (ScrHandle, Size); SetConsoleWindowInfo (ScrHandle, TRUE, &Rect); } else { SetConsoleWindowInfo (ScrHandle, TRUE, &Rect); SetConsoleScreenBufferSize (ScrHandle, Size); } // Set the global variables ScreenWidth = XSize; ScreenHeight = YSize; ScreenMode = Mode; } static u16 ScrGetCursor () // get the current cursor type { CONSOLE_CURSOR_INFO CursorInfo; if (!GetConsoleCursorInfo (ScrHandle, &CursorInfo)) { return 0; } u16 Cursor = CursorInfo.dwSize; if (CursorInfo.bVisible) { Cursor |= 0x8000; } return Cursor; } static void ScrSetCursor (u16 Cursor) // set a cursor { CONSOLE_CURSOR_INFO CursorInfo; CursorInfo.dwSize = Cursor & 0x7FFF; CursorInfo.bVisible = (Cursor & 0x8000) != 0; SetConsoleCursorInfo (ScrHandle, &CursorInfo); } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): CP437 (1), TransTable (NULL) { // open the screen ScrOpen (); // get startup values StartupCursor = ScrGetCursor (); // set mode to actual settings SetMode (vmAsk); // set cursor data CF_HiddenCursor = 25; CF_NormalCursor = 0x8000 + 20; CF_FatCursor = 0x8000 + 99; // Switch the cursor off SetCursorOff (); } Screen::~Screen () { // Reset old video mode and cursor ScrClose (); } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table { if (TransTable) { unsigned char* S = (unsigned char*) Target; unsigned char* T = (unsigned char*) Source; while (Len--) { *T++ = TransTable [*S++]; // Translate character *T++ = *S++; // Copy attribute } return Target; } else { // No translation table, return the source buffer return Source; } } void Screen::SetMode (u16 Mode) { if (Mode == vmInvalid) { return; } // set mode ScrSetMode (Mode); // Remember mode CurrentMode = ScreenMode; // Set the new size XSize = ScreenWidth; YSize = ScreenHeight; // Colors may have changed Color = ScreenColor; // Switch cursor off SetCursorOff (); } void Screen::SetCursorOn () { ScrSetCursor (CF_NormalCursor); } void Screen::SetCursorOff () { ScrSetCursor (CF_HiddenCursor); } void Screen::SetCursorFat () { ScrSetCursor (CF_FatCursor); } void Screen::SetCursorPos (const Point& Pos) { PRECONDITION (Pos.X < XSize && Pos.Y < YSize); // set new cursor position COORD NewPos = { Pos.X, Pos.Y }; SetConsoleCursorPosition (ScrHandle, NewPos); } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { int XCount = R.XSize (); int YCount = R.YSize (); int TotalCount = XCount * YCount; // Check if anything to do if (XCount == 0 || YCount == 0 || R.A.Y > YSize || R.A.X > XSize) { // Done return; } // If we have to translate the output, get buffer memory u16* Buf2 = 0; if (TransTable) { Buf2 = new u16 [TotalCount]; Buf = Translate (Buf2, Buf, TotalCount); } // get buffer CHAR_INFO* chiBuf = new CHAR_INFO [TotalCount]; // copy data into buffer CHAR_INFO* WorkBuf = chiBuf; for (int i = 0; i < TotalCount; i++, WorkBuf++, Buf++) { WorkBuf->Char.AsciiChar = (*Buf) & 0xff; WorkBuf->Attributes = (*Buf >> 8) & 0xff; } // set data for output COORD BufCoord = { 0, 0 }; COORD BufSize = { XCount, YCount }; SMALL_RECT WriteRect = { R.A.X, R.A.Y, R.B.X - 1, R.B.Y - 1}; // write data to screen CHECK (WriteConsoleOutput (ScrHandle, chiBuf, BufSize, BufCoord, &WriteRect) != 0); // delete buffers delete Buf2; delete chiBuf; } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { // We have always direct access to the screen return 10; } estic-1.61.orig/spunk/ntsrc/sema.cc0100644000176100001440000001066207031424715016545 0ustar debacleusers/*****************************************************************************/ /* */ /* SEMA.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // This module defines an envelope class for a binary operating system // supported semaphore. Currently the class is implemented for OS/2 and NT. #pragma pack(push) #include #pragma pack(pop) #include "check.h" #include "sema.h" /*****************************************************************************/ /* class SemHandle */ /*****************************************************************************/ class SemHandle { friend class Semaphore; HANDLE H; SemHandle (); // Constructor, set H to something invalid }; inline SemHandle::SemHandle (): H (INVALID_HANDLE_VALUE) { } /*****************************************************************************/ /* class Semaphore */ /*****************************************************************************/ void Semaphore::Init (const String& Name, unsigned InitialState) // Does the real work for the constructors { static SECURITY_ATTRIBUTES SA = { sizeof (SECURITY_ATTRIBUTES), NULL, 0 }; // Get memory for the semaphor handle and initialize it Handle = new SemHandle; // Create/open if the name is given, create otherwise if (Name.NotEmpty ()) { // We have a name, create/open a named semaphore char pszName [256]; // Copy the name into the psz buffer Name.PSZ (pszName, sizeof (pszName)); // Try to create the semaphore Handle->H = CreateMutex (&SA, InitialState, pszName); } else { // Create an unnamed semaphore Handle->H = CreateMutex (&SA, InitialState, 0); } // We must have a handle now CHECK (Handle->H != 0); } Semaphore::Semaphore (unsigned InitialState) // Create a new, unnamed semaphore with the given initial state { Init (EmptyString, InitialState); } Semaphore::Semaphore (const String& Name, unsigned InitialState) // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. { Init (Name, InitialState); } Semaphore::Semaphore (const char* Name, unsigned InitialState) // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. { Init (Name, InitialState); } Semaphore::~Semaphore () { // Delete the semaphore handle if (Handle->H != INVALID_HANDLE_VALUE) { CloseHandle (Handle->H); Handle->H = INVALID_HANDLE_VALUE; } // Delete the handle data structure delete Handle; } void Semaphore::Up () { CHECK (ReleaseMutex (Handle->H) != FALSE); } int Semaphore::Down (i32 T) { DWORD Timeout = T >= 0 ? T : INFINITE; // Do the down switch (WaitForSingleObject (Handle->H, Timeout)) { case WAIT_TIMEOUT: // Timeout while waiting return 0; case WAIT_OBJECT_0: case WAIT_ABANDONED: // we own the semaphore return 1; default: FAIL ("Semaphore::Down: WAIT_FAILED or bad return code"); return 0; // Never reached } } estic-1.61.orig/spunk/ntsrc/sercom.cc0100644000176100001440000004317507031424715017115 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1996-97 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // System independent serial communication package for the SPUNK library, // NT version. #include #include #include "check.h" #include "chartype.h" #include "delay.h" #include "sercom.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // internal used data struct _ComData { HANDLE hCom; // Port handle DCB dcb; // a copy of the actual dcb ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ static void ComError () // called for API Errors { FAIL (FormatStr ("ComPort error #%d", GetLastError ()).GetStr ()); } static void UpdateErrorCounter (_ComData* ComData, unsigned ErrorWord) // Error counter update { if (ErrorWord & CE_TXFULL) ComData->ErrorCounter [ceTXOverflow]++; if (ErrorWord & CE_RXOVER) ComData->ErrorCounter [ceRXOverflow]++; if (ErrorWord & CE_OVERRUN) ComData->ErrorCounter [ceOverrun]++; if (ErrorWord & CE_RXPARITY) ComData->ErrorCounter [ceParity]++; if (ErrorWord & CE_FRAME) ComData->ErrorCounter [ceFrame]++; if (ErrorWord & CE_BREAK) ComData->ErrorCounter [ceBreak]++; } static void GetComError (_ComData* ComData) // gets the error state of the port and updates the error counters { // Read the error information DWORD Error; COMSTAT Stat; if (!ClearCommError (ComData->hCom, &Error, &Stat)) { ComError (); } // Update the counters UpdateErrorCounter (ComData, Error); } /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (512), TXBufSize (512), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen ()) { Close (); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // If the name of the port is just a number, expand it by // inserting "COM". if (PortName.Len () == 1 && IsDigit (PortName [0])) { PortName.Ins (0, "COM"); } // Create an internally used data structure ComData = new _ComData; // Set up ComData ComData->hCom = INVALID_HANDLE_VALUE; // Port not open // reset dcb data memset (&ComData->dcb, 0, sizeof (ComData->dcb)); // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); } void ComPort::SetBufferSize (u16 aRXBufSize, u16 aTXBufSize) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // get values RXBufSize = aRXBufSize; TXBufSize = aTXBufSize; } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { HANDLE hCom; DCB dcb; // Open the port hCom = CreateFile ((PSZ) PortName.GetStr (), GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security attr. OPEN_EXISTING, // Com ports must use this 0, // no overlapped I/O NULL); // must be NULL for com devices if (hCom == INVALID_HANDLE_VALUE) { return GetLastError (); } // Port-Handle setzen ComData->hCom = hCom; // actual settings if (GetCommState (hCom, &dcb) == FALSE) { Close (); return GetLastError (); } // abort on errors dcb.fAbortOnError = 1; // set up the baudrate dcb.BaudRate = Baudrate; // set databits dcb.ByteSize = Databits; // set stopbits switch (Stopbits) { case 1 : dcb.StopBits = ONESTOPBIT; break; case 2 : dcb.StopBits = TWOSTOPBITS; break; default : FAIL ("ComPort::Open: Invalid stopbit setting"); } // set parity dcb.fParity = 1; // Enable parity checking switch (Parity) { case 'N' : dcb.Parity = NOPARITY; break; case 'O' : dcb.Parity = ODDPARITY; break; case 'E' : dcb.Parity = EVENPARITY; break; case 'M' : dcb.Parity = MARKPARITY; break; case 'S' : dcb.Parity = SPACEPARITY; break; default : FAIL ("ComPort::Open: Invalid parity setting"); } // Flow Control if (XonXoff == 'E') { // enable XON/XOFF dcb.fOutX = 1; dcb.fInX = 1; } else { // disable XON/XOFF dcb.fOutX = 0; dcb.fInX = 0; } // Handshake if (Connection == 'D') { // direct connection dcb.fOutxCtsFlow = 0; dcb.fOutxDsrFlow = 0; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 0; dcb.fRtsControl = RTS_CONTROL_DISABLE; } else if (Connection == 'M') { // using RTS/CTS, DTR/DSR handshake dcb.fOutxCtsFlow = 1; dcb.fOutxDsrFlow = 1; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 1; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; } else { FAIL ("ComPort: invalid connection setting"); } // set new dcb if (SetCommState (hCom, &dcb) == FALSE) { Close (); return GetLastError (); } // store a copy of actual dcb ComData->dcb = dcb; // read actual timeout settings COMMTIMEOUTS Timeouts; if (GetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { Close (); return GetLastError (); } // Set timeouts Timeouts.ReadIntervalTimeout = RXTimeout * 1000; Timeouts.ReadTotalTimeoutMultiplier = 0; Timeouts.ReadTotalTimeoutConstant = RXTimeout * 1000; Timeouts.WriteTotalTimeoutMultiplier = 0; Timeouts.WriteTotalTimeoutConstant = TXTimeout * 1000; if (SetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { Close (); return GetLastError (); } // Set the buffer sizes if (SetupComm (hCom, RXBufSize, TXBufSize) == FALSE) { Close (); return GetLastError (); } // because it is up to the driver what he does with the buffer values, // so read them back to have the real settings. // The Microsoft driver always has a TXBufSize of 0 !! COMMPROP Properties; if (GetCommProperties (hCom, &Properties) == FALSE) { Close (); return GetLastError (); } // get current buffer settings RXBufSize = Properties.dwCurrentRxQueue; TXBufSize = Properties.dwCurrentTxQueue; // Success return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open... PRECONDITION (IsOpen ()); // set DTR and RTS to OFF before closing the port DTROff (); RTSOff (); // closing CloseHandle (ComData->hCom); // reset handle ComData->hCom = INVALID_HANDLE_VALUE; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->hCom != INVALID_HANDLE_VALUE; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Port must be open and parameter valid PRECONDITION (IsOpen () && aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout < 0.01) { aRXTimeout = 0.01; } // Remember the timeout RXTimeout = aRXTimeout; // read actual settings COMMTIMEOUTS Timeouts; if (GetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { ComError (); } // Set the new timeout Timeouts.ReadIntervalTimeout = RXTimeout * 1000; Timeouts.ReadTotalTimeoutConstant = RXTimeout * 1000; if (SetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { ComError (); } } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Port must be open and parameter valid PRECONDITION (IsOpen () && aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; // read actual settings COMMTIMEOUTS Timeouts; if (GetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { ComError (); } // Set the new timeout Timeouts.WriteTotalTimeoutConstant = TXTimeout * 1000; if (SetCommTimeouts (ComData->hCom, &Timeouts) == FALSE) { ComError (); } } void ComPort::DTROn () // Make the DTR line active { // The port must be open PRECONDITION (IsOpen ()); if (EscapeCommFunction (ComData->hCom, SETDTR) == FALSE) { ComError (); } } void ComPort::DTROff () // Make the DTR line inactive { // The port must be open PRECONDITION (IsOpen ()); if (EscapeCommFunction (ComData->hCom, CLRDTR) == FALSE) { ComError (); } } void ComPort::RTSOn () // Make the RTS line active { // The port must be open PRECONDITION (IsOpen ()); if (EscapeCommFunction (ComData->hCom, SETRTS) == FALSE) { ComError (); } } void ComPort::RTSOff () // Make the RTS line inactive { // The port must be open PRECONDITION (IsOpen ()); if (EscapeCommFunction (ComData->hCom, CLRRTS) == FALSE) { ComError (); } } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer { // Read the error information (aha) DWORD Error; COMSTAT Stat; if (ClearCommError (ComData->hCom, &Error, &Stat) == FALSE) { ComError (); } // Update the counters UpdateErrorCounter (ComData, Error); // retrieve count return Stat.cbInQue; } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { // Read the error information (aha) DWORD Error; COMSTAT Stat; if (ClearCommError (ComData->hCom, &Error, &Stat) == FALSE) { ComError (); } // Update the counters UpdateErrorCounter (ComData, Error); // retrieve count return Stat.cbOutQue; } void ComPort::RXClear () // Clear the receive buffer { if (PurgeComm (ComData->hCom, PURGE_RXCLEAR) == FALSE) { ComError (); } } void ComPort::TXClear () // Clear the transmit buffer { if (PurgeComm (ComData->hCom, PURGE_TXCLEAR) == FALSE) { ComError (); } } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer { if (TXBufSize > 0) { return TXBufSize - TXCount (); } else { return (TXCount () == 0) ? 1 : 0; } } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { // read one character unsigned char B; DWORD chRead; do { ReadFile (ComData->hCom, &B, 1, &chRead, NULL); } while (chRead == 0); // get errors GetComError (ComData); // return character return B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } DWORD chWrite; WriteFile (ComData->hCom, &B, 1, &chWrite, NULL); // check if the character was really written if (chWrite != 1) { GetComError (ComData); return -1; } else { return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { unsigned char B; DWORD chRead; ReadFile (ComData->hCom, &B, 1, &chRead, NULL); // get errors GetComError (ComData); // Return the character read or -1 on timeout return chRead == 0 ? -1 : B; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { ULONG chWrite; WriteFile (ComData->hCom, &B, 1, &chWrite, NULL); GetComError (ComData); if (chWrite != 1) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { return B; } } void ComPort::TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount) // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. { // Check params PRECONDITION (Count > 0); // Read with timeout ReadCount = 0; while (ReadCount < Count) { DWORD chRead = 0; DWORD chToRead = min ((Count - ReadCount), 128); // read ReadFile (ComData->hCom, (char*) Buffer + ReadCount, chToRead, &chRead, NULL); // inc. ReadCount ReadCount += chRead; // check if all characters are read if (chToRead != chRead) { break; } } // Get errors GetComError (ComData); } void ComPort::TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount) // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. { // Check params PRECONDITION (Count > 0); // Read with timeout WriteCount = 0; while (WriteCount < Count) { DWORD chWritten = 0; DWORD chToWrite = min ((Count - WriteCount), 128); // read WriteFile (ComData->hCom, (char*) Buffer + WriteCount, chToWrite, &chWritten, NULL); // inc. ReadCount WriteCount += chWritten; // check if all characters are read if (chToWrite != chWritten) { // Get errors ComData->ErrorCounter [ceTXOverflow]++; GetComError (ComData); break; } } GetComError (ComData); } void ComPort::Break (double Duration) // Send a break with the given time in seconds { // The port must be open PRECONDITION (IsOpen ()); // BREAK ON SetCommBreak (ComData->hCom); // Wait... Delay (Duration * 1000); // BREAK OFF ClearCommBreak (ComData->hCom); } ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { DWORD Inputs; if (GetCommModemStatus (ComData->hCom, &Inputs) == FALSE) { ComError (); } // convert status bits unsigned Status = 0; if (Inputs & MS_CTS_ON) Status |= csCTS; if (Inputs & MS_DSR_ON) Status |= csDSR; if (Inputs & MS_RING_ON) Status |= csRI; if (Inputs & MS_RLSD_ON) Status |= csCD; // Return the bitmask return Status; } estic-1.61.orig/spunk/ntsrc/task.cc0100644000176100001440000001146507031424716016565 0ustar debacleusers/*****************************************************************************/ /* */ /* TASK.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // Threads #include #pragma pack(push) #include #pragma pack(pop) #include "delay.h" #include "check.h" #include "task.h" /*****************************************************************************/ /* class TaskHandle */ /*****************************************************************************/ class TaskHandle { friend class Task; HANDLE H; TaskHandle (); // Constructor, set H to something invalid }; inline TaskHandle::TaskHandle (): H (INVALID_HANDLE_VALUE) { } /*****************************************************************************/ /* class Task */ /*****************************************************************************/ Task::Task (size_t aStackSize): StackSize (aStackSize), Running (0), RunDown (0), Handle (new TaskHandle) // Constructor { } Task::~Task () // Destructor { // Stop the thread if not already done Stop (); // Under NT, delete the thread handle if (Handle->H != INVALID_HANDLE_VALUE) { CloseHandle (Handle->H); Handle->H = INVALID_HANDLE_VALUE; } // Delete the handle data structure delete Handle; } void Task::CreateFunc (void* ThisObj) // This function is started as a thread. { // Cast the given pointer into a pointer-to-object. Use the volatile // keyword to avoid problems with T when using longjmp Task* volatile T = (Task*) ThisObj; // Get the thread ID. Be shure to duplicate the pseudohandle to allow // access from outside this thread. CHECK (DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &T->Handle->H, 0, FALSE, DUPLICATE_SAME_ACCESS) == TRUE); // Set the running flag now. T->Running = 1; // Call the init routine T->Init (); // Run the task T->Run (); // Call the cleanup routine T->Done (); // If we get back from the run function, we are done - reset the Running flag T->Running = 0; } void Task::Init () // This function is called before Run() { } void Task::Done () // This function is called after Run() { } void Task::SetPriority (unsigned Priority, int /*Delta*/) // Allows the task to set it's priority { // Map the Priority to a system defined value int Prio = 0; switch (Priority) { case PrioIdle: Prio = THREAD_PRIORITY_IDLE; break; case PrioRegular: Prio = THREAD_PRIORITY_NORMAL; break; case PrioServer: Prio = THREAD_PRIORITY_HIGHEST; break; case PrioTimeCritical: Prio = THREAD_PRIORITY_TIME_CRITICAL; break; default: FAIL ("Task::SetPriority: Invalid priority value"); } CHECK (SetThreadPriority (Handle->H, Prio) != FALSE); } void Task::Start () // Start the task { // The task may not run already CHECK (!IsRunning ()); // Create the thread CHECK (_beginthread (CreateFunc, 0, StackSize, this) != -1); } void Task::Stop (unsigned WaitTime) // Stop the task { if (IsRunning ()) { // Set the rundown flag RunDown = 1; // Wait until WaitTime is over or the thread has terminated while (WaitTime && IsRunning ()) { // Calculate time slice to wait unsigned Time = 100; if (Time > WaitTime) { Time = WaitTime; } WaitTime -= Time; // Wait Delay (Time); } // If the thread did not terminate, kill it if (IsRunning ()) { // Kill the thread TerminateThread (Handle->H, 0); } } } estic-1.61.orig/spunk/os2src/0040755000176100001440000000000007061535305015372 5ustar debacleusersestic-1.61.orig/spunk/os2src/delay.cc0100644000176100001440000000351307031424716016776 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System dependent function for waiting some time. #define INCL_DOS #include #include "progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ u32 Delay (u32 ms) // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // An argument of zero has a special meaning: The function tries to give up // the current time slice, calls App->Idle () and returns after that. // // The function returns the real time passed or just ms. { const ChunkSize = 100; // Check the argument... if (ms <= ChunkSize) { // Wait some time while (DosSleep (ms) != 0) ; // Call the applications idle function Idle (); } else { u32 Counter = ms; while (Counter) { unsigned TimeToWait = Counter >= ChunkSize ? ChunkSize : Counter; // Recursive call to Delay... u32 WaitTime = Delay (TimeToWait); if (WaitTime > Counter) { Counter = 0; } else { Counter -= WaitTime; } } } // Return the argument return ms; } estic-1.61.orig/spunk/os2src/filesys.cc0100644000176100001440000002027107031424716017356 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // #include #include #define INCL_BASE #include #include "check.h" #include "str.h" #include "filepath.h" #include "filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '\\'; // Path separator extern const char FileSysListSep = ';'; // Path list separator extern const FileSysMaxPath = 259; // Maximum path length extern const FileSysMaxDir = 254; // Maximum directory length extern const FileSysMaxName = 254; // Maximum file name length extern const FileSysMaxExt = 254; // Maximum extension length (including the dot) /*****************************************************************************/ /* Code */ /*****************************************************************************/ static char* FSType (int Drive, char* Buf, unsigned BufSize, ULONG& Error) { char fsqbuf [512]; char* P; ULONG fsqbuflen = sizeof (fsqbuf); char DriveSpec [3]; // Set up drive if (Drive == 0) { // No Path or no path in drive Drive = FileSysGetDrive (); } DriveSpec [0] = Drive + 'A' - 1; DriveSpec [1] = ':'; DriveSpec [2] = '\0'; Error = DosQueryFSAttach (DriveSpec, 0, FSAIL_QUERYNAME, (PFSQBUFFER2) fsqbuf, &fsqbuflen); if (Error != 0) { return NULL; } // Set 'P' to point to the file system name P = fsqbuf + sizeof(USHORT); // Point past device type P += *((PUSHORT) P) + 3*sizeof(USHORT) + 1; // Point past drive name and FS name length */ return strncpy (Buf, P, BufSize - 1); } int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { ULONG Drive; ULONG DriveMap; if (DosQueryCurrentDisk (&Drive, &DriveMap) != 0) { // An error occured return -1; } else { // Completed without errors return Drive; } } int FileSysSetDrive (unsigned Drive) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { return DosSetDefaultDisk (Drive) == 0? 0 : -1; } int FileSysExtractDrive (const String& Path) // Return the drive spec from the given path. If none given or if the os // does not support drives (linux), the return value will be zero (== current). { if (Path.Len () >= 2 && Path [1] == ':') { // Drive in first char int Drive = Path [0]; return (Drive >= 'a') ? Drive - 'a' + 1 : Drive - 'A' + 1; } else { // No drive spec return 0; } } void FileSysGetInfo (FileSysInfo& Info, int Drive) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // Create the info ULONG Error; FSType (Drive, Info.fsName, sizeof (Info.fsName), Error); if (Error == 0 && strcmp (Info.fsName, "HPFS") == 0) { // HPFS file system Info.fsMaxPath = 259; Info.fsMaxDir = 254; Info.fsMaxName = 254; Info.fsMaxExt = 254; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 1; } else if (Error == 0 && strcmp (Info.fsName, "NFS") == 0) { // HPFS file system Info.fsMaxPath = 259; Info.fsMaxDir = 254; Info.fsMaxName = 254; Info.fsMaxExt = 254; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 1; } else if (Error == 0 || Error == ERROR_NOT_READY) { // FAT or some other file system Info.fsMaxPath = 79; Info.fsMaxDir = 65; Info.fsMaxName = 8; Info.fsMaxExt = 4; Info.fsPreservesCase = 0; Info.fsIgnoresCase = 1; } else { FAIL ("FileSysGetInfo: Requesting info on a non existing drive"); } // Get the current directory. Beware! OS/2 does not start the directory // with a path separator (contrary to the docs which state that the // directory is fully qualified). This may be a bug which will be corrected // in a future version. Since there is a path separator if the current // directory is the root dir, check before adding one... if (Error == 0) { char Buf [sizeof (Info.fsCurDir) - 1]; ULONG BufLen = sizeof (Buf); DosQueryCurrentDir (Drive, Buf, &BufLen); if (Buf [0] == FileSysPathSep) { // There is already a path separator, just copy the string strcpy (Info.fsCurDir, Buf); } else { // There is not path separator - add one Info.fsCurDir [0] = FileSysPathSep; strcpy (&Info.fsCurDir [1], Buf); } } else { // We had a "drive not ready error" before, assume root dir strcpy (Info.fsCurDir, "\\"); } } int FileSysPreservesCase (int Drive) // Return 1 if the file system on the given drive preserves the case in // filenames { // Get the name of the file system. On errors, assume FAT ULONG Error; char Buf [128]; if (FSType (Drive, Buf, sizeof (Buf), Error) == NULL) { return 0; } // Only HPFS is case preserving return strcmp (Buf, "HPFS") == 0; } int FileSysIgnoresCase (int /*Drive*/ ) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { // OS/2 does ignore case in file names return 1; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. { // Invald chars static char InvalidChars [] = " <>|+=:;,\"/\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int Drive) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { String Dir; // OS/2 file systems support drives, so check for IncludeDrive if (IncludeDrive) { // If the current drive should be included, get that if (Drive == 0) { ULONG DriveNumber, DriveMap; DosQueryCurrentDisk (&DriveNumber, &DriveMap); Drive = DriveNumber; } // Use lower case for the drive letter Dir += 'a' + Drive - 1; Dir += ':'; } // Now get the current working directory char Buf [512]; ULONG BufLen = sizeof (Buf); if (DosQueryCurrentDir (Drive, Buf, &BufLen) != 0) { // OOPS - unknown drive Dir.Clear (); } else { // Beware! Buf does not seem to contain a leading path separator under // OS/2 2.1. As the documentation states, DosQueryCurrentDrive returns // a fully qualified path name, so this seems to be a bug. Since there // is a path separator if the current directory is the root dir, check // before adding one... if (Buf [0] != FileSysPathSep) { Dir += FileSysPathSep; } Dir += Buf; AddPathSep (Dir); // If the file system does not preserve case, make the name lowercase if (FileSysPreservesCase (Drive) == 0) { Dir.ToLower (); } } // Return the result return Dir; } estic-1.61.orig/spunk/os2src/kbd.cc0100644000176100001440000001226407031424716016443 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #define INCL_NOPMAPI #define INCL_DOS #define INCL_KBD #include #undef KbdPeek // We are using the name somewhere #include "msgid.h" #include "program.h" #include "kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // The keyboard handle static HKBD KbdHandle; // Mapper table from virtual to extended keys. This table is fixed for DOS/OS2 static struct { Key EK; Key VK; } VirtualMap [] = { { kbEsc, vkAbort }, { kbF1, vkHelp }, { kbF10, vkAccept }, { kbPgUp, vkPgUp }, { kbPgDn, vkPgDn }, { kbCtrlPgUp, vkCtrlPgUp }, { kbCtrlPgDn, vkCtrlPgDn }, { kbUp, vkUp }, { kbDown, vkDown }, { kbLeft, vkLeft }, { kbRight, vkRight }, { kbIns, vkIns }, { kbDel, vkDel }, { kbHome, vkHome }, { kbEnd, vkEnd }, { kbCtrlUp, vkCtrlUp }, { kbCtrlDown, vkCtrlDown }, { kbCtrlLeft, vkCtrlLeft }, { kbCtrlRight, vkCtrlRight }, { kbCtrlIns, vkCtrlIns }, { kbCtrlDel, vkCtrlDel }, { kbCtrlHome, vkCtrlHome }, { kbCtrlEnd, vkCtrlEnd }, { kbF5, vkZoom }, { kbMetaF3, vkClose }, { kbF3, vkOpen }, { kbF2, vkSave }, { kbCtrlF5, vkResize }, { kbMetaX, vkQuit }, // Secondary mappings follow { kbCtrlR, vkPgUp }, { kbCtrlC, vkPgDn }, { kbCtrlE, vkUp }, { kbCtrlX, vkDown }, { kbCtrlS, vkLeft }, { kbCtrlD, vkRight }, { kbCtrlV, vkIns }, { kbCtrlG, vkDel }, { kbCtrlW, vkCtrlUp }, { kbCtrlZ, vkCtrlDown }, { kbCtrlA, vkCtrlLeft }, { kbCtrlF, vkCtrlRight }, }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int KbdCharAvail () // Return true if a char is available from the os { KBDKEYINFO Info; Kbd16Peek (&Info, KbdHandle); return (Info.fbStatus & KBDTRF_FINAL_CHAR_IN) ? 1 : 0; } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Keyboard::Keyboard (): Console (1), TransTable (NULL) { KBDINFO K; // Open the keyboard CHECK (KbdOpen (&KbdHandle) == 0); CHECK (KbdGetFocus (IO_WAIT, KbdHandle) == 0); K.cb = 10; K.fsMask = 0x04; CHECK (KbdSetStatus (&K, 0) == 0); } Keyboard::~Keyboard () { CHECK (KbdFreeFocus (KbdHandle) == 0); CHECK (KbdClose (KbdHandle) == 0); delete [] TransTable; } Key Keyboard::RawKey () // Get a raw (unmapped) key from the os { // Wait for a key calling repeatedly App->Idle () int I = 0; while (KbdCharAvail () == 0) { DosSleep (20); if (I == 0) { CurThread () -> Idle (); } if (++I == 5) { I = 0; } } // Get the key KBDKEYINFO Info; KbdCharIn (&Info, IO_WAIT, KbdHandle); Key K = Key ((Info.chScan << 8) + Info.chChar); // Translate char/scancode to plain/extended key if ((K & 0x00FF) == 0xE0 || (K & 0x00FF) == 0x00) { // Extended character return Key (0x0100 | (K >> 8)); } else { return Key (K & 0x00FF); } } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { // If waiting is not wanted, check if there are keys available before // grabbing them if (Wait == 0 && KbdCharAvail () == 0) { // No keys available, bail out return; } // Get a key, remap it and put it into the buffer KeyBuf.Put (KbdMapExtended (Translate (RawKey ()))); } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description return App->LoadMsg (MSGBASE_KBD + K); } estic-1.61.orig/spunk/os2src/nlsinit.cc0100644000176100001440000001422507031424716017362 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #define INCL_DOSNLS #include #include "check.h" #include "environ.h" #include "national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Translation table from the input character set to the internal used // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // Translation table from the internal used character set to the output // character set. On DOS/OS2 this is a no-op, but will change if more // codepages are supported. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { // Country code for the current country static COUNTRYCODE CountryCode = { 0, 0 }; COUNTRYINFO Info; ULONG DataLength; unsigned Country = DefaultCountry; unsigned Language = DefaultLanguage; // Get country information if (DosQueryCtryInfo (sizeof (Info), &CountryCode, &Info, &DataLength) == 0) { // Got the settings Country = Info.country; Language = NLSGetDefaultLanguage (Country); } // Try if there is an override for the country in the environment Country = GetEnvNum ("SPUNK_COUNTRY", Country); // Try if there is an override for the language in the environment Language = GetEnvNum ("SPUNK_LANGUAGE", Language); // Set the country data NLSSetCountry (Country); // Set the language NLSSetLanguage (Language); } estic-1.61.orig/spunk/os2src/screen.cc0100644000176100001440000001761007031424716017162 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #define INCL_VIO #include #include "screen.h" // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) Screen * TheScreen; /*****************************************************************************/ /* Data */ /*****************************************************************************/ struct _ModeInfo { u16 Mode; unsigned char Type; unsigned char ColorBits; u16 Cols; u16 Rows; u16 HRes; u16 VRes; }; const ModeCount = 11; static _ModeInfo ModeInfo [ModeCount] = { { vmBW40, 5, 4, 40, 25, 320, 200 }, { vmCO40, 1, 4, 40, 25, 320, 200 }, { vmBW80, 5, 4, 80, 25, 640, 350 }, { vmCO80, 1, 4, 80, 25, 720, 400 }, { vmMono, 0, 0, 80, 25, 720, 400 }, { vmVGA_80x30, 1, 4, 80, 30, 720, 480 }, { vmVGA_80x34, 1, 4, 80, 34, 720, 480 }, { vmVGA_80x43, 1, 4, 80, 43, 640, 350 }, { vmVGA_80x50, 1, 4, 80, 50, 720, 400 }, { vmVGA_80x60, 1, 4, 80, 60, 720, 480 }, { vmET4_100x40, 1, 4, 100, 40, 800, 600 } }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static u16 ScrGetMode () // return the current video mode { VIOMODEINFO ModeData; // Get mode info ModeData.cb = 12; VioGetMode (&ModeData, 0); // Search for the mode in the table for (_ModeInfo* M = ModeInfo; M < &ModeInfo [ModeCount]; M++) { if (M->Type == ModeData.fbType && M->ColorBits == ModeData.color && M->Cols == ModeData.col && M->Rows == ModeData.row) { // Found the mode return M->Mode; } } // OOPS - unknown mode return vmInvalid; } static void ScrSetMode (u16 Mode) { VIOMODEINFO ModeData; for (int I = 0; I < (sizeof (ModeInfo) / sizeof (ModeInfo [0])); I++) { if (Mode == ModeInfo [I].Mode) { ModeData.cb = 12; ModeData.fbType = ModeInfo [I].Type; ModeData.color = ModeInfo [I].ColorBits; ModeData.col = ModeInfo [I].Cols; ModeData.row = ModeInfo [I].Rows; ModeData.hres = ModeInfo [I].HRes; ModeData.vres = ModeInfo [I].VRes; VioSetMode (&ModeData, 0); return; } } } static u16 ScrGetCursor () // get the current cursor type { VIOCURSORINFO CursorInfo; VioGetCurType (&CursorInfo, 0); return ( (((u16) CursorInfo.yStart) << 8) | (((u16) CursorInfo.cEnd) & 0x00FF) ); } static void ScrSetCursor (u16 Cursor) // set a cursor { VIOCURSORINFO CursorInfo; CursorInfo.yStart = (Cursor >> 8); CursorInfo.cEnd = (Cursor & 0x00FF); CursorInfo.cx = 0; CursorInfo.attr = (Cursor == 0) ? 0xFFFF : 0; VioSetCurType (&CursorInfo, 0); } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): CP437 (1), TransTable (NULL) { // Remember old video mode and cursor form StartupMode = ScrGetMode (); StartupCursor = ScrGetCursor (); // Use current screen mode CurrentMode = StartupMode; // Set the mode data for this mode SetModeData (); // Switch the cursor off SetCursorOff (); } Screen::~Screen () { // Reset old video mode and cursor SetMode (StartupMode); ScrSetCursor (StartupCursor); } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table { if (TransTable) { unsigned char* S = (unsigned char*) Target; unsigned char* T = (unsigned char*) Source; while (Len--) { *T++ = TransTable [*S++]; // Translate character *T++ = *S++; // Copy attribute } return Target; } else { // No translation table, return the source buffer return Source; } } void Screen::SetModeData () // Internally called after setting a new mode, sets cursor data etc. { // Get size of screen and the character cell height VIOMODEINFO ModeInfo; ModeInfo.cb = sizeof (ModeInfo); VioGetMode (&ModeInfo, 0); XSize = ModeInfo.col; YSize = ModeInfo.row; unsigned YCell = ModeInfo.vres / ModeInfo.row; // Calculate the cursor settings from the character cell height CF_HiddenCursor = 0; // is constant under OS/2 CF_FatCursor = 0x0100 + YCell - 1; CF_NormalCursor = ((YCell - 2) << 8) + (YCell - 1); // Check if color mode if (CurrentMode == vmBW40 || CurrentMode == vmBW80 || CurrentMode == vmMono) { Color = 0; } else { Color = 1; } } void Screen::SetMode (u16 Mode) { if (Mode == vmInvalid) { return; } // Remember mode CurrentMode = Mode; // set mode ScrSetMode (Mode); // Get mode data SetModeData (); // Switch cursor off SetCursorOff (); } void Screen::SetCursorOn () { ScrSetCursor (CF_NormalCursor); } void Screen::SetCursorOff () { ScrSetCursor (CF_HiddenCursor); } void Screen::SetCursorFat () { ScrSetCursor (CF_FatCursor); } void Screen::SetCursorPos (const Point& Pos) { PRECONDITION (Pos.X < XSize && Pos.Y < YSize); VioSetCurPos ((USHORT) Pos.Y, (USHORT) Pos.X, 0); } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { int XtoDo, YtoDo; int XCount = R.XSize (); int YCount = R.YSize (); // Check if anything to do if (XCount == 0 || YCount == 0 || R.A.Y > YSize || R.A.X > XSize) { // Done return; } // Calculate the size of the output rectangle XtoDo = (R.B.X > XSize) ? XSize - R.A.X : XCount; YtoDo = (R.B.Y > YSize) ? YSize - R.A.Y : YCount; // If we have to translate the output, get buffer memory u16* Buf2; if (TransTable) { Buf2 = (u16*) alloca (XtoDo * sizeof (u16)); } int Y = R.A.Y; while (YtoDo--) { // Do a translation if neccessary if (TransTable) { // Translate and write to screen Translate (Buf2, Buf, XtoDo); VioWrtCellStr ((char*) Buf2, 2*XtoDo, Y, R.A.X, 0); } else { // No translation VioWrtCellStr ((char *) Buf, 2 * XtoDo, Y, R.A.X, 0); } Buf += XCount; Y++; } } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { // We have always direct access to the screen return 10; } estic-1.61.orig/spunk/os2src/sema.cc0100644000176100001440000001070507031424716016626 0ustar debacleusers/*****************************************************************************/ /* */ /* SEMA.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // This module defines an envelope class for a binary operating system // supported semaphore. Currently the class is implemented for OS/2 and NT. #define INCL_DOSERRORS #define INCL_DOSSEMAPHORES #pragma pack(push) #include #pragma pack(pop) #include "check.h" #include "sema.h" /*****************************************************************************/ /* class SemHandle */ /*****************************************************************************/ class SemHandle { friend class Semaphore; HMTX H; }; /*****************************************************************************/ /* class Semaphore */ /*****************************************************************************/ void Semaphore::Init (const String& Name, unsigned InitialState) // Does the real work for the constructors { APIRET RC; // Get memory for the semaphor handle and initialize it Handle = new SemHandle; Handle->H = (HMTX) -1; // Create/open if the name is given, create otherwise if (Name.NotEmpty ()) { // We have a name, create/open a named semaphore char pszName [256]; // Copy the name into the psz buffer Name.PSZ (pszName, sizeof (pszName)); // Try to create the semaphore RC = DosCreateMutexSem ( pszName, &Handle->H, DC_SEM_SHARED, InitialState ); if (RC == ERROR_DUPLICATE_NAME) { // The semaphore is already created, just open it RC = DosOpenMutexSem (pszName, &Handle->H); } } else { // Create an unnamed semaphore RC = DosCreateMutexSem ( NULL, &Handle->H, DC_SEM_SHARED, InitialState ); } // Return code of the last called function must be zero ZCHECK (RC); } Semaphore::Semaphore (unsigned InitialState) // Create a new, unnamed semaphore with the given initial state { Init (EmptyString, InitialState); } Semaphore::Semaphore (const String& Name, unsigned InitialState) // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. { Init (Name, InitialState); } Semaphore::Semaphore (const char* Name, unsigned InitialState) // Create/open a semaphore with the given name. The function will try to // create a semaphore with the given name. If a semaphore with this name // does already exist, it is opened instead. // InitialState gives the initial state of the semaphore if it is // created, the flag is ignored on an open. { Init (Name, InitialState); } Semaphore::~Semaphore () { DosCloseMutexSem (Handle->H); delete Handle; } void Semaphore::Up () { ZCHECK (DosReleaseMutexSem (Handle->H)); } int Semaphore::Down (i32 T) { ULONG Timeout = T >= 0 ? T : SEM_INDEFINITE_WAIT; // Do the down APIRET RC; do { RC = DosRequestMutexSem (Handle->H, Timeout); } while (RC == ERROR_INTERRUPT); if (RC == ERROR_TIMEOUT) { // We do not own the semaphore return 0; } else { // Check for errors ZCHECK (RC); // We own the semaphore now return 1; } } estic-1.61.orig/spunk/os2src/sercom.cc0100644000176100001440000005042407031424716017173 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1993,94 Michael Peschel */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // OS/2 version. #include #define INCL_DOSERRORS #define INCL_DOSFILEMGR #define INCL_DOSDEVICES #define INCL_DOSDEVIOCTL #define INCL_DOSPROCESS #include #include "check.h" #include "chartype.h" #include "delay.h" #include "sercom.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // additional commands, not implemented in bsedev.h #define ASYNC_SETEXTBAUDRATE 0x0043 #define ASYNC_SETENHPARAMETER 0x0054 #define ASYNC_GETEXTBAUDRATE 0x0063 #define ASYNC_GETENHPARAMETER 0x0074 // extended mode structures // for setting baudrates > 57500 baud typedef struct _EXTBAUDRATE { ULONG BAUDRATE; BYTE FRACTION; } EXTBAUDRATE; typedef EXTBAUDRATE *PEXTBAUDRATE; // checking the actual baudrate and the limits typedef struct _QEXTBAUDRATE { ULONG BAUDRATE; BYTE FRACTBAUD; ULONG MINBAUDRATE; BYTE MINFRACTBAUD; ULONG MAXBAUDRATE; BYTE MAXFRACTBAUD; } QEXTBAUDRATE; typedef QEXTBAUDRATE *PQEXTBAUDRATE; // checking the enhanced parameters typedef struct _ENHPARAMETER { BYTE EnhFlags; ULONG Reserverd; } ENHPARAMETER; typedef ENHPARAMETER *PENHPARAMETER; // enhanced parameter masks, ASYNC_GETENHPARAMETER #define ENHANCEDMODE_SUPPORTED 0x01 #define ENHANCEDMODE_ENABLE 0x02 #define DMA_RX_ENABLE 0x04 #define DMA_RX_DEDICATE 0x08 #define DMA_TX_ENABLE 0x10 #define DMA_TX_DEDICATE 0x20 #define DMA_RX_MODE 0x40 #define DMA_TX_MODE 0x80 // Code for "no error" #ifndef NO_ERROR #define NO_ERROR 0 #endif // internal used data struct _ComData { HFILE hf; // Port handle u16 RXCount; // characters in receive queue u16 TXCount; // characters in transmit queue DCBINFO dcb; // a copy of the actual dcb u16 APICode; // returncode of the last IOCtl-command ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ static void ComError (u32 ErrorCode) // called for API Errors { FAIL (FormatStr ("ComPort error #%d", ErrorCode).GetStr ()); } static void ASYNC_IOCtl (_ComData* ComData, u32 Function, void *ParmList, u32 ParmLen, void *DataList, u32 DataLen) // async device control { ULONG ParmLenInOut = ParmLen; ULONG DataLenInOut = DataLen; ComData->APICode = DosDevIOCtl (ComData->hf, IOCTL_ASYNC, Function, ParmList, ParmLen, &ParmLenInOut, DataList, DataLen, &DataLenInOut); if (ComData->APICode != NO_ERROR) { ComError (ComData->APICode); } } static void GENERAL_IOCtl (_ComData* ComData, u32 Function, void *ParmList, u32 ParmLen, void *DataList, u32 DataLen) // general device control { ULONG ParmLenInOut = ParmLen; ULONG DataLenInOut = DataLen; ComData->APICode = DosDevIOCtl (ComData->hf, IOCTL_GENERAL, Function, ParmList, ParmLen, &ParmLenInOut, DataList, DataLen, &DataLenInOut); if (ComData->APICode != NO_ERROR) { ComError (ComData->APICode); } } static void UpdateErrorCounter (_ComData* ComData, unsigned ErrorWord) // Error counter update { if (ErrorWord & RX_QUE_OVERRUN) ComData->ErrorCounter [ceRXOverflow]++; if (ErrorWord & RX_HARDWARE_OVERRUN) ComData->ErrorCounter [ceOverrun]++; if (ErrorWord & PARITY_ERROR) ComData->ErrorCounter [ceParity]++; if (ErrorWord & FRAMING_ERROR) ComData->ErrorCounter [ceFrame]++; } static void GetComError (_ComData* ComData) // gets the error state of the port and updates the error counters { // Read the error information u16 Error; ASYNC_IOCtl (ComData, ASYNC_GETCOMMERROR, NULL, 0, &Error, sizeof (Error)); // Update the counters UpdateErrorCounter (ComData, Error); } /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (512), // Just some value... TXBufSize (512), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen()) { Close(); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // If the name of the port is just a number, expand it by // inserting "COM". if (PortName.Len () == 1 && IsDigit (PortName [0])) { PortName.Ins (0, "COM"); } // Create an internally used data structure ComData = new _ComData; // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); // Set up ComData ComData->hf = -1; // Port not open ComData->RXCount = 0; ComData->TXCount = 0; } void ComPort::SetBufferSize (u16 /*aRXBufSize*/, u16 /*aTXBufSize*/) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Otherwise this function is ignored under OS/2 as we can not set any // buffer sizes (no harm done anyway) } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { HFILE hf; ULONG ulAction; DCBINFO DCBInfo; EXTBAUDRATE Baud; LINECONTROL LineCtrl; RXQUEUE Queue; // Open the port APIRET rc = DosOpen ((PSZ) PortName.GetStr (), &hf, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, (PEAOP2) NULL); if (rc) { return rc; } // Port-Handle setzen ComData->hf = hf; // actual settings ASYNC_IOCtl (ComData, ASYNC_GETDCBINFO, NULL, 0, &DCBInfo, sizeof (DCBInfo)); // setting timeouts to approx. 30 character times (assuming 1 char = 10 bit) DCBInfo.usWriteTimeout = (30 * 100) / (Baudrate / 10); DCBInfo.usReadTimeout = DCBInfo.usWriteTimeout; // Flow Control if (XonXoff == 'E') { // enable XON/XOFF DCBInfo.fbFlowReplace = 0xA3; // 1010 0011 } else { // disable XON/XOFF DCBInfo.fbFlowReplace = 0xA0; // 1010 0000 } if (Connection == 'D') { // direct connection DCBInfo.fbFlowReplace &= 0x3F; // disable RTS handshake } // Handshake if (Connection == 'M') { // using RTS/CTS, DTR/DSR handshake DCBInfo.fbCtlHndShake = 0x58; // 01011000 } else { DCBInfo.fbCtlHndShake = 0x00; // 00000000 } // Set timeouts and buffers. Beware: Enabling extended hardware buffering // on a device that does not support this setting results in an error. if ((DCBInfo.fbTimeout & 0x18) == 0) { // Device does not support extended hardware buffering DCBInfo.fbTimeout = 0x02; } else { // Extended hardware buffering supported, enable it DCBInfo.fbTimeout = 0xD2; // 11010010 } // Set new DCB ASYNC_IOCtl (ComData, ASYNC_SETDCBINFO, &DCBInfo, sizeof (DCBInfo), NULL, 0); // Get a copy ComData->dcb = DCBInfo; // set up the baudrate Baud.BAUDRATE = Baudrate; Baud.FRACTION = 0; ASYNC_IOCtl (ComData, ASYNC_SETEXTBAUDRATE, &Baud, sizeof (Baud), NULL, 0); // line control LineCtrl.bDataBits = Databits; LineCtrl.bStopBits = Stopbits-1; switch (Parity) { case 'N' : LineCtrl.bParity = 0; break; case 'O' : LineCtrl.bParity = 1; break; case 'E' : LineCtrl.bParity = 2; break; case 'M' : LineCtrl.bParity = 3; break; case 'S' : LineCtrl.bParity = 4; break; default : FAIL ("ComPort::Open: Invalid parity setting"); } ASYNC_IOCtl (ComData, ASYNC_SETLINECTRL, &LineCtrl, sizeof (LineCtrl), NULL, 0); // Get the buffer sizes ASYNC_IOCtl (ComData, ASYNC_GETINQUECOUNT, NULL, 0, &Queue, sizeof (Queue)); RXBufSize = Queue.cb; ASYNC_IOCtl (ComData, ASYNC_GETOUTQUECOUNT, NULL, 0, &Queue, sizeof (Queue)); TXBufSize = Queue.cb; // Success return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open... PRECONDITION (IsOpen ()); // allow changing RTS. RTS is set to OFF when closing the port ComData->dcb.fbFlowReplace &= 0x3F; ComData->dcb.fbFlowReplace |= 0x40; ASYNC_IOCtl (ComData, ASYNC_SETDCBINFO, &ComData->dcb, sizeof (ComData->dcb), NULL, 0); // closing DosClose (ComData->hf); // reset handle ComData->hf = -1; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->hf != -1; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Port must be open and parameter valid PRECONDITION (IsOpen () && aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout < 0.01) { aRXTimeout = 0.01; } // Remember the timeout RXTimeout = aRXTimeout; // Set the timeout ComData->dcb.usReadTimeout = (aRXTimeout * 100) - 1; ASYNC_IOCtl (ComData, ASYNC_SETDCBINFO, &ComData->dcb, sizeof (ComData->dcb), NULL, 0); } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Port must be open and the parameter must be valid PRECONDITION (IsOpen () && aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; // Set the timeout ComData->dcb.usWriteTimeout = (aTXTimeout * 100) - 1; ASYNC_IOCtl (ComData, ASYNC_SETDCBINFO, &ComData->dcb, sizeof (ComData->dcb), NULL, 0); } void ComPort::DTROn () // Make the DTR line active { MODEMSTATUS ModemState; USHORT ErrorWord; // The port must be open PRECONDITION (IsOpen ()); /* setting bitmasks */ ModemState.fbModemOn = DTR_ON; ModemState.fbModemOff = 0xFF; /* calling the driver */ ASYNC_IOCtl (ComData, ASYNC_SETMODEMCTRL, &ModemState, sizeof (ModemState), &ErrorWord, sizeof (ErrorWord)); /* get and reset errors */ if (ErrorWord) { GetComError (ComData); } } void ComPort::DTROff () // Make the DTR line inactive { MODEMSTATUS ModemState; USHORT ErrorWord; // The port must be open PRECONDITION (IsOpen ()); /* setting masks */ ModemState.fbModemOn = 0; ModemState.fbModemOff = DTR_OFF; /* calling the driver */ ASYNC_IOCtl (ComData, ASYNC_SETMODEMCTRL, &ModemState, sizeof (ModemState), &ErrorWord, sizeof (ErrorWord)); /* get and reset errors */ if (ErrorWord) { GetComError (ComData); } } void ComPort::RTSOn () // Make the RTS line active { MODEMSTATUS ModemState; USHORT ErrorWord; // The call is not allowed if the connection type is 'M'odem PRECONDITION (IsOpen () && Connection != 'M'); /* setting bitmasks */ ModemState.fbModemOn = RTS_ON; ModemState.fbModemOff = 0xFF; /* calling the driver */ ASYNC_IOCtl (ComData, ASYNC_SETMODEMCTRL, &ModemState, sizeof (ModemState), &ErrorWord, sizeof (ErrorWord)); /* get and reset errors */ if (ErrorWord) { GetComError (ComData); } } void ComPort::RTSOff () // Make the RTS line inactive { MODEMSTATUS ModemState; USHORT ErrorWord; // The call is not allowed if the connection type is 'M'odem PRECONDITION (IsOpen () && Connection != 'M'); /* setting masks */ ModemState.fbModemOn = 0; ModemState.fbModemOff = RTS_OFF; /* calling the driver */ ASYNC_IOCtl (ComData, ASYNC_SETMODEMCTRL, &ModemState, sizeof (ModemState), &ErrorWord, sizeof (ErrorWord)); /* get and reset errors */ if (ErrorWord) { GetComError (ComData); } } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer { // Port must be open PRECONDITION (IsOpen ()); RXQUEUE RXQueue; ASYNC_IOCtl (ComData, ASYNC_GETINQUECOUNT, NULL, 0, &RXQueue, sizeof (RXQueue)); return RXQueue.cch; } unsigned ComPort::TXCount () const // Return the count of chars in the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); RXQUEUE TXQueue; // same data format as RXQueue ASYNC_IOCtl (ComData, ASYNC_GETOUTQUECOUNT, NULL, 0, &TXQueue, sizeof (TXQueue)); return (TXQueue.cch); } void ComPort::RXClear () // Clear the receive buffer { // Port must be open PRECONDITION (IsOpen ()); BYTE ParmList = 0; BYTE DataList = 0; GENERAL_IOCtl (ComData, DEV_FLUSHINPUT, &ParmList, sizeof (ParmList), &DataList, sizeof (DataList)); } void ComPort::TXClear () // Clear the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); BYTE ParmList = 0; BYTE DataList = 0; GENERAL_IOCtl (ComData, DEV_FLUSHOUTPUT, &ParmList, sizeof (ParmList), &DataList, sizeof (DataList)); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer { return TXBufSize - TXCount (); } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { // Port must be open PRECONDITION (IsOpen ()); // read one character unsigned char B; ULONG chRead; do { DosRead (ComData->hf, &B, 1, &chRead); } while (chRead == 0); // get errors GetComError (ComData); // return character return B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { ULONG chWrite; if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { DosWrite (ComData->hf, &B, 1, &chWrite); GetComError (ComData); return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { unsigned char B; ULONG chRead; while (DosRead (ComData->hf, &B, 1, &chRead) == ERROR_INTERRUPT) ; // Get errors GetComError (ComData); // Return the character read or -1 on timeout return chRead == 0 ? -1 : B; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); // Send the char ULONG chWrite; DosWrite (ComData->hf, &B, 1, &chWrite); // Check for errors GetComError (ComData); // Setup return code if (chWrite != 1) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { return B; } } void ComPort::TimedReceiveBlock (void* Buffer, u32 Count, u32& ReadCount) // Wait until Count characters are read or the timeout is over. The // variable ReadCount returns the amount of character actually read. { // Check params PRECONDITION (Count > 0); // Read with timeout DosRead (ComData->hf, Buffer, Count, PULONG (&ReadCount)); // Get errors GetComError (ComData); } void ComPort::TimedSendBlock (const void* Buffer, u32 Count, u32& WriteCount) // Wait until Count characters have been written or the timeout is over. // The variable WriteCount returns the amount of character actually written. // If a timeout condition occurs, TXOverflow is incremented. { // Check params PRECONDITION (Count > 0); DosWrite (ComData->hf, (void*) Buffer, Count, PULONG (&WriteCount)); if (WriteCount != Count) { ComData->ErrorCounter [ceTXOverflow]++; } GetComError (ComData); } void ComPort::Break (double Duration) // Send a break with the given time in seconds { USHORT ErrorWord; // BREAK ON ASYNC_IOCtl (ComData, ASYNC_SETBREAKON, NULL, 0, &ErrorWord, sizeof (ErrorWord)); // Wait... Delay (Duration * 1000); // BREAK OFF ASYNC_IOCtl (ComData, ASYNC_SETBREAKOFF, NULL, 0, &ErrorWord, sizeof (ErrorWord)); } ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { BYTE Inputs; USHORT Events; // Read the inputs ASYNC_IOCtl (ComData, ASYNC_GETMODEMINPUT, NULL, 0, &Inputs, sizeof (Inputs)); // Read the event mask ASYNC_IOCtl (ComData, ASYNC_GETCOMMEVENT, NULL, 0, &Events, sizeof (Events)); // copy RI to bit 6 if (Events & 0x0100) { Events |= 0x0040; } else { Events &= 0xFFBF; } // shift to bits 0 - 3 Events >>= 3; // Return the bitmask return ((Events & 0x0F) | (Inputs & 0xF0)); } estic-1.61.orig/spunk/os2src/task.cc0100644000176100001440000001473707031424716016654 0ustar debacleusers/*****************************************************************************/ /* */ /* TASK.CC */ /* */ /* (C) 1996 MU Softwareentwicklung */ /* */ /* Ullrich von Bassewitz Michael Peschel */ /* Wacholderweg 14 Ledergasse 3 */ /* D-70597 Stuttgart D-72555 Metzingen */ /* uz@ibb.schwaben.com mipe@ibb.schwaben.com */ /* */ /*****************************************************************************/ // Threads #include #include #include #define INCL_BASE #pragma pack(push) #include #pragma pack(pop) #include "delay.h" #include "check.h" #include "task.h" /*****************************************************************************/ /* class TaskHandle */ /*****************************************************************************/ class TaskHandle { friend class Task; ULONG tid; }; /*****************************************************************************/ /* Exceptionhandler for class Task */ /*****************************************************************************/ typedef ULONG APIENTRY (*ExceptionHandler) (PEXCEPTIONREPORTRECORD, PEXCEPTIONREGISTRATIONRECORD, PCONTEXTRECORD, PVOID); struct TaskRegistrationRecord { // Data needed by the operating system EXCEPTIONREGISTRATIONRECORD* volatile PrevStruct; ExceptionHandler volatile Handler; // Private data Task* T; jmp_buf JumpBuf; }; static ULONG APIENTRY TaskException (PEXCEPTIONREPORTRECORD Report, PEXCEPTIONREGISTRATIONRECORD Reg, PCONTEXTRECORD /* Context */, PVOID /* DispatcherContext */ ) // This exception handler handles the exception XCPT_PROCESS_TERMINATE and // XCPT_ASYNC_PROCESS_TERMINATE { if (Report->ExceptionNum == XCPT_PROCESS_TERMINATE || Report->ExceptionNum == XCPT_ASYNC_PROCESS_TERMINATE) { // Cast the pointer to our own structure TaskRegistrationRecord* TR = (TaskRegistrationRecord*) Reg; // This is what we have installed the handler for longjmp (TR->JumpBuf, 1); } // Unknown exception - pass it to the next handler return XCPT_CONTINUE_SEARCH; } /*****************************************************************************/ /* class Task */ /*****************************************************************************/ Task::Task (size_t aStackSize): StackSize (aStackSize), Running (0), RunDown (0), Handle (new TaskHandle) // Constructor { Handle->tid = 0; } Task::~Task () // Destructor { // Stop the thread if not already done Stop (); // Delete the handle data delete Handle; } void Task::CreateFunc (void* ThisObj) // This function is started as a thread. { // Cast the given pointer into a pointer-to-object. Use the volatile // keyword to avoid problems with T when using longjmp Task* volatile T = (Task*) ThisObj; // Get the thread ID. There is no easy way to do that, the thread ID must // be extracted from the thread information block. PTIB ptib; PPIB ppib; ZCHECK (DosGetInfoBlocks (&ptib, &ppib)); T->Handle->tid = ptib->tib_ptib2->tib2_ultid; // Set the running flag now. T->Running = 1; // Call the init routine T->Init (); // Register an exception handler TaskRegistrationRecord Reg = { 0, TaskException, T }; if (setjmp (Reg.JumpBuf) == 0) { // Register the exception handler ZCHECK (DosSetExceptionHandler ((PEXCEPTIONREGISTRATIONRECORD) &Reg)); // Run the task T->Run (); // Deregister the exception handler. This is necessary only if we get // out of Run() without an exception, since longjmp (used by the // handler) will unwind all handlers including the one installed. ZCHECK (DosUnsetExceptionHandler ((PEXCEPTIONREGISTRATIONRECORD) &Reg)); } // Call the cleanup routine T->Done (); // If we get back from the run function, we are done - reset the Running flag T->Running = 0; } void Task::Init () // This function is called before Run() { } void Task::Done () // This function is called after Run() { } void Task::SetPriority (unsigned Priority, int Delta) // Allows the task to set it's priority { // Map the Priority to a system defined value ULONG Prio = 0; switch (Priority) { case PrioIdle: Prio = PRTYC_IDLETIME; break; case PrioRegular: Prio = PRTYC_REGULAR; break; case PrioServer: Prio = PRTYC_FOREGROUNDSERVER; break; case PrioTimeCritical: Prio = PRTYC_TIMECRITICAL; break; default: FAIL ("Task::SetPriority: Invalid priority value"); } DosSetPriority (PRTYS_THREAD, Prio, Delta, Handle->tid); } void Task::Start () // Start the task { // The task may not run already CHECK (!IsRunning ()); // Create the thread CHECK (_beginthread (CreateFunc, 0, StackSize, this) != -1); } void Task::Stop (unsigned WaitTime) // Stop the task { if (IsRunning ()) { // Set the rundown flag RunDown = 1; // Wait until WaitTime is over or the thread has terminated while (WaitTime && IsRunning ()) { // Calculate time slice to wait unsigned Time = 100; if (Time > WaitTime) { Time = WaitTime; } WaitTime -= Time; // Wait Delay (Time); } // If the thread did not terminate, kill it if (IsRunning ()) { // Send the Kill signal to the thread DosKillThread (Handle->tid); } } } estic-1.61.orig/spunk/samples/0040755000176100001440000000000007061535305015623 5ustar debacleusersestic-1.61.orig/spunk/samples/skel/0040755000176100001440000000000007061535305016561 5ustar debacleusersestic-1.61.orig/spunk/samples/skel/make/0040755000176100001440000000000007061535305017476 5ustar debacleusersestic-1.61.orig/spunk/samples/skel/make/watcom.mak0100644000176100001440000000661107031424717021464 0ustar debacleusers# ***************************************************************************** # * * # * ESTIC Makefile * # * * # * (C) 1993-96 Ullrich von Bassewitz * # * Wacholderweg 14 * # * D-70597 Stuttgart * # * EMail: uz@ibb.schwaben.com * # * * # ***************************************************************************** # $Id$ # # $Log$ # # # ------------------------------------------------------------------------------ # Generelle Einstellungen .AUTODEPEND .SUFFIXES .ASM .C .CC .CPP .SWAP # ------------------------------------------------------------------------------ # Allgemeine Definitionen # Names of executables AS = TASM AR = WLIB LD = WLINK !if $d(__OS2__) ZIP = zip MV = c:\os2\4os2\4os2 /C MOVE /Q !else ZIP = pkzip MV = mv !endif !if !$d(TARGET) !if $d(__OS2__) TARGET = OS2 !else TARGET = DOS !endif !endif LIBDIR= ..\.. INCDIR= ..\.. # target specific macros. !if $(TARGET)==OS2 # --------------------- OS2 --------------------- SYSTEM = os2v2 CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d2 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !elif $(TARGET)==DOS32 # -------------------- DOS4G -------------------- SYSTEM = dos4g CC = WPP386 CCCFG = -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==DOS # --------------------- DOS --------------------- SYSTEM = dos CC = WPP # Optimize for size when running under plain DOS, but use 286 code. Don't # include ANY debugging code to make as many programs runable under plain DOS # as possible. CCCFG = -bt=$(TARGET) -d$(TARGET) -dSPUNK_NODEBUG -i=$(INCDIR) -d1 -oailmns -s -zp2 -zc -2 -fp2 -ml -zq -w2 -ze -zt255 !elif $(TARGET)==NETWARE # --------------------- NETWARE ------------------- SYSTEM = netware CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi -zq -w2 -ze !elif $(TARGET)==NT # --------------------- NT ---------------------- SYSTEM = nt CC = WPP386 CCCFG = -bm -bt=$(TARGET) -d$(TARGET) -i=$(INCDIR) -d1 -onatx -zp4 -5 -fpi87 -zq -w2 -ze !else !error !endif LIB = $(LIBDIR)\$(TARGET)\SPUNK.LIB # ------------------------------------------------------------------------------ # Implicit rules .c.obj: $(CC) $(CCCFG) $< .cc.obj: $(CC) $(CCCFG) $< # -------------------------------------------------------------------- all: skel skel: skel.exe os2: $(MAKE) -DTARGET=OS2 nt: $(MAKE) -DTARGET=NT dos32: $(MAKE) -DTARGET=DOS32 dos: $(MAKE) -DTARGET=DOS # -------------------------------------------------------------------- # ESTIC skel.exe: skel.obj @copy makefile make\watcom.mak > nul $(LD) system $(SYSTEM) @&&| DEBUG all NAME skel.exe OPTION DOSSEG OPTION STACK=32K FILE skel.obj LIBRARY $(LIB) | # ------------------------------------------------------------------------------ # Aufr umen clean: -del *.bak zap: clean -del *.obj -del *.mbr -del *.dbr estic-1.61.orig/spunk/samples/skel/.cvsignore0100644000176100001440000000002207031424716020550 0ustar debacleusersmakefile Makefile estic-1.61.orig/spunk/samples/skel/skel.cc0100644000176100001440000001142607031424716020027 0ustar debacleusers/*****************************************************************************/ /* */ /* SKEL.CC */ /* */ /* (C) 1996 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include "program.h" #include "progutil.h" #include "menuitem.h" #include "menue.h" #include "stdmenue.h" #include "stdmsg.h" #include "skelmsg.h" #include "skel.h" /*****************************************************************************/ /* Message constants */ /*****************************************************************************/ // These are constants for messages loaded from the resource file. // The MSGBASE_XXX constants are defined in skelmsg.h. Usually I do // reserve a range of 100 messages for each source file, so the step // for the MSGBASE_XXX constants is 100. But this is just a convention. const u16 msSkel = MSGBASE_SKEL + 0; const u16 msAbout = MSGBASE_SKEL + 1; const u16 msQuit = MSGBASE_SKEL + 2; const u16 msAboutInfo = MSGBASE_SKEL + 3; /*****************************************************************************/ /* class SkelApp */ /*****************************************************************************/ SkelApp::SkelApp (int argc, char* argv []): Program (argc, argv, CreateMenueBar, CreateStatusLine, "skel") { } // The following code builds the main menu and the statusline at the bottom. // The somewhat weird syntax is the result of my plan, to incorporate menu // bars into the resource editor, so one would load (instead construct at // runtime) the top menu bar. I thought about overloading the '+' key for // menu items, but that lead to problems with submenues. static MenueItem* GetMenueItem (u16 MsgID, i16 ItemID, Key AccelKey, WindowItem* NextItem) { return (MenueItem*) SetAccelKey (new MenueItem (App->LoadAppMsg (MsgID), ItemID, NextItem), AccelKey); } static MenueLine* GetMenueLine (WindowItem* NextItem) { return new MenueLine (miNone, NextItem); } static MenueBarItem* GetMenueBarItem (u16 MsgID, i16 ItemID, WindowItem* MenueList, WindowItem* NextItem) { return new MenueBarItem (App->LoadAppMsg (MsgID), ItemID, MenueList, NextItem); } TopMenueBar* SkelApp::CreateMenueBar () { TopMenueBar* M = new TopMenueBar ( GetMenueBarItem (msSkel, miSkel, GetMenueItem (msAbout, miAbout, kbNoKey, GetMenueLine ( GetMenueItem (msQuit, miQuit, vkQuit, NULL ))), NULL )); // Register the accel keys of the submenues App->RegisterKey (M->GetAccelKey (miSkel)); // Register the accel keys App->RegisterKey (M->GetAccelKey (miQuit)); // Return the result return M; } BottomStatusLine* SkelApp::CreateStatusLine () { return new BottomStatusLine (siExit); } int SkelApp::Run () // Run the application { // These are the items for the quit menu const i16 miNo = 1; const i16 miYes = 2; // Activate the main menue MainMenue->Activate (); // Main loop while (!Quitting ()) { // Switch according to the users choice switch (MainMenue->GetChoice ()) { case miAbout: InformationMsg (LoadAppMsg (msAboutInfo)); break; case miQuit: // Close the windows if (MenueChoice ("@SKEL.QuitMenu") == miYes) { // The end... Quit = 1; } break; } } // Return the program exit code return 0; } int main (int argc, char* argv []) { // Set the default language and country // DefaultLanguage = laGerman; // DefaultCountry = 49; // Declare an application object SkelApp MyApp (argc, argv); // Use it... return MyApp.Run (); } estic-1.61.orig/spunk/samples/skel/skel.doc0100644000176100001440000000735107031424716020211 0ustar debacleusers Skeleton application source for the spunk library Documentation written at the end of 1996 Ullrich von Bassewitz 0. The modules that make up the sample skeleton application for spunk are: skel.h This file holds the class definitions for the application class. It must be a direct descendant of the Program class. This stuff may also go into skel.cc if it is not otherwise referenced (as in the case of the skel example). skel.cc This is the "real" source. Most of it is framework that is used in any spunk application (and in fact, the code is taken from the estic application, a control software for a ISDN PBX that is popular in Germany. The application runs under Linux, FreeBSD, serval other Unices, OS/2, Windows-NT and 16/32-Bit DOS without a change in the sources). skelmsg.h This holds the message base constants for the modules. There is a MSGBASE_XXX constant for every module that loads messages from the application resource. skel.res This is the base resource file from spunk with messages for two languages and a menu for two languages added. 1. Features used vs. Features not used The sample application doesn't use many of the features of spunk. There is no file viewer, no input lines and other menu stuff, no stream I/O, no serial I/O, no use of the dynamic data structures, spunk offers - and so on. On the other side, even the skeleton application has some of the basic spunk features: * It supports multiple languages. Try SET SPUNK_LANGUAGE=1 or SET SPUNK_LANGUAGE=2 or whatever is the appropriate command to set environment variables on your operating system. You will get different menus each time, since the resources are loaded from the resource file. And the loader automatically favours localized resources over generic ones as described in the spunk.doc file. * Use SPUNK_COUNTRY=xxx to use other country settings (under DOS, OS/2 or NT, the default setting is read from the operating system and should be ok, with Unix this is somewhat more a problem, so the SPUNK_COUNTRY environment variable may be used). * All resources are external to the application. Want to change the text of the ending menu? You don't like the copyright string? Start up resed (the resource editor), load the resource into the editor and change it to your liking. There is no reason to recompile your application, just to fix some typos or change the default selection for a menu. X. About spunk It is now nearly two years after I wrote the original spunk.doc file. I (and others) have written many programs using spunk. Here are some of my experiences with the library: * Spunk was developed for applications with not too much user interface. It is possible to write nearly any interface with spunk, but when the UI gets bigger and bigger, there are usually better tools than spunk to write your application. * Spunk was developed for technical software - and this is, where it really shines. Small to middle sized user interfaces (that are the usual case with technical software) are build very rapidly and give your application a professional touch. Your data sampling app (or whatever) will look *much* nicer with a colorful screen with two or three status windows. Having a few status windows and a logfile is usually done in less than one hour of work. * If you know, you have to support more than one operating system, you will estic-1.61.orig/spunk/samples/skel/skel.h0100644000176100001440000000353007031424716017666 0ustar debacleusers/*****************************************************************************/ /* */ /* SKEL.H */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #ifndef _SKEL_H #define _SKEL_H #include "program.h" /*****************************************************************************/ /* Menue items */ /*****************************************************************************/ const i16 miNone = 1; const i16 miSkel = 1000; const i16 miAbout = 1100; const i16 miQuit = 1200; /*****************************************************************************/ /* class SkelApp */ /*****************************************************************************/ class SkelApp: public Program { private: static TopMenueBar* CreateMenueBar (); static BottomStatusLine* CreateStatusLine (); public: SkelApp (int argc, char* argv []); // Construct an application object virtual int Run (); // Run the application }; // End of SKEL.H #endif estic-1.61.orig/spunk/samples/skel/skel.res0100644000176100001440000015613007031424716020235 0ustar debacleusersAnnaXÜq× @Skel@ber Skel ...@QuitC Beispielanwendung fr spunk (w) 1996 by Ullrich von Bassewitz 6P 7 6 hŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPprpopgprpapmpmp pwpiprpkplpipcphp pbpepepnpdpepnp?p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pNtepipnp p p p p p p p p p p p p p p p p p p p p p p p³p³p pJtap p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`č˙˙Programm wirklich beenden?s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpNNein Nein pJJa Ja 6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpfpapdp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pDtaptpepipepnp p p p p p p p p p p p p p p p p p p pVteprpzpepipcphpnpipspspep p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6D Dateien`6V/ Verzeichnisse2N1Name( 3ž`6é˙˙Pfadb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp p p p p p pBpepnpuptpzpeprpnpapmpep p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprptp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KBenutzer-ID Benutzername Passwort LevelPH6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pItDp p p p p p p p p p p p p p p                       p³p³p pBpepnpuptpzpeprp-pNtapmpep p p                                 p³p³p pPtapspspwpoprptp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStipcphpeprphpepiptpsp-pEpbpepnpep p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/I  Benutzer-ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N 1 Benutzer-Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPasswort "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSicherheits-Ebene0*)/ PH6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprptp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp— ˙˙ Passwort:  PH6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ Benutzer-ID: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōHilfe bernehmen Abbruch Ende Weiter ˇndern Drucken Grafik  Einfgen L”schen Auswahl Best„tigen Bewegen Login Logout Ende Zoom  Schliessen ™ffnen Gr”įe  Speichern  ~~ Auswahl  ~ÄŁ~ Auswahl  ~ Bild-~ Bl„ttern  ~~ Bewegen  ~Ctrl+~ Gr”įe Sind Sie sicher?dWirklich Ende?eˇnderungen verwerfen?fˇnderungen sichern?g @Ja @Neinh @Nein @Jai Fehler Č Information É Systemfehler Ź Best„tigen ŅAbbruch Ó Ignorieren Ō Wiederholen ÕEnde ÖEinen Moment bitte...×Ungltige Eingabe,Zu viele Nachkommastellen-"Wert ist zu klein (Minimum ist %g).!Wert ist zu groį (Maximum ist %g)/#Wert ist zu klein (Minimum ist %ld)0"Wert ist zu groį (Maximum ist %ld)1Leereingabe ist unzul„ssig2Keine Datei-Erweiterung erlaubt3Aus AnNein Ja‘Wert ist zu groįōWert ist zu kleinõFehlerhafte Eingabeö2%s: Sektion %s, %s nicht gefunden oder fehlerhaft.X*Fehler beim ™ffnen der Passwort-Datei^(%s)¼)Fehler beim Lesen der Passwort-Datei^(%s)½1Fehler beim Schreiben auf die Passwort-Datei^(%s)¾)Es muį eine Benutzer-ID angegeben werden!æ)Es muį ein Benutzername angegeben werden!Ą%Es muį ein Passwort angegeben werden!Į-Ein Benutzer mit dieser ID existiert bereits!Ā/Ungltige Benutzer-ID oder ungltiges Passwort!ĆSonntag Montag!Dienstag"Mittwoch# Donnerstag$Freitag%Samstag&So'Mo(Di)Mi*Do+Fr,Sa-Januar.Februar/M„rz0April1Mai2Juni3Juli4August5 September6Oktober7November8Dezember9Jan:Feb;M„r<Apr=Mai>Jun?Jul@AugASepBOktCNovDDezEKeine Hilfe verfgbar„ Keine Hilfe fr dieses Stichwort… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+Bild-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Bild-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Bild-™Alt+Ende Alt+Bild- Alt+Einfg¢Alt+Entf£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-EndeEsc-PgDn Esc-Einfg¢Esc-Entf£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Verzeichnis 5 Fehler %d: %süKein Fehler (OOPS!)żDatei oder Pfad nicht gefundenžNicht genug Speicher˙Zugriff verweigert Zu viele offene Files 9Nicht gengend Speicherplatz auf dem angesprochenen Ger„t %Tempor„rer Fehler - nochmal versuchen Ger„t/Datei ist in Benutzung Datei ist zu groį I/O Fehler Datei ist ein Verzeichnis Datei ist kein Verzeichnis Zu viele Links 'Operation nur mit Block Devices m”glich &Operation nur mit Char Devices m”glich Device existiert nicht 4Operation ist nur fr den Besitzer der Datei m”glich Broken Pipe Dateisystem ist readonly +Seek kann nicht auf Pipes ausgefhrt werden Prozess existiert nicht Ausfhrbare Datei ist busy Name ist zu lang Keine Locks verfgbar Verzeichnis ist nicht leer Datei nicht gefunden Pfad nicht gefunden Laufwerk ist ungltig 0Aktuelles Verzeichnis kann nicht gel”scht werden Datei existiert bereits Unbekannter Fehler (%d) "Es sind zu viele Fenster ge”ffnet!Ä 6P > = Fensterliste  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pFpepnpsptpeprplpipsptpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙ @Skel @About ...@QuitR Skeleton application for the spunk library (w) 1996 by Ullrich von Bassewitz 6P 7 6 tŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pDpop pypopup prpepaplplpyp pwpapnptp ptpop pqpupiptp?p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pNtop p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p pYtepsp p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`č˙˙Do you really want to quit?s0u˙˙ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄpNNo No pYYes Yes 6P‘ D C 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpaptphp p p p pPpaptphpLpipnpep p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pFtiplpepsp p p p p p p p p p p p p p p p p p p p p pDtiprpepcptpoprpipepsp p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pInfoLine1                                          p p³p³p p pInfoLine2                                          p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6F!Files`6D  Directories2N1Name( 3ž`6é˙˙Pathb * ˙˙PathLineb2 ˙˙ InfoLine1 b2 ˙˙ InfoLine2 6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp p p p p p p p p p pUpspeprp pNpapmpep p p p p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprpdp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KUser ID User Name Password LevelPH6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pItDp p p p p p p p p p p p p p p p p p p                       p³p³p pUpspeprp pNtapmpep p p p p p p                                 p³p³p pPtapspspwpoprpdp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStepcpuprpiptpyp pLpepvpeplp p p p p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/IUser ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N1 User Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPassword "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSecurity Level0*)/ PH6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  PH6P :9 ŲŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp” ˙˙User ID:  ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōHelpAccept Abort End Proceed Change Print  Graphics Insert Delete Select Confirm Move Login Logout Exit Zoom Close Open Resize Save  ~~ Select  ~ÄŁ~ Select  ~ PgDn PgUp~ Browse  ~~ Move  ~Ctrl-~ Resize Are you shure?d Really quit?eDiscard changes?f Save changes?g@Yes @Noh@No @Yesi Error Č Information É Fatal Error ŹConfirm ŅAbort ÓIgnore ŌRetry ÕEnd ÖOne moment please...× Invalid input,Too many trailing digits-"Value is too small (minimum is %g)."Value is too large (maximum is %g)/#Value is too small (minimum is %ld)0#Value is too large (maximum is %ld)1Input cannot be empty2No filename extension allowed3Off On NoYes‘Value is too largeōValue is too smallõ Invalid inputö,%s: Section %s, key %s not found or invalid.X$Error opening the password file^(%s)¼$Error reading the password file^(%s)½'Error writing to the password file^(%s)¾The user id cannot be empty!æThe user name cannot be empty!ĄAn empty password is invalid!Į'A user with this ID does already exist!Ā$Invalid user id or invalid password!ĆSunday Monday!Tuesday" Wednesday#Thursday$Friday%Saturday&Sun'Mon(Tue)Wed*Thu+Fri,Sat-January.February/March0April1May2June3July4August5 September6October7November8December9Jan:Feb;Mar<Apr=May>Jun?Jul@AugASepBOctCNovDDecENo help available„No help on this topic… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+PgUp™Alt+EndAlt+PgDnAlt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Error %d: %süNo error (OOPS!)żFile or path not foundžNot enough memory˙ Access denied Too many open files No space left on device Try again Device or file is busy File is too large I/O error File is a directory File is no directory Too many links Block device required Char device required Device does not exist !You are not the owner of the file Broken pipe File system is readonly Cannot seek on pipes Process does not exist Text file is busy Name is too long No locks available Directory is not empty File not found Path not found Drive is invalid Cannot remove current directory File exists Unknown error (%d) There are too many windows open!Ä 6P > = Window list  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pWpipnpdpopwp plpipsptp pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password:  PH6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p zIpDp puptpepnptpep:p z z z z                       z³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ ID utente: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙PHš ōGuida Accetta Annulla Termina  Continua  Modifica Stampa Grafica  Inserisci  Cancella Seleziona Conferma Muovi Login Logout Termina Zoom Chiudi Apri  Dimensione Salva  ~~ Seleziona  ~ÄŁ~ Seleziona  ~ Pag-~ sfoglia  ~~ Muovi  ~Ctrl+~ Dimensione E' proprio sicuro?dProprio terminare?eAnnullare modifiche?fSalvare modifiche?g@S¨ @Noh@No @S¨i Errore Č Informazione É Errore di sistema Ź Conferma ŅAnnulla ÓIgnora ŌRipeti ÕFine Ö Un momento...×Valore non valido,Troppi zero dopo la virgola-$Valore troppo piccolo (al minimo %g).$Valore troppo grande (al massimo %g)/%Valore troppo piccolo (al minimo %ld)0%Valore troppo grande (al massimo %ld)1Ci vuole qualcosa!2Estensione file non ammessa3Off OnNoS¨‘Valore troppo grandeōValore troppo piccoloõValore sbagliatoö+%s: sezione %s, %s non trovata o sbagliata.X/Errore di apertura del file delle password (%s)¼.Errore di lettura del file delle password (%s)½0Errore di scrittura del file delle password (%s)¾Ci vuole un ID utente!æCi vuole un nome utente!ĄCi vuole una password!Į#Un utente con questo ID esiste gi…!Ā ID utente o password non validi!ĆDomenica Luned¨!Marted¨" Mercoled¨#Gioved¨$Venerd¨%Sabato&Do'Lu(Ma)Me*Gi+Ve,Sa-Gennaio.Febbraio/Marzo0Aprile1Maggio2Giugno3Luglio4Agosto5 Settembre6Ottobre7Novembre8Dicembre9Gen:Feb;Mar<Apr=Mag>Giu?Lug@AgoASetBOttCNovDDicEGuida non disponibile„.Guida non disponibile per questa parola chiave… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁ Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+Pag-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Pag-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Pag-™Alt+Fine Alt+Pag-Alt+Ins¢Alt+Canc£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L Enter Ctrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscCancAlt+Esc Alt+SpazioCtrl+Ins Shift+Ins Ctrl+Canc Shift+Canc Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHPag-IKMFineOPPag-QInsRCancSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Fineu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-FineEsc-PgDnEsc-Ins¢Esc-Canc£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Byte 4 Directory 5 Errore %d: %süNessun errore (OOPS!)żFile o path non trovatižMemoria insufficiente˙Accesso negato Troppi files aperti ,Memoria insufficiente sul device indirizzato Errore temporaneo - riprovare Device/file in uso File troppo grande Errore di I/O Il file una directory Il file non una directory Troppi links /L'operazione possibile solo con block devices .L'operazione possibile solo con char devices Device non esistente :L'operazione possibile solo per il proprietario del file Broken Pipe $Il file di sistema e' a sola lettura %Seek non pu• essere eseguito su pipes Processo non esistente File eseguibile impegnato Nome troppo lungo Nessun lock disponibile La directory non vuota File non trovato Path non trovato Drive non valido .La directory attuale non pu• essere cancellata Il file esiste gi… Errore sconosciuto (%d) Sono aperte troppe finestre!Ä 6P > = Lista finestre  ČŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp pLpipsptpap pfpipnpepsptprpep pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp˙˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,./:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° .,-:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAA¸€EEEIIIA¸E’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨ˇ†‘‘“”•–—™›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° BEF.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙!"#$%&˙()*+,˙./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU›¯˛AIOUNN¦§Ø©Ŗ«¬­®Æ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüż˙˙° F ,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° ˛.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° L..,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° Fr'...,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙ČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚ¨ŪÜŻŽßąįāćä<=>?@ABCDEFGHIJ !"#$%&'()KLMNOPQ RST4U3 VWX6Y oZp–\ ]—_`abcdefghi™›klmn¯qrstuvw˛xyz{|}~ ¢£¤¦§Ø©€‚Ŗ«…¬­®Æ°†±²³´µ¶·ø¹ŗ‰»¼½¾ˇæ¸ĄĮĀ“”° ,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° SEK.,-.;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° DM.,.:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° mk ,..;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CYEA\A[CEEEIII\[E\\O]OUUY]Y$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° >< ^ >< ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ° »« ^ »« ^ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ĒüéāäąåēźėčļīģÄÅÉęĘōöņüł˙ÖÜ¢£PfįķóśńŃŖŗæ-¬Ę¼«»žžž|++++++|+++++++++-++++++++-+++++++++++++žžžžžaßcpZsµtpTOd80eU=±>tmp tar cfTz $(archive) tmp mcopy -n $(archive) a: mcopy -n $(archive) a:bkp rm $(archive) tmp mdir a: rcsbkp: tar cfz std-rcs.tgz RCS/* mcopy -n std-rcs.tgz a: rm std-rcs.tgz mdir a: #------------------------------------------------------------------------------ # dependencies #------------------------------------------------------------------------------ ifeq (.depend,$(wildcard .depend)) include .depend depend: else depend: $(SRCS1) $(CPP) -M $(INCLUDEDIRS) $(DEFS) $(SRCS1) > .depend endif estic-1.61.orig/spunk/samples/std/README0100644000176100001440000000175407031424717017302 0ustar debacleusers-----BEGIN PGP SIGNED MESSAGE----- This is an example application that uses the SPUNK library. It does some fancy things with a relais interface that is connected to a parallel port. It is a preliminary version of a program I write for a company. You may do with the code whatever you want. Apart from the handling of the library, there are some classes you might be interested in. Just read the source. Code should work on Linux and DJGPP (change Makefile). ralf@ark.franken.de Some security (MD5): 178ef52cd97abe1d8c80e04205fa73c4 CHANGES c9bb6e738135c26fc396ef8c4c9656ad Makefile a9baf5e924b169cb8ecd4e8e9597e21a std.cc 803b407117d2af58849779c4b55f59da std.h bb3a4cbc8c88ca5bae4a41b5d29d93f4 std.res -----BEGIN PGP SIGNATURE----- Version: 2.6.i iQCVAgUBMNLn5PUDwEOnE+zpAQEuGgP9HX/MxJftMnEYkPkGHyyWRsMk1QHLxAKB tjFAzvBRgB25G8/KaHzMc+0PHK9c6C7YB9CbKpI98TAMreaHGZIhDcsqrq3Ge+Il 9IW9c3J/eyHF/dHe/mqOpcz1bJYKa9MfqFXsaykksfUq5LF5rbSnXXZ4bbyyLk42 KfuE6Ub4VOA= =cHy0 -----END PGP SIGNATURE----- estic-1.61.orig/spunk/samples/std/std.cc0100644000176100001440000001366207031424717017524 0ustar debacleusers// ********************************************************************* // SuperTrans Demo (c) 1995,1996 Ralf Stephan static char rcsid[] __attribute__ ((unused)) = "$Id: std.cc,v 0.17 1995/11/27 14:51:26 ralf Exp $"; // ********************************************************************* #include #include "std.h" #include "menue.h" #include "window.h" #include "kbd.h" __link (Options, STD_ID_Options); //=========================================================== main (int argc, char** argv) { Std std (argc, argv); return std.Run(); } //=========================================================== Std::Std(int c, char** v) : Program (c,v,0,&CreateStatusLine,"std"), optf_("std.cfg") { if (optf_.GetSize()>0) optf_ >> opt_; } Std::~Std() { } BottomStatusLine* Std::CreateStatusLine () { const u32 Flags = siEnd | siSelectChooseKeys; return new BottomStatusLine (Flags); } int Std::Run() { Menue* M = (Menue*) LoadResource ("@STD.startmenu"); M->GrayItem (iStartDemo); M->GrayItem (iContDemo); M->GrayItem (iSingle); M->Activate (); while (true) { int Sel = M->GetChoice (); if (!Sel || Sel==iExit) break; switch (Sel) { case iStartDemo: StartDemo(); break; case iContDemo : ContDemo(); break; case iSingle : Single(); break; case iTablet : Tablet(); break; case iOptions : Config(); break; } } delete M; return 0; } //================================================================ void Std::StartDemo() { } //---------------------------------------------------------------- void Std::ContDemo() { } //---------------------------------------------------------------- void Std::Single() { } //---------------------------------------------------------------- void Std::Tablet() { Rect screen = Background->OuterBounds(); Rect r(0,0,37,12); r.Center(screen,cfCenterAll); Window w(r); w.SetHeader("Tablettsteuerung"); w.Clear(); int x=0, y=0; w.Write(x,++y," Fahren"); w.Write(x,++y," \\ | / 0 - Start/Stop"); w.Write(x,++y," \\ | /"); w.Write(x,++y," 7 8 9 + - Drive"); w.Write(x,++y," --4 6--"); w.Write(x,++y," 1 2 3 Enter - Mode"); w.Write(x,++y," / | \\"); w.Write(x,++y," / | \\ Esc - Beenden"); w.Activate(); ST st (opt_,opt_.portnr); while (1) { Key key = Kbd->Get(); if (key == vkAbort) break; if (!isdigit(key) && !(key==kbEnter || key=='+')) continue; switch (key) { case kbEnter: st << tcMode; break; case '+' : st << tcDrive; break; case '0' : st << tcStartStop; break; case '1' : st << tcSW; break; case '2' : st << tcS; break; case '3' : st << tcSE; break; case '4' : st << tcW; break; case '6' : st << tcE; break; case '7' : st << tcNW; break; case '8' : st << tcN; break; case '9' : st << tcNE; break; default : break; } } } //---------------------------------------------------------------- void Std::Config() { Menue* M = (Menue*) LoadResource ("@STD.options"); M->DeactivateItem (iDauer); M->DeactivateItem (iRelayNr); M->SetToggleValue (iPortnr, opt_.portnr-1); M->SetLongValue (iStartStop, opt_.startstop); M->SetLongValue (iDrive, opt_.drive); M->SetLongValue (iDir, opt_.dir); M->SetLongValue (iSPause, opt_.pause); M->SetLongValue (iLPause, opt_.longpause); M->SetToggleValue (iLeft, fastlog2(opt_.R_W)); M->SetToggleValue (iRight, fastlog2(opt_.R_E)); M->SetToggleValue (iUp, fastlog2(opt_.R_N)); M->SetToggleValue (iDown, fastlog2(opt_.R_S)); M->SetToggleValue (iSKey, fastlog2(opt_.R_x)); M->Activate (); while (true) { int Sel = M->GetChoice (); if (!Sel) break; } opt_.portnr = M->GetToggleValue (iPortnr)+1; opt_.startstop = M->GetLongValue (iStartStop); opt_.drive = M->GetLongValue (iDrive); opt_.dir = M->GetLongValue (iDir); opt_.pause = M->GetLongValue (iSPause); opt_.longpause = M->GetLongValue (iLPause); opt_.R_W = 1 << (M->GetToggleValue (iLeft)); opt_.R_E = 1 << (M->GetToggleValue (iRight)); opt_.R_N = 1 << (M->GetToggleValue (iUp)); opt_.R_S = 1 << (M->GetToggleValue (iDown)); opt_.R_x = 1 << (M->GetToggleValue (iSKey)); optf_ << opt_; delete M; } ST::ST (Options& o, int portnr) : opt_(o), ri_(portnr) {} //============================ friends ===================================== ST& operator<< (ST& st, TCommand t) { const RI& ri = st.ri_; const Options& opt = st.opt_; const dir = opt.dir, startstop = opt.startstop, drive = opt.drive, pause = opt.pause, longpause = opt.longpause, R_N=opt.R_N, R_W=opt.R_W, R_E=opt.R_E, R_S=opt.R_S, R_x=opt.R_x; switch (t) { case tcStartStop: ri << RISignal(R_x, startstop); break; case tcDrive : ri << RISignal(R_x, drive) << RISignal(R_Pause, longpause); break; case tcMode : ri << RISignal(R_x, drive) << RISignal(R_Pause, pause) << RISignal(R_x, drive) << RISignal(R_Pause, longpause); break; case tcSW : ri << RISignal(R_S|R_W, dir); break; case tcS : ri << RISignal(R_S, dir); break; case tcSE : ri << RISignal(R_S|R_E, dir); break; case tcW : ri << RISignal(R_W, dir); break; case tcE : ri << RISignal(R_E, dir); break; case tcNW : ri << RISignal(R_N|R_W, dir); break; case tcN : ri << RISignal(R_N, dir); break; case tcNE : ri << RISignal(R_N|R_E, dir); break; } return st; } int fastlog2(int n) { int num_bits, power = 0; if((n < 2) || (n % 2 != 0)) return(0); num_bits = sizeof(int) * 8; /* How big are ints on this machine? */ while(power <= num_bits) { n >>= 1; ++power; if(n & 0x01) { if(n > 1) continue; else return(power); } } return(0); } estic-1.61.orig/spunk/samples/std/std.h0100644000176100001440000001007007031424717017354 0ustar debacleusers#include #include #include "program.h" #include "statline.h" #include "stream.h" #include "streamid.h" static char rcsidh1[] __attribute__ ((unused)) = "$Id: std.h,v 0.17 1995/11/27 14:51:26 ralf Exp $"; //======================================================================= int fastlog2 (int); const STD_ID = ID_USER+1288; // persistent objects' IDs const STD_ID_Options = STD_ID; enum startmenu_iID { iStartDemo=1, iContDemo, iSingle, iTablet, iOptions, iExit }; enum optionsmenu_iID { iPortnr=1, iStartStop=3, iDir, iDrive, iSPause, iLPause, iLeft, iRight=19, iUp=25, iDown=34, iSKey=44, iDauer=48, iRelayNr }; //---------------------------Options------------------------------------ class Options : public Streamable { public: i16 portnr; i16 dir, startstop, drive, pause, longpause; i16 R_N, R_W, R_E, R_S, R_x; Options () : portnr(1), dir(350), startstop(400), drive(50), pause(100), longpause(700), R_N(2), R_W(1), R_E(8), R_S(4), R_x(16) {} Options (StreamableInit) {} virtual void Load (Stream& S) { S >> portnr >> dir >> startstop >> drive >> pause >> longpause >> R_N >> R_W >> R_E >> R_S >> R_x; } virtual void Store (Stream& S) const { S.Seek(0); S << portnr << dir << startstop << drive << pause << longpause << R_N << R_W << R_E << R_S << R_x; } virtual u16 StreamableID () const { return STD_ID_Options; } static Streamable* Build () { return new Options; } }; //===============================Std===================================== class Std : public Program { public: Std(int, char**); ~Std(); int Run(); static BottomStatusLine* CreateStatusLine(); void StartDemo(); void ContDemo(); void Single(); void Tablet(); void Config(); private: Options opt_; FileStream optf_; }; //--------------------------ParallelPort-------------------------------- #ifdef LINUX class ParallelPort { public: ParallelPort (int portnr) { char dev[] = "/dev/lp0"; dev[7] += portnr; fd_ = open (dev, O_WRONLY); if (fd_<0) { perror(strerror(errno)); exit(1); } } ~ParallelPort() { close (fd_); } void operator << (char c) const { write (fd_, &c, 1); } private: int fd_; }; #endif #ifdef DOS32 class ParallelPort { public: ParallelPort (int portnr) { char dev[] = "prn"; // dev[3] += portnr; fd_ = open (dev, O_WRONLY); if (fd_<0) { perror(strerror(errno)); exit(1); } } ~ParallelPort() { close (fd_); } void operator << (char c) const { write (fd_, &c, 1); } private: int fd_; }; #endif //--------------------------------RI------------------------------------ const R_1 = 0x01; const R_2 = 0x02; const R_3 = 0x04; const R_4 = 0x08; const R_5 = 0x10; const R_6 = 0x20; const R_7 = 0x40; const R_8 = 0x80; const R_Pause = 0x1000; inline void wait_for (int ms) { usleep (1000*ms); } struct RISignal { int relais, ms; RISignal (int r, int t) : relais(r), ms(t) {} }; class RI // class to switch on individual relais on a relaisinterface // for a specific time. NOTE: Signals are handled serially. // If you want to change relais in parallel, you have to keep the // RI state in the class, write a timer... { public: RI (int portnr) : pp_(portnr) {} ~RI() {} void relais_on (char r) const { pp_ << r; } void relais_off () const { pp_ << 0; } friend const RI& operator<< (const RI& ri, RISignal t) { ri.relais_on (char(t.relais)); wait_for (t.ms); ri.relais_off (); return ri; } private: const ParallelPort pp_; }; //---------------------------------ST------------------------------------- enum TCommand { tcStartStop=0, tcDrive, tcMode, tcSW, tcS, tcSE, tcW, tcE, tcNW, tcN, tcNE }; enum SCommand { }; const portnr=1; class ST { public: ST (Options &, int); ~ST() {} friend ST& operator<< (ST&, TCommand); friend ST& operator<< (ST&, SCommand); private: const Options& opt_; const RI ri_; };estic-1.61.orig/spunk/samples/std/std.res0100644000176100001440000011243407031424717017725 0ustar debacleusersAnna~į¼Ż6P4 3Supertrans Demo @ŚpÄpÄpÄpSpupppeprptprpapnpsp pDpepmpopÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p³p³p pDpepmpop psptpaprptpepnp p p p p p p p p p³p³p pDpepmpop pfpoprptpspeptpzpepnp p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pEpipnpzpeplpapnpsptpepupeprpupnpgp p.p.p.p³p³p pTpapbplpeptptpsptpepupeprpupnpgp p.p.p.p p³p³p pOppptpipopnpepnp p.p.p.p p p p p p p p p p³p³pÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄp³p³p pBpepepnpdpepnp p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁpp%˙˙ Demo starten% Demo starten p%˙˙Demo fortsetzen% Demo fortsetzen u˙˙Einzelansteuerung ... Einzelansteuerung ... u˙˙Tablettsteuerung ... Tablettsteuerung ... u˙˙ Optionen ... Optionen ... u%˙˙Beenden% Beenden s%0u˙˙%ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄs%1u˙˙%ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 6P‘ DC 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpfpapdp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pDtaptpepipepnp p p p p p p p p p p p p p p p p p p pVteprpzpepipcphpnpipspspep p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6D Dateien`6V/Verzeichnisse2N1Name( 3ž`6é˙˙Pfad6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp p p p p p pBpepnpuptpzpeprpnpapmpep p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprptp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KBenutzer-ID Benutzername Passwort Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pItDp p p p p p p p p p p p p p p                       p³p³p pBpepnpuptpzpeprp-pNtapmpep p p                                 p³p³p pPtapspspwpoprptp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStipcphpeprphpepiptpsp-pEpbpepnpep p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/I  Benutzer-ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N 1Benutzer-Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPasswort "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSicherheits-Ebene0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprptp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp— ˙˙ Passwort: 6P <; šŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pBpepnpuptpzpeprp-pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”$˙˙ Benutzer-ID: $˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ī ōHilfe bernehmen Abbruch Ende Weiter ˇndern Drucken Grafik  Einfgen L”schen Auswahl Best„tigen Bewegen Login Logout Ende Zoom  Schliessen ™ffnen Gr”įe  Speichern  ~~ Auswahl  ~ÄŁ~ Auswahl  ~ Bild- Bild-~ Bl„ttern  ~~ Bewegen  ~Ctrl+~ Gr”įe Sind Sie sicher?dWirklich Ende?eˇnderungen verwerfen?fˇnderungen sichern?g @Ja|@Neinh @Nein|@Jai Fehler Č Information É Systemfehler Ź Best„tigen ŅAbbruch Ó Ignorieren Ō Wiederholen ÕEnde ÖEinen Moment bitte...×Ungltige Eingabe,Zu viele Nachkommastellen-"Wert ist zu klein (Minimum ist %g).!Wert ist zu groį (Maximum ist %g)/#Wert ist zu klein (Minimum ist %ld)0"Wert ist zu groį (Maximum ist %ld)1Leereingabe ist unzul„ssig2Keine Datei-Erweiterung erlaubt3Aus AnNein Ja‘Wert ist zu groįōWert ist zu kleinõFehlerhafte Eingabeö2%s: Sektion %s, %s nicht gefunden oder fehlerhaft.X*Fehler beim ™ffnen der Passwort-Datei^(%s)¼)Fehler beim Lesen der Passwort-Datei^(%s)½1Fehler beim Schreiben auf die Passwort-Datei^(%s)¾)Es muį eine Benutzer-ID angegeben werden!æ)Es muį ein Benutzername angegeben werden!Ą%Es muį ein Passwort angegeben werden!Į-Ein Benutzer mit dieser ID existiert bereits!Ā/Ungltige Benutzer-ID oder ungltiges Passwort!ĆSonntag Montag!Dienstag"Mittwoch# Donnerstag$Freitag%Samstag&So'Mo(Di)Mi*Do+Fr,Sa-Januar.Februar/M„rz0April1Mai2Juni3Juli4August5 September6Oktober7November8Dezember9Jan:Feb;M„r<Apr=Mai>Jun?Jul@AugASepBOktCNovDDezEKeine Hilfe verfgbar„ Keine Hilfe fr dieses Stichwort… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁCtrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+EscAlt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+Bild-v Ctrl+Pos1wAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+Bild-„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Pos1— Alt+Bild-™Alt+Ende Alt+Bild- Alt+Einfg¢Alt+Entf£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L EnterCtrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+EscAlt+Leertaste Ctrl+Einfg Shift+Einfg Ctrl+Entf Shift+Entf Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DPos1GHBild-IKMEndeOPBild-QEinfgREntfSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+t Ctrl+Endeu Ctrl+PgDnv Ctrl+Pos1wEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Pos1—Esc-PgUp™Esc-EndeEsc-PgDn Esc-Einfg¢Esc-Entf£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Verzeichnis 5Fehler %d: %süKein Fehler (OOPS!)żDatei oder Pfad nicht gefundenžNicht genug Speicher˙Zugriff verweigert Zu viele offene Files 9Nicht gengend Speicherplatz auf dem angesprochenen Ger„t %Tempor„rer Fehler - nochmal versuchen Ger„t/Datei ist in Benutzung Datei ist zu groį I/O Fehler Datei ist ein Verzeichnis Datei ist kein Verzeichnis Zu viele Links 'Operation nur mit Block Devices m”glich &Operation nur mit Char Devices m”glich Device existiert nicht 4Operation ist nur fr den Besitzer der Datei m”glich Broken Pipe Dateisystem ist readonly +Seek kann nicht auf Pipes ausgefhrt werden Prozess existiert nicht Ausfhrbare Datei ist busy Name ist zu lang Keine Locks verfgbar Verzeichnis ist nicht leer Datei nicht gefunden Pfad nicht gefunden Laufwerk ist ungltig 0Aktuelles Verzeichnis kann nicht gel”scht werden Datei existiert bereits 6P‘ DC 0 ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pPpaptphp p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pNtapmpep p p p p                                           p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p pFtiplpepsp p p p p p p p p p p p p p p p p p p p p pDtiprpepcptpoprpipepsp p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`6F!Files`6D  Directories2N1Name( 3ž`6é˙˙Path6PPO @ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp p p p p p p p p p pUpspeprp pNpapmpep p p p p p p p p p p p p p p p p p p p p p p p p pPpapspspwpoprpdp p p p p p p p p p p pLpepvpeplp p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³p³p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp`T˙˙KUser ID User Name Password Level6P A @ dŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pItDp p p p p p p p p p p p p p p p p p p                       p³p³p pUpspeprp pNtapmpep p p p p p p                                 p³p³p pPtapspspwpoprpdp p p p p p p p p p p p p p p p p p p p p p p p p                p³p³p pStepcpuprpiptpyp pLpepvpeplp p p p p p p p p p p p p p p p p p p p p p p p p p p 0      p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp”/IUser ID /˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/N1 User Name /#˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙”/PPassword "!/ ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙’/SSecurity Level0*)/ 6P 76 ´ŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pPpapspspwpoprpdp:p p p                p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp—˙˙ Password: 6P :9 ŲŚpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpæp³p pUpspeprp pIpDp:p p p                       p³pĄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpÄpŁp” ˙˙User ID:  ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ī ōHelpAccept Abort End Proceed Change Print  Graphics Insert Delete Select Confirm Move Login Logout Exit Zoom Close Open Resize Save  ~~ Select  ~ÄŁ~ Select  ~ PgDn PgUp~ Browse  ~~ Move  ~Ctrl-~ Resize Are you shure?d Really quit?eDiscard changes?fSave changes?g@Yes|@Noh@No|@Yesi Error Č Information É Fatal Error ŹConfirm ŅAbort ÓIgnore ŌRetry ÕEnd ÖOne moment please...×Invalid input,Too many trailing digits-"Value is too small (minimum is %g)."Value is too large (maximum is %g)/#Value is too small (minimum is %ld)0#Value is too large (maximum is %ld)1Input cannot be empty2No filename extension allowed3Off On NoYes‘Value is too largeōValue is too smallõInvalid inputö,%s: Section %s, key %s not found or invalid.X$Error opening the password file^(%s)¼$Error reading the password file^(%s)½'Error writing to the password file^(%s)¾The user id cannot be empty!æThe user name cannot be empty!ĄAn empty password is invalid!Į'A user with this ID does already exist!Ā$Invalid user id or invalid password!ĆSunday Monday!Tuesday" Wednesday#Thursday$Friday%Saturday&Sun'Mon(Tue)Wed*Thu+Fri,Sat-January.February/March0April1May2June3July4August5 September6October7November8December9Jan:Feb;Mar<Apr=May>Jun?Jul@AugASepBOctCNovDDecENo help available„No help on this topic… Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L ÄŁCtrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabAlt+QAlt+WAlt+EAlt+RAlt+TAlt+YAlt+UAlt+IAlt+OAlt+PAlt+AAlt+SAlt+D Alt+F!Alt+G"Alt+H#Alt+J$Alt+K%Alt+L&Alt+Z,Alt+X-Alt+C.Alt+V/Alt+B0Alt+N1Alt+M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gAlt+F1hAlt+F2iAlt+F3jAlt+F4kAlt+F5lAlt+F6mAlt+F7nAlt+F8oAlt+F9pAlt+F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewAlt+1xAlt+2yAlt+3zAlt+4{Alt+5|Alt+6}Alt+7~Alt+8Alt+9€Alt+0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Alt+F11‹Alt+F12Ctrl+¨Ctrl+‘Ctrl+Tab”Alt+Home—Alt+PgUp™Alt+EndAlt+PgDnAlt+Ins¢Alt+Del£Alt+Tab Alt+Ctrl+A° Alt+Ctrl+B± Alt+Ctrl+C² Alt+Ctrl+D³ Alt+Ctrl+E´ Alt+Ctrl+Fµ Alt+Ctrl+G¶ Alt+Ctrl+H· Alt+Ctrl+Iø Alt+Ctrl+J¹ Alt+Ctrl+Kŗ Alt+Ctrl+L» Alt+Ctrl+M¼ Alt+Ctrl+N½ Alt+Ctrl+O¾ Alt+Ctrl+Pæ Alt+Ctrl+QĄ Alt+Ctrl+RĮ Alt+Ctrl+SĀ Alt+Ctrl+TĆ Alt+Ctrl+UÄ Alt+Ctrl+VÅ Alt+Ctrl+WĘ Alt+Ctrl+XĒ Alt+Ctrl+YČ Alt+Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Ctrl+ACtrl+BCtrl+CCtrl+DCtrl+ECtrl+FCtrl+GCtrl+HTab Ctrl+J Ctrl+K Ctrl+L EnterCtrl+NCtrl+OCtrl+PCtrl+QCtrl+RCtrl+SCtrl+TCtrl+UCtrl+VCtrl+WCtrl+XCtrl+YCtrl+ZEscDelAlt+Esc Alt+SpaceCtrl+Ins Shift+InsCtrl+Del Shift+Del Shift+TabEsc-QEsc-WEsc-EEsc-REsc-TEsc-YEsc-UEsc-IEsc-OEsc-PEsc-AEsc-SEsc-D Esc-F!Esc-G"Esc-H#Esc-J$Esc-K%Esc-L&Esc-Z,Esc-X-Esc-C.Esc-V/Esc-B0Esc-N1Esc-M2F1;F2<F3=F4>F5?F6@F7AF8BF9CF10DHomeGHPgUpIKMEndOPPgDnQInsRDelSShift+F1TShift+F2UShift+F3VShift+F4WShift+F5XShift+F6YShift+F7ZShift+F8[Shift+F9\ Shift+F10]Ctrl+F1^Ctrl+F2_Ctrl+F3`Ctrl+F4aCtrl+F5bCtrl+F6cCtrl+F7dCtrl+F8eCtrl+F9fCtrl+F10gEsc-F1hEsc-F2iEsc-F3jEsc-F4kEsc-F5lEsc-F6mEsc-F7nEsc-F8oEsc-F9pEsc-F10qCtrl+sCtrl+tCtrl+Endu Ctrl+PgDnv Ctrl+HomewEsc-1xEsc-2yEsc-3zEsc-4{Esc-5|Esc-6}Esc-7~Esc-8Esc-9€Esc-0 Ctrl+PgUp„F11…F12† Shift+F11‡ Shift+F12Ctrl+F11‰Ctrl+F12Esc-F11‹Esc-F12Ctrl+¨Ctrl+‘Ctrl+Tab”Esc-Home—Esc-PgUp™Esc-EndEsc-PgDnEsc-Ins¢Esc-Del£Esc-Tab Esc-Ctrl+A° Esc-Ctrl+B± Esc-Ctrl+C² Esc-Ctrl+D³ Esc-Ctrl+E´ Esc-Ctrl+Fµ Esc-Ctrl+G¶ Esc-Ctrl+H· Esc-Ctrl+Iø Esc-Ctrl+J¹ Esc-Ctrl+Kŗ Esc-Ctrl+L» Esc-Ctrl+M¼ Esc-Ctrl+N½ Esc-Ctrl+O¾ Esc-Ctrl+Pæ Esc-Ctrl+QĄ Esc-Ctrl+RĮ Esc-Ctrl+SĀ Esc-Ctrl+TĆ Esc-Ctrl+UÄ Esc-Ctrl+VÅ Esc-Ctrl+WĘ Esc-Ctrl+XĒ Esc-Ctrl+YČ Esc-Ctrl+ZÉEsc-EscŹCtrl+Q-SĖCtrl+Q-DĢCtrl+Q-RĶCtrl+Q-CĪCtrl+Q-EĻCtrl+Q-XŠ Bytes 4 Directory 5 Error %d: %süNo error (OOPS!)żFile or path not foundžNot enough memory˙Access denied Too many open files No space left on device Try again Device or file is busy File is too large I/O error File is a directory File is no directory Too many links Block device required Char device required Device does not exist !You are not the owner of the file Broken pipe File system is readonly Cannot seek on pipes Process does not exist Text file is busy Name is too long No locks available Directory is not empty File not found Path not found Drive is invalid Cannot remove current directory File exists ° $,.-:,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° $,./:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° .,-:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAA¸€EEEIIIA¸E’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨ˇ†‘‘“”•–—™›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’OOOUUOU›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° BEF.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙!"#$%&˙()*+,˙./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU›¯˛AIOUNN¦§Ø©Ŗ«¬­®Æ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüż˙˙° F ,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° ˛.,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€UEAAAA€EEEIIIAAEAAOOOUUYOU$$$$$AIOU¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° L..,/:;  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€EAˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~CUEAAAACEEEIIIAAEAAOOOUUYOU$$$$$AIOUNN¦§?©Ŗ«¬!""°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąSāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙° Fr'...,  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€AˇA¸€EEEIIIˇ¸’’O™OUUY™›¯˛AIOU¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~‡‚„…†‡‰‹¨„†‚‘‘“”•–—”›¯˛ ¢£¤¤¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙ČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚ¨ŪÜŻŽßąįāćä<=>?@ABCDEFGHIJ !"#$%&'()KLMNOPQ RST4U3 VWX6Y estic-1.61.orig/spunk/svr4src/0040755000176100001440000000000007061535305015565 5ustar debacleusersestic-1.61.orig/spunk/svr4src/sercom.cc0100644000176100001440000003777407031424717017404 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // SVR4 version. #include #include #include #include #include #include #include #include #include "../check.h" #include "../sercom.h" #include "../filepath.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // internal used data struct _ComData { int Handle; // Port handle unsigned RXCount; // characters in receive queue unsigned TXCount; // characters in transmit queue termios StartupSettings;// Device settings on startup termios CurrentSettings;// Current device settings ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ static void SetReadTimeout (_ComData* ComData, int Min, int Time) { if (ComData->CurrentSettings.c_cc [VMIN] != Min || ComData->CurrentSettings.c_cc [VTIME] != Time) { // Need to set the new values ComData->CurrentSettings.c_cc [VMIN] = Min; ComData->CurrentSettings.c_cc [VTIME] = Time; ZCHECK (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings)); } } /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (4096), // ## ??? TXBufSize (4096), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen()) { Close(); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // Create an internally used data structure ComData = new _ComData; // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); // setting up ComData ComData->Handle = -1; // Port not open ComData->RXCount = 0; ComData->TXCount = 0; } void ComPort::SetBufferSize (u16 /*aRXBufSize*/, u16 /*aTXBufSize*/) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Otherwise this function is ignored under FreeBSD we could not set any // buffer sizes (no harm done anyway) } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // First, check if the port contains a directory. If not, add /dev String Dir, Name; FSplit (PortName, Dir, Name); if (Dir.IsEmpty ()) { PortName.Ins (0, "/dev/"); } // Open the port ComData->Handle = open (PortName.GetStr (), O_RDWR | O_NONBLOCK); if (ComData->Handle == -1) { // Got an error, return the error code return errno; } // Device must be a tty if (!isatty (ComData->Handle)) { // Error, close and exit Close (); return ENOTTY; } // Remember the current settings tcgetattr (ComData->Handle, &ComData->StartupSettings); // Set up the new settings ComData->CurrentSettings = ComData->StartupSettings; // Set up input flags tcflag_t iflag = IGNBRK | IGNPAR; if (Databits == 7) { iflag |= ISTRIP; // Strip bit 7 } if (XonXoff == 'E') { iflag |= IXON | IXOFF; // Enable XON/XOFF protocol } ComData->CurrentSettings.c_iflag = iflag; // Set up output flags tcflag_t oflag = 0; ComData->CurrentSettings.c_oflag = oflag; // Set up control flags tcflag_t cflag = CREAD | HUPCL; switch (Databits) { case 5: cflag |= CS5; break; case 6: cflag |= CS6; break; case 7: cflag |= CS7; break; case 8: cflag |= CS8; break; default: FAIL ("ComPort::Init: Unsupported databits value"); } switch (Parity) { case 'N': break; case 'E': cflag |= PARENB; break; case 'O': cflag |= PARENB | PARODD; break; default: FAIL ("ComPort::Init: Unsupported parity setting"); } switch (Stopbits) { case 1: break; case 2: cflag |= CSTOPB; break; default: FAIL ("ComPort::Init: Unsupported stopbits value"); } switch (Connection) { case 'D': cflag |= CLOCAL; break; default: FAIL ("ComPort::Init: Unsupported connection setting"); } ComData->CurrentSettings.c_cflag = cflag; // Set up local flags tcflag_t lflag = 0; ComData->CurrentSettings.c_lflag = lflag; // Set XON/XOFF to Ctrl-S/Ctrl-Q ComData->CurrentSettings.c_cc [VSTART] = 0x11; ComData->CurrentSettings.c_cc [VSTOP] = 0x13; // Set the baudrate speed_t Baud = 0; switch (Baudrate) { case 50: Baud = B50; break; case 75: Baud = B75; break; case 110: Baud = B110; break; case 134: Baud = B134; break; case 150: Baud = B150; break; case 200: Baud = B200; break; case 300: Baud = B300; break; case 600: Baud = B600; break; case 1200: Baud = B1200; break; case 2400: Baud = B2400; break; case 4800: Baud = B4800; break; case 9600: Baud = B9600; break; case 19200: Baud = B19200; break; case 38400: Baud = B38400; break; default: FAIL ("ComPort::Init: Unsupported baudrate value"); } ComData->CurrentSettings.c_cflag |= Baud; cfsetispeed (&ComData->CurrentSettings, Baud); cfsetospeed (&ComData->CurrentSettings, Baud); // Set timeouts ComData->CurrentSettings.c_cc [VMIN] = 1; ComData->CurrentSettings.c_cc [VTIME] = int (RXTimeout / 0.1); // Actually set up the device if (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings) < 0) { // Could not set int Result = errno; Close (); return Result; } // Reset nonblocking mode int Flags = fcntl (ComData->Handle, F_GETFL, 0); if (Flags < 0) { // Error int Result = errno; Close (); return Result; } Flags &= ~O_NONBLOCK; if (fcntl (ComData->Handle, F_SETFL, Flags) < 0) { // Error int Result = errno; Close (); return Result; } // When we set cflags == CLOCAL on a direct connection, the RTS and DTR // lines will become active. This is not compatible to the other sercom // modules, so change it. Also make DTR low if hardware handshake is // enabled. DTROff (); if (Connection == 'D') { RTSOff (); } // Success return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open PRECONDITION (IsOpen ()); // Close the device close (ComData->Handle); // reset handle ComData->Handle = -1; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->Handle != -1; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout > 0 && aRXTimeout < 0.1) { aRXTimeout = 0.1; } // Remember the timeout RXTimeout = aRXTimeout; // Set the timeout SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; } void ComPort::DTROn () // Make the DTR line active { // Port must be open PRECONDITION (IsOpen ()); // Set DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::DTROff () // Make the DTR line inactive { // Port must be open PRECONDITION (IsOpen ()); // Clear DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } void ComPort::RTSOn () // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Set RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::RTSOff () // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Clear RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer, or just true 1 if the // exact amount of chars in the buffer cannot be determined and the value // is at least one. { // Port must be open PRECONDITION (IsOpen ()); int Res; while (ioctl (ComData->Handle, I_NREAD, &Res) > 0) { if (Res) { return Res; } struct strbuf cb, db; cb.maxlen = 1; cb.buf = (char*) &Res; db.maxlen = 1; db.buf = ((char*) &Res) + 1; int flag = 0; getmsg (ComData->Handle, &cb, &db, &flag); } return 0; } void ComPort::RXClear () // Clear the receive buffer { // Port must be open PRECONDITION (IsOpen ()); CHECK (tcflush (ComData->Handle, TCIFLUSH) == 0); } void ComPort::TXClear () // Clear the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); CHECK (tcflush (ComData->Handle, TCOFLUSH) == 0); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer. The function // may return the exact free space or just 1, if at least one character // can be placed into the send buffer (meaning, the Send function will // not block). { // Port must be open PRECONDITION (IsOpen ()); return ioctl (ComData->Handle, I_CANPUT,0) == 1; } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { // Port must be open PRECONDITION (IsOpen ()); // Set no timeout mode SetReadTimeout (ComData, 0, 0); // read one character unsigned char B; int ReadCount; do { ReadCount = read (ComData->Handle, &B, 1); } while (ReadCount != 1); // return character return B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { int WriteCount; do { WriteCount = write (ComData->Handle, &B, 1); } while (WriteCount != 1); return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { // Port must be open PRECONDITION (IsOpen ()); // Set up the device for timeout read SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); unsigned char B; int ReadCount = read (ComData->Handle, &B, 1); // Return the character read or -1 on timeout return ReadCount == 1 ? B : -1; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); if (ioctl (ComData->Handle, I_CANPUT, 0) == 1) { // Descriptor is ready for writing write (ComData->Handle, &B, 1); return B; } else { // Timeout or signal. Return an timeout error code when a signal // occurs ComData->ErrorCounter [ceTXOverflow]++; return -1; } } void ComPort::Break (double /*Duration*/) // Send a break with the given time in seconds { // Port must be open PRECONDITION (IsOpen ()); // Ignore Duration as values != zero have undefined behavior ZCHECK (tcsendbreak (ComData->Handle, 0)); } #if 0 // gcc 2.5.8 is not able to compile this (bug using the typedef) // Leave it out and hope no one will notice... ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } #endif unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { // Port must be open PRECONDITION (IsOpen ()); // Get the modem lines int Lines; CHECK (ioctl (ComData->Handle, TIOCMGET, &Lines) == 0); // Convert to sercom format, ignore the "delta" lines unsigned Status = 0; if (Lines & TIOCM_CTS) Status |= csCTS; if (Lines & TIOCM_DSR) Status |= csDSR; if (Lines & TIOCM_RNG) Status |= csRI; if (Lines & TIOCM_CAR) Status |= csCD; // Return the result return Status; } estic-1.61.orig/spunk/unixsrc/0040755000176100001440000000000007061535305015652 5ustar debacleusersestic-1.61.orig/spunk/unixsrc/delay.cc0100644000176100001440000000510707031424717017260 0ustar debacleusers/*****************************************************************************/ /* */ /* DELAY.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // This is a somewhat more generic "delay" module that should work on more // than one unix like OS. // Define the symbol DONT_HAS_USLEEP if usleep() is not available. The code // will use a implementation based on select() instead. If you don't have // select(), you are kind of stuck... #include #include #include "../progutil.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ #if defined (DONT_HAS_USLEEP) // Use an implementation of usleep based on select. This function is taken // from "Advanced Programming in the Unix Environment" by W. Richard Stevens. // This function may return earlier if the select function is interrupted - // this is ignored for simplicity. static void usleep (u32 usecs) { // Set the timeout timeval Timeout; Timeout.tv_usec = usecs % 1000000; Timeout.tv_sec = usecs / 1000000; // Wait... select (0, NULL, NULL, NULL, &Timeout); } #endif u32 Delay (u32 ms) // System dependent delay function that waits _at_least_ the given time in // milliseconds. The function is free to choose a longer time, if it is not // possible, to wait exactly the given time. This is especially true when // ms exceeds 100, in this case App->Idle () is called in addition to waiting, // so the _real_ time that is gone may be unpredictable. // An argument of zero has a special meaning: The function tries to give up // the current time slice, calls App->Idle () and returns after that. // // The function returns the real time passed or just ms. { const ChunkSize = 256; // Check the argument... if (ms <= ChunkSize) { // Wait some time usleep (ms * 1000); // Call the applications idle function Idle (); } else { u32 Counter = ms; while (Counter) { unsigned TimeToWait = Counter >= ChunkSize ? ChunkSize : Counter; // Recursive call to Delay... u32 WaitTime = Delay (TimeToWait); if (WaitTime > Counter) { Counter = 0; } else { Counter -= WaitTime; } } } // Return the argument return ms; } estic-1.61.orig/spunk/unixsrc/filesys.cc0100644000176100001440000001167607031424717017650 0ustar debacleusers/*****************************************************************************/ /* */ /* FILESYS.CC */ /* */ /* (C) 1995 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // // $Id$ // // $Log$ // // // This is a generic unix file system module. It assumes file names and // paths are 255 chars long. #include #include #include "../check.h" #include "../str.h" #include "../filepath.h" #include "../filesys.h" /*****************************************************************************/ /* File system & OS dependent constants */ /*****************************************************************************/ extern const char FileSysPathSep = '/'; // Path separator extern const char FileSysListSep = ':'; // Path list separator extern const FileSysMaxPath = 255; // Maximum path length extern const FileSysMaxDir = 255; // Maximum directory length extern const FileSysMaxName = 255; // Maximum file name length extern const FileSysMaxExt = 255; // Maximum extension length (including the dot) /*****************************************************************************/ /* Code */ /*****************************************************************************/ int FileSysGetDrive () // Return the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned. // This function may be called only if the system supports drives! { FAIL ("Call to FileSysGetDrive on system without drives"); return 0; } int FileSysSetDrive (unsigned /*Drive*/) // Set the current drive. 1 = A:, 2 = B: and so on. On error, -1 is returned, // otherwise zero. This function may be called only if the system supports // drives! { FAIL ("Call to FileSysSetDrive on system without drives"); return 0; } int FileSysExtractDrive (const String& /*Path*/) // Return the drive spec from the given path. If none given or if the os // does not support drives (*nix), the return value will be zero (== current). { // *nix does not support drives return 0; } void FileSysGetInfo (FileSysInfo& Info, int /*Drive*/) // Return detailed information regarding the file system on the given drive. // See declaration of struct FileSysInfo above. { // Use a generic description, even if this is not correct... strcpy (Info.fsName, "UNKNOWN"); Info.fsMaxPath = FileSysMaxPath; Info.fsMaxDir = FileSysMaxDir; Info.fsMaxName = FileSysMaxName; Info.fsMaxExt = FileSysMaxExt; Info.fsPreservesCase = 1; Info.fsIgnoresCase = 0; getcwd (Info.fsCurDir, sizeof (Info.fsCurDir)); } int FileSysPreservesCase (int /*Drive*/) // Return 1 if the file system on the given drive preserves the case in // filenames { // *nix always(?) preserves the case of names return 1; } int FileSysIgnoresCase (int /*Drive*/) // Return 1 if the file system on the given drive ignores the case in file // names. Beware: This is not the same as FileSysPreservesCase! The latter // will return true if the file system preserves case in file names given, // but when searching for files, the case can be ignored (this is the case // with OS/2's HPFS file systems). { // *nix never(?) ignores case in file names return 0; } int FileSysValidChar (const char C) // Return 1 if the given char is a valid part of a directory or file name. // Because the function has no information about the file system, it assumes // "worst case" and rejects every character that may be illegal on any of the // supported file systems. { // Invald chars static char InvalidChars [] = " <>|=:\"\\[]"; // Characters below and including the space are invalid if (C <= ' ') { return 0; } return strchr (InvalidChars, C) == NULL; } int FileSysValidName (const String& Path) // Return 1 if the given path name consists of valid chars for the given // file system. Beware: This function does not check if the path exists! { for (int I = 0; I < Path.Len (); I++) { if (FileSysValidChar (Path [I]) == 0) { return 0; } } return 1; } String FileSysCurrentDir (int IncludeDrive, int /* Drive */) // Return the current directory. If IncludeDrive is true, the drive letter is // included in the current directory. The default is to include the drive // letter on systems that support drives. If the given drive is invalid, an // empty string is returned. // The returned path includes a trailing path separator. { // *nix does not support drives, so a request to include the drive // letter is invalid PRECONDITION (IncludeDrive == 0); // Return the current working directory char Buf [1024]; if (getcwd (Buf, sizeof (Buf)) == NULL) { // OOPS, working dir is not readable return ""; } else { String Dir (Buf); AddPathSep (Dir); return Dir; } } estic-1.61.orig/spunk/unixsrc/kbd.cc0100644000176100001440000004750607031424720016725 0ustar debacleusers/*****************************************************************************/ /* */ /* KBD.CC */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #ifdef SVR4 # include typedef struct termio SGTTY; typedef unsigned long chtype; # include #else # include #endif #include #include #include "../machine.h" #include "../msgid.h" #include "../object.h" #include "../stack.h" #include "../charset.h" #include "../environ.h" #include "../keymap.h" #include "../program.h" #include "../kbd.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // An instance of class KeyMapper to map char sequences to keys static KeyMapper Mapper; // A charset containing the available extended keys static CharSet AvailExtKeys; // An array for mapping extended to virtual keys const VirtualMapSize = 50; struct { Key EK; Key VK; } VirtualMap [VirtualMapSize]; static unsigned VirtualMapCount = 0; // Terminal settings at startup static termios StartupSettings; // Translation table for the ISO8859-1 charset to the IBM codepage 437 unsigned char TT_ISO_8859_1 [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 8 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 9 32,173,155,156, 32,157, 32, 32, 32, 32,166,174,170, 32, 32, 32, // A 248,241,253, 32, 32,230, 32,249, 32, 32,167,175,172, 32, 32,168, // B 32, 32, 32, 32,142,143,146,128, 32,144, 32, 32, 32, 32, 32, 32, // C 32,165, 32, 32, 32, 32,153, 32, 32, 32, 32, 32,154, 32, 32,225, // D 133,160,131, 32,132,134,145,135,138,130,136,137,141,161,140,139, // E 32,164,149,162,147, 32,148,246, 32,151,163, 32,129, 32,176,152 // F }; unsigned char TT_NOP [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, // 6 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 7 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static int KbdCharAvail () // Use select() to check for characters { // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // File descriptor is 0 (stdin) fd_set Desc; FD_ZERO (&Desc); FD_SET (0, &Desc); // Check input status return select (1, &Desc, NULL, NULL, &Timeout); } static void KbdInit () // Remember the current keyboard settings, then switch to raw mode { // Get current settings tcgetattr (0, &StartupSettings); // switch to raw mode termios Settings = StartupSettings; Settings.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IXANY | IXON | IXOFF | INPCK | ISTRIP); Settings.c_iflag |= (BRKINT | IGNPAR); Settings.c_oflag &= ~OPOST; Settings.c_lflag &= ~(ECHONL | NOFLSH | ICANON | ISIG | ECHO); Settings.c_cflag |= CREAD; Settings.c_cc[VTIME] = 1; // wait 100 ms for keys Settings.c_cc[VMIN] = 0; // return if timeout or keys available tcsetattr (0, TCSADRAIN, &Settings); } static void KbdExit () // Reset the keyboard to the startup state { // Reset keyboard settings tcsetattr (0, TCSADRAIN, &StartupSettings); } static char* KbdGetCap (const char* Cap) // Get a capability from the termcap file { static char CapBuf [128]; char* CapPtr = CapBuf; return tgetstr (Cap, &CapPtr); } static void KbdAddToMap (const char* S, Key K) // Add the given string to the mapper. If K is an extended key, add it to // the map of available extended keys. { Mapper.Add (S, K); if (S && IsExtendedKey (K)) { AvailExtKeys += (K & 0xFF); } } static void KbdAddCapToMap (const char* Cap, Key K) // Search the termcap entry for the capability Cap and add it to the Mapper // using the key K. { KbdAddToMap (KbdGetCap (Cap), K); } static int KbdHasKey (Key K) // Return true if the given extended(!) key is available on the keyboard { return AvailExtKeys [K & 0xFF] != 0; } static void KbdAddVMap (Key VK, Key EK) // Add the mapping to the virtual key map { // Check for overflow if (VirtualMapCount >= VirtualMapSize) { // Overflow! FAIL ("KbdAddVirtualMap: Buffer overflow!"); } // Add the mapping VirtualMap [VirtualMapCount].EK = EK; VirtualMap [VirtualMapCount].VK = VK; VirtualMapCount++; } static void KbdAddVMap (Key VK, Key MainKey, Key AltKey) // If MainKey is available on the keyboard, add a mapping MainKey --> VK. In // any case, add a mapping AltKey --> VK. Because the latter will be added // later, a search for a virtual key first finds MainKey as the equivalent // extended key. If there is no mapping for MainKey, AltKey is found. { // Conditionally add VK --> MainKey if (KbdHasKey (MainKey)) { // Key exists, add a mapping KbdAddVMap (VK, MainKey); } // Always add VK --> AltKey KbdAddVMap (VK, AltKey); } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (int I = 0; I < VirtualMapCount; I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* Class Keyboard */ /*****************************************************************************/ Key Keyboard::RawKey () { // Not used return (Key) kbNoKey; } Keyboard::Keyboard (): Console (0), TransTable (new unsigned char [256]) { // Switch the keyboard into raw mode KbdInit (); // Check out the LC_CTYPE environment variable and assign the correct // translation table. There are only two possibilities until now, so // don't bother. switch (GetEnvVal ("LC_CTYPE", String ("0^NONE|1^ISO_8859_1|"))) { case 1: // ISO 8859-1 memcpy (TransTable, TT_ISO_8859_1, 256); break; default: // use a 1:1 mapping memcpy (TransTable, TT_NOP, 256); } // The termcap entry has been read before. Read in some key translations // and add them to the mapper // Function keys KbdAddCapToMap ("k1", kbF1); KbdAddCapToMap ("k2", kbF2); KbdAddCapToMap ("k3", kbF3); KbdAddCapToMap ("k4", kbF4); KbdAddCapToMap ("k5", kbF5); KbdAddCapToMap ("k6", kbF6); KbdAddCapToMap ("k7", kbF7); KbdAddCapToMap ("k8", kbF8); KbdAddCapToMap ("k9", kbF9); KbdAddCapToMap ("k0", kbF10); // Cursor keys needed KbdAddCapToMap ("kl", kbLeft); KbdAddCapToMap ("kr", kbRight); KbdAddCapToMap ("kd", kbDown); KbdAddCapToMap ("ku", kbUp); // Page up/down, home, end etc. KbdAddCapToMap ("kN", kbPgDn); KbdAddCapToMap ("kP", kbPgUp); KbdAddCapToMap ("kh", kbHome); KbdAddCapToMap ("kH", kbEnd); KbdAddCapToMap ("kD", kbDel); KbdAddCapToMap ("kI", kbIns); // Add the meta keys and other sequences to the mapper KbdAddToMap ("\033a", kbMetaA); KbdAddToMap ("\033b", kbMetaB); KbdAddToMap ("\033c", kbMetaC); KbdAddToMap ("\033d", kbMetaD); KbdAddToMap ("\033e", kbMetaE); KbdAddToMap ("\033f", kbMetaF); KbdAddToMap ("\033g", kbMetaG); KbdAddToMap ("\033h", kbMetaH); KbdAddToMap ("\033i", kbMetaI); KbdAddToMap ("\033j", kbMetaJ); KbdAddToMap ("\033k", kbMetaK); KbdAddToMap ("\033l", kbMetaL); KbdAddToMap ("\033m", kbMetaM); KbdAddToMap ("\033n", kbMetaN); KbdAddToMap ("\033o", kbMetaO); KbdAddToMap ("\033p", kbMetaP); KbdAddToMap ("\033q", kbMetaQ); KbdAddToMap ("\033r", kbMetaR); KbdAddToMap ("\033s", kbMetaS); KbdAddToMap ("\033t", kbMetaT); KbdAddToMap ("\033u", kbMetaU); KbdAddToMap ("\033v", kbMetaV); KbdAddToMap ("\033w", kbMetaW); KbdAddToMap ("\033x", kbMetaX); KbdAddToMap ("\033y", kbMetaY); KbdAddToMap ("\033z", kbMetaZ); KbdAddToMap ("\033""0", kbMeta0); KbdAddToMap ("\033""1", kbMeta1); KbdAddToMap ("\033""2", kbMeta2); KbdAddToMap ("\033""3", kbMeta3); KbdAddToMap ("\033""4", kbMeta4); KbdAddToMap ("\033""5", kbMeta5); KbdAddToMap ("\033""6", kbMeta6); KbdAddToMap ("\033""7", kbMeta7); KbdAddToMap ("\033""8", kbMeta8); KbdAddToMap ("\033""9", kbMeta9); KbdAddToMap ("\033\x01", kbEscCtrlA); KbdAddToMap ("\033\x02", kbEscCtrlB); KbdAddToMap ("\033\x03", kbEscCtrlC); KbdAddToMap ("\033\x04", kbEscCtrlD); KbdAddToMap ("\033\x05", kbEscCtrlE); KbdAddToMap ("\033\x06", kbEscCtrlF); KbdAddToMap ("\033\x07", kbEscCtrlG); KbdAddToMap ("\033\x08", kbEscCtrlH); KbdAddToMap ("\033\x09", kbEscCtrlI); KbdAddToMap ("\033\x0A", kbEscCtrlJ); KbdAddToMap ("\033\x0B", kbEscCtrlK); KbdAddToMap ("\033\x0C", kbEscCtrlL); KbdAddToMap ("\033\x0D", kbEscCtrlM); KbdAddToMap ("\033\x0E", kbEscCtrlN); KbdAddToMap ("\033\x0F", kbEscCtrlO); KbdAddToMap ("\033\x10", kbEscCtrlP); KbdAddToMap ("\033\x11", kbEscCtrlQ); KbdAddToMap ("\033\x12", kbEscCtrlR); KbdAddToMap ("\033\x13", kbEscCtrlS); KbdAddToMap ("\033\x14", kbEscCtrlT); KbdAddToMap ("\033\x15", kbEscCtrlU); KbdAddToMap ("\033\x16", kbEscCtrlV); KbdAddToMap ("\033\x17", kbEscCtrlW); KbdAddToMap ("\033\x18", kbEscCtrlX); KbdAddToMap ("\033\x19", kbEscCtrlY); KbdAddToMap ("\033\x1A", kbEscCtrlZ); KbdAddToMap ("\033\033", kbEscEsc); KbdAddToMap ("\x11\x13", kbCtrlQS); KbdAddToMap ("\x11""s", kbCtrlQS); KbdAddToMap ("\x11""S", kbCtrlQS); KbdAddToMap ("\x11\x04", kbCtrlQD); KbdAddToMap ("\x11""d", kbCtrlQD); KbdAddToMap ("\x11""D", kbCtrlQD); KbdAddToMap ("\x11\x12", kbCtrlQR); KbdAddToMap ("\x11""r", kbCtrlQR); KbdAddToMap ("\x11""E", kbCtrlQR); KbdAddToMap ("\x11\x03", kbCtrlQC); KbdAddToMap ("\x11""c", kbCtrlQC); KbdAddToMap ("\x11""C", kbCtrlQC); KbdAddToMap ("\x11\x05", kbCtrlQC); KbdAddToMap ("\x11""e", kbCtrlQC); KbdAddToMap ("\x11""E", kbCtrlQC); KbdAddToMap ("\x11\x18", kbCtrlQX); KbdAddToMap ("\x11""x", kbCtrlQX); KbdAddToMap ("\x11""X", kbCtrlQX); // Now create the mappings extended --> virtual (primary/secondary) KbdAddVMap (vkHelp, kbF1, kbEscCtrlH); KbdAddVMap (vkPgDn, kbPgDn, kbCtrlC); KbdAddVMap (vkPgUp, kbPgUp, kbCtrlR); KbdAddVMap (vkUp, kbUp, kbCtrlE); KbdAddVMap (vkDown, kbDown, kbCtrlX); KbdAddVMap (vkLeft, kbLeft, kbCtrlS); KbdAddVMap (vkRight, kbRight, kbCtrlD); KbdAddVMap (vkIns, kbIns, kbCtrlV); KbdAddVMap (vkDel, kbDel, kbCtrlG); KbdAddVMap (vkHome, kbHome, kbCtrlQS); KbdAddVMap (vkEnd, kbEnd, kbCtrlQD); KbdAddVMap (vkZoom, kbF5, kbEscCtrlZ); KbdAddVMap (vkClose, kbMetaF3, kbEscCtrlC); KbdAddVMap (vkOpen, kbF3, kbEscCtrlO); KbdAddVMap (vkSave, kbF2, kbEscCtrlS); KbdAddVMap (vkAccept, kbF10, kbEscCtrlA); // Keys that have no secondary form under linux KbdAddVMap (vkCtrlUp, kbCtrlW); KbdAddVMap (vkCtrlDown, kbCtrlZ); KbdAddVMap (vkCtrlLeft, kbCtrlA); KbdAddVMap (vkCtrlRight, kbCtrlF); KbdAddVMap (vkCtrlPgUp, kbCtrlQR); KbdAddVMap (vkCtrlPgDn, kbCtrlQC); KbdAddVMap (vkCtrlHome, kbCtrlQE); KbdAddVMap (vkCtrlEnd, kbCtrlQX); KbdAddVMap (vkResize, kbEscCtrlR); KbdAddVMap (vkQuit, kbMetaX); // Handle the abort key separate KbdAddVMap (vkAbort, IsConsole () ? kbEsc : kbEscEsc); // Map the character that c_cc[VERASE] sends to backspace (bug? // is c_cc signed?) if (StartupSettings.c_cc [VERASE] > 0 && StartupSettings.c_cc [VERASE] <= 256) { TransTable [StartupSettings.c_cc [VERASE]] = (unsigned char) kbBack; } else { // It seems that the setting is invalid, check the termcap database // for a kb entry. If the entry is only one char, translate it via // the translation table, otherwise use the mapper char* BS = KbdGetCap ("kb"); if (BS) { if (strlen (BS) == 1) { // Just one char TransTable [(unsigned char) (*BS)] = (unsigned char) kbBack; } else { // A sequence... KbdAddToMap (BS, kbBack); } } } } Keyboard::~Keyboard () { // Reset the keyboard state KbdExit (); // Delete the translation table delete [] TransTable; } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { static int BufFill = 0; static unsigned char Buf [64] = ""; // Not the console. If we have keys left in the buffer, try to find a // match. If we have a partial match, read more chars, until we get // a full or no match. char SBuf [sizeof (Buf)]; int SCount = 1; while (1) { while (SCount <= BufFill) { // Add the next char from Buf to SBuf, add the trailing zero SBuf [SCount-1] = Buf [SCount-1]; SBuf [SCount] = '\0'; // Now search for this portion of Buf int Index; Key K; switch (Mapper.Find (SBuf, Index)) { case 0: // No match. Return the translated equivalent of the // first char in Buf, then delete it from Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; case 1: // Partial match. Increase the length of the sequence, // we search for. If the length succeeds some arbitary // limit, handle it like no match. if (SCount < 16) { SCount++; } else { // Suspicious... Return the translated equivalent // of the first char in Buf, then delete it from // Buf. K = KbdMapExtended (Translate (Buf [0])); memmove (&Buf [0], &Buf [1], BufFill); BufFill--; // One char less KeyBuf.Put (K); return; } break; case 2: // Full match. Delete the sequence from the buffer. memmove (&Buf [0], &Buf [SCount], BufFill - SCount + 1); BufFill -= SCount; K = KbdMapExtended (Mapper [Index]->GetKey ()); KeyBuf.Put (K); return; } } // If we get here, the buffer is exhausted and we still have a // partial match (or the buffer has been empty on startup). // If we should read without a wait, check if there are characters // waiting. If not, don't do a blocking read but return without // doing anything. if (Wait == 0 && KbdCharAvail () == 0) { // No chars waiting return; } // Before trying to read more chars, check for a buffer overflow // (this should not happen, but who knows...) if (SCount >= sizeof (Buf)) { FAIL ("Keyboard::GetMappedKey: Buffer overflow"); } // Now read in a new chunk of chars. int Count; do { Count = read (0, &Buf [BufFill], sizeof (Buf) - BufFill - 1); if (Count == 0) { // Timeout waiting for a key, allow some idle processing App->Idle (); } } while (Count <= 0); BufFill += Count; Buf [BufFill] = '\0'; } } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } return App->LoadMsg (MSGBASE_KBD + 0x200 + K); } estic-1.61.orig/spunk/unixsrc/nlsinit.cc0100644000176100001440000001331407031424720017633 0ustar debacleusers/*****************************************************************************/ /* */ /* NLSINIT.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "../check.h" #include "../environ.h" #include "../national.h" /*****************************************************************************/ /* Types and data */ /*****************************************************************************/ // Translation table from the input character set to the internal used // character set. Under linux, the only supported character set is ISO8859-1. // This may change in a future version. static _NLSTransTable InputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xAD, 0x9B, 0x9C, 0x20, 0x9D, 0x20, 0x20, 0x20, 0x20, 0xA6, 0xAE, 0xAA, 0x20, 0x20, 0x20, 0xF8, 0xF1, 0xFD, 0x20, 0x20, 0xE6, 0x20, 0xF9, 0x20, 0x20, 0xA7, 0xAF, 0xAC, 0x20, 0x20, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x8E, 0x8F, 0x92, 0x80, 0x20, 0x90, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xA5, 0x20, 0x20, 0x20, 0x20, 0x99, 0x20, 0x20, 0x20, 0x20, 0x20, 0x9A, 0x20, 0x20, 0xE1, 0x85, 0xA0, 0x83, 0x20, 0x84, 0x86, 0x91, 0x87, 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, 0x20, 0xA4, 0x95, 0xA2, 0x93, 0x20, 0x94, 0xF6, 0x20, 0x97, 0xA3, 0x20, 0x81, 0x20, 0xB0, 0x98 }; // Translation table from the internal used character set to the output // character set. Under linux, the only supported character set is ISO8859-1. // This may change in a future version. static _NLSTransTable OutputMap = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFC, 0xF9, 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x50, 0x66, 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, 0xBF, 0x2D, 0xAC, 0xC6, 0xBC, 0xA1, 0xAB, 0xBB, 0xFE, 0xFE, 0xFE, 0x7C, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x7C, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2D, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2D, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x61, 0xDF, 0x63, 0x70, 0x5A, 0x73, 0xB5, 0x74, 0x70, 0x54, 0x4F, 0x64, 0x38, 0x30, 0x65, 0x55, 0x3D, 0xB1, 0x3E, 0x3C, 0x66, 0x4A, 0xF7, 0x7E, 0xB0, 0xB7, 0xB7, 0x2F, 0x6E, 0xB2, 0xFE, 0xFF }; // External references to above tables const _NLSTransTable& NLSInputMap = InputMap; const _NLSTransTable& NLSOutputMap = OutputMap; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void NLSInit () // Sets up the data for the NLS. This function has to be called before any call // to another function in this module! { // In *nix, there's no system default country information available // (or, maybe, but I don't know!) // Use USA or the country in SPUNK_COUNTRY NLSSetCountry (GetEnvNum ("SPUNK_COUNTRY", DefaultCountry)); // Use english or the language in SPUNK_LANGUAGE NLSSetLanguage (GetEnvNum ("SPUNK_LANGUAGE", DefaultLanguage)); } estic-1.61.orig/spunk/unixsrc/screen.cc0100644000176100001440000000320007031424720017423 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-95 Ullrich von Bassewitz */ /* Zwehrenbuehlstrasse 33 */ /* D-72070 Tuebingen */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "../environ.h" #include "../screen.h" /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): Color (0), // Default is no color Console (0), CP437 (0), // Default is no codepage 437 TransTable (NULL) { // Initialize the termcap system TCInit (); } char* Screen::GetIS (char* IS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { return IS; } char* Screen::GetRS (char* RS) // Return a replacement for the init strings IS and RS. Used for *nixen // only. { return RS; } estic-1.61.orig/spunk/unixsrc/screen2.cc0100644000176100001440000004732207031424720017522 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1993-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include #include #include #ifdef SVR4 # include typedef struct termio SGTTY; typedef unsigned long chtype; # include #else # include #endif #include #include "../cont.h" #include "../winattr.h" #include "../environ.h" #include "../progutil.h" #include "../screen.h" // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) Screen* TheScreen; /*****************************************************************************/ /* Data */ /*****************************************************************************/ static char TermBuf [2048]; // Buffer for the termcap entry static char CapBuf [1024]; // Buffer for selected capabilities // Terminal capabilities static char* IS = NULL; // Initialization string static char* RS = NULL; // Reset string static char* KS = NULL; // Keyboard init static char* KE = NULL; // Keyboard exit static char* CM = NULL; // Cursor motion static char* VI = NULL; // Cursor off static char* VE = NULL; // Cursor on static char* VS = NULL; // Cursor fat static char* US = NULL; // Underline on static char* UE = NULL; // Underline off static char* SO = NULL; // Standout mode on (reverse in most cases) static char* SE = NULL; // Standout mode off static char* MR = NULL; // Reverse on static char* MB = NULL; // Blink on static char* MD = NULL; // Bold on static char* ME = NULL; // Clear all attributes static char* LE = NULL; // cursor left one position static char* IC = NULL; // Insert char static char* IM = NULL; // Enter insert mode static char* EI = NULL; // Exit insert mode static int XN = 0; // Delayed newline // Abstract capabilities static char* BoldOn; // Use this if bold requested static char* ReverseOn; // Use this if reverse requested static char* BlinkOn; // Use this if blink requested // Second last char if the terminal does not have the XN capability static u16 SecLastChar = 0x0720; // A space (is updated before first use) // Current attribute static unsigned LastAttr = 0xFFFF; // Function pointer for setting attributes static void (*SetAttr) (unsigned); // Output buffer and handle for terminal writes static int ScreenHandle = 1; static unsigned char ScrBuf [2048]; static unsigned ScrBufFill = 0; // Last cursor position. Under Linux, screen output is not possible without // moving the cursor. So we have to restore the cursor position after the // output. static Point CursorPos; /*****************************************************************************/ /* Buffer management */ /*****************************************************************************/ static void ScrFlushBuffer () // Flush the terminal buffer { unsigned char* Buf = ScrBuf; while (ScrBufFill) { int BytesWritten = write (ScreenHandle, Buf, ScrBufFill); if (BytesWritten > 0) { Buf += BytesWritten; ScrBufFill -= BytesWritten; } } } static inline void ScrWriteChar (unsigned char C) { if (ScrBufFill == sizeof (ScrBuf)) { ScrFlushBuffer (); } ScrBuf [ScrBufFill++] = C; } static void ScrWriteStr (const char* S) // Write a string to the terminal { if (S) { while (*S) { ScrWriteChar (*S++); } } } /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void ScrGoto (unsigned X, unsigned Y) // Goto a specific cursor location { ScrWriteStr (tgoto (CM, X, Y)); } static void ScrSetColor (unsigned Attr) // Set a new color attribute. This should only be called when the screen is // the console, because all escape sequences are hardcoded. { static char ForegroundColors [8][3] = { "30", "34", "32", "36", "31", "35", "33", "37" }; static char BackgroundColors [8][3] = { "40", "44", "42", "46", "41", "45", "43", "47" }; // Check if anything changed if (Attr == LastAttr) { // Nothing to do return; } // Write the start of the color escape sequence ScrWriteStr ("\033["); unsigned HadValue = 0; if ((Attr & 0x0F) != (LastAttr & 0x0F)) { // Set intensity ScrWriteStr (Attr & 0x08 ? "01;" : "21;"); // Set foreground color ScrWriteStr (ForegroundColors [Attr & 0x07]); HadValue = 1; } if ((Attr & 0xF0) != (LastAttr & 0xF0)) { // Add a separator if needed if (HadValue) { ScrWriteChar (';'); } // Set blink attribute ScrWriteStr (Attr & 0x80 ? "05;" : "25;"); // Set background color ScrWriteStr (BackgroundColors [(Attr >> 4) & 0x07]); } // End the color escape sequence and remember the new attribute ScrWriteChar ('m'); LastAttr = Attr; } static void ScrSetAttr (unsigned Attr) // Set a monochrome attribute. { // Check if anything changed if (Attr == LastAttr) { // Nothing to do return; } // Reset all attributes if (ME) { // We have the ME (clear all attributes) cap ScrWriteStr (ME); } else { // OOPS. Check what attributes have been set and try to reset them if (LastAttr & 0x70) { // LastAttr has been reverse, if ME is not defined, assume that // standout mode has been used. ScrWriteStr (SE); } if (LastAttr & 0x80) { // LastAttr has the blink attribute set. We can not do anything // to reset this... } if (LastAttr & 0x08) { // LastAttr has been bold. Assume that underline mode has been // used. ScrWriteStr (UE); } } // Set new attributes if (Attr & 0x08) { // Bold requested. ScrWriteStr (BoldOn); } if (Attr & 0x70) { // Reverse mode has been requested. ScrWriteStr (ReverseOn); } if (Attr & 0x80) { // Blink mode has been requested ScrWriteStr (BlinkOn); } // Remember the new attribute LastAttr = Attr; } static inline void ScrWriteAttrChar (u16 C) // Write one char with attribute to the screen { // Set the new attribute SetAttr (C >> 8); // Write the character ScrWriteChar (C); } static void ScrWriteBuf (u16* Buf, u16 X, u16 Y, u16 Count) // Write the buffer contents to the screen { // Goto the cursor location ScrGoto (X, Y); // Write the buffer while (Count--) { // Write the character ScrWriteAttrChar (*Buf++); } } /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ void Screen::TCInit () // Termcap initialization { // Check if we have a color override Color = GetEnvBool ("SPUNK_COLOR", Color); // Determine the character set and the corresponding translation table CP437 = GetEnvBool ("SPUNK_CP437", CP437); if (CP437 == 0) { // Use a replacement string for the frame chars ActiveFrame = InactiveFrame = SimpleFrame; // We don't have the codepage 437. Check if we have ISO 8859-1 support // and load a matching translation table. Allow for both environment // variables, SPUNK_CTYPE and LC_CTYPE and allow for some permutations // of the ISO-8859-1 name, since everyone handles it different :-( String Var = GetEnvVar ("SPUNK_CTYPE"); if (Var.IsEmpty ()) { Var = GetEnvVar ("LC_CTYPE"); } // Ok, we now have the value of the environment variable. Match it // against a pattern to cover the maximum count of possible cases. Var.ToUpper (); char* ResName; if (Var.Match ("*ISO[-_]8859[-_]1*")) { // We got some iso-8859-1 string or the other ResName = "SCREEN.ISO-8859-1-Table"; // } else if (Var.Match ("*KOI-8R*")) { // // Currently not used // ResName = "SCREEN.KOI-8R-Table"; } else { ResName = "SCREEN.7BIT-ASCII-Table"; } // Load the translation table from the resource Container* C = (Container*) LoadResource (ResName); TransTable = (unsigned char*) C->RetrieveData (); delete C; } // Check the term environment variable char* T; if ((T = getenv ("TERM")) == NULL) { // OOPS - no way out! FAIL ("TERM environment variable not set!"); } // Get the termcap entry for the terminal switch (tgetent (TermBuf, T)) { case 0: FAIL ("No termcap entry for your terminal found!"); break; case -1: FAIL ("No /etc/termcap file found!"); break; } // Set the starting pointer to the capability buffer char* CapPtr = CapBuf; // Search for selected terminal capabilities. The cursor motion string // is a special case, because it is needed in any case CM = tgetstr ("cm", &CapPtr); if (CM == NULL) { FAIL ("No cursor motion capability found!"); } // Read some other termcap capabilities IS = GetIS (tgetstr ("is", &CapPtr)); // Init RS = GetRS (tgetstr ("rs", &CapPtr)); // Exit KS = tgetstr ("ks", &CapPtr); // Keyboard init KE = tgetstr ("ke", &CapPtr); // Keyboard exit VI = tgetstr ("vi", &CapPtr); // Cursor off VE = tgetstr ("ve", &CapPtr); // Cursor on VS = tgetstr ("vs", &CapPtr); // Cursor fat US = tgetstr ("us", &CapPtr); // Underline on UE = tgetstr ("ue", &CapPtr); // Underline off SO = tgetstr ("so", &CapPtr); // Standout mode on (reverse in most cases) SE = tgetstr ("se", &CapPtr); // Standout mode off MR = tgetstr ("mr", &CapPtr); // Reverse on MB = tgetstr ("mb", &CapPtr); // Blink on MD = tgetstr ("md", &CapPtr); // Bold on ME = tgetstr ("me", &CapPtr); // Clear all attributes LE = tgetstr ("le", &CapPtr); // Cursor left one position IC = tgetstr ("ic", &CapPtr); // Insert char IM = tgetstr ("im", &CapPtr); // Enter insert mode EI = tgetstr ("ei", &CapPtr); // Exit insert mode XN = tgetflag ("xn"); // Delayed newline // If we don't have color, try to determine the abstract attributes if (!Color) { // Try to set the bold attribute if (MD) { // We have bold BoldOn = MD; } else if (SO) { // Use standout instead of bold BoldOn = SO; } else { // OOPS! Menues without bold? Unthinkable! FAIL ("Terminal capability missing: BOLD (md)"); } // Try to set the reverse attribute if (MR) { // We have reverse ReverseOn = MR; } else if (SO) { // Use standout instead ReverseOn = SO; } else { // OOPS! Menues without reverse? Unthinkable! FAIL ("Terminal capability missing: REVERSE (mr)"); } // Try to set the blink attribute. Don't bother if it's missing BlinkOn = MB; } // Now set the attribute setting function for ScrWriteBuf // Beware: ?: does not work when using gcc 2.5.8 if (Color) { SetAttr = ScrSetColor; } else { SetAttr = ScrSetAttr; } // Send the terminal and keyboard init strings ScrWriteStr (IS); ScrWriteStr (KS); // Set the mode data for this mode SetModeData (); } Screen::~Screen () { // Move the cursor to position 0/0. This is necessary with some terminals ScrGoto (0, 0); // Reset the terminal ScrWriteStr (VE); // Cursor enable ScrWriteStr (KE); ScrWriteStr (RS); // reset string ScrFlushBuffer (); // delete the translation table delete [] TransTable; } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table, return the valid // one of the two given buffers { if (TransTable) { unsigned char* T = (unsigned char*) Target; unsigned char* S = (unsigned char*) Source; while (Len--) { *T++ = TransTable [*S++]; // Translate character *T++ = *S++; // Copy attribute } return Target; } else { // No translation, return the original buffer return Source; } } void Screen::SetModeData () // Internally called after setting a new mode, sets cursor data etc. { // Get the size of the screen. Try TIOCGWINSZ first, then try the // environment variables COLUMNS/LINES, at last ressort, use the // termcap file. winsize WinSize; WinSize.ws_row = 0; WinSize.ws_col = 0; ioctl (STDOUT_FILENO, TIOCGWINSZ, &WinSize); // Get number of cols if ((XSize = WinSize.ws_col) == 0) { if ((XSize = GetEnvNum ("COLUMNS")) == 0) { int X = tgetnum ("co"); if (X <= 0) { FAIL ("Cannot determine number of terminal columns!"); } XSize = X; } } // Get number of rows if ((YSize = WinSize.ws_row) == 0) { if ((YSize = GetEnvNum ("LINES")) == 0) { int Y = tgetnum ("li"); if (Y <= 0) { FAIL ("Cannot determine number of terminal lines!"); } YSize = Y; } } // Reset the fore/background attribute LastAttr = 0xFFFF; // Switch off the cursor and put it on position 0/0 SetCursorOff (); SetCursorPos (Point (0, 0)); } void Screen::SetMode (u16 /*Mode*/) { // Set the new mode data in case the size has changed, but otherwise // ignore the request SetModeData (); } void Screen::SetCursorOn () { ScrWriteStr (VE); ScrFlushBuffer (); } void Screen::SetCursorOff () { ScrWriteStr (VI); ScrFlushBuffer (); } void Screen::SetCursorFat () { ScrWriteStr (VS); ScrFlushBuffer (); } void Screen::SetCursorPos (const Point& Pos) { // Check the parameters PRECONDITION (Pos.X < XSize && Pos.Y < YSize); // Output the terminal sequence, then flush the output buffer ScrGoto (Pos.X, Pos.Y); ScrFlushBuffer (); // Remember the new position CursorPos = Pos; } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { // Get a copy of the output rectangle Rect Bounds = R; // Get the size of the unclipped rectangle int XCount = Bounds.XSize (); int YCount = Bounds.YSize (); // Check if there is anything to do if (XCount == 0 || YCount == 0 || Bounds.A.Y > YSize || Bounds.A.X > XSize) { // Done return; } // Clip the rectangle to the lower right border if (Bounds.B.X > XSize) { Bounds.B.X = XSize; } if (Bounds.B.Y > YSize) { Bounds.B.Y = YSize; } // Calculate the size of the output rectangle int XtoDo = Bounds.XSize (); int YtoDo = Bounds.YSize (); // Check if anything to do if (XtoDo == 0 || YtoDo == 0) { return; } // Get buffer memory for translation (alloca is cheap enough to do this // regardless of real needs) u16* Buf2 = (u16*) alloca (XtoDo * sizeof (u16)); // If we will update the second last char in the last line, remember this // char if (Bounds.Contains (Point (XSize - 2, YSize - 1))) { SecLastChar = *Translate (Buf2, Buf + (YtoDo-1) * XCount + XtoDo-2, 1); } // Check if we need to use the "xn hack" for some terminals... int NeedXNHack = 0; if (!XN && Bounds.B.Y == YSize && Bounds.B.X == XSize) { // Terminal don't has the xn capability and we are about to write // the last char on the screen. NeedXNHack = 1; YtoDo--; // Use separate algorithm for last line } // Write the stuff to the screen int Y = Bounds.A.Y; while (YtoDo--) { // Translate the buffer line u16* B = Translate (Buf2, Buf, XtoDo); // Write the buffer to the screen ScrWriteBuf (B, Bounds.A.X, Y, XtoDo); // Next line Buf += XCount; Y++; } // Apply the "xn hack" if needed if (NeedXNHack) { // Buf points to the last line. Translate this last line. u16* B = Translate (Buf2, Buf, XtoDo); // Draw all characters of this line but the last two if (XtoDo > 2) { ScrWriteBuf (B, Bounds.A.X, Y, XtoDo-2); } else { // Code below expects the cursor to point to the second last char ScrGoto (XSize - 2, YSize - 1); } // We can only update the last char if we have the "insert mode" or // "insert char" capability if (IC || (IM && EI)) { // Write out the last char in place of the second last ScrWriteAttrChar (B [XtoDo-1]); // Now go one character back if (LE) { ScrWriteStr (LE); } else { ScrGoto (XSize - 2, YSize - 1); } // Check out which one of both caps to use if (IC) { // We have the "insert char" capability ScrWriteStr (IC); ScrWriteAttrChar (SecLastChar); } else { // Use "insert mode" SetAttr (SecLastChar >> 8); ScrWriteStr (IM); ScrWriteChar (SecLastChar & 0xFF); ScrWriteStr (EI); } } else { // We don't have any insert capabilities, so just update the // second last char and ignore the last one. Cursor position is // allright... ScrWriteAttrChar (SecLastChar); } } // Restore the old cursor position ScrGoto (CursorPos.X, CursorPos.Y); // Flush the tty buffer ScrFlushBuffer (); } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { if (IsConsole ()) { // We have always direct access to the screen return 10; } else { // Assume a serial line (this is wrong in an XTerm window!! ## ) return 5; } } estic-1.61.orig/spunk/unixsrc/sercom.cc0100644000176100001440000004162007031424720017444 0ustar debacleusers/*****************************************************************************/ /* */ /* SERCOM.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // System independent serial communication package for the SPUNK library, // generic unix version. #include #include #include #include #include #include #include #include "../check.h" #include "../sercom.h" #include "../filepath.h" /*****************************************************************************/ /* Types and constants */ /*****************************************************************************/ // internal used data struct _ComData { int Handle; // Port handle unsigned RXCount; // characters in receive queue unsigned TXCount; // characters in transmit queue termios StartupSettings;// Device settings on startup termios CurrentSettings;// Current device settings ComErrorCounter ErrorCounter; // Error counters }; /******************************************************************************/ /* Utility and support functions */ /******************************************************************************/ static void SetReadTimeout (_ComData* ComData, int Min, int Time) { if (ComData->CurrentSettings.c_cc [VMIN] != Min || ComData->CurrentSettings.c_cc [VTIME] != Time) { // Need to set the new values ComData->CurrentSettings.c_cc [VMIN] = Min; ComData->CurrentSettings.c_cc [VTIME] = Time; ZCHECK (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings)); } } /******************************************************************************/ /* Code */ /******************************************************************************/ ComPort::ComPort (const String& aPortName, u32 aBaudrate, char aDatabits, char aParity, char aStopbits, char aConnection, char aXonXoff, unsigned /*UARTBase*/, unsigned /*IntNum*/): PortName (aPortName), Baudrate (aBaudrate), Databits (aDatabits), Parity (aParity), Stopbits (aStopbits), Connection (aConnection), XonXoff (aXonXoff), RXBufSize (4096), // ## ??? TXBufSize (4096), RXTimeout (5.0), TXTimeout (5.0) // Create a ComPort object, use defaults for timeouts and buffer sizes { Init (); } ComPort::~ComPort () { if (IsOpen()) { Close(); } delete ComData; } void ComPort::Init (unsigned /*UARTBase*/, unsigned /*IntNum*/) // Initialization procedure, called from the constructors { // Create an internally used data structure ComData = new _ComData; // Reset the error counters memset (ComData->ErrorCounter, 0, sizeof (ComData->ErrorCounter)); // setting up ComData ComData->Handle = -1; // Port not open ComData->RXCount = 0; ComData->TXCount = 0; } void ComPort::SetBufferSize (u16 /*aRXBufSize*/, u16 /*aTXBufSize*/) // Set the sizes for receive and transmit buffer. This function cannot // be called if the port is already open, you have to call it after // constructing the object or after a close. The function may be ignored // if it is not possible to change buffer sizes. { // This function cannot be called if the port is already open PRECONDITION (!IsOpen ()); // Otherwise this function is ignored under FreeBSD we could not set any // buffer sizes (no harm done anyway) } unsigned ComPort::Open () // Open the port, return an error code or 0 on success { // First, check if the port contains a directory. If not, add /dev String Dir, Name; FSplit (PortName, Dir, Name); if (Dir.IsEmpty ()) { PortName.Ins (0, "/dev/"); } // Open the port ComData->Handle = open (PortName.GetStr (), O_RDWR | O_NONBLOCK); if (ComData->Handle == -1) { // Got an error, return the error code return errno; } // Device must be a tty if (!isatty (ComData->Handle)) { // Error, close and exit Close (); return ENOTTY; } // Remember the current settings tcgetattr (ComData->Handle, &ComData->StartupSettings); // Set up the new settings ComData->CurrentSettings = ComData->StartupSettings; // Set up input flags tcflag_t iflag = IGNBRK | IGNPAR; if (Databits == 7) { iflag |= ISTRIP; // Strip bit 7 } if (XonXoff == 'E') { iflag |= IXON | IXOFF; // Enable XON/XOFF protocol } ComData->CurrentSettings.c_iflag = iflag; // Set up output flags tcflag_t oflag = 0; ComData->CurrentSettings.c_oflag = oflag; // Set up control flags tcflag_t cflag = CREAD | HUPCL; switch (Databits) { case 5: cflag |= CS5; break; case 6: cflag |= CS6; break; case 7: cflag |= CS7; break; case 8: cflag |= CS8; break; default: FAIL ("ComPort::Init: Unsupported databits value"); } switch (Parity) { case 'N': break; case 'E': cflag |= PARENB; break; case 'O': cflag |= PARENB | PARODD; break; default: FAIL ("ComPort::Init: Unsupported parity setting"); } switch (Stopbits) { case 1: break; case 2: cflag |= CSTOPB; break; default: FAIL ("ComPort::Init: Unsupported stopbits value"); } switch (Connection) { case 'M': cflag |= CRTSCTS; break; // not POSIX! case 'D': cflag |= CLOCAL; break; default: FAIL ("ComPort::Init: Unsupported connection setting"); } ComData->CurrentSettings.c_cflag = cflag; // Set up local flags tcflag_t lflag = 0; ComData->CurrentSettings.c_lflag = lflag; // Set XON/XOFF to Ctrl-S/Ctrl-Q ComData->CurrentSettings.c_cc [VSTART] = 0x11; ComData->CurrentSettings.c_cc [VSTOP] = 0x13; // Set the baudrate speed_t Baud = 0; switch (Baudrate) { case 50: Baud = B50; break; case 75: Baud = B75; break; case 110: Baud = B110; break; case 134: Baud = B134; break; case 150: Baud = B150; break; case 200: Baud = B200; break; case 300: Baud = B300; break; case 600: Baud = B600; break; case 1200: Baud = B1200; break; case 2400: Baud = B2400; break; case 4800: Baud = B4800; break; case 9600: Baud = B9600; break; case 19200: Baud = B19200; break; case 38400: Baud = B38400; break; case 57600: Baud = B57600; break; case 115200: Baud = B115200; break; case 230400: Baud = B230400; break; default: FAIL ("ComPort::Init: Unsupported baudrate value"); } ComData->CurrentSettings.c_cflag |= Baud; cfsetispeed (&ComData->CurrentSettings, Baud); cfsetospeed (&ComData->CurrentSettings, Baud); // Set timeouts ComData->CurrentSettings.c_cc [VMIN] = 1; ComData->CurrentSettings.c_cc [VTIME] = int (RXTimeout / 0.1); // Actually set up the device if (tcsetattr (ComData->Handle, TCSANOW, &ComData->CurrentSettings) < 0) { // Could not set int Result = errno; Close (); return Result; } // Reset nonblocking mode int Flags = fcntl (ComData->Handle, F_GETFL, 0); if (Flags < 0) { // Error int Result = errno; Close (); return Result; } Flags &= ~O_NONBLOCK; if (fcntl (ComData->Handle, F_SETFL, Flags) < 0) { // Error int Result = errno; Close (); return Result; } // When we set cflags == CLOCAL on a direct connection, the RTS and DTR // lines will become active. This is not compatible to the other sercom // modules, so change it. Also make DTR low if hardware handshake is // enabled. DTROff (); if (Connection == 'D') { RTSOff (); } // Success return 0; } void ComPort::Close () // Close the port { // Cannot close a port that is not open PRECONDITION (IsOpen ()); // Close the device close (ComData->Handle); // reset handle ComData->Handle = -1; } int ComPort::IsOpen () const // Return a value != zero if the port is opened, return 0 otherwise { return ComData->Handle != -1; } void ComPort::SetRXTimeout (double aRXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aRXTimeout >= 0.0); // Make shure the timeout is not too small if (aRXTimeout > 0 && aRXTimeout < 0.1) { aRXTimeout = 0.1; } // Remember the timeout RXTimeout = aRXTimeout; // Set the timeout SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); } void ComPort::SetTXTimeout (double aTXTimeout) // Set the timeout value { // Check the parameter PRECONDITION (aTXTimeout >= 0.0); // Make shure the timeout is not too small if (aTXTimeout < 0.01) { aTXTimeout = 0.01; } // Remember the timeout TXTimeout = aTXTimeout; } void ComPort::DTROn () // Make the DTR line active { // Port must be open PRECONDITION (IsOpen ()); // Set DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::DTROff () // Make the DTR line inactive { // Port must be open PRECONDITION (IsOpen ()); // Clear DTR int Status = TIOCM_DTR; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } void ComPort::RTSOn () // Make the RTS line active. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Set RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIS, &Status)); } void ComPort::RTSOff () // Make the RTS line inactive. A call to this function is not allowed if the // connection type is 'M'odem { // Port must be open and no hardware handshaking enabled PRECONDITION (IsOpen () && Connection != 'M'); // Clear RTS int Status = TIOCM_RTS; ZCHECK (ioctl (ComData->Handle, TIOCMBIC, &Status)); } unsigned ComPort::RXCount () const // Return the count of chars in the receive buffer, or just true 1 if the // exact amount of chars in the buffer cannot be determined and the value // is at least one. { // Port must be open PRECONDITION (IsOpen ()); // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // Set the file descriptor to ComData->Handle fd_set Desc; FD_ZERO (&Desc); FD_SET (ComData->Handle, &Desc); // Check input status int Res; while ((Res = select (ComData->Handle+1, &Desc, NULL, NULL, &Timeout)) < 0); // We have characters waiting if the ready count is greater than zero return Res > 0; } void ComPort::RXClear () // Clear the receive buffer { // Port must be open PRECONDITION (IsOpen ()); CHECK (tcflush (ComData->Handle, TCIFLUSH) == 0); } void ComPort::TXClear () // Clear the transmit buffer { // Port must be open PRECONDITION (IsOpen ()); CHECK (tcflush (ComData->Handle, TCOFLUSH) == 0); } unsigned ComPort::TXFree () const // Return the amount of free space in the transmit buffer. The function // may return the exact free space or just 1, if at least one character // can be placed into the send buffer (meaning, the Send function will // not block). { // Port must be open PRECONDITION (IsOpen ()); // Timeout is zero timeval Timeout; Timeout.tv_usec = 0; Timeout.tv_sec = 0; // Set the file descriptor to ComData->Handle fd_set Desc; FD_ZERO (&Desc); FD_SET (ComData->Handle, &Desc); // Check output status int Res; while ((Res = select (ComData->Handle+1, NULL, &Desc, NULL, &Timeout)) < 0); // We can write to the descriptor, if the ready count is greater than zero return Res > 0; } int ComPort::Receive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available. { // Port must be open PRECONDITION (IsOpen ()); // Set no timeout mode SetReadTimeout (ComData, 0, 0); // read one character unsigned char B; int ReadCount; do { ReadCount = read (ComData->Handle, &B, 1); } while (ReadCount != 1); // return character return B; } int ComPort::Send (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the error counter is incremented, the // character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); if (TXFree () == 0) { ComData->ErrorCounter [ceTXOverflow]++; return -1; } else { int WriteCount; do { WriteCount = write (ComData->Handle, &B, 1); } while (WriteCount != 1); return B; } } int ComPort::TimedReceive () // Return a character from the receive buffer. If the buffer is empty, // the function waits until a character is available or the time given // with SetReceiveTimeout is over. If a timeout condition occurred, the // function returns -1, otherwise the character received. { // Port must be open PRECONDITION (IsOpen ()); // Set up the device for timeout read SetReadTimeout (ComData, 0, int (RXTimeout / 0.1)); unsigned char B; int ReadCount = read (ComData->Handle, &B, 1); // Return the character read or -1 on timeout return ReadCount == 1 ? B : -1; } int ComPort::TimedSend (unsigned char B) // Send the character (put it into the transmit buffer). If there is no // room in the transmit buffer, the function waits until there is free // room in the transmit buffer or the time given with SetSendTimeout is // over. If a timeout condition occurred, the error counter is incremented, // the character is discarded and the function returns -1. To avoid this, // check TXFree before calling this function. If the character could be // placed into the transmit buffer, B is returned. { // Port must be open PRECONDITION (IsOpen ()); // Use select to check if write is possible timeval Timeout; Timeout.tv_usec = u32 (TXTimeout * 1000000) % 1000000; Timeout.tv_sec = long (TXTimeout); fd_set Desc; FD_ZERO (&Desc); FD_SET (ComData->Handle, &Desc); if (select (ComData->Handle + 1, NULL, &Desc, NULL, &Timeout)) { // Descriptor is ready for writing write (ComData->Handle, &B, 1); return B; } else { // Timeout or signal. Return an timeout error code when a signal // occurs ComData->ErrorCounter [ceTXOverflow]++; return -1; } } void ComPort::Break (double /*Duration*/) // Send a break with the given time in seconds { // Port must be open PRECONDITION (IsOpen ()); // Ignore Duration as values != zero have undefined behavior ZCHECK (tcsendbreak (ComData->Handle, 0)); } #if 0 // gcc 2.5.8 is not able to compile this (bug using the typedef) // Leave it out and hope no one will notice... ComErrorCounter& ComPort::GetErrors () // Get a reference to the array of error counters. These counters are // incremented but never decremented or zeroed by the object. { return ComData->ErrorCounter; } #endif unsigned ComPort::ModemStatus () const // Return the state of the modem status lines { // Port must be open PRECONDITION (IsOpen ()); // Get the modem lines int Lines; CHECK (ioctl (ComData->Handle, TIOCMGET, &Lines) == 0); // Convert to sercom format, ignore the "delta" lines unsigned Status = 0; if (Lines & TIOCM_CTS) Status |= csCTS; if (Lines & TIOCM_DSR) Status |= csDSR; if (Lines & TIOCM_RNG) Status |= csRI; if (Lines & TIOCM_CAR) Status |= csCD; // Return the result return Status; } estic-1.61.orig/spunk/xsrc/0040755000176100001440000000000007061535305015136 5ustar debacleusersestic-1.61.orig/spunk/xsrc/console.cc0100644000176100001440000015267207031424720017114 0ustar debacleusers/*****************************************************************************/ /* */ /* CONSOLE.CC */ /* */ /* (C) 1995-97 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // // X Window backend for the spunk library. Because of the naming conventions // of X Window there are name collisions between Xlib and spunk. To resolve // them, we implement the functionality of class Screen here, but have an // extra module for class Screen that calls functions from console.cc. // Maybe namespaces are a better solution - but they are not yet supported // by all compilers. #include #include #include #include #include #include "../machine.h" #include "../msgid.h" #include "../object.h" #include "../stack.h" #include "../charset.h" #include "../environ.h" #include "../keymap.h" #include "../progutil.h" #include "../scrmodes.h" #include "../kbd.h" #include "../wincolor.h" // Be shure to include all X11 stuff _after_ the spunk includes #include #include #include #include #include /*****************************************************************************/ /* Constants */ /*****************************************************************************/ // Window dimensions (in chars) const int MinWidth = 80; const int MinHeight = 25; const int MaxWidth = 100; const int MaxHeight = 50; // Indices into the KeySymMap array const unsigned kiPlane = 0; const unsigned kiShift = 1; const unsigned kiCtrl = 2; const unsigned kiMeta = 3; const unsigned kiCount = 4; // The Alt modifiers const unsigned AltGrMask = Mod3Mask; const unsigned AltMask = Mod4Mask; /*****************************************************************************/ /* Data */ /*****************************************************************************/ // The one and only keyboard instance Keyboard* Kbd; // X variables static Display* SpunkDisplay; static Window SpunkWindow; static GC SpunkGC; static Font SpunkFont; // Character dimensions (fixed font) static unsigned CharHeight; static unsigned CharWidth; static unsigned CharDescent; static unsigned long CharULPos; // Underline position static unsigned long CharULThickness; // Underline thickness // The screen dimensions int ScreenHeight; int ScreenWidth; // Screen is using codepage 437 int ScreenCP437; // Screen is using a color mode int ScreenColor; // Cursor static enum { csOff, csOn, csFat } CursorType = csOff; static unsigned CursorX = 0; static unsigned CursorY = 0; // Attribute and color management static unsigned long Foreground = (unsigned long) -1; static unsigned long Background = (unsigned long) -1; static int LastAttr = -1; enum _ColorMode { cmMono, cmBW, cmColor }; static _ColorMode ColorMode; // Current colormode static _ColorMode InitColorMode; // Colormode at startup static int Underline = 0; // Attribute has underline set static unsigned ColorDepth; // Server color depth static unsigned MonoBG; // Index of bg color in bw/mono mode static unsigned MonoFG; // Index of fg color in bw/mono mode // The application color map static XColor Colors [coCount] = { { 0, 0*1024, 0*1024, 0*1024 }, // black { 0, 0*1024, 0*1024, 42*1024 }, // blue { 0, 0*1024, 42*1024, 0*1024 }, // green { 0, 0*1024, 42*1024, 42*1024 }, // cyan { 0, 42*1024, 0*1024, 0*1024 }, // red { 0, 42*1024, 0*1024, 42*1024 }, // magenta { 0, 42*1024, 21*1024, 0*1024 }, // brown { 0, 42*1024, 42*1024, 42*1024 }, // lightgray { 0, 21*1024, 21*1024, 21*1024 }, // darkgray { 0, 21*1024, 21*1024, 63*1024 }, // lightblue { 0, 21*1024, 63*1024, 21*1024 }, // lightgreen { 0, 21*1024, 63*1024, 63*1024 }, // lightcyan { 0, 63*1024, 21*1024, 21*1024 }, // lightred { 0, 63*1024, 21*1024, 63*1024 }, // lightmagenta { 0, 63*1024, 63*1024, 21*1024 }, // yellow { 0, 63*1024, 63*1024, 63*1024 } // white }; // The virtual screen we are writing to. Don't bother to resize the screen, // use the maximum dimensions instead static u16 ActualScreen [MaxHeight][MaxWidth]; static u16 VirtualScreen [MaxHeight][MaxWidth]; // Global keyboard buffer static CircularBuffer KbdBuffer; // Mapper table from virtual to extended keys. This table is fixed. struct { Key EK; Key VK; } VirtualMap [] = { { kbEsc, vkAbort }, { kbF1, vkHelp }, { kbF10, vkAccept }, { kbPgUp, vkPgUp }, { kbPgDn, vkPgDn }, { kbCtrlPgUp, vkCtrlPgUp }, { kbCtrlPgDn, vkCtrlPgDn }, { kbUp, vkUp }, { kbDown, vkDown }, { kbLeft, vkLeft }, { kbRight, vkRight }, { kbIns, vkIns }, { kbDel, vkDel }, { kbHome, vkHome }, { kbEnd, vkEnd }, { kbCtrlUp, vkCtrlUp }, { kbCtrlDown, vkCtrlDown }, { kbCtrlLeft, vkCtrlLeft }, { kbCtrlRight, vkCtrlRight }, { kbCtrlIns, vkCtrlIns }, { kbCtrlDel, vkCtrlDel }, { kbCtrlHome, vkCtrlHome }, { kbCtrlEnd, vkCtrlEnd }, { kbF5, vkZoom }, { kbMetaF3, vkClose }, { kbF3, vkOpen }, { kbF2, vkSave }, { kbCtrlF5, vkResize }, { kbMetaX, vkQuit }, // Secondary mappings follow { kbCtrlR, vkPgUp }, { kbCtrlC, vkPgDn }, { kbCtrlE, vkUp }, { kbCtrlX, vkDown }, { kbCtrlS, vkLeft }, { kbCtrlD, vkRight }, { kbCtrlV, vkIns }, { kbCtrlG, vkDel }, { kbCtrlW, vkCtrlUp }, { kbCtrlZ, vkCtrlDown }, { kbCtrlA, vkCtrlLeft }, { kbCtrlF, vkCtrlRight }, }; // Mapping table keysym --> Key struct { KeySym Sym; Key Keys [kiCount]; } KeySymMap [] = { // KeySym Key Shift-Key Ctrl-Ctrl Meta-Key #ifdef XK_Left { XK_Left, { kbLeft, kbNoKey, kbCtrlLeft, kbMetaLeft }}, #endif #ifdef XK_Up { XK_Up, { kbUp, kbNoKey, kbCtrlUp, kbMetaUp }}, #endif #ifdef XK_Right { XK_Right, { kbRight, kbNoKey, kbCtrlRight, kbMetaRight }}, #endif #ifdef XK_Down { XK_Down, { kbDown, kbNoKey, kbCtrlDown, kbMetaDown }}, #endif #ifdef XK_Page_Up { XK_Page_Up, { kbPgUp, kbNoKey, kbCtrlPgUp, kbMetaPgUp }}, #endif #ifdef XK_Page_Down { XK_Page_Down, { kbPgDn, kbNoKey, kbCtrlPgDn, kbMetaPgDn }}, #endif #ifdef XK_End { XK_End, { kbEnd, kbNoKey, kbCtrlEnd, kbMetaEnd }}, #endif #ifdef XK_Home { XK_Home, { kbHome, kbNoKey, kbCtrlHome, kbMetaHome }}, #endif #ifdef XK_Begin { XK_Begin, { kbHome, kbNoKey, kbCtrlHome, kbMetaHome }}, #endif #ifdef XK_F1 { XK_F1, { kbF1, kbShiftF1, kbCtrlF1, kbMetaF1 }}, #endif #ifdef XK_F2 { XK_F2, { kbF2, kbShiftF2, kbCtrlF2, kbMetaF2 }}, #endif #ifdef XK_F3 { XK_F3, { kbF3, kbShiftF3, kbCtrlF3, kbMetaF3 }}, #endif #ifdef XK_F4 { XK_F4, { kbF4, kbShiftF4, kbCtrlF4, kbMetaF4 }}, #endif #ifdef XK_F5 { XK_F5, { kbF5, kbShiftF5, kbCtrlF5, kbMetaF5 }}, #endif #ifdef XK_F6 { XK_F6, { kbF6, kbShiftF6, kbCtrlF6, kbMetaF6 }}, #endif #ifdef XK_F7 { XK_F7, { kbF7, kbShiftF7, kbCtrlF7, kbMetaF7 }}, #endif #ifdef XK_F8 { XK_F8, { kbF8, kbShiftF8, kbCtrlF8, kbMetaF8 }}, #endif #ifdef XK_F9 { XK_F9, { kbF9, kbShiftF9, kbCtrlF9, kbMetaF9 }}, #endif #ifdef XK_F10 { XK_F10, { kbF10, kbShiftF10, kbCtrlF10, kbMetaF10 }}, #endif #ifdef XK_F11 { XK_F11, { kbF11, kbShiftF11, kbCtrlF11, kbMetaF11 }}, #endif #ifdef XK_F12 { XK_F12, { kbF12, kbShiftF12, kbCtrlF12, kbMetaF12 }}, #endif #ifdef XK_BackSpace { XK_BackSpace, { kbBack, kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_Tab { XK_Tab, { kbTab, kbShiftTab, kbCtrlTab, kbMetaTab }}, #endif #ifdef XK_KP_Enter { XK_KP_Enter, { kbEnter, kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_Return { XK_Return, { kbEnter, kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_Escape { XK_Escape, { kbEsc, kbNoKey, kbNoKey, kbMetaEsc }}, #endif #ifdef XK_Delete { XK_Delete, { kbDel, kbShiftDel, kbCtrlDel, kbMetaDel }}, #endif #ifdef XK_Insert { XK_Insert, { kbIns, kbShiftIns, kbCtrlIns, kbMetaIns }}, #endif #ifdef XK_KP_Enter { XK_KP_Enter, { kbEnter, kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_KP_Left { XK_KP_Left, { kbLeft, kbNoKey, kbCtrlLeft, kbMetaLeft }}, #endif #ifdef XK_KP_Up { XK_KP_Up, { kbUp, kbNoKey, kbCtrlUp, kbMetaUp }}, #endif #ifdef XK_KP_Right { XK_KP_Right, { kbRight, kbNoKey, kbCtrlRight, kbMetaRight }}, #endif #ifdef XK_KP_Down { XK_KP_Down, { kbDown, kbNoKey, kbCtrlDown, kbMetaDown }}, #endif #ifdef XK_KP_Page_Up { XK_KP_Page_Up, { kbPgUp, kbNoKey, kbCtrlPgUp, kbMetaPgUp }}, #endif #ifdef XK_KP_Page_Down { XK_KP_Page_Down, { kbPgDn, kbNoKey, kbCtrlPgDn, kbMetaPgDn }}, #endif #ifdef XK_KP_End { XK_KP_End, { kbEnd, kbNoKey, kbCtrlEnd, kbMetaEnd }}, #endif #ifdef XK_KP_Home { XK_KP_Home, { kbHome, kbNoKey, kbCtrlHome, kbMetaHome }}, #endif #ifdef XK_KP_Begin { XK_KP_Begin, { kbHome, kbNoKey, kbCtrlHome, kbMetaHome }}, #endif #ifdef XK_KP_Delete { XK_KP_Delete, { kbDel, kbShiftDel, kbCtrlDel, kbMetaDel }}, #endif #ifdef XK_KP_Insert { XK_KP_Insert, { kbIns, kbShiftIns, kbCtrlIns, kbMetaIns }}, #endif #ifdef XK_KP_F1 { XK_KP_F1, { kbF1, kbShiftF1, kbCtrlF1, kbMetaF1 }}, #endif #ifdef XK_KP_F2 { XK_KP_F2, { kbF2, kbShiftF2, kbCtrlF2, kbMetaF2 }}, #endif #ifdef XK_KP_F3 { XK_KP_F3, { kbF3, kbShiftF3, kbCtrlF3, kbMetaF3 }}, #endif #ifdef XK_KP_F4 { XK_KP_F4, { kbF4, kbShiftF4, kbCtrlF4, kbMetaF4 }}, #endif #ifdef XK_space { XK_space, { ' ', ' ', kbNoKey, kbMetaSpace }}, #endif #ifdef XK_exclam { XK_exclam, { '!', '!', kbNoKey, kbNoKey }}, #endif #ifdef XK_quotedbl { XK_quotedbl, { '\"', '\"', kbNoKey, kbNoKey }}, #endif #ifdef XK_numbersign { XK_numbersign, { '#', '#', kbNoKey, kbNoKey }}, #endif #ifdef XK_dollar { XK_dollar, { '$', '$', kbNoKey, kbNoKey }}, #endif #ifdef XK_percent { XK_percent, { '%', '%', kbNoKey, kbNoKey }}, #endif #ifdef XK_ampersand { XK_ampersand, { '&', '&', kbNoKey, kbNoKey }}, #endif #ifdef XK_apostrophe { XK_apostrophe, { '\'', '\'', kbNoKey, kbNoKey }}, #endif #ifdef XK_parenleft { XK_parenleft, { '(', '(', kbNoKey, kbNoKey }}, #endif #ifdef XK_parenright { XK_parenright, { ')', ')', kbNoKey, kbNoKey }}, #endif #ifdef XK_asterisk { XK_asterisk, { '*', '*', kbNoKey, kbNoKey }}, #endif #ifdef XK_plus { XK_plus, { '+', '+', kbNoKey, kbNoKey }}, #endif #ifdef XK_comma { XK_comma, { ',', ',', kbNoKey, kbNoKey }}, #endif #ifdef XK_minus { XK_minus, { '-', '-', kbNoKey, kbNoKey }}, #endif #ifdef XK_period { XK_period, { '.', '.', kbNoKey, kbNoKey }}, #endif #ifdef XK_slash { XK_slash, { '/', '/', kbNoKey, kbNoKey }}, #endif #ifdef XK_0 { XK_0, { '0', kbNoKey, kbNoKey, kbMeta0 }}, #endif #ifdef XK_1 { XK_1, { '1', kbNoKey, kbNoKey, kbMeta1 }}, #endif #ifdef XK_2 { XK_2, { '2', kbNoKey, kbNoKey, kbMeta2 }}, #endif #ifdef XK_3 { XK_3, { '3', kbNoKey, kbNoKey, kbMeta3 }}, #endif #ifdef XK_4 { XK_4, { '4', kbNoKey, kbNoKey, kbMeta4 }}, #endif #ifdef XK_5 { XK_5, { '5', kbNoKey, kbNoKey, kbMeta5 }}, #endif #ifdef XK_6 { XK_6, { '6', kbNoKey, kbNoKey, kbMeta6 }}, #endif #ifdef XK_7 { XK_7, { '7', kbNoKey, kbNoKey, kbMeta7 }}, #endif #ifdef XK_8 { XK_8, { '8', kbNoKey, kbNoKey, kbMeta8 }}, #endif #ifdef XK_9 { XK_9, { '9', kbNoKey, kbNoKey, kbMeta9 }}, #endif #ifdef XK_colon { XK_colon, { ':', ':', kbNoKey, kbNoKey }}, #endif #ifdef XK_semicolon { XK_semicolon, { ';', ';', kbNoKey, kbNoKey }}, #endif #ifdef XK_less { XK_less, { '<', '<', kbNoKey, kbNoKey }}, #endif #ifdef XK_equal { XK_equal, { '=', '=', kbNoKey, kbNoKey }}, #endif #ifdef XK_greater { XK_greater, { '>', '>', kbNoKey, kbNoKey }}, #endif #ifdef XK_question { XK_question, { '?', '?', kbNoKey, kbNoKey }}, #endif #ifdef XK_at { XK_at, { '@', '@', kbNoKey, kbNoKey }}, #endif #ifdef XK_A { XK_A, { 'A', 'A', kbCtrlA, kbMetaA }}, #endif #ifdef XK_B { XK_B, { 'B', 'B', kbCtrlB, kbMetaB }}, #endif #ifdef XK_C { XK_C, { 'C', 'C', kbCtrlC, kbMetaC }}, #endif #ifdef XK_D { XK_D, { 'D', 'D', kbCtrlD, kbMetaD }}, #endif #ifdef XK_E { XK_E, { 'E', 'E', kbCtrlE, kbMetaE }}, #endif #ifdef XK_F { XK_F, { 'F', 'F', kbCtrlF, kbMetaF }}, #endif #ifdef XK_G { XK_G, { 'G', 'G', kbCtrlG, kbMetaG }}, #endif #ifdef XK_H { XK_H, { 'H', 'H', kbCtrlH, kbMetaH }}, #endif #ifdef XK_I { XK_I, { 'I', 'I', kbCtrlI, kbMetaI }}, #endif #ifdef XK_J { XK_J, { 'J', 'J', kbCtrlJ, kbMetaJ }}, #endif #ifdef XK_K { XK_K, { 'K', 'K', kbCtrlK, kbMetaK }}, #endif #ifdef XK_L { XK_L, { 'L', 'L', kbCtrlL, kbMetaL }}, #endif #ifdef XK_M { XK_M, { 'M', 'M', kbCtrlM, kbMetaM }}, #endif #ifdef XK_N { XK_N, { 'N', 'N', kbCtrlN, kbMetaN }}, #endif #ifdef XK_O { XK_O, { 'O', 'O', kbCtrlO, kbMetaO }}, #endif #ifdef XK_P { XK_P, { 'P', 'P', kbCtrlP, kbMetaP }}, #endif #ifdef XK_Q { XK_Q, { 'Q', 'Q', kbCtrlQ, kbMetaQ }}, #endif #ifdef XK_R { XK_R, { 'R', 'R', kbCtrlR, kbMetaR }}, #endif #ifdef XK_S { XK_S, { 'S', 'S', kbCtrlS, kbMetaS }}, #endif #ifdef XK_T { XK_T, { 'T', 'T', kbCtrlT, kbMetaT }}, #endif #ifdef XK_U { XK_U, { 'U', 'U', kbCtrlU, kbMetaU }}, #endif #ifdef XK_V { XK_V, { 'V', 'V', kbCtrlV, kbMetaV }}, #endif #ifdef XK_W { XK_W, { 'W', 'W', kbCtrlW, kbMetaW }}, #endif #ifdef XK_X { XK_X, { 'X', 'X', kbCtrlX, kbMetaX }}, #endif #ifdef XK_Y { XK_Y, { 'Y', 'Y', kbCtrlY, kbMetaY }}, #endif #ifdef XK_Z { XK_Z, { 'Z', 'Z', kbCtrlZ, kbMetaZ }}, #endif #ifdef XK_bracketleft { XK_bracketleft, { '[', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_backslash { XK_backslash, { '\\', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_bracketright { XK_bracketright, { ']', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_asciicircum { XK_asciicircum, { '^', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_underscore { XK_underscore, { '_', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_grave { XK_grave, { '`', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_a { XK_a, { 'a', 'A', kbCtrlA, kbMetaA }}, #endif #ifdef XK_b { XK_b, { 'b', 'B', kbCtrlB, kbMetaB }}, #endif #ifdef XK_c { XK_c, { 'c', 'C', kbCtrlC, kbMetaC }}, #endif #ifdef XK_d { XK_d, { 'd', 'D', kbCtrlD, kbMetaD }}, #endif #ifdef XK_e { XK_e, { 'e', 'E', kbCtrlE, kbMetaE }}, #endif #ifdef XK_f { XK_f, { 'f', 'F', kbCtrlF, kbMetaF }}, #endif #ifdef XK_g { XK_g, { 'g', 'G', kbCtrlG, kbMetaG }}, #endif #ifdef XK_h { XK_h, { 'h', 'H', kbCtrlH, kbMetaH }}, #endif #ifdef XK_i { XK_i, { 'i', 'I', kbCtrlI, kbMetaI }}, #endif #ifdef XK_j { XK_j, { 'j', 'J', kbCtrlJ, kbMetaJ }}, #endif #ifdef XK_k { XK_k, { 'k', 'K', kbCtrlK, kbMetaK }}, #endif #ifdef XK_l { XK_l, { 'l', 'L', kbCtrlL, kbMetaL }}, #endif #ifdef XK_m { XK_m, { 'm', 'M', kbCtrlM, kbMetaM }}, #endif #ifdef XK_n { XK_n, { 'n', 'N', kbCtrlN, kbMetaN }}, #endif #ifdef XK_o { XK_o, { 'o', 'O', kbCtrlO, kbMetaO }}, #endif #ifdef XK_p { XK_p, { 'p', 'P', kbCtrlP, kbMetaP }}, #endif #ifdef XK_q { XK_q, { 'q', 'Q', kbCtrlQ, kbMetaQ }}, #endif #ifdef XK_r { XK_r, { 'r', 'R', kbCtrlR, kbMetaR }}, #endif #ifdef XK_s { XK_s, { 's', 'S', kbCtrlS, kbMetaS }}, #endif #ifdef XK_t { XK_t, { 't', 'T', kbCtrlT, kbMetaT }}, #endif #ifdef XK_u { XK_u, { 'u', 'U', kbCtrlU, kbMetaU }}, #endif #ifdef XK_v { XK_v, { 'v', 'V', kbCtrlV, kbMetaV }}, #endif #ifdef XK_w { XK_w, { 'w', 'W', kbCtrlW, kbMetaW }}, #endif #ifdef XK_x { XK_x, { 'x', 'X', kbCtrlX, kbMetaX }}, #endif #ifdef XK_y { XK_y, { 'y', 'Y', kbCtrlY, kbMetaY }}, #endif #ifdef XK_z { XK_z, { 'z', 'Z', kbCtrlZ, kbMetaZ }}, #endif #ifdef XK_braceleft { XK_braceleft, { '{', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_bar { XK_bar, { '|', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_braceright { XK_braceright, { '}', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_asciitilde { XK_asciitilde, { '~', kbNoKey, kbNoKey, kbNoKey }}, #endif #ifdef XK_ssharp { XK_ssharp, { 0xE1, 0xE1, kbNoKey, kbNoKey }}, #endif #ifdef XK_adiaeresis { XK_adiaeresis, { 0x84, 0x8E, kbNoKey, kbNoKey }}, #endif #ifdef XK_odiaeresis { XK_odiaeresis, { 0x94, 0x99, kbNoKey, kbNoKey }}, #endif #ifdef XK_udiaeresis { XK_udiaeresis, { 0x81, 0x9A, kbNoKey, kbNoKey }}, #endif }; /*****************************************************************************/ /* Argument handling stuff */ /*****************************************************************************/ static String GetStringArg (const char* ArgName) // Try to find a program parameter with the given name. If we find one, return // the parameter following this name and remove both from the argument list. { // Get the argument vector char** Args = GetArgVec (); // search for the given argument int I = 1; while (Args [I] != 0) { if (strcmp (Args [I], ArgName) == 0) { // found if (Args [I+1] != 0) { // Remember the argument value String ArgVal = Args [I+1]; // Remove the argument name and the argument value RemoveArg (I+1); RemoveArg (I); // Return the value read return ArgVal; } } I++; } // Not found return ""; } /*****************************************************************************/ /* External visible stuff for class Screen */ /*****************************************************************************/ static inline unsigned ScrXPos (unsigned X) // Calculate a graphics X position from a character X position { return X * CharWidth; } static inline unsigned ScrYPos (unsigned Y) // Calculate a graphics Y position from a character Y position { return (Y + 1) * CharHeight - CharDescent; } static void ScrSetBackground (unsigned Index) // Set the background color to the color with the given index { unsigned long Pixel = Colors [Index].pixel; if (Pixel != Background) { Background = Pixel; XSetBackground (SpunkDisplay, SpunkGC, Pixel); } } static void ScrSetForeground (unsigned Index) // Set the foreground color to the color with the given index { unsigned long Pixel = Colors [Index].pixel; if (Pixel != Foreground) { Foreground = Pixel; XSetForeground (SpunkDisplay, SpunkGC, Pixel); } } static void ScrSetupAttr (unsigned char Attr) // Set up the colors for the new attribute and remember the new attribute { // Remove the blink attribute - it's not used Attr &= 0x7F; // Check if something has changed if (Attr != LastAttr) { // Assume no underlining Underline = 0; // Set the colors according to the color model used switch (ColorMode) { case cmMono: // Set the foreground color switch (Attr & 0x0F) { case 0x00: // Black ScrSetForeground (MonoBG); break; case 0x01: // Black/underline ScrSetForeground (MonoBG); Underline = 1; break; case 0x07: // Black ScrSetForeground (MonoFG); break; case 0x09: // White/underline ScrSetForeground (MonoFG); Underline = 1; break; case 0x0F: // White ScrSetForeground (MonoFG); break; default: // Handle as normal text ScrSetForeground (MonoFG); break; } // Set the background color switch (Attr & 0x70) { case 0x00: // Black ScrSetBackground (MonoBG); break; case 0x70: ScrSetBackground (MonoFG); break; default: // Handle as normal text ScrSetBackground (MonoBG); break; } break; case cmBW: // Set the foreground color switch (Attr & 0x0F) { case 0x00: // Black ScrSetForeground (MonoBG); break; case 0x01: // Black/underline ScrSetForeground (MonoBG); Underline = 1; break; case 0x07: // Lightgray ScrSetForeground (coLightGray); break; case 0x09: // White/underline ScrSetForeground (MonoFG); Underline = 1; break; case 0x0F: // White ScrSetForeground (MonoFG); break; default: // Handle as normal text ScrSetForeground (coLightGray); break; } // Set the background color switch (Attr & 0x70) { case 0x00: // Black ScrSetBackground (MonoBG); break; case 0x70: ScrSetBackground (coLightGray); break; default: // Handle as normal text ScrSetBackground (MonoBG); break; } break; case cmColor: ScrSetBackground ((Attr >> 4) & 0x0F); ScrSetForeground (Attr & 0x0F); break; default: FAIL ("ScrSetupAttr: Unknown color mode"); break; } // Remember the new attribute LastAttr = Attr; } } static void ScrDrawText (unsigned X, unsigned Y, const char* Buf, unsigned Count) // Draw text using XDrawImageString. Underline the text if needed. { // Draw the string XDrawImageString (SpunkDisplay, SpunkWindow, SpunkGC, ScrXPos (X), ScrYPos (Y), Buf, Count); // If the underline attribute is set, underline the text if (Underline) { XFillRectangle (SpunkDisplay, SpunkWindow, SpunkGC, ScrXPos (X), ScrYPos (Y) + CharULPos, CharWidth * Count, CharULThickness); } } static void ScrDrawCell (unsigned X, unsigned Y, u16 Cell) // Draw a single cell unconditionally { // Set the colors for the new attribute ScrSetupAttr (Cell >> 8); // Draw the cell char Buf [1]; Buf [0] = Cell & 0xFF; ScrDrawText (X, Y, Buf, 1); } static void ScrDrawCursor () { static const char CursorOnString [] = "_"; u16 Cell; // Draw the cursor according to the current cursor state switch (CursorType) { case csOn: // Use an underline character as cursor Cell = ActualScreen [CursorY][CursorX]; ScrSetupAttr (Cell >> 8); XDrawString (SpunkDisplay, SpunkWindow, SpunkGC, ScrXPos (CursorX), ScrYPos (CursorY), CursorOnString, 1); break; case csFat: // Redraw the character with the attribute inverted Cell = ActualScreen [CursorY][CursorX]; Cell = (Cell & 0x00FF) | ((Cell & 0x0F00) << 4) | ((Cell & 0xF000) >> 4); ScrDrawCell (CursorX, CursorY, Cell); break; case csOff: break; default: FAIL ("ScrDrawCursor: Invalid cursor type"); break; } } void ScrCursorOn () // Set the cursor state to on { // If we had a fat cursor before, we need to redraw the cell to remove the // old cursor if (CursorType == csFat) { ScrDrawCell (CursorX, CursorY, ActualScreen [CursorY][CursorX]); } // Remember the new cursor CursorType = csOn; // Now draw the actual cursor ScrDrawCursor (); } void ScrCursorOff () // Set the cursor state to off { // Just redraw the cell ScrDrawCell (CursorX, CursorY, ActualScreen [CursorY][CursorX]); // Remember the new cursor CursorType = csOff; } void ScrCursorFat () // Set the cursor state to fat { // Remember the new state CursorType = csFat; // Draw the new cursor ScrDrawCursor (); } void ScrSetCursorPos (unsigned X, unsigned Y) // Set the cursor position { // Check if the cursor position has changed if (X != CursorX || Y != CursorY) { // Cursor position has changed. If we had a visible cursor before, // remove it at the old cursor position if (CursorType != csOff) { ScrDrawCell (CursorX, CursorY, ActualScreen [CursorY][CursorX]); } // Remember the new position CursorX = X; CursorY = Y; // Draw the new cursor ScrDrawCursor (); } } void ScrSetMode (unsigned Mode) // Set a screen mode { unsigned XSize, YSize; _ColorMode NewColorMode = ColorMode; // Check the new dimensions switch (Mode) { case vmAsk: // Request the current window size. Assume, color depth // and other window parameters have not changed. XWindowAttributes WA; XGetWindowAttributes (SpunkDisplay, SpunkWindow, &WA); XSize = WA.width / CharWidth; YSize = WA.height / CharHeight; break; case vmBW40: XSize = 40; YSize = 25; NewColorMode = (ColorDepth == 1)? cmMono : cmBW; break; case vmMono: case vmBW80: XSize = 80; YSize = 25; NewColorMode = (ColorDepth == 1)? cmMono : cmBW; break; case vmCO40: XSize = 40; YSize = 25; NewColorMode = cmColor; break; case vmCO80: XSize = 80; YSize = 25; NewColorMode = cmColor; break; case vmVGA_80x30: XSize = 80; YSize = 30; NewColorMode = cmColor; break; case vmVGA_80x34: XSize = 80; YSize = 34; NewColorMode = cmColor; break; case vmVGA_80x43: XSize = 80; YSize = 43; NewColorMode = cmColor; break; case vmVGA_80x50: XSize = 80; YSize = 50; NewColorMode = cmColor; break; case vmVGA_80x60: XSize = 80; YSize = 60; NewColorMode = cmColor; break; case vmVGA_94x25: XSize = 94; YSize = 25; NewColorMode = cmColor; break; case vmVGA_94x30: XSize = 94; YSize = 30; NewColorMode = cmColor; break; case vmVGA_94x34: XSize = 94; YSize = 34; NewColorMode = cmColor; break; case vmVGA_94x43: XSize = 94; YSize = 43; NewColorMode = cmColor; break; case vmVGA_94x50: XSize = 94; YSize = 50; NewColorMode = cmColor; break; case vmVGA_94x60: XSize = 94; YSize = 60; NewColorMode = cmColor; break; case vmET4_100x40: XSize = 100; YSize = 40; NewColorMode = cmColor; break; default: // Ignore modes we do not know return; } // Check if we support the color setting. If we cannot accept the color // setting, use the maximum color setting instead (honor the size) if (NewColorMode > InitColorMode) { NewColorMode = InitColorMode; } // Check if we can resize the screen, bail out if not if (XSize < MinWidth || XSize > MaxWidth || YSize < MinHeight || YSize > MaxHeight) { return; } // Set the global variables ScreenWidth = XSize; ScreenHeight = YSize; ColorMode = NewColorMode; ScreenColor = ColorMode == cmColor; // Switch the cursor off CursorType = csOff; // Resize the window XResizeWindow (SpunkDisplay, SpunkWindow, ScreenWidth * CharWidth, ScreenHeight * CharHeight); // Clear the shadow screen to force an update on the next writes memset (ActualScreen, 0, sizeof (ActualScreen)); // Reset the attribute and color settings LastAttr = -1; Foreground = (unsigned long) -1; Background = (unsigned long) -1; } void ScrInit (unsigned XSize, unsigned YSize) // Initialize the screen { // Set the screen size ScreenHeight = YSize; ScreenWidth = XSize; // Initialize some other stuff CursorType = csOff; memset (VirtualScreen, ' ', sizeof (VirtualScreen)); memset (ActualScreen, 0, sizeof (ActualScreen)); // Open the X display. If a display is given as argument use it, otherwise // use the DISPLAY environment variable (the latter should be automatic, // But it seems to fail on some operating systems). String DisplayName = GetStringArg ("-display"); if (DisplayName.IsEmpty ()) { DisplayName = GetEnvVar ("DISPLAY"); } SpunkDisplay = XOpenDisplay (DisplayName.GetStr ()); if (SpunkDisplay == NULL) { FAIL ("ScrInit: Cannot open display"); } // Get a screen int SpunkScreen = DefaultScreen (SpunkDisplay); // Decide which color model to use. If we have more than 16 colors, use // the color model. If we have more than two colors, but less or equal // to 16, use the black/white model. If we have two colors, use the // monochrome model. // All this may be overridden by the SPUNK_COLOR environment variable. ColorDepth = XDefaultDepth (SpunkDisplay, SpunkScreen); if (ColorDepth == 1) { // One plane - pure monochrome ColorMode = cmMono; } else if (ColorDepth <= 4) { // More than one but less than five - black/white ColorMode = cmBW; } else { // 16 color mode ColorMode = cmColor; } // Check for an explicit override if (!GetEnvVar ("SPUNK_COLOR").IsEmpty ()) { // There is an explicit override if (GetEnvBool ("SPUNK_COLOR", ColorMode == cmColor)) { ColorMode = cmColor; } else { ColorMode = (ColorDepth > 1)? cmBW : cmMono; } } // Get all needed colors Colormap CM; switch (ColorMode) { case cmMono: Colors [coBlack].pixel = XBlackPixel (SpunkDisplay, SpunkScreen); Colors [coWhite].pixel = XWhitePixel (SpunkDisplay, SpunkScreen); break; case cmBW: CM = DefaultColormap (SpunkDisplay, SpunkScreen); if (XAllocColor (SpunkDisplay, CM, &Colors [coBlack]) == 0) { FAIL ("ScrInit: Cannot allocate color"); } if (XAllocColor (SpunkDisplay, CM, &Colors [coLightGray]) == 0) { FAIL ("ScrInit: Cannot allocate color"); } if (XAllocColor (SpunkDisplay, CM, &Colors [coWhite]) == 0) { FAIL ("ScrInit: Cannot allocate color"); } break; case cmColor: CM = DefaultColormap (SpunkDisplay, SpunkScreen); for (unsigned C = 0; C < coCount; C++) { if (XAllocColor (SpunkDisplay, CM, &Colors [C]) == 0) { FAIL ("ScrInit: Cannot allocate color"); } } break; default: FAIL ("ScrInit: Invalid color mode"); break; } // Check for inverse video (mono and bw only) if (GetEnvBool ("SPUNK_XINVERTMONO", 0)) { MonoBG = coWhite; MonoFG = coBlack; } else { MonoBG = coBlack; MonoFG = coWhite; } // Remember the startup color mode for later mode switches InitColorMode = ColorMode; // Set the palette color flag ScreenColor = (ColorMode == cmColor); // Load the font. If the font is specified by the user, use the given // font. If the font is not spcified, try "vga", then some other defaults. XFontStruct* FontInfo = 0; String Font = GetEnvVar ("SPUNK_XFONT"); if (Font.IsEmpty ()) { // A list of fonts to try static const char* Fonts [] = { "vga", "fixed", "8x13" }; // Try to load the fonts in the given order for (unsigned I = 0; I < sizeof (Fonts) / sizeof (Fonts [0]); I++) { // Try to load the font FontInfo = XLoadQueryFont (SpunkDisplay, Fonts [I]); // End the search if we got the font if (FontInfo) { // We got the font Font = Fonts [I]; break; } } // If we could not load the font, bail out if (FontInfo == 0) { FAIL ("ScrInit: Could not load X font"); } } else { // A user font has been given. Try to load that font FontInfo = XLoadQueryFont (SpunkDisplay, Font.GetStr ()); } // If we could not load the font, bail out if (FontInfo == 0) { FAIL ("ScrInit: Could not load X font"); } // Remember the font identifier SpunkFont = FontInfo->fid; // Get the width and height of the font int Direction, Ascent, Descent; XCharStruct Overall; XTextExtents (FontInfo, "", 0, &Direction, &Ascent, &Descent, &Overall); CharWidth = XTextWidth (FontInfo, "M", 1); CharHeight = Ascent + Descent; CharDescent = Descent; // Get the font parameters needed for the underlining of text if (XGetFontProperty (FontInfo, XA_UNDERLINE_POSITION, &CharULPos) == 0) { // Not defined, use default CharULPos = 2; } if (XGetFontProperty (FontInfo, XA_UNDERLINE_THICKNESS, &CharULThickness) == 0) { // Not defined, use default CharULThickness = 1; } // Determine the character set and the corresponding translation table // The default is to assume codepage 437 with any font that's name starts // with "vga", if not overridden by environment. Font.ToUpper (); ScreenCP437 = GetEnvBool ("SPUNK_CP437", Font.Match ("VGA*")); // Set up the window size XSizeHints SizeHints; XWMHints WMHints; SizeHints.x = 100; SizeHints.y = 100; SizeHints.flags = 0; // Search for a -geometry command argument String Geometry = GetStringArg ("-geometry"); if (!Geometry.IsEmpty ()) { // Set up the default string char DefaultGeometry [100]; sprintf (DefaultGeometry, "%ux%u+%d+%d", ScreenWidth, ScreenHeight, SizeHints.x, SizeHints.y); // We got something, parse it. int Flag = XGeometry (SpunkDisplay, SpunkScreen, Geometry.GetStr (), DefaultGeometry, 5, CharWidth, CharHeight, 0, 0, &SizeHints.x, &SizeHints.y, &ScreenWidth, &ScreenHeight); if (Flag & (XValue | YValue)) { SizeHints.flags |= USPosition; } else { SizeHints.flags |= PPosition; } if (Flag & (WidthValue | HeightValue)) { // Be shure, we have valid values if (ScreenWidth < MinWidth) { ScreenWidth = MinWidth; } else if (ScreenWidth > MaxWidth) { ScreenWidth = MaxWidth; } if (ScreenHeight < MinHeight) { ScreenHeight = MinHeight; } else if (ScreenHeight > MaxHeight) { ScreenHeight = MaxHeight; } SizeHints.flags |= USSize; } else { SizeHints.flags |= PSize; } } else { // No geometry argument given SizeHints.flags |= PPosition | PSize; } // Set up the remaining fields of the SizeHints structure SizeHints.width = ScreenWidth * CharWidth; SizeHints.height = ScreenHeight * CharHeight; SizeHints.min_width = MinWidth * CharWidth; SizeHints.min_height = MinHeight * CharHeight; SizeHints.max_width = MaxWidth * CharWidth; SizeHints.max_height = MaxHeight * CharHeight; SizeHints.width_inc = CharWidth; SizeHints.height_inc = CharHeight; SizeHints.flags |= PMinSize | PMaxSize | PResizeInc; WMHints.flags = InputHint; WMHints.input = True; // Create the window SpunkWindow = XCreateSimpleWindow (SpunkDisplay, DefaultRootWindow (SpunkDisplay), SizeHints.x, SizeHints.y, SizeHints.width, SizeHints.height, 5, Colors [coWhite].pixel, Colors [coBlack].pixel); XSetStandardProperties (SpunkDisplay, // Display SpunkWindow, // Window GetProgName ().GetStr (), // Window name GetProgName ().GetStr (), // Icon name None, // Icon Pixmap GetArgVec (), // argv GetArgCount (), // argc &SizeHints); // Hints XSetWMHints (SpunkDisplay, SpunkWindow, &WMHints); // GC creation and initialization SpunkGC = XCreateGC (SpunkDisplay, SpunkWindow, 0, 0); // Load the font to use XSetFont (SpunkDisplay, SpunkGC, SpunkFont); // Set the cursor to show over the spunk window Cursor C = XCreateFontCursor (SpunkDisplay, XC_pirate); XDefineCursor (SpunkDisplay, SpunkWindow, C); // Select input events XSelectInput (SpunkDisplay, SpunkWindow, KeyPressMask | ExposureMask | StructureNotifyMask); // Show the window XMapRaised (SpunkDisplay, SpunkWindow); } void ScrExit () // Destroy the window { XUndefineCursor (SpunkDisplay, SpunkWindow); XFreeGC (SpunkDisplay, SpunkGC); XDestroyWindow (SpunkDisplay, SpunkWindow); XCloseDisplay (SpunkDisplay); } static void ScrUpdateRow (unsigned X0, unsigned Y0, unsigned Width, int MustUpdate = 0) // Update a screen row { // Buffer management char Buf [MaxWidth]; unsigned Count = 0; unsigned StartX = 0; // initialize to avoid gcc warning... // Loop over a row for (unsigned X = X0; X < X0 + Width; X++) { // Get the screen cell u16 Cell = VirtualScreen [Y0][X]; // Check if the screen cell needs an update. if (MustUpdate == 0 && Cell == ActualScreen [Y0][X]) { // We do not need an update and the cell is already ok. // If we have characters in the output buffer, draw them, // then start over with the next char. if (Count) { // Draw the text ScrDrawText (StartX, Y0, Buf, Count); // Buffer is empty now Count = 0; } // Next char continue; } // If the new attribute is different from the last one, there's // something to do unsigned char Attr = (Cell >> 8) & 0x7F; if (Attr != LastAttr) { // New attribute. Check if there are characters in the buffer // that have the old attribute. If so, write them out if (Count) { // Draw the text ScrDrawText (StartX, Y0, Buf, Count); // Buffer is empty now Count = 0; } // Put the new character in the buffer and remember the starting // position Buf [Count++] = char (Cell & 0x00FF); StartX = X; // Setup the colors for the new attribute ScrSetupAttr (Attr); } else { // No attribute change. If this is the first char in the buffer, // remember the position if (Count == 0) { StartX = X; } // Add the character to the buffer Buf [Count++] = char (Cell & 0x00FF); } // Ok, we did the update. Remember the actual screen contents ActualScreen [Y0][X] = Cell; } // If there are characters in the buffer, write them out if (Count) { ScrDrawText (StartX, Y0, Buf, Count); } // If we overwrote the cursor, redraw it if (CursorY == Y0 && CursorX >= X0 && CursorX < X0 + Width) { ScrDrawCursor (); } } void ScrWriteBuf (unsigned X, unsigned Y, const u16* Buf, unsigned Count) // Write a buffer line to the screen, clipping right if needed { if (Y >= (unsigned) ScreenHeight || X >= (unsigned) ScreenWidth) { // Completely outside return; } // Clip to the right if (X + Count > (unsigned) ScreenWidth) { Count = ScreenWidth - X; } // Copy the buffer in place, clearing the high bit of the attribute // (the blink bit). Blinking is not supported anyway, so we use the // high bit of the attribute to mark the cursor position. unsigned RunX = X; unsigned C = Count; while (C--) { VirtualScreen [Y][RunX++] = *Buf++ & 0x7FFF; } // Update the buffer row on the screen ScrUpdateRow (X, Y, Count); } static void ScrUpdateArea (unsigned X0, unsigned Y0, unsigned Width, unsigned Height, int MustUpdate = 0) // Update a window area from the virtual screen. R must be already clipped! { // Loop over all rows for (unsigned Y = Y0; Y < Y0 + Height; Y++) { // Update each row in turn ScrUpdateRow (X0, Y, Width, MustUpdate); } } void ScrFlush () // Flush the output command queue { XFlush (SpunkDisplay); } /*****************************************************************************/ /* Code */ /*****************************************************************************/ static void KbdPress (XEvent& Event) // Handle a keypress event { // Remember the state unsigned State = Event.xkey.state; // Make a keysym KeySym Sym; XLookupString (&Event.xkey, NULL, 0, &Sym, NULL); // Determine the modifier state unsigned Table = kiPlane; if (State & ShiftMask) { Table = kiShift; } else if (State & ControlMask) { Table = kiCtrl; } else if (State & AltMask) { Table = kiMeta; } // Look for the symbol (### should be binary search - but needs sorting) for (unsigned I = 0; I < sizeof (KeySymMap) / sizeof (KeySymMap [0]); I++) { if (KeySymMap [I].Sym == Sym) { // Found Key K = KeySymMap [I].Keys [Table]; if (K != kbNoKey) { KbdBuffer.Put (K); } return; } } // Not found - ignore the key } static void EventLoop () // Get all waiting events and handle them { // Read input events while (XEventsQueued (SpunkDisplay, QueuedAfterFlush) != 0) { // Read an event XEvent Event; XNextEvent (SpunkDisplay, &Event); // switch (Event.type) { case Expose: if (Event.xexpose.count == 0) { // Calculate the area to redraw unsigned X1 = Event.xexpose.x / CharWidth; unsigned Y1 = Event.xexpose.y / CharHeight; unsigned X2 = (Event.xexpose.x + Event.xexpose.width - 1) / CharWidth; unsigned Y2 = (Event.xexpose.y + Event.xexpose.height - 1) / CharHeight; ScrUpdateArea (X1, Y1, X2 - X1 + 1, Y2 - Y1 + 1, 1); } break; case MappingNotify: XRefreshKeyboardMapping (&Event.xmapping); break; case KeyPress: KbdPress (Event); break; case ConfigureNotify: if (Event.xconfigure.width != int (ScreenWidth * CharWidth) || Event.xconfigure.height != int (ScreenHeight * CharHeight)) { // Size has changed, notify the application raise (SIGWINCH); } break; } } // Flush the outgoing event queue XFlush (SpunkDisplay); } static Key KbdMapExtended (Key K) // Map an extended key to a virtual key. Return the virtual key if a map // exists, otherwise return the key unchanged. { for (unsigned I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].EK == K) { return VirtualMap [I].VK; } } return K; } static Key KbdMapVirtual (Key K) // Map a virtual key to an extended key. Return the extended key if a map // exists, otherwise return the key unchanged. { for (unsigned I = 0; I < sizeof (VirtualMap) / sizeof (VirtualMap [0]); I++) { if (VirtualMap [I].VK == K) { return VirtualMap [I].EK; } } return K; } /*****************************************************************************/ /* class Keyboard */ /*****************************************************************************/ Keyboard::Keyboard (): Console (1), TransTable (NULL) // Don't need a translation table, translation // is done via table in KbdPress { } Keyboard::~Keyboard () { delete [] TransTable; } Key Keyboard::RawKey () // Get a raw (unmapped) key { while (1) { // Get all waiting events EventLoop (); // End the loop if we got an input key if (!KbdBuffer.IsEmpty ()) { break; } // Get the file handle of the window connection int Handle = ConnectionNumber (SpunkDisplay); int Result; do { // No waiting events - call the applications idle function before // waiting for more Idle (); // Use select() with a timeout of 100ms to wait for new events timeval Timeout; Timeout.tv_usec = 100000; Timeout.tv_sec = 0; // Set the file descriptor fd_set Desc; FD_ZERO (&Desc); FD_SET (Handle, &Desc); // Check the connection status Result = select (Handle+1, &Desc, NULL, NULL, &Timeout); CHECK (Result >= 0); } while (Result == 0); } // Return the key from the buffer return KbdBuffer.Get (); } void Keyboard::GetMappedKey (int Wait) // Read keys until the needed key is not found in the mapper or until // a valid sequence is found. If Wait is zero, return immediately if // no match is found and no more keys are available. { // Handling incoming events EventLoop (); // If we should not wait, check if keys are available before grabbing them if (Wait == 0 && KbdBuffer.IsEmpty ()) { // No keys available, bail out return; } // Get a key and remap it KeyBuf.Put (KbdMapExtended (RawKey ())); } String Keyboard::GetKeyName (Key K) // Return a string describing the give key { if (IsVirtualKey (K)) { // It is a virtual key, remap it to it's extended form K = KbdMapVirtual (K); } // Now return the key description return LoadMsg (MSGBASE_KBD + K); } estic-1.61.orig/spunk/xsrc/screen.cc0100644000176100001440000001425507031424720016723 0ustar debacleusers/*****************************************************************************/ /* */ /* SCREEN.CC */ /* */ /* (C) 1995-96 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@ibb.schwaben.com */ /* */ /*****************************************************************************/ // $Id$ // // $Log$ // // #include #include "../cont.h" #include "../winattr.h" #include "../environ.h" #include "../progutil.h" #include "../screen.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ // Instance of the screen class to handle screen output. Must be initialized // from outside (RootWindow) Screen* TheScreen; // Screen dimensions extern unsigned ScreenHeight; extern unsigned ScreenWidth; // Screen is using codepage 437 extern int ScreenCP437; // Screen is using a color mode extern int ScreenColor; /*****************************************************************************/ /* Code */ /*****************************************************************************/ // Because of name clashes with the X Window system, the complete functionality // of class Screen is implemented outside in module console.cc (maybe // namespaces will help avoid this problem one day). // The following functions are all external visible and defined in console.cc. void ScrSetMode (unsigned Mode); // Set a screen mode void ScrInit (unsigned XSize, unsigned YSize); // Initialize the screen void ScrExit (); // Destroy the window void ScrWriteBuf (unsigned X, unsigned Y, const u16* Buf, unsigned Count); // Write a buffer line to the screen, clipping right if needed void ScrFlush (); // Flush the output command queue void ScrCursorOn (); // Set the cursor state to on void ScrCursorOff (); // Set the cursor state to off void ScrCursorFat (); // Set the cursor state to fat void ScrSetCursorPos (unsigned X, unsigned Y); // Set the cursor position /*****************************************************************************/ /* class Screen */ /*****************************************************************************/ Screen::Screen (): XSize (80), YSize (25), CurrentMode (vmVGA_80x25), Color (1), Console (1), CP437 (1), TransTable (NULL) { // Initialize the screen stuff ScrInit (XSize, YSize); // The values given to the call above are default values. They may be // overridden by the user. So get the actual values now. XSize = ScreenWidth; YSize = ScreenHeight; // Check for the codepage 437/850 if (ScreenCP437 == 0) { // Use a replacement string for the frame chars ActiveFrame = InactiveFrame = SimpleFrame; // We don't have the codepage 437. Check if we have ISO 8859-1 support // and load a matching translation table. Allow for both environment // variables, SPUNK_CTYPE and LC_CTYPE and allow for some permutations // of the ISO-8859-1 name, since everyone handles it different :-( String Var = GetEnvVar ("SPUNK_CTYPE"); if (Var.IsEmpty ()) { Var = GetEnvVar ("LC_CTYPE"); } // Ok, we now have the value of the environment variable. Match it // against a pattern to cover the maximum count of possible cases. Var.ToUpper (); char* ResName; if (Var.Match ("*ISO[-_]8859[-_]1*")) { // We got some iso-8859-1 string or the other ResName = "SCREEN.ISO-8859-1-Table"; // } else if (Var.Match ("*KOI-8R*")) { // // Currently not used // ResName = "SCREEN.KOI-8R-Table"; } else { ResName = "SCREEN.7BIT-ASCII-Table"; } // Load the translation table from the resource Container* C = (Container*) LoadResource (ResName); TransTable = (unsigned char*) C->RetrieveData (); delete C; } // Remember if we are using colors Color = ScreenColor; } Screen::~Screen () { // Destroy the window ScrExit (); // Delete the translation table delete [] TransTable; } u16* Screen::Translate (u16* Target, u16* Source, unsigned Len) // Translate a complete buffer via the translation table { if (TransTable) { u16* T = Target; while (Len--) { *T = (*Source & 0xFF00) | TransTable [(*Source & 0xFF)]; Source++; T++; } return Target; } else { return Source; } } void Screen::SetMode (u16 Mode) { // Remember mode CurrentMode = Mode; // Set the mode ScrSetMode (Mode); // Set the new size XSize = ScreenWidth; YSize = ScreenHeight; // Colors may have changed Color = ScreenColor; } void Screen::SetCursorOn () { ScrCursorOn (); } void Screen::SetCursorOff () { ScrCursorOff (); } void Screen::SetCursorFat () { ScrCursorFat (); } void Screen::SetCursorPos (const Point &Pos) { ScrSetCursorPos (unsigned (Pos.X), unsigned (Pos.Y)); } void Screen::DisplayBuffer (const Rect& R, u16* Buf) { int XtoDo, YtoDo; int XCount = R.XSize (); int YCount = R.YSize (); // Check if there is anything to do if (XCount == 0 || YCount == 0 || R.A.Y > YSize || R.A.X > XSize) { // Done return; } // Calculate the size of the output rectangle XtoDo = (R.B.X > XSize) ? XSize - R.A.X : XCount; YtoDo = (R.B.Y > YSize) ? YSize - R.A.Y : YCount; // If we have to translate the output, get buffer memory. This operation // is cheap, so do it, even if we don't need the buffer to avoid warnings u16* Buf2 = (u16*) alloca (XtoDo * sizeof (u16)); // Write the stuff to the screen for (unsigned Y = R.A.Y; Y < R.A.Y + YtoDo; Y++) { // Copy the data into the virtual screen ScrWriteBuf (R.A.X, Y, Translate (Buf2, Buf, XtoDo), XtoDo); // Next line Buf += XCount; } // Flush the output queue ScrFlush (); } unsigned Screen::TerminalSpeed () // Get some information on the terminal speed. This will return a value // between 0..10, where 10 is a very fast (direct access) screen and // 0 is a very slow (300 baud) serial line. // This may be used to change the amount of screen output, a program // produces. { // We have always direct access to the screen return 10; } estic-1.61.orig/spunk/xsrc/x.doc0100644000176100001440000000026207031424720016064 0ustar debacleusersDie beiden Alt-Tasten dürfen nicht "parallelgeschaltet" sein, in meinem Fall war dazu ein xmodmap -e "remove mod5 = Alt_L" notwendig. VGA Font sollte vorhanden sein.