From ff62746743f3fd21f73d05ff89bcc5e6d3815dac Mon Sep 17 00:00:00 2001 From: Jens Kallup Date: Sat, 4 Nov 2023 16:34:21 +0100 Subject: [PATCH] update --- src/Interpreter.cc | 12 +- src/Turbo.cc | 208 ++++ src/build.sh | 151 ++- src/datacoll.cc | 126 ++ src/datacoll.h | 57 + src/formcmds.h | 44 + src/forms.cc | 201 ++++ src/forms.h | 58 + src/include/pch.h | 6 + src/include/tvision/app.h | 350 ++++++ src/include/tvision/buffers.h | 89 ++ src/include/tvision/colors.h | 751 ++++++++++++ src/include/tvision/colorsel.h | 467 ++++++++ src/include/tvision/compat/borland/_defs.h | 44 + src/include/tvision/compat/borland/_null.h | 26 + src/include/tvision/compat/borland/alloc.h | 12 + src/include/tvision/compat/borland/dir.h | 76 ++ src/include/tvision/compat/borland/dos.h | 87 ++ src/include/tvision/compat/borland/fstream.h | 18 + src/include/tvision/compat/borland/io.h | 45 + src/include/tvision/compat/borland/iomanip.h | 19 + src/include/tvision/compat/borland/iosfwd.h | 24 + src/include/tvision/compat/borland/iostream.h | 28 + src/include/tvision/compat/borland/mem.h | 25 + src/include/tvision/compat/borland/strstrea.h | 19 + src/include/tvision/compat/malloc/malloc.h | 16 + src/include/tvision/compat/windows/windows.h | 326 +++++ src/include/tvision/config.h | 33 + src/include/tvision/dialogs.h | 1047 +++++++++++++++++ src/include/tvision/drawbuf.h | 95 ++ src/include/tvision/editors.h | 549 +++++++++ src/include/tvision/hardware.h | 318 +++++ src/include/tvision/help.h | 74 ++ src/include/tvision/helpbase.h | 192 +++ src/include/tvision/internal/ansidisp.h | 154 +++ src/include/tvision/internal/base64.h | 36 + src/include/tvision/internal/codepage.h | 71 ++ src/include/tvision/internal/constarr.h | 31 + src/include/tvision/internal/constmap.h | 111 ++ src/include/tvision/internal/cursor.h | 101 ++ src/include/tvision/internal/dispbuff.h | 114 ++ src/include/tvision/internal/events.h | 177 +++ src/include/tvision/internal/far2l.h | 27 + src/include/tvision/internal/findfrst.h | 87 ++ src/include/tvision/internal/getenv.h | 31 + src/include/tvision/internal/gpminput.h | 51 + src/include/tvision/internal/linuxcon.h | 66 ++ src/include/tvision/internal/ncurdisp.h | 62 + src/include/tvision/internal/ncursinp.h | 51 + src/include/tvision/internal/pathconv.h | 45 + src/include/tvision/internal/platform.h | 204 ++++ src/include/tvision/internal/scrlife.h | 31 + src/include/tvision/internal/sighandl.h | 81 ++ src/include/tvision/internal/sigwinch.h | 36 + src/include/tvision/internal/stdioctl.h | 57 + src/include/tvision/internal/strings.h | 49 + src/include/tvision/internal/termdisp.h | 66 ++ src/include/tvision/internal/terminal.h | 218 ++++ src/include/tvision/internal/unixcon.h | 50 + src/include/tvision/internal/utf8.h | 94 ++ src/include/tvision/internal/win32con.h | 107 ++ src/include/tvision/internal/winwidth.h | 56 + src/include/tvision/menus.h | 551 +++++++++ src/include/tvision/msgbox.h | 87 ++ src/include/tvision/objects.h | 296 +++++ src/include/tvision/outline.h | 217 ++++ src/include/tvision/resource.h | 278 +++++ src/include/tvision/scrncell.h | 281 +++++ src/include/tvision/stddlg.h | 731 ++++++++++++ src/include/tvision/surface.h | 88 ++ src/include/tvision/system.h | 558 +++++++++ src/include/tvision/textview.h | 129 ++ src/include/tvision/tkeys.h | 216 ++++ src/include/tvision/tobjstrm.h | 665 +++++++++++ src/include/tvision/tspan.h | 125 ++ src/include/tvision/tstrview.h | 248 ++++ src/include/tvision/ttext.h | 490 ++++++++ src/include/tvision/ttypes.h | 177 +++ src/include/tvision/tv.h | 778 ++++++++++++ src/include/tvision/tvobjs.h | 152 +++ src/include/tvision/util.h | 105 ++ src/include/tvision/validate.h | 303 +++++ src/include/tvision/views.h | 1045 ++++++++++++++++ src/win32api.cc | 6 +- 84 files changed, 15325 insertions(+), 58 deletions(-) create mode 100644 src/Turbo.cc create mode 100644 src/datacoll.cc create mode 100644 src/datacoll.h create mode 100644 src/formcmds.h create mode 100644 src/forms.cc create mode 100644 src/forms.h create mode 100644 src/include/pch.h create mode 100644 src/include/tvision/app.h create mode 100644 src/include/tvision/buffers.h create mode 100644 src/include/tvision/colors.h create mode 100644 src/include/tvision/colorsel.h create mode 100644 src/include/tvision/compat/borland/_defs.h create mode 100644 src/include/tvision/compat/borland/_null.h create mode 100644 src/include/tvision/compat/borland/alloc.h create mode 100644 src/include/tvision/compat/borland/dir.h create mode 100644 src/include/tvision/compat/borland/dos.h create mode 100644 src/include/tvision/compat/borland/fstream.h create mode 100644 src/include/tvision/compat/borland/io.h create mode 100644 src/include/tvision/compat/borland/iomanip.h create mode 100644 src/include/tvision/compat/borland/iosfwd.h create mode 100644 src/include/tvision/compat/borland/iostream.h create mode 100644 src/include/tvision/compat/borland/mem.h create mode 100644 src/include/tvision/compat/borland/strstrea.h create mode 100644 src/include/tvision/compat/malloc/malloc.h create mode 100644 src/include/tvision/compat/windows/windows.h create mode 100644 src/include/tvision/config.h create mode 100644 src/include/tvision/dialogs.h create mode 100644 src/include/tvision/drawbuf.h create mode 100644 src/include/tvision/editors.h create mode 100644 src/include/tvision/hardware.h create mode 100644 src/include/tvision/help.h create mode 100644 src/include/tvision/helpbase.h create mode 100644 src/include/tvision/internal/ansidisp.h create mode 100644 src/include/tvision/internal/base64.h create mode 100644 src/include/tvision/internal/codepage.h create mode 100644 src/include/tvision/internal/constarr.h create mode 100644 src/include/tvision/internal/constmap.h create mode 100644 src/include/tvision/internal/cursor.h create mode 100644 src/include/tvision/internal/dispbuff.h create mode 100644 src/include/tvision/internal/events.h create mode 100644 src/include/tvision/internal/far2l.h create mode 100644 src/include/tvision/internal/findfrst.h create mode 100644 src/include/tvision/internal/getenv.h create mode 100644 src/include/tvision/internal/gpminput.h create mode 100644 src/include/tvision/internal/linuxcon.h create mode 100644 src/include/tvision/internal/ncurdisp.h create mode 100644 src/include/tvision/internal/ncursinp.h create mode 100644 src/include/tvision/internal/pathconv.h create mode 100644 src/include/tvision/internal/platform.h create mode 100644 src/include/tvision/internal/scrlife.h create mode 100644 src/include/tvision/internal/sighandl.h create mode 100644 src/include/tvision/internal/sigwinch.h create mode 100644 src/include/tvision/internal/stdioctl.h create mode 100644 src/include/tvision/internal/strings.h create mode 100644 src/include/tvision/internal/termdisp.h create mode 100644 src/include/tvision/internal/terminal.h create mode 100644 src/include/tvision/internal/unixcon.h create mode 100644 src/include/tvision/internal/utf8.h create mode 100644 src/include/tvision/internal/win32con.h create mode 100644 src/include/tvision/internal/winwidth.h create mode 100644 src/include/tvision/menus.h create mode 100644 src/include/tvision/msgbox.h create mode 100644 src/include/tvision/objects.h create mode 100644 src/include/tvision/outline.h create mode 100644 src/include/tvision/resource.h create mode 100644 src/include/tvision/scrncell.h create mode 100644 src/include/tvision/stddlg.h create mode 100644 src/include/tvision/surface.h create mode 100644 src/include/tvision/system.h create mode 100644 src/include/tvision/textview.h create mode 100644 src/include/tvision/tkeys.h create mode 100644 src/include/tvision/tobjstrm.h create mode 100644 src/include/tvision/tspan.h create mode 100644 src/include/tvision/tstrview.h create mode 100644 src/include/tvision/ttext.h create mode 100644 src/include/tvision/ttypes.h create mode 100644 src/include/tvision/tv.h create mode 100644 src/include/tvision/tvobjs.h create mode 100644 src/include/tvision/util.h create mode 100644 src/include/tvision/validate.h create mode 100644 src/include/tvision/views.h diff --git a/src/Interpreter.cc b/src/Interpreter.cc index 347997e9..01785cb6 100644 --- a/src/Interpreter.cc +++ b/src/Interpreter.cc @@ -28,6 +28,7 @@ std::string file_output_ct; // output misc/tools C++ file extern void asm_parser_main(void); extern "C" int yyparse(void); extern "C" FILE * yyin; +extern int TurboMain(void); // console TUI - Turbo Vision static bool found_args = false; // program command line arguments @@ -785,7 +786,8 @@ int main(int argc, char **argv) options_description general("General Options"); general.add_options() ("help,h" , "Help screen") - ("locale,l", value< std::string >()->default_value("en" ), "locale"); + ("locale,l", value< std::string >()->default_value("en" ), "country locale") + ("gui,g" , "TUI - Text User Interface"); options_description input_long("Input Options (long)"); input_long.add_options() @@ -866,6 +868,14 @@ int main(int argc, char **argv) found_args = true; } + + // -------------------------------------- + // open textual GUI: TurboVision for DOS + // -------------------------------------- + if (vm.count("gui")) { + return TurboMain(); + } + // -------------------------------------- // check, if input, and output file is ok // -------------------------------------- diff --git a/src/Turbo.cc b/src/Turbo.cc new file mode 100644 index 00000000..8569db8a --- /dev/null +++ b/src/Turbo.cc @@ -0,0 +1,208 @@ +// ----------------------------------------------------------------- +// File: Turbo.cc +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- +# define Uses_TKeys +# define Uses_TApplication +# define Uses_TEvent +# define Uses_TRect +# define Uses_TDialog +# define Uses_TStaticText +# define Uses_TButton +# define Uses_TMenuBar +# define Uses_TSubMenu +# define Uses_TMenuItem +# define Uses_TStatusLine +# define Uses_TStatusItem +# define Uses_TStatusDef +# define Uses_TDeskTop +# define Uses_TChDirDialog +# define Uses_TFileDialog +# define Uses_MsgBox +# define Uses_TDisplay +# define Uses_TScreen +# define Uses_TEditor +# define Uses_TEditWindow +# define Uses_TMemo +# define Uses_TStreamableClass +# include + +# include +# include + +#include "formcmds.h" + +#define FORM_WILDCARD "*.f32" + +extern TPoint shadowSize; +const int MAXSIZE = 150; + +ushort execDialog( TDialog *d, void *data ) +{ + TView *p = TProgram::application->validView( d ); + if( p == 0 ) + return cmCancel; + else + { + if( data != 0 ) + p->setData( data ); + ushort result = TProgram::deskTop->execView( p ); + if( result != cmCancel && data != 0 ) + p->getData( data ); + TObject::destroy( p ); + return result; + } +} + +class TFormApp : public TApplication +{ +public: + + TFormApp(); + + void handleEvent( TEvent& Event); + static TMenuBar *initMenuBar( TRect r); + static TStatusLine *initStatusLine( TRect r); + void changeDir(); + + TEditWindow * openEditor( const char *fileName, Boolean visible ); + void fileNew(); + void fileOpen(); +}; + +TEditWindow *TFormApp::openEditor( const char *fileName, Boolean visible ) +{ + TRect r = deskTop->getExtent(); + TView *p = validView( new TEditWindow( r, fileName, wnNoNumber ) ); + if( !visible ) + p->hide(); + deskTop->insert( p ); + return (TEditWindow *)p; +} + +void TFormApp::fileOpen() +{ + char fileName[MAXPATH]; + strcpy( fileName, "*.*" ); + + if( execDialog( new TFileDialog( "*.*", "Open file", + "~N~ame", fdOpenButton, 100 ), fileName) != cmCancel ) + openEditor( fileName, True ); +} + +void TFormApp::fileNew() +{ + openEditor( 0, True ); +} + +// TFormApp +TFormApp::TFormApp() : + TProgInit(&TFormApp::initStatusLine, + &TFormApp::initMenuBar, + &TFormApp::initDeskTop), + TApplication() +{ + TEvent event; + + // Display about box + event.what = evCommand; + event.message.command = cmAboutBox; + putEvent(event); +} + +void TFormApp::changeDir() +{ + TView *d = validView( new TChDirDialog( 0, hlChangeDir ) ); + + if( d != 0 ) { + deskTop->execView( d ); + destroy(d); + } +} + +void TFormApp::handleEvent(TEvent& event) +{ + int newMode; + char aboutMsg[80]; + + TApplication::handleEvent(event); + if (event.what == evCommand) + { + switch (event.message.command) + { + case cmListOpen: + fileOpen(); + break; + case cmChgDir: + changeDir(); + break; + case cmAboutBox: + strcpy(aboutMsg, "\x3Turbo Vision AsmJit 1.0\n\n\x3non-profit Project"); + messageBox(aboutMsg, mfInformation | mfOKButton); + break; + case cmVideoMode: + newMode = TScreen::screenMode ^ TDisplay::smFont8x8; + if ((newMode & TDisplay::smFont8x8) != 0) + shadowSize.x = 1; + else + shadowSize.x = 2; + setScreenMode((ushort)newMode); + break; + + default: + return; + } + clearEvent(event); + } +} + +TMenuBar *TFormApp::initMenuBar( TRect r) +{ + + r.b.y = r.a.y + 1; + return new TMenuBar(r, + *new TSubMenu( "~\xF0~", hcNoContext ) + + *new TMenuItem( "~V~ideo mode", cmVideoMode, kbNoKey, hcNoContext, "" ) + + newLine() + + *new TMenuItem( "~A~bout...", cmAboutBox, kbNoKey, hcNoContext ) + + *new TSubMenu( "~F~ile", hcNoContext) + + *new TMenuItem( "~O~pen...", cmListOpen, kbF3, hcNoContext, "F3" ) + + *new TMenuItem( "~S~ave", cmListSave, kbF2, hcNoContext, "F2" ) + + newLine() + + *new TMenuItem( "~C~hange directory...", cmChgDir, kbNoKey, hcNoContext ) + + *new TMenuItem( "~D~OS shell", cmDosShell, kbNoKey, hcNoContext ) + + *new TMenuItem( "E~x~it", cmQuit, kbAltX, hcNoContext, "Alt-X" ) + + *new TSubMenu( "~W~indow", hcNoContext ) + + *new TMenuItem( "~M~ove", cmResize, kbCtrlF5, hcNoContext, "Cntl-F5") + + *new TMenuItem( "~N~ext", cmNext, kbF6, hcNoContext, "F6") + + *new TMenuItem( "~P~rev", cmPrev, kbShiftF6, hcNoContext, "Shift-F6") + + *new TMenuItem( "~C~lose", cmClose, kbAltF3, hcNoContext, "Alt-F3") + ); +} + +TStatusLine *TFormApp::initStatusLine( TRect r ) +{ + r.a.y = r.b.y - 1; + return new TStatusLine( r, + *new TStatusDef( 0, 0xFFFF ) + + *new TStatusItem( "~F2~ Save", kbF2, cmListSave ) + + *new TStatusItem( "~F3~ Open", kbF3, cmListOpen ) + + *new TStatusItem( "~F10~ Menu", kbF10, cmMenu) + + *new TStatusItem( 0, kbShiftDel, cmCut ) + + *new TStatusItem( 0, kbCtrlIns, cmCopy ) + + *new TStatusItem( 0, kbShiftIns, cmPaste ) + + *new TStatusItem( "", kbCtrlF5, cmResize ) + ); +} + +int TurboMain(void) +{ + TFormApp *formApp = new TFormApp; + formApp->run(); + TObject::destroy(formApp); + + return 0; +} diff --git a/src/build.sh b/src/build.sh index 57d21c0d..e990b2bb 100644 --- a/src/build.sh +++ b/src/build.sh @@ -13,11 +13,13 @@ TMP=$(echo "${PWD}/${TEMP}") FLAGS=$(echo "-std=c++20 -O2 -fPIC " \ "-Wno-pmf-conversions " \ "-Wno-register " \ + "-Wno-volatile " \ "-Wno-write-strings " \ "-DASMJIT_STATIC " \ "-DASMJIT_BUILD_RELEASE " \ "-DASMJIT_NO_AARCH64 " \ - "-I/E/msys64/mingw64/usr/include -I${SRC}/asmjit -I${TMP}") + "-I/E/msys64/mingw64/usr/include " \ + "-I../include -I../include/tvision -I${SRC}/asmjit -I${TMP}") # ----------------------------------------------------------------- ST1="s/\\\"Last\\-Translator\\: .*\\n\\\"/\\\"Last-Translator\\:" ST2="Jens Kallup \\\\n\\\"/g" @@ -81,6 +83,12 @@ msg_de_DE_0022="Übersetzung abgeschloßen" msg_de_DE_0023="\nDas Programm/Package wurde erfolgreich erstellt." msg_de_DE_0024="Erfolgreich" msg_de_DE_0025="\nAlle Aufgaben wurden erfolgreich ausgeführt." +msg_de_DE_0026="Löschen der Debug-Informationen" +msg_de_DE_0027="\nverkleinere Anwendungs-Datei, um die Debug-Informationen-" +msg_de_DE_0028="Erstelle Script Dateien" +msg_de_DE_0029="Die Skript-Dateien für Lexer,und Parser werden erstellt..." +msg_en_US_0030="Fehler aufgetretten" +msg_en_US_0031="Es wurde ein Fehler vom Compiler zurückgegeben." # ----------------------------------------------------------------- msg_en_US_0000="English" msg_en_US_0001="gattering setup data..." @@ -112,6 +120,12 @@ msg_en_US_0023="\nThe Compiler return successfully.\n" msg_en_US_0023+="Application/Package was built." msg_en_US_0024="Successfull" msg_en_US_0025="\nAll task's was built successfully." +msg_en_US_0026="Delete Debug-Information" +msg_en_US_0027="shrink Application, delete Debug-Informations-" +msg_en_US_0028="Create Lexer/Parser" +msg_en_US_0029="Create script files for Lexer, and Parser..." +msg_en_US_0030="Error occured." +msg_en_US_0031="Error occured while compile file: " # ----------------------------------------------------------------- xlen=$(tput cols) ylen=$(tput lines) @@ -125,10 +139,9 @@ dwidth=$(($xlen - $(($bx * 2)))) # leave some padding at the bottom dheight=$(($ylen - $(($by + $padbottom)))) lic=$(cat ../LICENSE) -bgtitle="Pascal Doxy version 0.0.1 (c) 2923 by paule32" cols="92" rows="$(stty size | cut -d ' ' -f 1)" -dlgs="${DLG} --backtitle '$bgtitle'" +dlgs="${DLG} --backtitle \"Pascal Doxy version 0.0.1 (c) 2923 by paule32\"" # ----------------------------------------------------------------- # place holder to provide a global common abort function: # ----------------------------------------------------------------- @@ -164,7 +177,7 @@ function run_build_prepare () { # -------------------------------------- # fill the localization array with text: # -------------------------------------- - for cnt in {0..27}; do + for cnt in {0..31}; do number=$(printf "%04d" $cnt) eval "Z=msg_${build_locale}_\$number" errloc+=("${Z}") @@ -313,12 +326,25 @@ function run_build_prepare () { # check last command return value. if it > 0 then error message ... # ----------------------------------------------------------------- function run_check () { - if [[ ! $1 -eq 0 ]]; then - echo "Error: ($2) exec failed. =]" - echo "aborted." + if [[ $1 -eq 0 ]]; then + return + fi + if [[ -z "$2" ]]; then + printf '\033[8;%d;%dt' $rows $cols + /usr/bin/dialog --backtitle "Pascal Doxy version 0.0.1 (c) 2923 by paule32" \ + --title "Success" --msgbox "no error detected" 14 79 cd ${SRC} - exit $1 + clear + exit 1 + fi + if [[ -n "${DLG}" ]]; then + printf '\033[8;%d;%dt' $rows $cols + /usr/bin/dialog --backtitle "Pascal Doxy version 0.0.1 (c) 2923 by paule32" \ + --title "Error" --msgbox "$2" 14 79 fi + cd ${SRC} + clear + exit 1 } # ----------------------------------------------------------------- # check, if file exists. no? then exit ... @@ -655,7 +681,7 @@ if [[ -n "${built_app}" ]]; then if [[ -n "${DLG}" ]]; then printf '\033[8;%d;%dt' $rows $cols - dlg="(sleep 4 ; exit 1) | $dlgs --title \"${!errloc[25]}\" \ + dlg="(exit 1) | $dlgs --title \"${!errloc[25]}\" \ --msgbox \"${!errloc[26]}\" 10 79" eval "$dlg" fi @@ -668,10 +694,17 @@ fi # ---------------------------------------- if [[ -n "${built_dis}" ]]; then cd ${TMP} - echo "compile disassemler..." - + run_build_prepare + if [[ -z "${DLG}" ]]; then + echo "compile disassemler..." + else + printf '\033[8;%d;%dt' $rows $cols + dlg="(exit 1) | $dlgs --title \"${!errloc[29]}\" \ + --gauge \"${!errloc[30]}\" 10 79 70" + eval "$dlg" + fi # ---------------------------------------- - # built parser script files ... + # buils parser script files ... # ---------------------------------------- ${BISON} -d \ -Wno-conflicts-rr \ @@ -680,59 +713,69 @@ if [[ -n "${built_dis}" ]]; then -o${TMP}/AssemblerParser.cc ${SRC}/assembler.y ${FLEX} -i -o${TMP}/AssemblerScanner.cc ${SRC}/assembler.lex - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/Interpreter.o -c ${SRC}/Interpreter.cc - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/AssemblerParser.o -c ${TMP}/AssemblerParser.cc - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/AssemblerScanner.o -c ${TMP}/AssemblerScanner.cc + if [[ -z "${DLG}" ]]; then + echo "compile parser objects..." + else + printf '\033[8;%d;%dt' $rows $cols + dlg="(exit 1) | $dlgs --title \"${!errloc[19]}\" \ + --gauge \"${!errloc[20]}\" 10 79 70" + eval "$dlg" + fi + # ---------------------------------------- + # build parser object files ... + # ---------------------------------------- + cmd=$(${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/Interpreter.o -c ${SRC}/Interpreter.cc 2>&1 ); run_check $? "${cmd}" + cmd=$(${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/AssemblerParser.o -c ${TMP}/AssemblerParser.cc 2>&1 ); run_check $? "${cmd}" + cmd=$(${GXX} ${FLAGS} -DHAVE_PARSER_ASM -UYY_USE_CLASS -o${TMP}/AssemblerScanner.o -c ${TMP}/AssemblerScanner.cc 2>&1 ); run_check $? "${cmd}" + + # ---------------------------------------- + # build turbo vision stuff ... + # ---------------------------------------- + cmd=$(${GXX} ${FLAGS} -o${TMP}/Turbo.o -c ${SRC}/Turbo.cc 2>&1 ); run_check $? "${cmd}" + cmd=$(${GXX} ${FLAGS} -o${TMP}/forms.o -c ${SRC}/forms.cc 2>&1 ); run_check $? "${cmd}" + cmd=$(${GXX} ${FLAGS} -o${TMP}/datacoll.o -c ${SRC}/datacoll.cc 2>&1 ); run_check $? "${cmd}" - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -o ${TMP}/diss.exe \ + # ---------------------------------------- + # link diss.exe application ... + # ---------------------------------------- + cmd=$(${GXX} ${FLAGS} -DHAVE_PARSER_ASM -o ${TMP}/diss.exe \ + ${TMP}/Turbo.o \ + ${TMP}/forms.o \ ${TMP}/Interpreter.o \ ${TMP}/AssemblerParser.o \ ${TMP}/AssemblerScanner.o \ - -L./asmjit -lasmjit -lintl -lboost_program_options-mt + -L./ -L./asmjit \ + -lasmjit \ + -lintl \ + -ltvision \ + -lboost_program_options-mt \ + -static-libgcc -static-libstdc++ 2>&1 ); run_check $? "${cmd}" - strip ${TMP}/diss.exe - echo "done" + if [[ -z "${DLG}" ]]; then + echo "compile disassemler..." + else + printf '\033[8;%d;%dt' $rows $cols + dlg="(exit 1) | $dlgs --title \"${!errloc[27]}\" \ + --gauge \"${!errloc[28]}\" 10 79 78" + eval "$dlg" + fi - cd ${SRC} - exit 1 - - # ---------------------------------------- - # compile C++ source files ... - # ---------------------------------------- - DAT="" - for i in ${!obj_array2[@]}; do - DAT="${obj_array2[$i]}" - - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -o ${TMP}/${DAT}.o \ - -c ${SRC}/${DAT}.cc - - run_check $? "${DAT}.o" - done # ---------------------------------------- - # compile lexe + parser source files ... + # strip debug informations, shrink .exe # ---------------------------------------- - for i in ${!obj_array3[@]}; do - DAT="${obj_array3[$i]}" - - ${GXX} ${FLAGS} -DHAVE_PARSER_ASM -o ${TMP}/${DAT}.o \ - -c ${TMP}/${DAT}.cc - - run_check $? "${DAT}.o" - done + cmd=$(strip ${TMP}/diss.exe 2>&1); run_check $? "${cmd}" + # ---------------------------------------- - # link all together (.o files) ... + # display "done" message ... # ---------------------------------------- - DAT="" - for i in ${!obj_array2[@]}; do DAT+="${TMP}/${obj_array2[$i]}.o "; done - for i in ${!obj_array3[@]}; do DAT+="${TMP}/${obj_array3[$i]}.o "; done + if [[ -n "${DLG}" ]]; then + printf '\033[8;%d;%dt' $rows $cols + dlg="(exit 1) | $dlgs --title \"${!errloc[25]}\" \ + --msgbox \"${!errloc[26]}\" 10 79" + eval "$dlg" + clear + fi - ${GXX} -o ${TMP}/diss.exe ${DAT} \ - -L${TMP}/asmjit -lasmjit \ - -lintl -lgmpxx - run_check $? "diss.exe" - - strip diss.exe - printf "done.\n" cd ${SRC} exit 1 fi diff --git a/src/datacoll.cc b/src/datacoll.cc new file mode 100644 index 00000000..af4eb389 --- /dev/null +++ b/src/datacoll.cc @@ -0,0 +1,126 @@ +// ----------------------------------------------------------------- +// File: datacoll.cc +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- + +# define Uses_TStreamableClass +# define Uses_TStringCollection +# define Uses_ipstream +# define Uses_opstream + +# include + +#include "datacoll.h" +#include + +const char * const TDataCollection::name = "TDataCollection"; + +void TDataCollection::write( opstream& os ) +{ + os << itemSize; + TStringCollection::write(os); + int temp = int(keyType); + os << temp; +} + +void *TDataCollection::read( ipstream& is ) +{ + is >> itemSize; + TStringCollection::read( is ); + int temp; + is >> temp; + keyType = KeyTypes(temp); + status = 0; + return this; +} + +TStreamable *TDataCollection::build() +{ + return new TDataCollection( streamableInit ); +} + +void TDataCollection::writeItem( void *obj, opstream& os ) +{ + os.writeBytes( obj, itemSize ); +} + +void *TDataCollection::readItem( ipstream& is ) +{ + void *obj; + + obj = new char[itemSize]; + is.readBytes(obj, itemSize); + return obj; +} + +TStreamableClass RDataCollection( TDataCollection::name, + TDataCollection::build, + __DELTA(TDataCollection) + ); + +TDataCollection::TDataCollection( short aLimit, short aDelta, + int anItemSize, + KeyTypes aKeyType) : + TStringCollection( aLimit, aDelta ), + itemSize( anItemSize ), + keyType( aKeyType ) +{ +} + +int TDataCollection::compare( void *key1, void *key2 ) +{ + + if (keyType == stringKey) + return stricmp((char*)key1, (char*) key2); + else + { + if (!key1 || !key2 || *(int32_t *)key1 < *(int32_t *)key2) + return -1; + else if (*(int32_t *)key1 == *(int32_t *)key2) + return 0; + else + return 1; + } +} + +void TDataCollection::error( int code ) +// Save error status instead of giving a runtime error +{ + status = code; +} + +void TDataCollection::freeItem( void *item ) +{ + if (item != NULL) + delete[] (char *) item; +} + +void TDataCollection::setLimit( int aLimit ) +{ + void **aItems; + + if (aLimit < count) + aLimit = count; + if (aLimit > maxCollectionSize) + aLimit = maxCollectionSize; + if (aLimit != limit) + { + if (aLimit == 0) + aItems = NULL; + else + { + // Restrict collection: don't allow it to eat into safety pool. + // Requires careful checking for success at point of insertion. + aItems = new void *[aLimit]; + if ( (count != 0) && (items != 0) ) + memcpy(aItems, items, count * sizeof(void *)); + } + if (limit != 0) + delete[] items; + items = aItems; + limit = aLimit; + } +} diff --git a/src/datacoll.h b/src/datacoll.h new file mode 100644 index 00000000..c7896c00 --- /dev/null +++ b/src/datacoll.h @@ -0,0 +1,57 @@ +// ----------------------------------------------------------------- +// File: x86code.cc +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- +# pragma once + +# define Uses_TStringCollection +# define Uses_TStreamable +# include + +enum KeyTypes {stringKey, longIntKey}; + +class TDataCollection : public TStringCollection +{ + +public: + + TDataCollection( short, short, int , KeyTypes ); + virtual int compare( void *, void * ); + virtual void error( int code ); + virtual void freeItem( void * ); + virtual void setLimit( int ); + +protected: + + TDataCollection( StreamableInit) : TStringCollection( streamableInit ) {}; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +private: + + virtual const char *streamableName() const + { return name; } + virtual void *readItem( ipstream& ); + virtual void writeItem( void *, opstream& ); + +public: + + static const char * const name; + unsigned int itemSize; + KeyTypes keyType; + int status; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TDataCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TDataCollection*& cl ) + { return is >> (void *&)cl; } +inline opstream& operator << ( opstream& os, TDataCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TDataCollection* cl ) + { return os << (TStreamable *)cl; } diff --git a/src/formcmds.h b/src/formcmds.h new file mode 100644 index 00000000..4223254c --- /dev/null +++ b/src/formcmds.h @@ -0,0 +1,44 @@ +// ----------------------------------------------------------------- +// File: formcmds.h +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- +#pragma once + +// Misc UI commands + +const ushort + cmAboutBox = 2000, + cmChgDir = 2001, + cmVideoMode = 2002; + +// List & form-oriented commands +// (Cannot be disabled) + +const ushort + cmListOpen = 3000, + cmListSave = 3001, + cmFormEdit = 3002, + cmFormNew = 3003, + cmFormSave = 3004, + cmFormDel = 3005; + +// Broadcast commands + +const ushort + cmTopForm = 3050, + cmRegisterForm = 3051, + cmEditingForm = 3052, + cmCanCloseForm = 3053, + cmCloseForm = 3054, + cmTopList = 3055, + cmEditingFile = 3056; + +// History list IDs + +const ushort + hlChangeDir = 1, + hlOpenListDlg = 2; + diff --git a/src/forms.cc b/src/forms.cc new file mode 100644 index 00000000..e8341cbf --- /dev/null +++ b/src/forms.cc @@ -0,0 +1,201 @@ +// ----------------------------------------------------------------- +// File: forms.cc +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- +# define Uses_TKeys +# define Uses_TEvent +# define Uses_TRect +# define Uses_TDialog +# define Uses_TStreamableClass +# define Uses_MsgBox + +#include + +#include "forms.h" +#include "formcmds.h" + +#include + +// Compares two buffers and returns True if contents are equal + +Boolean compBlocks( void *buf1, void *buf2, ushort bufSize ) +{ + return Boolean(memcmp( buf1, buf2, bufSize ) == 0); +} + +const char * const TForm::name = "TForm"; + +void TForm::write( opstream& os ) +{ + + TDialog::write( os ); + os << keyWidth; + +} + +void *TForm::read( ipstream& is ) +{ + + TDialog::read( is ); + is >> keyWidth; + return this; +} + +TStreamable *TForm::build() +{ + return new TForm( streamableInit ); +} + + +TStreamableClass RForm( TForm::name, + TForm::build, + __DELTA(TForm) + ); + +TForm::TForm( const TRect& bounds, const char *aTitle) : + TWindowInit(&TForm::initFrame), + TDialog(bounds, aTitle) +{ +} + +Boolean TForm::changed() +{ + void *curData; + ushort compSize; + Boolean newForm, result; + + compSize = dataSize(); + curData = new char[compSize]; + getData(curData); + if (prevData == NULL) + newForm = True; + else + newForm = False; + + if (newForm) + { + // Dummy up empty record for comparison + prevData = new char[compSize]; + memset(prevData, 0, compSize); + } + if (compBlocks(prevData, curData, compSize)) + result = False; + else + result = True; + + delete[] (char *) curData; + if (newForm) + { + delete[] (char *) prevData; + prevData = NULL; + } + if (result) + return True; + else + return False; +} + +void TForm::handleEvent( TEvent& event) +{ + // Respond to CANCEL button and ESC + if ( ( (event.what == evKeyDown) && (event.keyDown.keyCode == kbEsc) ) || + ( (event.what == evCommand) && (event.message.command == cmCancel) ) ) + { + clearEvent(event); + destroy(this); + return; + } + + // Respond to SAVE button + if ( (event.what == evCommand) && (event.message.command == cmFormSave) ) + { + clearEvent(event); + if (changed() == True) + { +/* + if (((TListDialog *)listDialog)->saveForm(this)) + { + destroy(this); + return; + } +*/ + } + else + { + destroy(this); // not changed + return; + } + } + + TDialog::handleEvent(event); + + // Respond to TopForm messages + if (event.what == evBroadcast) + { + if (event.message.command == cmEditingForm) + { + // Already editing broadcast form? + if ( (prevData != NULL) && (event.message.infoPtr == prevData) ) + clearEvent(event); + } +/* else + // Belong to sending ListDialog? + + if (listDialog == event.message.infoPtr) + { + if (event.message.command == cmTopForm) + clearEvent(event); + else if (event.message.command == cmCanCloseForm) + { + if (!valid(cmClose)) + clearEvent(event); + } + else if (event.message.command == cmCloseForm) + destroy(this); + } +*/ + } +} + +Boolean TForm::valid(ushort command) +{ + ushort action; + + action = cmYes; // assume calling inherited + if (command == cmClose) + { + if (changed()) + { + select(); + action = messageBox("Form data has been modified. Save? ", + mfYesNoCancel); + switch (action) + { + case cmYes: + // Try to save changes. Cancel if save fails +// if (!((TListDialog *)listDialog)->saveForm(this)) +// action = cmCancel; + break; + case cmNo: + break; // abandon changes + default : + action = cmCancel; // cancel close request + } + } + else + action = cmNo; // no changes + } + if (action == cmYes) + return TDialog::valid(command); + else + { + if (action != cmCancel) + return True; + else + return False; + + } +} diff --git a/src/forms.h b/src/forms.h new file mode 100644 index 00000000..cb04eb33 --- /dev/null +++ b/src/forms.h @@ -0,0 +1,58 @@ +// ----------------------------------------------------------------- +// File: forms.h +// Author: (c) 2023 Jens Kallup - paule32 +// All rights reserved +// +// only for education, and non-profit usage ! +// ----------------------------------------------------------------- +# pragma once + +# define Uses_TStreamable +# define Uses_TEvent +# define Uses_TRect +# define Uses_TDialog +# define Uses_TView + +# include + +class TForm : public TDialog +{ + +public: + + TForm( StreamableInit ) : TWindowInit(&TForm::initFrame), TDialog (streamableInit) {}; + TForm( const TRect&, const char* ); + virtual Boolean changed(); + virtual void handleEvent( TEvent& ); + virtual Boolean valid( ushort ); + +// TView *listDialog; + void *prevData; + ushort keyWidth; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TForm& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TForm*& cl ) + { return is >> (void *&)cl; } +inline opstream& operator << ( opstream& os, TForm& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TForm* cl ) + { return os << (TStreamable *)cl; } + diff --git a/src/include/pch.h b/src/include/pch.h new file mode 100644 index 00000000..4b72e062 --- /dev/null +++ b/src/include/pch.h @@ -0,0 +1,6 @@ +#define Uses_TApplication +#define Uses_TDialog +#include +#include +#include +#include diff --git a/src/include/tvision/app.h b/src/include/tvision/app.h new file mode 100644 index 00000000..5b1b1e27 --- /dev/null +++ b/src/include/tvision/app.h @@ -0,0 +1,350 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* APP.H */ +/* */ +/* defines the classes TBackground, TDeskTop, TProgram, and TApplication */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TBackground ) && !defined( __TBackground ) +#define __TBackground + +class _FAR TRect; + +class TBackground : public TView +{ + +public: + + TBackground( const TRect& bounds, char aPattern ) noexcept; + virtual void draw(); + virtual TPalette& getPalette() const; + + char pattern; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TBackground( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TBackground& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TBackground*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TBackground& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TBackground* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TBackground + + +#if defined( Uses_TDeskTop ) && !defined( __TDeskTop ) +#define __TDeskTop + +class _FAR TBackground; +class _FAR TRect; +struct _FAR TEvent; + +class TDeskInit +{ + +public: + + TDeskInit( TBackground *(*cBackground)( TRect ) ) noexcept; + +protected: + + TBackground *(*createBackground)( TRect ); + +}; + +class TDeskTop : public TGroup, public virtual TDeskInit +{ + +public: + + TDeskTop( const TRect& ) noexcept; + + void cascade( const TRect& ); + virtual void handleEvent( TEvent& ); + static TBackground *initBackground( TRect ); + void tile( const TRect& ); + virtual void tileError(); + virtual void shutDown(); + + TBackground *background; + +protected: + + Boolean tileColumnsFirst; + +private: + + static const char _NEAR defaultBkgrnd; + + virtual const char *streamableName() const + { return name; } + +protected: + + TDeskTop( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TDeskTop& cl ) + { return is >> (TStreamable&)(TGroup&)cl; } +inline ipstream& operator >> ( ipstream& is, TDeskTop*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TDeskTop& cl ) + { return os << (TStreamable&)(TGroup&)cl; } +inline opstream& operator << ( opstream& os, TDeskTop* cl ) + { return os << (TStreamable *)(TGroup *)cl; } + +#endif + +// Turbo Vision 2.0 Color Palettes + +#define cpAppColor \ + "\x71\x70\x78\x74\x20\x28\x24\x17\x1F\x1A\x31\x31\x1E\x71\x1F" \ + "\x37\x3F\x3A\x13\x13\x3E\x21\x3F\x70\x7F\x7A\x13\x13\x70\x7F\x7E" \ + "\x70\x7F\x7A\x13\x13\x70\x70\x7F\x7E\x20\x2B\x2F\x78\x2E\x70\x30" \ + "\x3F\x3E\x1F\x2F\x1A\x20\x72\x31\x31\x30\x2F\x3E\x31\x13\x38\x00" \ + "\x17\x1F\x1A\x71\x71\x1E\x17\x1F\x1E\x20\x2B\x2F\x78\x2E\x10\x30" \ + "\x3F\x3E\x70\x2F\x7A\x20\x12\x31\x31\x30\x2F\x3E\x31\x13\x38\x00" \ + "\x37\x3F\x3A\x13\x13\x3E\x30\x3F\x3E\x20\x2B\x2F\x78\x2E\x30\x70" \ + "\x7F\x7E\x1F\x2F\x1A\x20\x32\x31\x71\x70\x2F\x7E\x71\x13\x78\x00" \ + "\x37\x3F\x3A\x13\x13\x30\x3E\x1E" // help colors + +#define cpAppBlackWhite \ + "\x70\x70\x78\x7F\x07\x07\x0F\x07\x0F\x07\x70\x70\x07\x70\x0F" \ + "\x07\x0F\x07\x70\x70\x07\x70\x0F\x70\x7F\x7F\x70\x07\x70\x07\x0F" \ + "\x70\x7F\x7F\x70\x07\x70\x70\x7F\x7F\x07\x0F\x0F\x78\x0F\x78\x07" \ + "\x0F\x0F\x0F\x70\x0F\x07\x70\x70\x70\x07\x70\x0F\x07\x07\x08\x00" \ + "\x07\x0F\x0F\x07\x70\x07\x07\x0F\x0F\x70\x78\x7F\x08\x7F\x08\x70" \ + "\x7F\x7F\x7F\x0F\x70\x70\x07\x70\x70\x70\x07\x7F\x70\x07\x78\x00" \ + "\x70\x7F\x7F\x70\x07\x70\x70\x7F\x7F\x07\x0F\x0F\x78\x0F\x78\x07" \ + "\x0F\x0F\x0F\x70\x0F\x07\x70\x70\x70\x07\x70\x0F\x07\x07\x08\x00" \ + "\x07\x0F\x07\x70\x70\x07\x0F\x70" // help colors + +#define cpAppMonochrome \ + "\x70\x07\x07\x0F\x70\x70\x70\x07\x0F\x07\x70\x70\x07\x70\x00" \ + "\x07\x0F\x07\x70\x70\x07\x70\x00\x70\x70\x70\x07\x07\x70\x07\x00" \ + "\x70\x70\x70\x07\x07\x70\x70\x70\x0F\x07\x07\x0F\x70\x0F\x70\x07" \ + "\x0F\x0F\x07\x70\x07\x07\x70\x07\x07\x07\x70\x0F\x07\x07\x70\x00" \ + "\x70\x70\x70\x07\x07\x70\x70\x70\x0F\x07\x07\x0F\x70\x0F\x70\x07" \ + "\x0F\x0F\x07\x70\x07\x07\x70\x07\x07\x07\x70\x0F\x07\x07\x01\x00" \ + "\x70\x70\x70\x07\x07\x70\x70\x70\x0F\x07\x07\x0F\x70\x0F\x70\x07" \ + "\x0F\x0F\x07\x70\x07\x07\x70\x07\x07\x07\x70\x0F\x07\x07\x01\x00" \ + "\x07\x0F\x07\x70\x70\x07\x0F\x70" // help colors + +#if defined( Uses_TProgram ) && !defined( __TProgram ) +#define __TProgram + +// Standard application help contexts + +// Note: range $FF00 - $FFFF of help contexts are reserved by Borland + +const unsigned short hcNew = 0xFF01; +const unsigned short hcOpen = 0xFF02; +const unsigned short hcSave = 0xFF03; +const unsigned short hcSaveAs = 0xFF04; +const unsigned short hcSaveAll = 0xFF05; +const unsigned short hcChangeDir = 0xFF06; +const unsigned short hcDosShell = 0xFF07; +const unsigned short hcExit = 0xFF08; + +const unsigned short hcUndo = 0xFF10; +const unsigned short hcCut = 0xFF11; +const unsigned short hcCopy = 0xFF12; +const unsigned short hcPaste = 0xFF13; +const unsigned short hcClear = 0xFF14; + +const unsigned short hcTile = 0xFF20; +const unsigned short hcCascade = 0xFF21; +const unsigned short hcCloseAll = 0xFF22; +const unsigned short hcResize = 0xFF23; +const unsigned short hcZoom = 0xFF24; +const unsigned short hcNext = 0xFF25; +const unsigned short hcPrev = 0xFF26; +const unsigned short hcClose = 0xFF27; + + +class _FAR TStatusLine; +class _FAR TMenuBar; +class _FAR TDeskTop; +struct _FAR TEvent; +class _FAR TView; + +class TProgInit +{ + +public: + + TProgInit( TStatusLine *(*cStatusLine)( TRect ), + TMenuBar *(*cMenuBar)( TRect ), + TDeskTop *(*cDeskTop )( TRect ) + ) noexcept; + +protected: + + TStatusLine *(*createStatusLine)( TRect ); + TMenuBar *(*createMenuBar)( TRect ); + TDeskTop *(*createDeskTop)( TRect ); + +}; + +/* ---------------------------------------------------------------------- */ +/* class TProgram */ +/* */ +/* Palette layout */ +/* 1 = TBackground */ +/* 2- 7 = TMenuView and TStatusLine */ +/* 8-15 = TWindow(Blue) */ +/* 16-23 = TWindow(Cyan) */ +/* 24-31 = TWindow(Gray) */ +/* 32-63 = TDialog */ +/* ---------------------------------------------------------------------- */ + +const int + +// TApplication palette entries + + apColor = 0, + apBlackWhite = 1, + apMonochrome = 2; + +class _FAR TDialog; +class _FAR TWindow; +class _FAR TTimerQueue; + +class TProgram : public TGroup, public virtual TProgInit +{ + +public: + + TProgram() noexcept; + virtual ~TProgram(); + + virtual Boolean canMoveFocus(); + virtual ushort executeDialog(TDialog*, void*data = 0); + virtual void getEvent(TEvent& event); + virtual TPalette& getPalette() const; + virtual void handleEvent(TEvent& event); + virtual void idle(); + virtual void initScreen(); + virtual void outOfMemory(); + virtual void putEvent( TEvent& event ); + virtual void run(); + virtual TWindow* insertWindow(TWindow*); + void setScreenMode( ushort mode ); + TView *validView( TView *p ) noexcept; + virtual void shutDown(); + + virtual TTimerId setTimer( uint timeoutMs, int periodMs = -1 ); + virtual void killTimer( TTimerId id ); + + virtual void suspend() {} + virtual void resume() {} + + static TStatusLine *initStatusLine( TRect ); + static TMenuBar *initMenuBar( TRect ); + static TDeskTop *initDeskTop( TRect ); + + static TProgram * _NEAR application; + static TStatusLine * _NEAR statusLine; + static TMenuBar * _NEAR menuBar; + static TDeskTop * _NEAR deskTop; + static int _NEAR appPalette; + static int _NEAR eventTimeout; + +protected: + + static TEvent _NEAR pending; + +private: + + static int eventWaitTimeout(); + + static const char * _NEAR exitText; + static TTimerQueue _NEAR timerQueue; + +}; + +#endif + +#if defined( Uses_TApplication ) && !defined( __TApplication ) +#define __TApplication + +class TStaticInit +{ + +public: + TStaticInit() noexcept; + +}; + +// Virtual inheritance of TStaticInit to ensure its constructor is ran first. +class TApplication : public TProgram, public virtual TStaticInit +{ + +protected: + + TApplication() noexcept; + virtual ~TApplication(); + +public: + virtual void suspend(); + virtual void resume(); + + void cascade(); + void dosShell(); + virtual TRect getTileRect(); + virtual void handleEvent(TEvent &event); + void tile(); + virtual void writeShellMsg(); + +}; + +#endif + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/buffers.h b/src/include/tvision/buffers.h new file mode 100644 index 00000000..cf4b0981 --- /dev/null +++ b/src/include/tvision/buffers.h @@ -0,0 +1,89 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* BUFFERS.H */ +/* */ +/* defines the functions getBufMem() and freeBufMem() for use */ +/* in allocating and freeing viedo buffers */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TVMemMgr ) && !defined( __TVMemMgr ) +#define __TVMemMgr + +const int DEFAULT_SAFETY_POOL_SIZE = 4096; + +class TBufListEntry +{ + +private: + + TBufListEntry( void*&, size_t sz ) noexcept; +#if __cplusplus >= 201103L + TBufListEntry(const TBufListEntry &) = default; +#endif + void destroy() noexcept; + + void *operator new( size_t, size_t ) noexcept; + void *operator new( size_t ) noexcept; + void operator delete( void * ) noexcept; + + TBufListEntry *next; + TBufListEntry *prev; + void*& owner; + size_t sz; + + static TBufListEntry *_NEAR bufList; + static Boolean freeHead() noexcept; + + friend class TVMemMgr; + friend void *operator new( size_t ); + friend void * allocBlock( size_t ); + +}; + +class TVMemMgr +{ + +public: + + TVMemMgr() noexcept; + ~TVMemMgr(); + + static void resizeSafetyPool( size_t = DEFAULT_SAFETY_POOL_SIZE ) noexcept; + static int safetyPoolExhausted() noexcept; + + static void allocateDiscardable( void *&, size_t ) noexcept; + static void reallocateDiscardable( void *&, size_t ) noexcept; + static void freeDiscardable( void * ) noexcept; + +private: + + static void * _NEAR safetyPool; + static size_t _NEAR safetyPoolSize; + static int _NEAR inited; + static int initMemMgr() noexcept; + +}; + +#endif // Uses_TVMemMgr + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/colors.h b/src/include/tvision/colors.h new file mode 100644 index 00000000..7da99126 --- /dev/null +++ b/src/include/tvision/colors.h @@ -0,0 +1,751 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* COLORS.H */ +/* */ +/* Defines the structs TColorBIOS, TColorRGB, TColorXTerm, */ +/* TColorDesired, TColorAttr and TAttrPair. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#ifndef TVISION_COLORS_H +#define TVISION_COLORS_H + +#ifdef __BORLANDC__ + +inline TColorDesired getFore(const TColorAttr &attr) +{ + return uchar(attr & 0xF); +} + +inline TColorDesired getBack(const TColorAttr &attr) +{ + return uchar(attr >> 4); +} + +inline void setFore(TColorAttr &attr, TColorDesired color) +{ + attr = uchar(attr & 0xF0) | uchar(color & 0xF); +} + +inline void setBack(TColorAttr &attr, TColorDesired color) +{ + attr = uchar(attr & 0xF) | uchar(color << 4); +} + +inline TColorAttr reverseAttribute(TColorAttr attr) +{ + return uchar(attr << 4) | uchar(attr >> 4); +} + +#else // __BORLANDC__ + +#include + +// Helper class for trivial types. + +namespace colors +{ + + template(-1)> + struct alignas(T) trivially_convertible + { + + using trivial_t = T; + + // If you want the derived classes to be trivial, make sure you also + // define a trivial default constructor in them. + trivially_convertible() = default; + + trivially_convertible(T asT) + { + asT &= mask; + memcpy(this, &asT, sizeof(T)); + } + + operator T() const + { + T asT; + memcpy(&asT, this, sizeof(T)); + return asT & mask; + } + + }; + +} // namespace colors + +//// Color Formats + +////// TColorRGB +// +// Can be initialized like this: +// TColorRGB rgb = {127, 0, 187}; // {red, green, blue}. +// Or with an integer: +// TColorRGB rgb = 0x7F00BB; // 0xRRGGBB +// Can be converted back to integer types: +// uint32_t asInt = TColorRGB(127, 0, 187); +// When doing so, the unused bits are discarded: +// uint32_t(TColorRGB(0xAABBCCDD)) == 0xBBCCDD; + +struct TColorRGB : colors::trivially_convertible +{ + uint32_t + b : 8, + g : 8, + r : 8, + _unused : 8; + + using trivially_convertible::trivially_convertible; + TColorRGB() = default; + constexpr inline TColorRGB(uint8_t r, uint8_t g, uint8_t b); +}; + +constexpr inline TColorRGB::TColorRGB(uint8_t r, uint8_t g, uint8_t b) : + b(b), + g(g), + r(r), + _unused(0) +{ +} + +////// TColorBIOS +// +// This is the 4-bit color encoding used originally by Turbo Vision on MS-DOS. +// +// Can be initialized with an integer: +// TColorBIOS black = 0x0, +// blue = 0x1, +// dark_gray = 0x8; +// And converted back to a integer types: +// uint8_t asChar = TColorBIOS(0xC); +// When doing so, the unused bits are discarded: +// uint8_t(TColorBIOS(0xAB)) == 0xB; + +struct TColorBIOS : colors::trivially_convertible +{ + uint8_t + b : 1, + g : 1, + r : 1, + bright : 1, + _unused : 4; + + using trivially_convertible::trivially_convertible; + TColorBIOS() = default; +}; + +////// TColorXTerm +// +// Index into an 256-color palette recognized by the 'xterm-256color' terminal type. +// Some terminal emulators support modifying the palette, but Turbo Vision does +// not make use of this feature. So we assume index values 16 to 255 can be +// unequivocally converted from and into RGB as per the table in: +// +// https://jonasjacek.github.io/colors/ +// +// Indices 0 to 15 will be displayed just like BIOS colors. +// +// This type can be converted from and into integer types: +// TColorXTerm xterm = 0xFE; +// uint8_t asChar = xterm; + +struct TColorXTerm : colors::trivially_convertible +{ + uint8_t idx; + + using trivially_convertible::trivially_convertible; + TColorXTerm() = default; +}; + +//// Color Conversion Functions +// +// They convert between the color types defined previously and other common +// color formats. +// +// No conversion from XTerm16 to RGB is provided because there is no consensus +// on how these colors should be represented and we don't want to encourage +// developers to assume the opposite. Most terminal emulators allow users to +// configure these colors through color schemes. +// +// That's not the case of XTerm256 indices 16 to 255 (with 0 to 15 being the +// same as XTerm16). So we assume these can be unambiguously mapped to a single +// RGB value as per the tables in: +// +// https://jonasjacek.github.io/colors/ + +inline uint8_t BIOStoXTerm16(TColorBIOS); +inline TColorBIOS RGBtoBIOS(TColorRGB); +inline uint8_t RGBtoXTerm16(TColorRGB); +inline uint8_t RGBtoXTerm256(TColorRGB); +inline TColorBIOS XTerm16toBIOS(uint8_t); +inline TColorRGB XTerm256toRGB(uint8_t); // Only for indices 16..255. +inline uint8_t XTerm256toXTerm16(uint8_t); + +namespace tvision +{ + template + struct constarray; + + uint8_t RGBtoXTerm16Impl(TColorRGB) noexcept; + extern const constarray XTerm256toXTerm16LUT; + extern const constarray XTerm256toRGBLUT; +} + +inline uint8_t BIOStoXTerm16(TColorBIOS c) +{ + // Swap the Red and Blue bits. + uchar aux = c.b; + c.b = c.r; + c.r = aux; + return c; +} + +inline TColorBIOS RGBtoBIOS(TColorRGB c) +{ + return XTerm16toBIOS(RGBtoXTerm16(c)); +} + +inline uint8_t RGBtoXTerm16(TColorRGB c) +{ + using namespace tvision; + return RGBtoXTerm16Impl(c); +} + +inline uint8_t RGBtoXTerm256(TColorRGB c) +{ + // The xterm-256color palette consists of: + // + // * [0..15]: 16 colors as in xterm-16color. + // * [16..231]: 216 colors in a 6x6x6 cube. + // * [232..255]: 24 grayscale colors. + // + // This function does not return indices in the range [0..15]. For that, + // use 'RGBtoXTerm16' instead. + // + // Dark colors are underrepresented in the 6x6x6 cube. The channel values + // [0, 1, 2, 3, 4, 5] correspond to the 8-bit values + // [0, 95, 135, 175, 215, 255]. Thus there is a distance of 40 between + // values, except for 0. Any 8-bit value smaller than 95 - 40/2 = 75 + // would have to be mapped into 0. To compensate a bit for this, we allow + // values [55..74] to also be mapped into 1. + // + // Additionally, we fall back on the grayscale colors whenever using + // the 6x6x6 color cube would round the color to pure black. This + // makes it possible to preserve details that would otherwise be lost. + auto cnvColor = [] (TColorRGB c) + { + auto scale = [] (uchar c) + { + c += 20 & -(c < 75); + return uchar(max(c, 35) - 35)/40; + }; + uchar r = scale(c.r), + g = scale(c.g), + b = scale(c.b); + return 16 + uchar(r*uchar(6) + g)*uchar(6) + b; + }; + auto cnvGray = [] (uchar l) + { + if (l < 8 - 5) + return 16; + if (l >= 238 + 5) + return 231; + return 232 + uchar(max(l, 3) - 3)/uchar(10); + }; + + uchar idx = cnvColor(c); + if (c != XTerm256toRGB(idx)) + { + uchar Xmin = min(min(c.r, c.g), c.b), + Xmax = max(max(c.r, c.g), c.b); + uchar C = Xmax - Xmin; // Chroma in the HSL/HSV theory. + if (C < 12 || idx == 16) // Grayscale if Chroma < 12 or rounded to black. + { + uchar L = ushort(Xmax + Xmin)/2; // Lightness, as in HSL. + idx = cnvGray(L); + } + } + return idx; +} + +inline TColorBIOS XTerm16toBIOS(uint8_t idx) +{ + return BIOStoXTerm16(idx); +} + +inline uint8_t XTerm256toXTerm16(uint8_t idx) +{ + using namespace tvision; + return ((const uint8_t (&) [256]) XTerm256toXTerm16LUT)[idx]; +} + +inline TColorRGB XTerm256toRGB(uint8_t idx) +{ + using namespace tvision; + return ((const uint32_t (&) [256]) XTerm256toRGBLUT)[idx]; +} + +//// TColorDesired +// +// This is a union type of the different possible kinds of color: BIOS, RGB, +// XTerm or Default. +// The purpose of this type is to describe the foreground *or* background color +// of a screen cell. +// +// You can initialize as BIOS color with a char literal, as RGB with an integer +// literal and as Default with zero-initialization: +// TColorDesired bios = '\xF', +// rgb = 0x7F00BB, +// def = {}; +// +// In a terminal emulator, the 'default color' is the color of text that has no +// display attributes (bold, color...) enabled. + +const uchar + ctDefault = 0x0, // Terminal default. + ctBIOS = 0x1, // TColorBIOS. + ctRGB = 0x2, // TColorRGB. + ctXTerm = 0x3; // TColorXTerm. + +struct TColorDesired +{ + + uint32_t _data; + + TColorDesired() = default; + + // Constructors for use with literals. + + constexpr inline TColorDesired(char bios); // e.g. {'\xF'} + constexpr inline TColorDesired(uchar bios); + constexpr inline TColorDesired(int rgb); // e.g. {0x7F00BB} + // Use zero-initialization for for type Default: {} + + // Constructors with explicit type names. + + inline TColorDesired(TColorBIOS bios); + inline TColorDesired(TColorRGB rgb); + inline TColorDesired(TColorXTerm xterm); + + TV_TRIVIALLY_ASSIGNABLE(TColorDesired) + + constexpr inline uchar type() const; + constexpr inline bool isDefault() const; + constexpr inline bool isBIOS() const; + constexpr inline bool isRGB() const; + constexpr inline bool isXTerm() const; + + // No conversion is performed! Make sure to check the type first. + + inline TColorBIOS asBIOS() const; + inline TColorRGB asRGB() const; + inline TColorXTerm asXTerm() const; + + // Quantization to TColorBIOS. + + inline TColorBIOS toBIOS(bool isForeground) const; + + inline bool operator==(TColorDesired other) const; + inline bool operator!=(TColorDesired other) const; + + constexpr inline uint32_t bitCast() const; + constexpr inline void bitCast(uint32_t val); + +}; + +constexpr inline TColorDesired::TColorDesired(char bios) : + TColorDesired(uchar(bios)) +{ +} + +constexpr inline TColorDesired::TColorDesired(uchar bios) : + _data((bios & 0xF) | (ctBIOS << 24)) +{ +} + +constexpr inline TColorDesired::TColorDesired(int rgb) : + _data((rgb & 0xFFFFFF) | (ctRGB << 24)) +{ +} + +inline TColorDesired::TColorDesired(TColorBIOS bios) : + TColorDesired(uchar(bios)) +{ +} + +inline TColorDesired::TColorDesired(TColorRGB rgb) : + TColorDesired(int(rgb)) +{ +} + +inline TColorDesired::TColorDesired(TColorXTerm xterm) : + _data(xterm | (ctXTerm << 24)) +{ +} + +constexpr inline uchar TColorDesired::type() const +{ + return _data >> 24; +} + +constexpr inline bool TColorDesired::isDefault() const +{ + return type() == ctDefault; +} + +constexpr inline bool TColorDesired::isBIOS() const +{ + return type() == ctBIOS; +} + +constexpr inline bool TColorDesired::isRGB() const +{ + return type() == ctRGB; +} + +constexpr inline bool TColorDesired::isXTerm() const +{ + return type() == ctXTerm; +} + +inline TColorBIOS TColorDesired::asBIOS() const +{ + return _data; +} + +inline TColorRGB TColorDesired::asRGB() const +{ + return _data; +} + +inline TColorXTerm TColorDesired::asXTerm() const +{ + return _data; +} + +inline TColorBIOS TColorDesired::toBIOS(bool isForeground) const +{ + switch (type()) + { + case ctBIOS: + return asBIOS(); + case ctRGB: + return RGBtoBIOS(asRGB()); + case ctXTerm: + { + uint8_t idx = asXTerm(); + if (idx >= 16) + idx = XTerm256toXTerm16(idx); + return XTerm16toBIOS(idx); + } + default: + return isForeground ? 0x7 : 0x0; + } +} + +inline bool TColorDesired::operator==(TColorDesired other) const +{ + return memcmp(this, &other, sizeof(*this)) == 0; +} + +inline bool TColorDesired::operator!=(TColorDesired other) const +{ + return !(*this == other); +} + +constexpr inline uint32_t TColorDesired::bitCast() const +{ + return _data; +} + +constexpr inline void TColorDesired::bitCast(uint32_t val) +{ + _data = val; +} + +//// TColorAttr +// +// Represents the color attributes of a screen cell. +// Examples: +// +// /* Foreground: BIOS 0x7. */ +// /* Background: RGB 0x7F00BB. */ +// /* Style: Bold, Italic. */ +// TColorAttr a = {'\x07', 0x7F00BB, slBold | slItalic}; +// +// /* Foreground: Default. */ +// /* Background: BIOS 0xF. */ +// /* Style: Normal. */ +// TColorAttr b = {{}, '\xF'}; +// +// For backward-compatibility, you can also use initialize a TColorAttr +// with a BIOS color attribute: +// +// /* Foreground: BIOS 0xD. */ +// /* Background: BIOS 0x3. */ +// /* Style: Normal. */ +// TColorAttr c = 0x3D; +// +// A zero-initialized TColorAttr has both the foreground and background +// colors set to 'default'. Therefore, a zero-initialized TColorAttr produces +// visible text. + +const ushort + +// TColorAttr Style masks + + slBold = 0x001, + slItalic = 0x002, + slUnderline = 0x004, + slBlink = 0x008, + slReverse = 0x010, // Prefer using 'reverseAttribute()' instead. + slStrike = 0x020, + +// Private masks + + slNoShadow = 0x200; // Don't draw window shadows over this cell. + +struct TAttrPair; + +struct TColorAttr +{ + using Style = ushort; + + uint64_t + _style : 10, + _fg : 27, + _bg : 27; + + TColorAttr() = default; + constexpr inline TColorAttr(int bios); + constexpr inline TColorAttr(TColorDesired fg, TColorDesired bg, ushort style=0); + inline TColorAttr(const TAttrPair &attrs); + TV_TRIVIALLY_ASSIGNABLE(TColorAttr) + + inline bool isBIOS() const; + inline uchar asBIOS() const; // Result is meaningful only if it actually is BIOS. + inline uchar toBIOS() const; // Quantization. + + inline operator uchar() const; + inline TAttrPair operator<<(int shift) const; + + inline bool operator==(const TColorAttr &other) const; + inline bool operator!=(const TColorAttr &other) const; + + inline bool operator==(int bios) const; + inline bool operator!=(int bios) const; + +}; + +constexpr inline TColorDesired getFore(const TColorAttr &attr); +constexpr inline TColorDesired getBack(const TColorAttr &attr); +constexpr inline ushort getStyle(const TColorAttr &attr); +constexpr inline void setFore(TColorAttr &attr, TColorDesired fg); +constexpr inline void setBack(TColorAttr &attr, TColorDesired bg); +constexpr inline void setStyle(TColorAttr &attr, ushort style); +constexpr inline TColorAttr reverseAttribute(TColorAttr attr); + +constexpr inline TColorAttr::TColorAttr(int bios) : + _style(0), + _fg(TColorDesired(uchar(bios)).bitCast()), + _bg(TColorDesired(uchar(bios >> 4)).bitCast()) +{ +} + +constexpr inline TColorAttr::TColorAttr(TColorDesired fg, TColorDesired bg, ushort style) : + _style(style), + _fg(fg.bitCast()), + _bg(bg.bitCast()) +{ +} + +inline bool TColorAttr::isBIOS() const +{ + return (int) ::getFore(*this).isBIOS() & ::getBack(*this).isBIOS() & !::getStyle(*this); +} + +inline uchar TColorAttr::asBIOS() const +{ + // 'this' must be a BIOS attribute. If it is not, the result will be + // bogus but harmless. The important is that the result isn't '\x0' + // unless this is BIOS attribute '\x0'. + uchar bios = uchar(_fg) | uchar(_bg << 4); + return isBIOS() ? bios : 0x5F; +} + +inline uchar TColorAttr::toBIOS() const +{ + auto fg = ::getFore(*this), + bg = ::getBack(*this); + return fg.toBIOS(true) | (bg.toBIOS(false) << 4); +} + +inline TColorAttr::operator uchar() const +{ + return asBIOS(); +} + +inline bool TColorAttr::operator==(const TColorAttr &other) const +{ + return memcmp(this, &other, sizeof(*this)) == 0; +} + +inline bool TColorAttr::operator!=(const TColorAttr &other) const +{ + return !(*this == other); +} + +inline bool TColorAttr::operator==(int bios) const +{ + return *this == TColorAttr {(uchar) bios}; +} + +inline bool TColorAttr::operator!=(int bios) const +{ + return !(*this == bios); +} + +constexpr inline TColorDesired getFore(const TColorAttr &attr) +{ + TColorDesired color {}; + color.bitCast(attr._fg); + return color; +} + +constexpr inline TColorDesired getBack(const TColorAttr &attr) +{ + TColorDesired color {}; + color.bitCast(attr._bg); + return color; +} + +constexpr inline ushort getStyle(const TColorAttr &attr) +{ + return attr._style; +} + +constexpr inline void setFore(TColorAttr &attr, TColorDesired color) +{ + attr._fg = color.bitCast(); +} + +constexpr inline void setBack(TColorAttr &attr, TColorDesired color) +{ + attr._bg = color.bitCast(); +} + +constexpr inline void setStyle(TColorAttr &attr, ushort style) +{ + attr._style = style; +} + +constexpr inline TColorAttr reverseAttribute(TColorAttr attr) +{ + auto fg = ::getFore(attr), + bg = ::getBack(attr); + // The 'slReverse' attribute is represented differently by every terminal, + // so it is better to swap the colors manually unless any of them is default. + if ((int) fg.isDefault() | bg.isDefault()) + ::setStyle(attr, ::getStyle(attr) ^ slReverse); + else + { + ::setFore(attr, bg); + ::setBack(attr, fg); + } + return attr; +} + +//// TAttrPair +// +// Represents a pair of color attributes. +// Example: +// +// TColorAttr cNormal = {0x234983, 0x267232}; +// TColorAttr cHigh = {0x309283, 0x127844}; +// TAttrPair attrs = {cNormal, cHigh}; +// TDrawBuffer b; +// b.moveCStr(0, "Normal text, ~Highlighted text~", attrs); + +struct TAttrPair +{ + + TColorAttr _attrs[2]; + + TAttrPair() = default; + constexpr inline TAttrPair(int bios); + constexpr inline TAttrPair(const TColorAttr &lo, const TColorAttr &hi=uchar(0)); + TV_TRIVIALLY_ASSIGNABLE(TAttrPair) + + inline ushort asBIOS() const; + + inline operator ushort() const; + inline TAttrPair operator>>(int shift) const; + inline TAttrPair& operator|=(TColorAttr attr); + + inline TColorAttr& operator[](size_t i); + inline const TColorAttr& operator[](size_t i) const; + +}; + +constexpr inline TAttrPair::TAttrPair(int bios) : + _attrs {uchar(bios & 0xFF), uchar(bios >> 8)} +{ +} + +constexpr inline TAttrPair::TAttrPair(const TColorAttr &lo, const TColorAttr &hi) : + _attrs {lo, hi} +{ +} + +inline ushort TAttrPair::asBIOS() const +{ + return _attrs[0].asBIOS() | ushort(_attrs[1].asBIOS() << 8); +} + +inline TAttrPair::operator ushort() const +{ + return asBIOS(); +} + +inline TAttrPair TAttrPair::operator>>(int shift) const +{ + // Legacy code may use '>> 8' on an attribute pair to get the higher attribute. + if (shift == 8) + return {_attrs[1]}; + return asBIOS() >> shift; +} + +inline TAttrPair& TAttrPair::operator|=(TColorAttr attr) +{ + // Legacy code may use '|=' on an attribute pair to set the lower attribute. + _attrs[0] = attr; + return *this; +} + +inline TColorAttr& TAttrPair::operator[](size_t i) +{ + return _attrs[i]; +} + +inline const TColorAttr& TAttrPair::operator[](size_t i) const +{ + return _attrs[i]; +} + +// Pending methods from TColorAttr. + +inline TColorAttr::TColorAttr(const TAttrPair &attrs) +{ + *this = attrs[0]; +} + +inline TAttrPair TColorAttr::operator<<(int shift) const +{ + // Legacy code may use '<< 8' on an attribute to construct an attribute pair. + if (shift == 8) + return {uchar(0), *this}; + return asBIOS() << shift; +} + +#endif // __BORLANDC__ + +#endif // TVISION_COLORS_H diff --git a/src/include/tvision/colorsel.h b/src/include/tvision/colorsel.h new file mode 100644 index 00000000..ff2c26d9 --- /dev/null +++ b/src/include/tvision/colorsel.h @@ -0,0 +1,467 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* COLORSEL.H */ +/* */ +/* defines the class TColorDialog, used to set application palettes */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __COLOR_COMMAND_CODES ) +#define __COLOR_COMMAND_CODES + +const int + cmColorForegroundChanged = 71, + cmColorBackgroundChanged = 72, + cmColorSet = 73, + cmNewColorItem = 74, + cmNewColorIndex = 75, + cmSaveColorIndex = 76; + +#endif // __COLOR_COMMAND_CODES + +class _FAR TColorItem; +class _FAR TColorGroup; + +TColorItem& operator + ( TColorItem& i1, TColorItem& i2 ) noexcept; +TColorGroup& operator + ( TColorGroup& g, TColorItem& i ) noexcept; +TColorGroup& operator + ( TColorGroup& g1, TColorGroup& g2 ) noexcept; + +#if defined( Uses_TColorItem ) && !defined( __TColorItem ) +#define __TColorItem + +class _FAR TColorGroup; + +class TColorItem +{ + +public: + + TColorItem( const char *nm, uchar idx, TColorItem *nxt = 0 ) noexcept; + virtual ~TColorItem(); + const char *name; + uchar index; + TColorItem *next; + friend TColorGroup& operator + ( TColorGroup&, TColorItem& ) noexcept; + friend TColorItem& operator + ( TColorItem& i1, TColorItem& i2 ) noexcept; + +}; + +#endif // Uses_TColorItem + +#if defined( Uses_TColorGroup ) && !defined( __TColorGroup ) +#define __TColorGroup + +class _FAR TColorItem; + +class TColorGroup +{ + +public: + + TColorGroup( const char *nm, TColorItem *itm = 0, TColorGroup *nxt = 0 ) noexcept; + virtual ~TColorGroup(); + const char *name; + uchar index; + TColorItem *items; + TColorGroup *next; + friend TColorGroup& operator + ( TColorGroup&, TColorItem& ) noexcept; + friend TColorGroup& operator + ( TColorGroup& g1, TColorGroup& g2 ) noexcept; + + +}; + +class TColorIndex +{ +public: + uchar groupIndex; + uchar colorSize; + uchar colorIndex[256]; +}; + + +#endif // Uses_TColorGroup + +#if defined( Uses_TColorSelector ) && !defined( __TColorSelector ) +#define __TColorSelector + +class _FAR TRect; +struct _FAR TEvent; + +class TColorSelector : public TView +{ + +public: + + enum ColorSel { csBackground, csForeground }; + + TColorSelector( const TRect& Bounds, ColorSel ASelType ) noexcept; + virtual void draw(); + virtual void handleEvent( TEvent& event ); + +protected: + + uchar color; + ColorSel selType; + +private: + + void colorChanged(); + + static const char _NEAR icon; + + virtual const char *streamableName() const + { return name; } + +protected: + + TColorSelector( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TColorSelector& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TColorSelector*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TColorSelector& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TColorSelector* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TColorSelector + + +#if defined( Uses_TMonoSelector ) && !defined( __TMonoSelector ) +#define __TMonoSelector + +class _FAR TRect; +struct _FAR TEvent; + +class TMonoSelector : public TCluster +{ + +public: + + TMonoSelector( const TRect& bounds ) noexcept; + virtual void draw(); + virtual void handleEvent( TEvent& event ); + virtual Boolean mark( int item ); + void newColor(); + virtual void press( int item ); + void movedTo( int item ); + +private: + + static const char * _NEAR button; + static const char * _NEAR normal; + static const char * _NEAR highlight; + static const char * _NEAR underline; + static const char * _NEAR inverse; + + virtual const char *streamableName() const + { return name; } + +protected: + + TMonoSelector( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TMonoSelector& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMonoSelector*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMonoSelector& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMonoSelector* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TMonoSelector + +#if defined( Uses_TColorDisplay ) && !defined( __TColorDisplay ) +#define __TColorDisplay + +class _FAR TRect; +struct _FAR TEvent; + +class TColorDisplay : public TView +{ + +public: + + TColorDisplay( const TRect& bounds, TStringView aText ) noexcept; + virtual ~TColorDisplay(); + virtual void draw(); + virtual void handleEvent( TEvent& event ); + virtual void setColor( TColorAttr *aColor ); + +protected: + + TColorAttr *color; + const char *text; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TColorDisplay( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TColorDisplay& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TColorDisplay*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TColorDisplay& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TColorDisplay* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TColorDisplay + + +#if defined( Uses_TColorGroupList ) && !defined( __TColorGroupList ) +#define __TColorGroupList + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TColorGroup; +class _FAR TColorItem; + +class TColorGroupList : public TListViewer +{ + +public: + + TColorGroupList( const TRect& bounds, + TScrollBar *aScrollBar, + TColorGroup *aGroups + ) noexcept; + virtual ~TColorGroupList(); + virtual void focusItem( short item ); + virtual void getText( char *dest, short item, short maxLen ); + + virtual void handleEvent(TEvent&); + + +protected: + + TColorGroup *groups; + +private: + + virtual const char *streamableName() const + { return name; } + static void writeItems( opstream&, TColorItem * ); + static void writeGroups( opstream&, TColorGroup * ); + static TColorItem *readItems( ipstream& ); + static TColorGroup *readGroups( ipstream& ); + +protected: + + TColorGroupList( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + void setGroupIndex(uchar groupNum, uchar itemNum); + TColorGroup* getGroup(uchar groupNum); + uchar getGroupIndex(uchar groupNum); + uchar getNumGroups(); + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TColorGroupList& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TColorGroupList*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TColorGroupList& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TColorGroupList* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TColorGroupList + + +#if defined( Uses_TColorItemList ) && !defined( __TColorItemList ) +#define __TColorItemList + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TColorItem; +struct _FAR TEvent; + +class TColorItemList : public TListViewer +{ + +public: + + TColorItemList( const TRect& bounds, + TScrollBar *aScrollBar, + TColorItem *aItems + ) noexcept; + virtual void focusItem( short item ); + virtual void getText( char *dest, short item, short maxLen ); + virtual void handleEvent( TEvent& event ); + +protected: + + TColorItem *items; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TColorItemList( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TColorItemList& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TColorItemList*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TColorItemList& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TColorItemList* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TColorItemList + + +#if defined( Uses_TColorDialog ) && !defined( __TColorDialog ) +#define __TColorDialog + +class _FAR TColorGroup; +struct _FAR TEvent; +class _FAR TColorDisplay; +class _FAR TColorGroupList; +class _FAR TLabel; +class _FAR TColorSelector; +class _FAR TMonoSelector; +class _FAR TPalette; + +class TColorDialog : public TDialog +{ + +public: + + TColorDialog( TPalette *aPalette, TColorGroup *aGroups ) noexcept; + ~TColorDialog(); + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void handleEvent( TEvent& event ); + virtual void setData( void *rec); + + TPalette *pal; + +protected: + + TColorDisplay *display; + TColorGroupList *groups; + TLabel *forLabel; + TColorSelector *forSel; + TLabel *bakLabel; + TColorSelector *bakSel; + TLabel *monoLabel; + TMonoSelector *monoSel; + uchar groupIndex; + +private: + + static const char * _NEAR colors; + static const char * _NEAR groupText; + static const char * _NEAR itemText; + static const char * _NEAR forText; + static const char * _NEAR bakText; + static const char * _NEAR textText; + static const char * _NEAR colorText; + static const char * _NEAR okText; + static const char * _NEAR cancelText; + + virtual const char *streamableName() const + { return name; } + +protected: + + TColorDialog( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + void getIndexes(TColorIndex*&); + void setIndexes(TColorIndex*&); + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TColorDialog& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TColorDialog*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TColorDialog& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TColorDialog* cl ) + { return os << (TStreamable *)cl; } + +#endif // TColorDialog + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/compat/borland/_defs.h b/src/include/tvision/compat/borland/_defs.h new file mode 100644 index 00000000..bef9d7f1 --- /dev/null +++ b/src/include/tvision/compat/borland/_defs.h @@ -0,0 +1,44 @@ +/* _defs.h + + Common definitions for pointer size and calling conventions. + + Calling conventions: + _RTLENTRY Specifies the calling convention used by the RTL + + _USERENTRY Specifies the calling convention the RTL expects user + compiled functions to use (for callbacks) + + Export (and size for DOS) information: + _EXPCLASS Exports class if building DLL version of library + For DOS16 also provides size information + + _EXPDATA Exports data if building DLL version of library + + _EXPFUNC Exports function if building DLL version of library + For DOS16 also provides size information + + _FAR Promotes data pointers to far in DLLs (DOS16 only) + + Obsolete versions: + _Cdecl Use _RTLENTRY + _CLASSTYPE Use _EXPCLASS + _FARFUNC Use _EXPFUNC + _FARCALL Use _EXPFUNC and declare function explicity __far + + Copyright (c) 1991, 1992 by Borland International + All Rights Reserved. +*/ + +#ifdef __BORLANDC__ +#include <_defs.h> +#else + +#ifndef TVISION_COMPAT__DEFS_H +#define TVISION_COMPAT__DEFS_H + +#define _RTLENTRY __cdecl +#define _Cdecl _RTLENTRY + +#endif // TVISION_COMPAT__DEFS_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/_null.h b/src/include/tvision/compat/borland/_null.h new file mode 100644 index 00000000..a99bbc4e --- /dev/null +++ b/src/include/tvision/compat/borland/_null.h @@ -0,0 +1,26 @@ +/* _null.h + + Definition of NULL. + +*/ + +/* + * C/C++ Run Time Library - Version 6.0 + * + * Copyright (c) 1987, 1993 by Borland International + * All Rights Reserved. + * + */ + +#ifdef __BORLANDC__ +#include <_null.h> +#else + +#ifndef TVISION_COMPAT__NULL_H +#define TVISION_COMPAT__NULL_H + +#include + +#endif // TVISION_COMPAT__NULL_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/alloc.h b/src/include/tvision/compat/borland/alloc.h new file mode 100644 index 00000000..8ec93ded --- /dev/null +++ b/src/include/tvision/compat/borland/alloc.h @@ -0,0 +1,12 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_ALLOC_H +#define TVISION_COMPAT_ALLOC_H + +#include + +#endif // TVISION_COMPAT_ALLOC_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/dir.h b/src/include/tvision/compat/borland/dir.h new file mode 100644 index 00000000..843291b3 --- /dev/null +++ b/src/include/tvision/compat/borland/dir.h @@ -0,0 +1,76 @@ +/* dir.h + + Defines structures, macros, and functions for dealing with + directories and pathnames. + +*/ + +/* + * C/C++ Run Time Library - Version 6.0 + * + * Copyright (c) 1987, 1993 by Borland International + * All Rights Reserved. + * + */ + +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_DIR_H +#define TVISION_COMPAT_DIR_H + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "_defs.h" + +#include + +#define WILDCARDS 0x01 +#define EXTENSION 0x02 +#define FILENAME 0x04 +#define DIRECTORY 0x08 +#define DRIVE 0x10 + +#define MAXDRIVE 3 + +#ifndef _FFBLK_DEF +#define _FFBLK_DEF +struct ffblk { + int32_t ff_reserved; + int32_t ff_fsize; + uint32_t ff_attrib; + unsigned short ff_ftime; + unsigned short ff_fdate; + char ff_name[256]; +}; +#endif + +#define MAXPATH 260 +#define MAXDIR 256 +#define MAXFILE 256 +#define MAXEXT 256 + +int findfirst( const char *__path, struct ffblk *__ffblk, int __attrib ) noexcept; +int findnext( struct ffblk *__ffblk ) noexcept; +void fnmerge( char *__path, + const char *__drive, + const char *__dir, + const char *__name, + const char *__ext ) noexcept; +int fnsplit( const char *__path, + char *__drive, + char *__dir, + char *__name, + char *__ext ) noexcept; +int getcurdir( int __drive, char *__directory ) noexcept; +int getdisk( void ) noexcept; +int setdisk( int __drive ) noexcept; + +#endif // TVISION_COMPAT_DIR_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/dos.h b/src/include/tvision/compat/borland/dos.h new file mode 100644 index 00000000..87e44b67 --- /dev/null +++ b/src/include/tvision/compat/borland/dos.h @@ -0,0 +1,87 @@ +/* dos.h + + Defines structs, unions, macros, and functions for dealing + with MSDOS and the Intel iAPX86 microprocessor family. + +*/ +/* + * C/C++ Run Time Library - Version 6.0 + * + * Copyright (c) 1987, 1993 by Borland International + * All Rights Reserved. + * + */ + +#ifdef __BORLANDC__ +#include +#else + +#ifdef TVISION_COMPAT_DOS_INCNEXT +#undef TVISION_COMPAT_DOS_INCNEXT +#include_next +#endif // TVISION_COMPAT_DOS_INCNEXT + +#ifndef TVISION_COMPAT_DOS_H +#define TVISION_COMPAT_DOS_H + +#include "_defs.h" + +#ifdef _MSC_VER +#include +#elif defined(__MINGW32__) +#define TVISION_COMPAT_DOS_INCNEXT +#include +#undef TVISION_COMPAT_DOS_INCNEXT +#endif + +#include +#include + +#define FA_NORMAL 0x00 /* Normal file, no attributes */ +#define FA_RDONLY 0x01 /* Read only attribute */ +#define FA_HIDDEN 0x02 /* Hidden file */ +#define FA_SYSTEM 0x04 /* System file */ +#define FA_LABEL 0x08 /* Volume label */ +#define FA_DIREC 0x10 /* Directory */ +#define FA_ARCH 0x20 /* Archive */ + +/* MSC names for file attributes */ + +#define _A_NORMAL 0x00 /* Normal file, no attributes */ +#define _A_RDONLY 0x01 /* Read only attribute */ +#define _A_HIDDEN 0x02 /* Hidden file */ +#define _A_SYSTEM 0x04 /* System file */ +#define _A_VOLID 0x08 /* Volume label */ +#define _A_SUBDIR 0x10 /* Directory */ +#define _A_ARCH 0x20 /* Archive */ + +#ifndef _FFBLK_DEF +#define _FFBLK_DEF +struct ffblk { + int32_t ff_reserved; + int32_t ff_fsize; + uint32_t ff_attrib; + unsigned short ff_ftime; + unsigned short ff_fdate; + char ff_name[256]; +}; +#endif /* __FFBLK_DEF */ + +/* The MSC find_t structure corresponds exactly to the ffblk structure */ +struct find_t { + int32_t reserved; + int32_t size; /* size of file */ + uint32_t attrib; /* attribute byte for matched file */ + unsigned short wr_time; /* time of last write to file */ + unsigned short wr_date; /* date of last write to file */ + char name[256]; /* asciiz name of matched file */ +}; + +#include // SEEK_SET, SEEK_CUR, SEEK_END + +unsigned _dos_findfirst( const char * __path, unsigned __attrib, struct find_t *__finfo ) noexcept; +unsigned _dos_findnext( struct find_t *__finfo ) noexcept; + +#endif // TVISION_COMPAT_DOS_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/fstream.h b/src/include/tvision/compat/borland/fstream.h new file mode 100644 index 00000000..dde20588 --- /dev/null +++ b/src/include/tvision/compat/borland/fstream.h @@ -0,0 +1,18 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_FSTREAM_H +#define TVISION_COMPAT_FSTREAM_H + +#include "iostream.h" +#include + +using std::filebuf; +using std::fstream; +using std::ifstream; +using std::ofstream; + +#endif // TVISION_COMPAT_FSTREAM_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/io.h b/src/include/tvision/compat/borland/io.h new file mode 100644 index 00000000..c0fda0d0 --- /dev/null +++ b/src/include/tvision/compat/borland/io.h @@ -0,0 +1,45 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifdef TVISION_COMPAT_IO_INCNEXT +#undef TVISION_COMPAT_IO_INCNEXT +#include_next +#endif // TVISION_COMPAT_IO_INCNEXT + +#ifndef TVISION_COMPAT_IO_H +#define TVISION_COMPAT_IO_H + +struct ftime { + unsigned ft_tsec : 5; /* Two second interval */ + unsigned ft_min : 6; /* Minutes */ + unsigned ft_hour : 5; /* Hours */ + unsigned ft_day : 5; /* Days */ + unsigned ft_month : 4; /* Months */ + unsigned ft_year : 7; /* Year */ +}; + +#ifdef _MSC_VER +#include +#elif defined(__MINGW32__) +#define TVISION_COMPAT_IO_INCNEXT +#include +#undef TVISION_COMPAT_IO_INCNEXT +#elif !defined(_WIN32) + +#include +#include + +inline off_t filelength( int fd ) noexcept +{ + struct stat s; + if ( fstat( fd, &s ) == (off_t) -1 ) + return -1; + return s.st_size; +} + +#endif // !_MSC_VER && !__MINGW32__ && !_WIN32 + +#endif // TVISION_COMPAT_IO_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/iomanip.h b/src/include/tvision/compat/borland/iomanip.h new file mode 100644 index 00000000..59611f96 --- /dev/null +++ b/src/include/tvision/compat/borland/iomanip.h @@ -0,0 +1,19 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_IOMANIP_H +#define TVISION_COMPAT_IOMANIP_H + +#include + +using std::resetiosflags; +using std::setiosflags; +using std::setbase; +using std::setfill; +using std::setprecision; +using std::setw; + +#endif // TVISION_COMPAT_IOMANIP_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/iosfwd.h b/src/include/tvision/compat/borland/iosfwd.h new file mode 100644 index 00000000..88fc6968 --- /dev/null +++ b/src/include/tvision/compat/borland/iosfwd.h @@ -0,0 +1,24 @@ +#ifndef TVISION_IOSFWD_H +#define TVISION_IOSFWD_H + +#ifdef __BORLANDC__ + +#include <_defs.h> + +class _EXPCLASS ostream; +class _EXPCLASS streambuf; +typedef long streampos; +typedef long streamoff; + +#else + +#include + +using std::ostream; +using std::streambuf; +using std::streampos; +using std::streamoff; + +#endif // __BORLANDC__ + +#endif // TVISION_IOSFWD_H diff --git a/src/include/tvision/compat/borland/iostream.h b/src/include/tvision/compat/borland/iostream.h new file mode 100644 index 00000000..5d280ede --- /dev/null +++ b/src/include/tvision/compat/borland/iostream.h @@ -0,0 +1,28 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_IOSTREAM_H +#define TVISION_COMPAT_IOSTREAM_H + +#include +#include +#include +#include + +using std::cerr; +using std::cin; +using std::cout; +using std::dec; +using std::endl; +using std::flush; +using std::hex; +using std::ios; +using std::ostream; +using std::streambuf; +using std::streamoff; +using std::streampos; + +#endif // TVISION_COMPAT_IOSTREAM_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/mem.h b/src/include/tvision/compat/borland/mem.h new file mode 100644 index 00000000..68c020e1 --- /dev/null +++ b/src/include/tvision/compat/borland/mem.h @@ -0,0 +1,25 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_MEM_H +#define TVISION_COMPAT_MEM_H + +#ifdef _MSC_VER +#include +#endif + +#include "_defs.h" +#include "_null.h" + +#include +#include + +inline void movmem(const void *src, void *dest, unsigned length) noexcept +{ + memmove(dest, src, length); +} + +#endif // TVISION_COMPAT_MEM_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/borland/strstrea.h b/src/include/tvision/compat/borland/strstrea.h new file mode 100644 index 00000000..2b629717 --- /dev/null +++ b/src/include/tvision/compat/borland/strstrea.h @@ -0,0 +1,19 @@ +#ifdef __BORLANDC__ +#include +#else + +#ifndef TVISION_COMPAT_STRSTREA_H +#define TVISION_COMPAT_STRSTREA_H + +#include +#include + +using std::ends; +using std::istrstream; +using std::ostrstream; +using std::strstream; +using std::strstreambuf; + +#endif // TVISION_COMPAT_STRSTREA_H + +#endif // __BORLANDC__ diff --git a/src/include/tvision/compat/malloc/malloc.h b/src/include/tvision/compat/malloc/malloc.h new file mode 100644 index 00000000..89a47f7d --- /dev/null +++ b/src/include/tvision/compat/malloc/malloc.h @@ -0,0 +1,16 @@ +#ifndef TVISION_COMPAT_MALLOC_H +#define TVISION_COMPAT_MALLOC_H + +#include + +#if __has_include() +#include +#endif + +// Also include extensions, just in case. + +#if __has_include() +#include +#endif + +#endif // TVISION_COMPAT_MALLOC_H diff --git a/src/include/tvision/compat/windows/windows.h b/src/include/tvision/compat/windows/windows.h new file mode 100644 index 00000000..253fe1ea --- /dev/null +++ b/src/include/tvision/compat/windows/windows.h @@ -0,0 +1,326 @@ +/* + * C/C++ Run Time Library - Version 6.0 + * + * Copyright (c) 1987, 1993 by Borland International + * All Rights Reserved. + * + */ + +#ifndef TVISION_COMPAT_WINDOWS_H +#define TVISION_COMPAT_WINDOWS_H + +#if defined(__BORLANDC__) || defined(_WIN32) +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#else + +#include + +extern "C" +{ + +// winnt.h + +typedef void *PVOID; +typedef PVOID HANDLE; +typedef char CHAR; +typedef short SHORT; +typedef int32_t LONG; +typedef wchar_t WCHAR; +typedef int64_t LONGLONG; +typedef uint64_t ULONGLONG; + +// windef.h + +typedef uint32_t DWORD; +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef int INT; +typedef unsigned int UINT; + +#define MAX_PATH 260 + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +// winuser.h + +// +// Virtual Keys, Standard Set +// + +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_CANCEL 0x03 +#define VK_MBUTTON 0x04 // NOT contiguous with L & RBUTTON + +#define VK_BACK 0x08 +#define VK_TAB 0x09 + +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 + +#define VK_ESCAPE 0x1B + +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F + +// VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) +// VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) + +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D + +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 + +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 + +// VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. +// Used only as parameters to GetAsyncKeyState() and GetKeyState(). +// No other API or message will distinguish left and right keys in this way. + +#define VK_LSHIFT 0xA0 +#define VK_RSHIFT 0xA1 +#define VK_LCONTROL 0xA2 +#define VK_RCONTROL 0xA3 +#define VK_LMENU 0xA4 +#define VK_RMENU 0xA5 + +#if WINVER >= 0x0400 +#define VK_PROCESSKEY 0xE5 +#endif // WINVER >= 0x0400 + +#define VK_ATTN 0xF6 +#define VK_CRSEL 0xF7 +#define VK_EXSEL 0xF8 +#define VK_EREOF 0xF9 +#define VK_PLAY 0xFA +#define VK_ZOOM 0xFB +#define VK_NONAME 0xFC +#define VK_PA1 0xFD +#define VK_OEM_CLEAR 0xFE + +// +// Predefined Clipboard Formats +// + +#define CF_TEXT 1 + +// winnls.h + +#define CP_UTF8 65001 // UTF-8 translation + +// wincon.h + +typedef struct _COORD { + SHORT X; + SHORT Y; +} COORD; + +typedef struct _SMALL_RECT { + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; +} SMALL_RECT; + +typedef struct _KEY_EVENT_RECORD { + BOOL bKeyDown; + WORD wRepeatCount; + WORD wVirtualKeyCode; + WORD wVirtualScanCode; + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } uChar; + DWORD dwControlKeyState; +} KEY_EVENT_RECORD; + +// +// ControlKeyState flags +// + +#define RIGHT_ALT_PRESSED 0x0001 // the right alt key is pressed. +#define LEFT_ALT_PRESSED 0x0002 // the left alt key is pressed. +#define RIGHT_CTRL_PRESSED 0x0004 // the right ctrl key is pressed. +#define LEFT_CTRL_PRESSED 0x0008 // the left ctrl key is pressed. +#define SHIFT_PRESSED 0x0010 // the shift key is pressed. +#define NUMLOCK_ON 0x0020 // the numlock light is on. +#define SCROLLLOCK_ON 0x0040 // the scrolllock light is on. +#define CAPSLOCK_ON 0x0080 // the capslock light is on. +#define ENHANCED_KEY 0x0100 // the key is enhanced. + +typedef struct _MOUSE_EVENT_RECORD { + COORD dwMousePosition; + DWORD dwButtonState; + DWORD dwControlKeyState; + DWORD dwEventFlags; +} MOUSE_EVENT_RECORD; + +#define MOUSE_MOVED 0x0001 +#define DOUBLE_CLICK 0x0002 + +typedef struct _WINDOW_BUFFER_SIZE_RECORD { + COORD dwSize; +} WINDOW_BUFFER_SIZE_RECORD; + +typedef struct _MENU_EVENT_RECORD { + UINT dwCommandId; +} MENU_EVENT_RECORD; + +typedef struct _FOCUS_EVENT_RECORD { + BOOL bSetFocus; +} FOCUS_EVENT_RECORD; + +typedef struct _INPUT_RECORD { + WORD EventType; + union { + KEY_EVENT_RECORD KeyEvent; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + } Event; +} INPUT_RECORD; + +// +// EventType flags: +// + +#define MOUSE_EVENT 0x0002 // Event contains mouse event record + +typedef struct _CHAR_INFO { + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } Char; + WORD Attributes; +} CHAR_INFO; + +// +// Attributes flags: +// + +#define FOREGROUND_BLUE 0x0001 // text color contains blue. +#define FOREGROUND_GREEN 0x0002 // text color contains green. +#define FOREGROUND_RED 0x0004 // text color contains red. +#define FOREGROUND_INTENSITY 0x0008 // text color is intensified. +#define BACKGROUND_BLUE 0x0010 // background color contains blue. +#define BACKGROUND_GREEN 0x0020 // background color contains green. +#define BACKGROUND_RED 0x0040 // background color contains red. +#define BACKGROUND_INTENSITY 0x0080 // background color is intensified. + +typedef struct _CONSOLE_SCREEN_BUFFER_INFO { + COORD dwSize; + COORD dwCursorPosition; + WORD wAttributes; + SMALL_RECT srWindow; + COORD dwMaximumWindowSize; +} CONSOLE_SCREEN_BUFFER_INFO; + +typedef struct _CONSOLE_CURSOR_INFO { + DWORD dwSize; + BOOL bVisible; +} CONSOLE_CURSOR_INFO; + +#define CTRL_C_EVENT 0 +#define CTRL_BREAK_EVENT 1 + +// winbase.h + +DWORD GetTickCount(void) noexcept; +ULONGLONG GetTickCount64(void) noexcept; + +} // extern "C" + +#endif // __BORLANDC__ || _WIN32 + +// Flags that are often missing from outdated headers. + +#ifndef MOUSE_WHEELED +#define MOUSE_WHEELED 0x0004 +#endif +#ifndef MOUSE_HWHEELED +#define MOUSE_HWHEELED 0x0008 +#endif +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif +#ifndef DISABLE_NEWLINE_AUTO_RETURN +#define DISABLE_NEWLINE_AUTO_RETURN 0x0008 +#endif + +#endif // TVISION_COMPAT_WINDOWS_H diff --git a/src/include/tvision/config.h b/src/include/tvision/config.h new file mode 100644 index 00000000..9e5e110c --- /dev/null +++ b/src/include/tvision/config.h @@ -0,0 +1,33 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* CONFIG.H */ +/* */ +/* miscellaneous system-wide configuration parameters */ +/* FOR INTERNAL USE ONLY */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __CONFIG_H ) +#define __CONFIG_H + +#if !defined( __LIMITS_H ) +#include +#endif // __LIMITS_H + +const int eventQSize = 16; +const int keyEventQSize = 3; +const int maxCollectionSize = (int)(( (unsigned long) UINT_MAX - 16)/sizeof( void * )); + +const int maxViewWidth = 132; + +const int maxFindStrLen = 80; +const int maxReplaceStrLen = 80; + +#endif // __CONFIG_H diff --git a/src/include/tvision/dialogs.h b/src/include/tvision/dialogs.h new file mode 100644 index 00000000..4abe0ea3 --- /dev/null +++ b/src/include/tvision/dialogs.h @@ -0,0 +1,1047 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* DIALOGS.H */ +/* */ +/* defines the classes TDialog, TInputLine, TButton, TCluster, */ +/* TRadioButtons, TCheckBoxes, TMultiCheckBoxes, TStaticText, */ +/* TParamText, TLabel, THistoryViewer, and THistoryWindow. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __BUTTON_TYPE ) +#define __BUTTON_TYPE + +const int + bfNormal = 0x00, + bfDefault = 0x01, + bfLeftJust = 0x02, + bfBroadcast = 0x04, + bfGrabFocus = 0x08, + + cmRecordHistory = 60; + +#endif // __BUTTON_TYPE + +/* ---------------------------------------------------------------------- */ +/* class TDialog */ +/* */ +/* Palette layout */ +/* 1 = Frame passive */ +/* 2 = Frame active */ +/* 3 = Frame icon */ +/* 4 = ScrollBar page area */ +/* 5 = ScrollBar controls */ +/* 6 = StaticText */ +/* 7 = Label normal */ +/* 8 = Label selected */ +/* 9 = Label shortcut */ +/* 10 = Button normal */ +/* 11 = Button default */ +/* 12 = Button selected */ +/* 13 = Button disabled */ +/* 14 = Button shortcut */ +/* 15 = Button shadow */ +/* 16 = Cluster normal */ +/* 17 = Cluster selected */ +/* 18 = Cluster shortcut */ +/* 19 = InputLine normal text */ +/* 20 = InputLine selected text */ +/* 21 = InputLine arrows */ +/* 22 = History arrow */ +/* 23 = History sides */ +/* 24 = HistoryWindow scrollbar page area */ +/* 25 = HistoryWindow scrollbar controls */ +/* 26 = ListViewer normal */ +/* 27 = ListViewer focused */ +/* 28 = ListViewer selected */ +/* 29 = ListViewer divider */ +/* 30 = InfoPane */ +/* 31 = Cluster Disabled */ +/* 32 = Reserved */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TDialog ) && !defined( __TDialog ) +#define __TDialog + +#define cpGrayDialog \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"\ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" + +#define cpBlueDialog \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"\ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" + +#define cpCyanDialog \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"\ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" + +#define cpDialog cpGrayDialog + +const int + dpBlueDialog = 0, + dpCyanDialog = 1, + dpGrayDialog = 2; + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TValidator; + +class TDialog : public TWindow +{ + +public: + + TDialog( const TRect& bounds, TStringView aTitle ) noexcept; + + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual Boolean valid( ushort command ); + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TDialog( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TDialog& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TDialog*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TDialog& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TDialog* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TDialog + +/* ---------------------------------------------------------------------- */ +/* class TInputLine */ +/* */ +/* Palette layout */ +/* 1 = Passive */ +/* 2 = Active */ +/* 3 = Selected */ +/* 4 = Arrows */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TInputLine ) && !defined( __TInputLine ) +#define __TInputLine + +const ushort + ilMaxBytes = 0, + ilMaxWidth = 1, + ilMaxChars = 2; + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TValidator; + +class TInputLine : public TView +{ + +public: + + TInputLine( const TRect& bounds, uint limit, TValidator *aValid = 0, ushort limitMode = ilMaxBytes ) noexcept; + ~TInputLine(); + + virtual ushort dataSize(); + virtual void draw(); + virtual void getData( void *rec ); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + void selectAll( Boolean enable, Boolean scroll=True ); + virtual void setData( void *rec ); + virtual void setState( ushort aState, Boolean enable ); + virtual Boolean valid( ushort cmd ); + void setValidator( TValidator* aValid ); + + char* data; + uint maxLen; + uint maxWidth; + uint maxChars; + int curPos; + int firstPos; + int selStart; + int selEnd; + +private: + + Boolean canScroll( int delta ); + int mouseDelta( TEvent& event ); + int mousePos( TEvent& event ); + int displayedPos( int pos ); + void deleteSelect(); + void deleteCurrent(); + void adjustSelectBlock(); + void saveState(); + void restoreState(); + Boolean checkValid(Boolean); + Boolean canUpdateCommands(); + void setCmdState( ushort, Boolean ); + void updateCommands(); + + static const char _NEAR rightArrow; + static const char _NEAR leftArrow; + + virtual const char *streamableName() const + { return name; } + + TValidator* validator; + + int anchor; + char* oldData; + int oldCurPos; + int oldFirstPos; + int oldSelStart; + int oldSelEnd; + +protected: + + TInputLine( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TInputLine& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TInputLine*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TInputLine& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TInputLine* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TInputLine + + +/* ---------------------------------------------------------------------- */ +/* TButton object */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Default text */ +/* 3 = Selected text */ +/* 4 = Disabled text */ +/* 5 = Normal shortcut */ +/* 6 = Default shortcut */ +/* 7 = Selected shortcut */ +/* 8 = Shadow */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TButton ) && !defined( __TButton ) +#define __TButton + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TDrawBuffer; + +class TButton : public TView +{ + +public: + + TButton( const TRect& bounds, + TStringView aTitle, + ushort aCommand, + ushort aFlags + ) noexcept; + ~TButton(); + + virtual void draw(); + void drawState( Boolean down ); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + void makeDefault( Boolean enable ); + virtual void press(); + virtual void setState( ushort aState, Boolean enable ); + + const char *title; + +protected: + + ushort command; + uchar flags; + Boolean amDefault; + +private: + + void drawTitle( TDrawBuffer&, int, int, TAttrPair, Boolean ); + void pressButton( TEvent& ); + TRect getActiveRect(); + + enum { animationDuration = 100 }; + TTimerId animationTimer; + + static const char * _NEAR shadows; + static const char * _NEAR markers; + + virtual const char *streamableName() const + { return name; } + +protected: + + TButton( StreamableInit ) noexcept : TView( streamableInit ) {}; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TButton& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TButton*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TButton& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TButton* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TButton + + +#if defined( Uses_TSItem ) && !defined( __TSItem ) +#define __TSItem + +class TSItem +{ + +public: + + TSItem( TStringView aValue, TSItem *aNext ) noexcept + { value = newStr(aValue); next = aNext; } + ~TSItem() { delete[] (char *) value; } + + const char *value; + TSItem *next; +}; + +#endif // Uses_TSItem + +/* ---------------------------------------------------------------------- */ +/* class TCluster */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* 3 = Normal shortcut */ +/* 4 = Selected shortcut */ +/* 5 = Disabled text */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TCluster ) && !defined( __TCluster ) +#define __TCluster + +class _FAR TRect; +class _FAR TSItem; +struct _FAR TEvent; +class _FAR TPoint; +class _FAR TStringCollection; + +class TCluster : public TView +{ + +public: + + TCluster( const TRect& bounds, TSItem *aStrings ) noexcept; + ~TCluster(); + + virtual ushort dataSize(); + void drawBox( const char *icon, char marker ); + void drawMultiBox(const char *icon, const char* marker); + virtual void getData( void *rec ); + ushort getHelpCtx(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual Boolean mark( int item ); + virtual uchar multiMark( int item ); + + virtual void press( int item ); + virtual void movedTo( int item ); + virtual void setData( void *rec ); + virtual void setState( ushort aState, Boolean enable ); + virtual void setButtonState(uint32_t aMask, Boolean enable); + +protected: + + uint32_t value; + uint32_t enableMask; + int sel; + TStringCollection *strings; + +private: + + int column( int item ); + int findSel( TPoint p ); + int row( int item ); + void moveSel(int, int); + + virtual const char *streamableName() const + { return name; } + +protected: + + TCluster( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + Boolean buttonState(int ); + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TCluster& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TCluster*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TCluster& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TCluster* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TCluster + + +/* ---------------------------------------------------------------------- */ +/* class TRadioButtons */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* 3 = Normal shortcut */ +/* 4 = Selected shortcut */ +/* ---------------------------------------------------------------------- */ + + +#if defined( Uses_TRadioButtons ) && !defined( __TRadioButtons ) +#define __TRadioButtons + +class _FAR TRect; +class _FAR TSItem; + +class TRadioButtons : public TCluster +{ + +public: + + TRadioButtons( const TRect& bounds, TSItem *aStrings ) noexcept; + + virtual void draw(); + virtual Boolean mark( int item ); + virtual void movedTo( int item ); + virtual void press( int item ); + virtual void setData( void *rec ); + +private: + + static const char * _NEAR button; + virtual const char *streamableName() const + { return name; } + +protected: + + TRadioButtons( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TRadioButtons& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TRadioButtons*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TRadioButtons& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TRadioButtons* cl ) + { return os << (TStreamable *)cl; } + +inline TRadioButtons::TRadioButtons( const TRect& bounds, TSItem *aStrings ) noexcept : + TCluster( bounds, aStrings ) +{ +} + +#endif // Uses_TRadioButtons + + +/* ---------------------------------------------------------------------- */ +/* TCheckBoxes */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* 3 = Normal shortcut */ +/* 4 = Selected shortcut */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TCheckBoxes ) && !defined( __TCheckBoxes ) +#define __TCheckBoxes + +class _FAR TRect; +class _FAR TSItem; + +class TCheckBoxes : public TCluster +{ + +public: + + TCheckBoxes( const TRect& bounds, TSItem *aStrings) noexcept; + + virtual void draw(); + + virtual Boolean mark( int item ); + virtual void press( int item ); + +private: + + static const char * _NEAR button; + + virtual const char *streamableName() const + { return name; } + +protected: + + TCheckBoxes( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TCheckBoxes& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TCheckBoxes*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TCheckBoxes& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TCheckBoxes* cl ) + { return os << (TStreamable *)cl; } + +inline TCheckBoxes::TCheckBoxes( const TRect& bounds, TSItem *aStrings) noexcept : + TCluster( bounds, aStrings ) +{ +} + +#endif // Uses_TCheckBoxes + + +#if defined( Uses_TMultiCheckBoxes ) && !defined( __TMultiCheckBoxes ) +#define __TMultiCheckBoxes + +const unsigned short cfOneBit = 0x0101, + cfTwoBits = 0x0203, + cfFourBits = 0x040F, + cfEightBits = 0x08FF; + +/* ---------------------------------------------------------------------- */ +/* TMultiCheckBoxes */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* 3 = Normal shortcut */ +/* 4 = Selected shortcut */ +/* ---------------------------------------------------------------------- */ + +class _FAR TRect; +class _FAR TSItem; + +class TMultiCheckBoxes : public TCluster +{ +public: + TMultiCheckBoxes(TRect&, TSItem*, uchar, ushort, const char*) noexcept; + ~TMultiCheckBoxes(); + virtual ushort dataSize(); + virtual void draw(); + virtual void getData(void *); + virtual uchar multiMark(int item); + virtual void press( int item ); + virtual void setData(void*); + +private: + uchar selRange; + ushort flags; + char* states; + + virtual const char *streamableName() const + { return name; } + +protected: + + TMultiCheckBoxes( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TMultiCheckBoxes& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMultiCheckBoxes*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMultiCheckBoxes& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMultiCheckBoxes* cl ) + { return os << (TStreamable *)cl; } + +#endif + + +#if defined( Uses_TListBox ) && !defined( __TListBox ) +#define __TListBox + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TCollection; + +struct TListBoxRec +{ + TCollection *items; + ushort selection; +}; + +class TListBox : public TListViewer +{ + +public: + + TListBox( const TRect& bounds, ushort aNumCols, TScrollBar *aScrollBar ) noexcept; + ~TListBox(); + + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void getText( char *dest, short item, short maxLen ); + virtual void newList( TCollection *aList ); + virtual void setData( void *rec ); + + TCollection *list(); + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TCollection *items; + + TListBox( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TListBox& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TListBox*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TListBox& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TListBox* cl ) + { return os << (TStreamable *)cl; } + +inline TCollection *TListBox::list() +{ + return items; +} + +#endif // Uses_TListBox + + +/* ---------------------------------------------------------------------- */ +/* class TStaticText */ +/* */ +/* Palette layout */ +/* 1 = Text */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TStaticText ) && !defined( __TStaticText ) +#define __TStaticText + +class _FAR TRect; + +class TStaticText : public TView +{ + +public: + + TStaticText( const TRect& bounds, TStringView aText ) noexcept; + ~TStaticText(); + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void getText( char * ); + +protected: + + const char *text; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TStaticText( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TStaticText& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TStaticText*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TStaticText& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TStaticText* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TStaticText + + +/* ---------------------------------------------------------------------- */ +/* class TParamText */ +/* */ +/* Palette layout */ +/* 1 = Text */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TParamText ) && !defined( __TParamText ) +#define __TParamText + +class _FAR TRect; + +class TParamText : public TStaticText +{ + +public: + TParamText( const TRect& bounds ) noexcept; + ~TParamText(); + + virtual void getText( char *str ); + virtual void setText( const char *fmt, ... ); + virtual int getTextLen(); + +protected: + + char *str; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TParamText( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TParamText& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TParamText*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TParamText& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TParamText* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TParamText + + +/* ---------------------------------------------------------------------- */ +/* class TLabel */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* 3 = Normal shortcut */ +/* 4 = Selected shortcut */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TLabel ) && !defined( __TLabel ) +#define __TLabel + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TView; + +class TLabel : public TStaticText +{ + +public: + + TLabel( const TRect& bounds, TStringView aText, TView *aLink ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual void shutDown(); + +protected: + + TView *link; + Boolean light; + +private: + + virtual const char *streamableName() const + { return name; } + void focusLink(TEvent&); + +protected: + + TLabel( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TLabel& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TLabel*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TLabel& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TLabel* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TLabel + + +/* ---------------------------------------------------------------------- */ +/* class THistoryViewer */ +/* */ +/* Palette layout */ +/* 1 = Active */ +/* 2 = Inactive */ +/* 3 = Focused */ +/* 4 = Selected */ +/* 5 = Divider */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_THistoryViewer ) && !defined( __THistoryViewer ) +#define __THistoryViewer + +class _FAR TRect; +class _FAR TScrollBar; + +class THistoryViewer : public TListViewer +{ + +public: + + THistoryViewer( const TRect& bounds, + TScrollBar *aHScrollBar, + TScrollBar *aVScrollBar, + ushort aHistoryId + ) noexcept; + + virtual TPalette& getPalette() const; + virtual void getText( char *dest, short item, short maxLen ); + virtual void handleEvent( TEvent& event ); + int historyWidth() noexcept; + +protected: + + ushort historyId; + +}; + +#endif // Uses_THistoryViewer + +#if defined( Uses_THistoryWindow ) && !defined( __THistoryWindow ) +#define __THistoryWindow + +class _FAR TListViewer; +class _FAR TRect; +class _FAR TWindow; +class _FAR TInputLine; + +class THistInit +{ + +public: + + THistInit( TListViewer *(*cListViewer)( TRect, TWindow *, ushort ) ) noexcept; + +protected: + + TListViewer *(*createListViewer)( TRect, TWindow *, ushort ); + +}; + +/* ---------------------------------------------------------------------- */ +/* THistoryWindow */ +/* */ +/* Palette layout */ +/* 1 = Frame passive */ +/* 2 = Frame active */ +/* 3 = Frame icon */ +/* 4 = ScrollBar page area */ +/* 5 = ScrollBar controls */ +/* 6 = HistoryViewer normal text */ +/* 7 = HistoryViewer selected text */ +/* ---------------------------------------------------------------------- */ + +class THistoryWindow : public TWindow, public virtual THistInit +{ + +public: + + THistoryWindow( const TRect& bounds, ushort historyId ) noexcept; + + virtual TPalette& getPalette() const; + virtual void getSelection( char *dest ); + virtual void handleEvent( TEvent& event ); + static TListViewer *initViewer( TRect, TWindow *, ushort ); + +protected: + + TListViewer *viewer; +}; + +#endif // Uses_THistoryWindow + +#if defined( Uses_THistory ) && !defined( __THistory ) +#define __THistory + +class _FAR TRect; +class _FAR TInputLine; +struct _FAR TEvent; +class _FAR THistoryWindow; + +class THistory : public TView +{ + +public: + + THistory( const TRect& bounds, TInputLine *aLink, ushort aHistoryId ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual THistoryWindow *initHistoryWindow( const TRect& bounds ); + virtual void recordHistory(const char *s); + virtual void shutDown(); + +protected: + + TInputLine *link; + ushort historyId; + +private: + + static const char * _NEAR icon; + + virtual const char *streamableName() const + { return name; } + +protected: + + THistory( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, THistory& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, THistory*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, THistory& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, THistory* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_THistory + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/drawbuf.h b/src/include/tvision/drawbuf.h new file mode 100644 index 00000000..cb38ea1f --- /dev/null +++ b/src/include/tvision/drawbuf.h @@ -0,0 +1,95 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* DRAWBUF.H */ +/* */ +/* defines the class TDrawBuffer, which provides the high-level */ +/* interface to the Screen Manager. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TDrawBuffer ) && !defined( __TDrawBuffer ) +#define __TDrawBuffer + +class TDrawBuffer +{ + + friend class TSystemError; + friend class TView; + friend void genRefs(); + +public: + + void moveChar( ushort indent, char c, TColorAttr attr, ushort count ) noexcept; + ushort moveStr( ushort indent, TStringView str, TColorAttr attr ) noexcept; + ushort moveStr( ushort indent, TStringView str, TColorAttr attr, ushort width, ushort begin = 0 ) noexcept; + ushort moveCStr( ushort indent, TStringView str, TAttrPair attrs ) noexcept; + ushort moveCStr( ushort indent, TStringView str, TAttrPair attrs, ushort width, ushort begin = 0 ) noexcept; + void moveBuf( ushort indent, const void _FAR *source, TColorAttr attr, ushort count ) noexcept; + + void putAttribute( ushort indent, TColorAttr attr ) noexcept; + void putChar( ushort indent, uchar c ) noexcept; + size_t length() const noexcept; + +#ifdef __FLAT__ + TDrawBuffer() noexcept; + ~TDrawBuffer(); +#endif + +protected: + +#ifdef __FLAT__ + static TSpan allocData() noexcept; + + const TSpan data; +#else + TScreenCell data[maxViewWidth]; +#endif + +}; + +#define loByte(w) (((uchar *)&w)[0]) +#define hiByte(w) (((uchar *)&w)[1]) + +inline void TDrawBuffer::putAttribute( ushort indent, TColorAttr attr ) noexcept +{ + if (indent < length()) + ::setAttr(data[indent], attr); +} + +inline void TDrawBuffer::putChar( ushort indent, uchar c ) noexcept +{ + if (indent < length()) + ::setChar(data[indent], c); +} + +inline size_t TDrawBuffer::length() const noexcept +{ +#ifdef __FLAT__ + return data.size(); +#else + return maxViewWidth; +#endif +} + +#endif // Uses_TDrawBuffer + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/editors.h b/src/include/tvision/editors.h new file mode 100644 index 00000000..fd7d16d3 --- /dev/null +++ b/src/include/tvision/editors.h @@ -0,0 +1,549 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* EDITORS.H */ +/* */ +/* defines the classes TIndicator, TEditor, TMemo, TFileEditor, */ +/* and TEditWindow */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __DIR_H ) +#include +#endif // __DIR_H + +#if !defined( __STRING_H ) +#include +#endif // __STRING_H + +#if !defined( __LIMITS_H ) +#include +#endif // __LIMITS_H + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __EDIT_COMMAND_CODES ) +#define __EDIT_COMMAND_CODES + +const int + ufUpdate = 0x01, + ufLine = 0x02, + ufView = 0x04; + +const int + smExtend = 0x01, + smDouble = 0x02, + smTriple = 0x04; + +const unsigned + sfSearchFailed = -0x01; + +const int + cmFind = 82, + cmReplace = 83, + cmSearchAgain = 84; + +const int + cmCharLeft = 500, + cmCharRight = 501, + cmWordLeft = 502, + cmWordRight = 503, + cmLineStart = 504, + cmLineEnd = 505, + cmLineUp = 506, + cmLineDown = 507, + cmPageUp = 508, + cmPageDown = 509, + cmTextStart = 510, + cmTextEnd = 511, + cmNewLine = 512, + cmBackSpace = 513, + cmDelChar = 514, + cmDelWord = 515, + cmDelStart = 516, + cmDelEnd = 517, + cmDelLine = 518, + cmInsMode = 519, + cmStartSelect = 520, + cmHideSelect = 521, + cmIndentMode = 522, + cmUpdateTitle = 523, + cmSelectAll = 524, + cmDelWordLeft = 525, + cmEncoding = 526; + +const int + edOutOfMemory = 0, + edReadError = 1, + edWriteError = 2, + edCreateError = 3, + edSaveModify = 4, + edSaveUntitled = 5, + edSaveAs = 6, + edFind = 7, + edSearchFailed = 8, + edReplace = 9, + edReplacePrompt = 10; + +const int + efCaseSensitive = 0x0001, + efWholeWordsOnly = 0x0002, + efPromptOnReplace = 0x0004, + efReplaceAll = 0x0008, + efDoReplace = 0x0010, + efBackupFiles = 0x0100; + +const int + maxLineLength = 256; + +#endif // __EDIT_COMMAND_CODES + +typedef ushort (*TEditorDialog)( int, ... ); +ushort defEditorDialog( int dialog, ... ); + +#if defined( Uses_TIndicator ) && !defined( __TIndicator ) +#define __TIndicator + +class _FAR TRect; + +class TIndicator : public TView +{ + +public: + + TIndicator( const TRect& ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void setState( ushort, Boolean ); + void setValue( const TPoint&, Boolean ); + +protected: + + TPoint location; + Boolean modified; + +private: + + static const char _NEAR dragFrame; + static const char _NEAR normalFrame; + + virtual const char *streamableName() const + { return name; } + +protected: + + TIndicator( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TIndicator& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TIndicator*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TIndicator& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TIndicator* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TIndicator + + +#if defined( Uses_TEditor ) && !defined( __TEditor ) +#define __TEditor + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TIndicator; +struct _FAR TEvent; +class _FAR TMenuItem; + +class TEditor : public TView +{ + +public: + + friend void genRefs(); + + TEditor( const TRect&, TScrollBar *, TScrollBar *, TIndicator *, uint ) noexcept; + virtual ~TEditor(); + + virtual void shutDown(); + + char bufChar( uint ); + uint bufPtr( uint ); + virtual void changeBounds( const TRect& ); + virtual void convertEvent( TEvent& ); + Boolean cursorVisible(); + void deleteSelect(); + virtual void doneBuffer(); + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& ); + virtual void initBuffer(); + virtual TMenuItem& initContextMenu( TPoint ); + uint insertMultilineText( const char *, uint ); + Boolean insertBuffer( const char *, uint, uint, Boolean, Boolean ); + Boolean insertEOL( Boolean ); + virtual Boolean insertFrom( TEditor * ); + Boolean insertText( const void *, uint, Boolean ); + void scrollTo( int, int ); + Boolean search( const char *, ushort ); + virtual Boolean setBufSize( uint ); + void setCmdState( ushort, Boolean ); + void setSelect( uint, uint, Boolean); + virtual void setState( ushort, Boolean ); + void trackCursor( Boolean ); + void undo(); + virtual void updateCommands(); + virtual Boolean valid( ushort ); + + int charPos( uint, uint ); + uint charPtr( uint, int ); + Boolean clipCopy(); + void clipCut(); + void clipPaste(); + void deleteRange( uint, uint, Boolean ); + void doUpdate(); + void doSearchReplace(); + void drawLines( int, int, uint ); + void formatLine(TScreenCell *, uint, int, TAttrPair ); + void find(); + uint getMousePtr( TPoint ); + Boolean hasSelection(); + void hideSelect(); + Boolean isClipboard(); + uint lineEnd( uint ); + uint lineMove( uint, int ); + uint lineStart( uint ); + uint indentedLineStart( uint ); + void lock(); + void newLine(); + uint nextChar( uint ); + uint nextLine( uint ); + uint nextWord( uint ); + uint prevChar( uint ); + uint prevLine( uint ); + uint prevWord( uint ); + void replace(); + void setBufLen( uint ); + void setCurPtr( uint, uchar ); + void startSelect(); + void toggleEncoding(); + void toggleInsMode(); + void unlock(); + void update( uchar ); + void checkScrollBar( const TEvent&, TScrollBar *, int& ); + void detectEOL(); + + TScrollBar *hScrollBar; + TScrollBar *vScrollBar; + TIndicator *indicator; + char *buffer; + uint bufSize; + uint bufLen; + uint gapLen; + uint selStart; + uint selEnd; + uint curPtr; + TPoint curPos; + TPoint delta; + TPoint limit; + int drawLine; + uint drawPtr; + uint delCount; + uint insCount; + Boolean isValid; + Boolean canUndo; + Boolean modified; + Boolean selecting; + Boolean overwrite; + Boolean autoIndent; + + enum EOLTypes { eolCRLF, eolLF, eolCR } eolType; + + Boolean encSingleByte; + void nextChar( TStringView, uint &P, uint &width ); + Boolean formatCell( TSpan, uint&, TStringView, uint& , TColorAttr ); + TStringView bufChars( uint ); + TStringView bufPrevChars( uint ); + + static TEditorDialog _NEAR editorDialog; + static ushort _NEAR editorFlags; + static char _NEAR findStr[maxFindStrLen]; + static char _NEAR replaceStr[maxReplaceStrLen]; + static TEditor * _NEAR clipboard; + uchar lockCount; + uchar updateFlags; + int keyState; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TEditor( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TEditor& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TEditor*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TEditor& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TEditor* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TEditor + +#if defined( Uses_TMemo ) && !defined( __TMemo ) +#define __TMemo + +struct _FAR TEvent; + +struct TMemoData +{ + ushort length; + char buffer[1]; +}; + +class TMemo : public TEditor +{ + +public: + + TMemo( const TRect&, TScrollBar *, TScrollBar *, TIndicator *, ushort ) noexcept; + virtual void getData( void *rec ); + virtual void setData( void *rec ); + virtual ushort dataSize(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& ); + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TMemo( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TMemo& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMemo*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMemo& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMemo* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TMemo + + +#if defined( Uses_TFileEditor ) && !defined( __TFileEditor ) +#define __TFileEditor + +#if !defined( __DIR_H ) +#include +#endif // __DIR_H + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TIndicator; +struct _FAR TEvent; + +class TFileEditor : public TEditor +{ + +public: + + char fileName[MAXPATH]; + TFileEditor( const TRect&, + TScrollBar *, + TScrollBar *, + TIndicator *, + TStringView + ) noexcept; + virtual void doneBuffer(); + virtual void handleEvent( TEvent& ); + virtual void initBuffer(); + Boolean loadFile() noexcept; + Boolean save() noexcept; + Boolean saveAs() noexcept; + Boolean saveFile() noexcept; + virtual Boolean setBufSize( uint ); + virtual void shutDown(); + virtual void updateCommands(); + virtual Boolean valid( ushort ); + +private: + + static const char * _NEAR backupExt; + + virtual const char *streamableName() const + { return name; } + +protected: + + TFileEditor( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileEditor& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileEditor*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileEditor& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileEditor* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TFileEditor + + +#if defined( Uses_TEditWindow ) && !defined( __TEditWindow ) +#define __TEditWindow + +class _FAR TFileEditor; + +class TEditWindow : public TWindow +{ + +public: + + TEditWindow( const TRect&, TStringView, int ) noexcept; + virtual void close(); + virtual const char *getTitle( short ); + virtual void handleEvent( TEvent& ); + virtual void sizeLimits( TPoint& min, TPoint& max ); + + TFileEditor *editor; + +private: + + static const char * _NEAR clipboardTitle; + static const char * _NEAR untitled; + + virtual const char *streamableName() const + { return name; } + +protected: + + TEditWindow( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TEditWindow& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TEditWindow*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TEditWindow& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TEditWindow* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TEditWindow + + +#if defined( Uses_TFindDialogRec ) && !defined( __TFindDialogRec ) +#define __TFindDialogRec + +#if !defined( __STRING_H ) +#include +#endif // __STRING_H + +struct TFindDialogRec +{ + TFindDialogRec( const char *str, ushort flgs ) noexcept + { + strnzcpy( find, str, sizeof(find) ); + options = flgs; + } + char find[maxFindStrLen]; + ushort options; +}; + +#endif // Uses_TFindDialogRec + +#if defined( Uses_TReplaceDialogRec ) && !defined( __TReplaceDialogRec ) +#define __TReplaceDialogRec + +#if !defined( __STRING_H ) +#include +#endif // __STRING_H + +struct TReplaceDialogRec +{ + TReplaceDialogRec( const char *str, const char *rep, ushort flgs ) noexcept + { + strnzcpy( find, str, sizeof(find) ); + strnzcpy( replace, rep, sizeof(replace) ); + options = flgs; + } + char find[maxFindStrLen]; + char replace[maxReplaceStrLen]; + ushort options; +}; + +#endif // Uses_TReplaceDialogRec + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/hardware.h b/src/include/tvision/hardware.h new file mode 100644 index 00000000..ae9dfe75 --- /dev/null +++ b/src/include/tvision/hardware.h @@ -0,0 +1,318 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* HARDWARE.H */ +/* */ +/* defines the class THardwareInfo */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_THardwareInfo ) && !defined( __THardwareInfo ) +#define __THardwareInfo + +#if defined( __FLAT__ ) + +#if !defined( __WINDOWS_H ) +#include +#endif + +#else + +#if !defined( MAKELONG ) +#define MAKELONG(h,l) \ + ((long)(((unsigned)(l)) | (((long)((unsigned)(h))) << 16))) +#endif + +#endif + +struct TEvent; +struct MouseEventType; + +class THardwareInfo +{ + +public: + + THardwareInfo() noexcept; + ~THardwareInfo(); + + static uint32_t getTickCount() noexcept; + +#if defined( __FLAT__ ) + + enum ConsoleType { cnInput = 0, cnOutput = 1, cnStartup = 2 }; + enum PlatformType { plDPMI32 = 1, plWinNT = 2, plOS2 = 4 }; + + static PlatformType getPlatform() noexcept; + +// Caret functions. + + static void setCaretSize( ushort size ) noexcept; + static ushort getCaretSize() noexcept; + static void setCaretPosition( ushort x, ushort y ) noexcept; + static BOOL isCaretVisible() noexcept; + +// Screen functions. + + static ushort getScreenRows() noexcept; + static ushort getScreenCols() noexcept; + static ushort getScreenMode() noexcept; + static void setScreenMode( ushort mode ) noexcept; + static void clearScreen( ushort w, ushort h ) noexcept; + static void flushScreen() noexcept; + static void screenWrite( ushort x, ushort y, TScreenCell *buf, DWORD len ) noexcept; + static TScreenCell *allocateScreenBuffer() noexcept; + static void freeScreenBuffer( TScreenCell *buffer ) noexcept; + static void setUpConsole() noexcept; + static void restoreConsole() noexcept; + +// Mouse functions. + + static DWORD getButtonCount() noexcept; + static void cursorOn() noexcept; + static void cursorOff() noexcept; + +// Event functions. + + static BOOL getMouseEvent( MouseEventType& event ) noexcept; + static BOOL getKeyEvent( TEvent& event ) noexcept; + static void clearPendingEvent() noexcept; + static void waitForEvent( int timeoutMs ) noexcept; + static void stopEventWait() noexcept; + static BOOL setClipboardText( TStringView text ) noexcept; + static BOOL requestClipboardText( void (&accept)( TStringView ) ) noexcept; + +// System functions. + + static BOOL setCtrlBrkHandler( BOOL install ) noexcept; + static BOOL setCritErrorHandler( BOOL install ) noexcept; + + static const ushort NormalCvt[89]; + static const ushort ShiftCvt[89]; + static const ushort CtrlCvt[89]; + static const ushort AltCvt[89]; + +private: + + static BOOL __stdcall ctrlBreakHandler( DWORD dwCtrlType ) noexcept; + + static BOOL insertState; + static PlatformType platform; + static HANDLE consoleHandle[3]; + static DWORD consoleMode; + static DWORD pendingEvent; + static INPUT_RECORD irBuffer; + static CONSOLE_CURSOR_INFO crInfo; + static CONSOLE_SCREEN_BUFFER_INFO sbInfo; + +#ifndef __BORLANDC__ + enum { eventQSize = 24 }; + static TEvent eventQ[eventQSize]; + static size_t eventCount; + static BOOL getPendingEvent(TEvent &event, Boolean mouse) noexcept; + static void readEvents() noexcept; +#endif + +#else + + static ushort *getColorAddr( ushort offset = 0 ); + static ushort *getMonoAddr( ushort offset = 0 ); + static uchar getShiftState(); + static uchar getBiosScreenRows(); + static uchar getBiosVideoInfo(); + static void setBiosVideoInfo( uchar info ); + static ushort getBiosEquipmentFlag(); + static ushort huge getBiosEquipmentFlag(int); // Non-inline version. + static void setBiosEquipmentFlag( ushort flag ); + static Boolean getDPMIFlag(); + +private: + + static ushort huge getBiosSelector(); // For SYSINT.ASM. + + static Boolean dpmiFlag; + static ushort colorSel; + static ushort monoSel; + static ushort biosSel; + +#endif + +}; + +#if defined( __FLAT__ ) + +inline THardwareInfo::PlatformType THardwareInfo::getPlatform() noexcept +{ + return platform; +} + +#ifdef __BORLANDC__ +// Caret functions. + +inline ushort THardwareInfo::getCaretSize() noexcept +{ + return crInfo.dwSize; +} + +inline BOOL THardwareInfo::isCaretVisible() noexcept +{ + return crInfo.bVisible; +} + + +// Screen functions. + +inline ushort THardwareInfo::getScreenRows() noexcept +{ + return sbInfo.dwSize.Y; +} + +inline ushort THardwareInfo::getScreenCols() noexcept +{ + return sbInfo.dwSize.X; +} + +#pragma option -w-inl + +inline void THardwareInfo::clearScreen( ushort w, ushort h ) noexcept +{ + COORD coord = { 0, 0 }; + DWORD read; + + FillConsoleOutputAttribute( consoleHandle[cnOutput], 0x07, w*h, coord, &read ); + FillConsoleOutputCharacterA( consoleHandle[cnOutput], ' ', w*h, coord, &read ); +} + +#pragma option -w+inl + +inline void THardwareInfo::flushScreen() noexcept +{ +} + +inline TScreenCell *THardwareInfo::allocateScreenBuffer() noexcept +{ + GetConsoleScreenBufferInfo( consoleHandle[cnOutput], &sbInfo ); + short x = sbInfo.dwSize.X, y = sbInfo.dwSize.Y; + + if( x < 80 ) // Make sure we allocate at least enough for + x = 80; // a 80x50 screen. + if( y < 50 ) + y = 50; + + return (TScreenCell *) VirtualAlloc( 0, x * y * 4, MEM_COMMIT, PAGE_READWRITE ); +} + +inline void THardwareInfo::freeScreenBuffer( TScreenCell *buffer ) noexcept +{ + VirtualFree( buffer, 0, MEM_RELEASE ); +} + + +// Mouse functions. + +inline DWORD THardwareInfo::getButtonCount() +{ + DWORD num; + GetNumberOfConsoleMouseButtons(&num); + return num; +} + +inline void THardwareInfo::cursorOn() +{ + SetConsoleMode( consoleHandle[cnInput], consoleMode | ENABLE_MOUSE_INPUT ); +} + +inline void THardwareInfo::cursorOff() +{ + SetConsoleMode( consoleHandle[cnInput], consoleMode & ~ENABLE_MOUSE_INPUT ); +} +#endif // __BORLANDC__ + + +// Event functions. + +inline void THardwareInfo::clearPendingEvent() noexcept +{ + pendingEvent = 0; +} + + +// System functions. + +inline BOOL THardwareInfo::setCtrlBrkHandler( BOOL install ) noexcept +{ +#ifdef _WIN32 + return SetConsoleCtrlHandler( &THardwareInfo::ctrlBreakHandler, install ); +#else +/* Sets THardwareInfo::ctrlBreakHandle as the handler of control signals + * CTRL_C_EVENT and CTRL_BREAK_EVENT. When the signal is received, the + * handler sets the attribute TSystemError::ctrlBreakHit to true. + * https://docs.microsoft.com/en-us/windows/console/handlerroutine + */ + // Stub + return TRUE; +#endif +} + +inline BOOL THardwareInfo::setCritErrorHandler( BOOL install ) noexcept +{ + return TRUE; // Handled by NT or DPMI32.. +} + + +#else + +inline ushort *THardwareInfo::getColorAddr( ushort offset ) + { return (ushort *) MAKELONG( colorSel, offset ); } + +inline ushort *THardwareInfo::getMonoAddr( ushort offset ) + { return (ushort *) MAKELONG( monoSel, offset ); } + +inline uint32_t THardwareInfo::getTickCount() + { return *(uint32_t *) MAKELONG( biosSel, 0x6C ); } + +inline uchar THardwareInfo::getShiftState() + { return *(uchar *) MAKELONG( biosSel, 0x17 ); } + + +inline uchar THardwareInfo::getBiosScreenRows() + { return *(uchar *) MAKELONG( biosSel, 0x84 ); } + +inline uchar THardwareInfo::getBiosVideoInfo() + { return *(uchar *) MAKELONG( biosSel, 0x87 ); } + +inline void THardwareInfo::setBiosVideoInfo( uchar info ) + { *(uchar *) MAKELONG( biosSel, 0x87 ) = info; } + +inline ushort THardwareInfo::getBiosEquipmentFlag() + { return *(ushort *) MAKELONG( biosSel, 0x10 ); } + +inline void THardwareInfo::setBiosEquipmentFlag( ushort flag ) + { *(ushort *) MAKELONG( biosSel, 0x10 ) = flag; } + +inline Boolean THardwareInfo::getDPMIFlag() + { return dpmiFlag; } + +#endif + +#endif // __THardwareInfo + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/help.h b/src/include/tvision/help.h new file mode 100644 index 00000000..422924ed --- /dev/null +++ b/src/include/tvision/help.h @@ -0,0 +1,74 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* HELP.H */ +/* */ +/* defines the classes THelpViewer and THelpWindow */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __HELP_H ) +#define __HELP_H + +#define Uses_TStreamable +#define Uses_ipstream +#define Uses_opstream +#define Uses_fpstream +#define Uses_TObject +#define Uses_TPoint +#define Uses_TRect +#define Uses_TEvent +#define Uses_TScroller +#define Uses_TScrollBar +#define Uses_TWindow +#include + +#include + +// THelpViewer + +class THelpViewer : public TScroller +{ +public: + + THelpViewer( const TRect&, TScrollBar*, TScrollBar*, THelpFile*, ushort ) noexcept; + ~THelpViewer(); + + virtual void changeBounds( const TRect& ); + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& ); + void makeSelectVisible( int, TPoint&, uchar&, int& ); + void switchToTopic( int ); + + THelpFile *hFile; + THelpTopic *topic; + int selected; +}; + +// THelpWindow + +class THelpWindow : public TWindow +{ + + static const char * _NEAR helpWinTitle; + +public: + + THelpWindow( THelpFile*, ushort ) noexcept; + + virtual TPalette& getPalette() const; +}; + + +extern void notAssigned( opstream& s, int value ); + +extern TCrossRefHandler crossRefHandler; + +#endif // __HELP_H diff --git a/src/include/tvision/helpbase.h b/src/include/tvision/helpbase.h new file mode 100644 index 00000000..8b77b329 --- /dev/null +++ b/src/include/tvision/helpbase.h @@ -0,0 +1,192 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* HELPBASE.H */ +/* */ +/* defines the classes TParagraph, TCrossRef, THelpTopic, THelpIndex, */ +/* THelpFile */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __HELPBASE_H ) +#define __HELPBASE_H + +const int32_t magicHeader = 0x46484246L; //"FBHF" + +#define cHelpViewer "\x06\x07\x08" +#define cHelpWindow "\x80\x81\x82\x83\x84\x85\x86\x87" + +// TParagraph + +class TParagraph +{ + +public: + + TParagraph() noexcept {} + TParagraph *next; + Boolean wrap; + ushort size; + char *text; + +}; + +// TCrossRef + +class TCrossRef +{ + +public: + + TCrossRef() noexcept {} + int ref; + int offset; + uchar length; + +}; + + +typedef void (*TCrossRefHandler) ( opstream&, int ); + +class THelpTopic: public TObject, public TStreamable +{ + +public: + + THelpTopic() noexcept; + THelpTopic( StreamableInit ) noexcept {}; + virtual ~THelpTopic(); + + void addCrossRef( TCrossRef ref ) noexcept; + void addParagraph( TParagraph *p ) noexcept; + void getCrossRef( int i, TPoint& loc, uchar& length, int& ref ) noexcept; + TStringView getLine( int line ) noexcept; + int getNumCrossRefs() noexcept; + int numLines() noexcept; + void setCrossRef( int i, TCrossRef& ref ) noexcept; + void setNumCrossRefs( int i ) noexcept; + void setWidth( int aWidth ) noexcept; + + TParagraph *paragraphs; + + int numRefs; + TCrossRef *crossRefs; + +private: + + TStringView wrapText( char *text, int size, int& offset, Boolean wrap ) noexcept; + void readParagraphs( ipstream& s ); + void readCrossRefs( ipstream& s ); + void writeParagraphs( opstream& s ); + void writeCrossRefs( opstream& s ); + void disposeParagraphs() noexcept; + virtual const char *streamableName() const + { return name; } + int width; + int lastOffset; + int lastLine; + TParagraph *lastParagraph; + +protected: + + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, THelpTopic& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, THelpTopic*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, THelpTopic& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, THelpTopic* cl ) + { return os << (TStreamable *)cl; } + + +// THelpIndex + +class THelpIndex : public TObject, public TStreamable +{ +public: + + + THelpIndex() noexcept; + THelpIndex( StreamableInit ) noexcept {}; + virtual ~THelpIndex(); + + int32_t position( int ) noexcept; + void add( int, int32_t ); + + ushort size; + int32_t *index; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, THelpIndex& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, THelpIndex*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, THelpIndex& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, THelpIndex* cl ) + { return os << (TStreamable *)cl; } + + +// THelpFile + +class THelpFile : public TObject +{ + + static const char * _NEAR invalidContext; + +public: + + THelpFile( iopstream& s ); + virtual ~THelpFile(); + + THelpTopic *getTopic( int ); + THelpTopic *invalidTopic(); + void recordPositionInIndex( int ); + void putTopic( THelpTopic* ); + + iopstream *stream; + Boolean modified; + + THelpIndex *index; + int32_t indexPos; +}; + +extern void notAssigned( opstream& s, int value ); + +extern TCrossRefHandler crossRefHandler; + +#endif // __HELPBASE_H diff --git a/src/include/tvision/internal/ansidisp.h b/src/include/tvision/internal/ansidisp.h new file mode 100644 index 00000000..c6b22cb4 --- /dev/null +++ b/src/include/tvision/internal/ansidisp.h @@ -0,0 +1,154 @@ +#ifndef TVISION_ANSIDISP_H +#define TVISION_ANSIDISP_H + +#define Uses_TScreenCell +#include + +#include + +namespace tvision +{ + +// TermColor represents a color that is to be printed to screen +// using certain ANSI escape sequences. + +struct TermColor +{ + enum TermColorTypes : uint8_t { Default, Indexed, RGB, NoColor }; + + union + { + uint8_t idx; + uint8_t bgr[3]; + }; + TermColorTypes type; + + TermColor() = default; + + // GCC has issues optimizing the initialization of this struct. + // So do bit-casting manually. + + TermColor& operator=(uint32_t val) noexcept + { + memcpy(this, &val, sizeof(*this)); + return *this; + static_assert(sizeof(*this) == 4, ""); + } + operator uint32_t() const noexcept + { + uint32_t val; + memcpy(&val, this, sizeof(*this)); + return val; + } + TermColor(uint8_t aIdx, TermColorTypes aType) noexcept + { + *this = aIdx | (uint32_t(aType) << 24); + } + TermColor(TColorRGB c, TermColorTypes aType) noexcept + { + *this = uint32_t(c) | (uint32_t(aType) << 24); + } + TermColor(TermColorTypes aType) noexcept + { + *this = uint32_t(aType) << 24; + } + +}; + +struct TermAttr +{ + TermColor fg, bg; + TColorAttr::Style style; +}; + +/* AnsiDisplay is a simple diplay backend which prints characters and ANSI + * escape codes directly to stdout. + * + * AnsiDisplay implements only a subset of DisplayStrategy's pure virtual + * functions, so it depends on another implementation from which it inherits, + * which is the template parameter. In particular, AnsiDisplay implements the + * lowlevel<*> functions. + * + * This templated inheritance also makes it possible to combine this class + * with input strategies which depend on a certain display strategy, + * as is the case of NcursesInput and NcursesDisplay. */ + +class AnsiDisplayBase +{ + class Buffer + { + char *head {nullptr}; + size_t capacity {0}; + public: + char *tail {nullptr}; + + ~Buffer(); + char *data() noexcept; + size_t size() const noexcept; + void clear() noexcept; + void push(TStringView) noexcept; + void push(char) noexcept; + void reserve(size_t) noexcept; + }; + + const StdioCtl &io; + Buffer buf; + TermAttr lastAttr {}; + + void bufWriteCSI1(uint a, char F) noexcept; + void bufWriteCSI2(uint a, uint b, char F) noexcept; + +protected: + + AnsiDisplayBase(const StdioCtl &aIo) noexcept : + io(aIo) + { + } + + ~AnsiDisplayBase(); + + void clearAttributes() noexcept; + void clearScreen() noexcept; + + void lowlevelWriteChars(TStringView chars, TColorAttr attr, const TermCap &) noexcept; + void lowlevelMoveCursor(uint x, uint y) noexcept; + void lowlevelMoveCursorX(uint x, uint y) noexcept; + void lowlevelFlush() noexcept; +}; + +template +class AnsiDisplay : public DisplayBase, public AnsiDisplayBase +{ + +public: + + template + AnsiDisplay(Args&& ...args) noexcept : + DisplayBase(static_cast(args)...), + AnsiDisplayBase(TerminalDisplay::io) + { + static_assert(std::is_base_of::value, + "The base class of AnsiDisplay must be a derived of TerminalDisplay." + ); + } + + void lowlevelWriteChars(TStringView chars, TColorAttr attr) noexcept override + { AnsiDisplayBase::lowlevelWriteChars(chars, attr, TerminalDisplay::termcap); } + void lowlevelMoveCursor(uint x, uint y) noexcept override + { AnsiDisplayBase::lowlevelMoveCursor(x, y); } + void lowlevelMoveCursorX(uint x, uint y) noexcept override + { AnsiDisplayBase::lowlevelMoveCursorX(x, y); } + void lowlevelFlush() noexcept override + { AnsiDisplayBase::lowlevelFlush(); } + + void reloadScreenInfo() noexcept override + { + DisplayBase::reloadScreenInfo(); + clearAttributes(); + } + +}; + +} // namespace tvision + +#endif // TVISION_ANSIDISP_H diff --git a/src/include/tvision/internal/base64.h b/src/include/tvision/internal/base64.h new file mode 100644 index 00000000..0d654f98 --- /dev/null +++ b/src/include/tvision/internal/base64.h @@ -0,0 +1,36 @@ +#ifndef TVISION_BASE64_H +#define TVISION_BASE64_H + +#include +#include + +namespace tvision +{ + +// Returns the region of 'output' that contains the encoded data. +// Pre: the capacity of 'output' is no less than 4/3 of 'input.size()'. +TStringView encodeBase64(TStringView input, char *output) noexcept; + +// Returns the region of 'output' that contains the decoded data. +// Pre: the capacity of 'output' is no less than 3/4 of 'input.size()'. +TStringView decodeBase64(TStringView input, char *output) noexcept; + +inline std::string encodeBase64(TStringView input) +{ + std::string result((input.size() * 4)/3 + 4, '\0'); + auto encoded = encodeBase64(input, &result[0]); + result.resize(encoded.size()); + return result; +} + +inline std::string decodeBase64(TStringView input) +{ + std::string result((input.size() * 3)/4 + 3, '\0'); + auto encoded = decodeBase64(input, &result[0]); + result.resize(encoded.size()); + return result; +} + +} // namespace tvision + +#endif // TVISION_BASE64_H diff --git a/src/include/tvision/internal/codepage.h b/src/include/tvision/internal/codepage.h new file mode 100644 index 00000000..444aa5c7 --- /dev/null +++ b/src/include/tvision/internal/codepage.h @@ -0,0 +1,71 @@ +#ifndef TVISION_CODEPAGE_H +#define TVISION_CODEPAGE_H + +#ifndef _TV_VERSION +#include +#endif + +#include +#include + +namespace tvision +{ + +class CpTranslator +{ + + CpTranslator() noexcept; + static CpTranslator instance; + + struct CpTable + { + TStringView cp; + const uint32_t *toUtf8Int; + const std::unordered_map fromUtf8; + + CpTable( TStringView cp, + const TStringView toUtf8[256], + const std::array &toUtf8Int ) noexcept; + }; + + static const CpTable tables[2]; + static const CpTable *activeTable; + + static void useTable(const CpTable *table) noexcept + { + activeTable = table; + } + +public: + + static void use(TStringView cp) noexcept + { + for (const CpTable &t : tables) + if (t.cp == cp) + { + useTable(&t); + return; // Watch out! + } + useTable(&tables[0]); + } + + static uint32_t toUtf8Int(unsigned char c) noexcept + { + return activeTable->toUtf8Int[c]; + } + + static char fromUtf8(TStringView s) noexcept; + + static char printableFromUtf8(TStringView s) noexcept + { + uchar c = fromUtf8(s); + if (c < ' ') + return '\0'; + return c; + } + +}; + +} // namespace tvision + +#endif // TVISION_CODEPAGE_H diff --git a/src/include/tvision/internal/constarr.h b/src/include/tvision/internal/constarr.h new file mode 100644 index 00000000..e295093d --- /dev/null +++ b/src/include/tvision/internal/constarr.h @@ -0,0 +1,31 @@ +#ifndef TVISION_CONSTARR_H +#define TVISION_CONSTARR_H + +#include + +// std::array is not constexpr until C++17. So we make our own, which costs +// nothing. + +namespace tvision +{ + +template +struct constarray +{ + T elems[N]; + + constexpr T& operator[](size_t i) noexcept + { + return elems[i]; + } + + constexpr const T& operator[](size_t i) const noexcept + { + return elems[i]; + } + +}; + +} // namespace tvision + +#endif // TVISION_CONSTARR_H diff --git a/src/include/tvision/internal/constmap.h b/src/include/tvision/internal/constmap.h new file mode 100644 index 00000000..50d9b04a --- /dev/null +++ b/src/include/tvision/internal/constmap.h @@ -0,0 +1,111 @@ +#ifndef TVISION_CONSTMAP_H +#define TVISION_CONSTMAP_H + +#include +#include + +#include +#include +#include +#include + +namespace tvision +{ + +// Same as unordered_map, but with operator[] const. + +template +class const_unordered_map_base : public std::unordered_map +{ + + using super = std::unordered_map; + +public: + + using super::super; + + Value operator[](const Key &key) const noexcept + { + auto it = super::find(key); + if (it == super::end()) + return {}; + return it->second; + } + +}; + +template +class const_unordered_map : public const_unordered_map_base +{ + + using super = const_unordered_map_base; + +public: + + using super::super; + +}; + +// Overload of const_unordered_map for Key=uint64_t, which provides an additional +// constructor function 'with_string_keys'. +// +// 'with_string_keys' allows using short strings as keys. These strings are reinterpreted +// as integers on-the-fly. For example, "012" becomes (uint64_t) 0x323130. +// +// Complete example: +// +// const auto map = const_unordered_map::with_string_keys({ +// { "012", true }, +// }); +// +// assert(map["012"] == true); +// assert(map[0x323130] == true); +// assert(map["abc"] == false); + +template +class const_unordered_map : public const_unordered_map_base +{ + + using super = const_unordered_map_base; + + struct StringAsIntPair : const_unordered_map::super::value_type + { + + using super = typename const_unordered_map::super::value_type; + + using super::super; + + constexpr StringAsIntPair(TStringView s, const Value &v) noexcept : + super(string_as_int(s), v) + { + } + + constexpr StringAsIntPair(TStringView s, Value &&v) noexcept : + super(string_as_int(s), std::move(v)) + { + } + + }; + +public: + + using super::super; + + static const_unordered_map with_string_keys(std::initializer_list init) noexcept + { + return const_unordered_map( + static_cast(init.begin()), + static_cast(init.end()) + ); + } + + Value operator[](TStringView key) const noexcept + { + return super::operator[](string_as_int(key)); + } + +}; + +} // namespace tvision + +#endif // TVISION_CONSTMAP_H diff --git a/src/include/tvision/internal/cursor.h b/src/include/tvision/internal/cursor.h new file mode 100644 index 00000000..9385eacc --- /dev/null +++ b/src/include/tvision/internal/cursor.h @@ -0,0 +1,101 @@ +#ifndef TVISION_CURSOR_H +#define TVISION_CURSOR_H + +#define Uses_TColorAttr +#include + +#include + +namespace tvision +{ + +class ScreenCursor +{ +public: + + ScreenCursor() noexcept; + ~ScreenCursor(); + + void show() noexcept; + void hide() noexcept; + bool isVisible() const noexcept; + void setPos(const TPoint &p) noexcept; + const TPoint& getPos() const noexcept; + void apply(TColorAttr &attr) noexcept; + void restore(TColorAttr &attr) const noexcept; + +protected: + + TPoint pos; + bool visible; + TColorAttr backup; + + virtual void draw(TColorAttr &attr) const noexcept = 0; +}; + +inline ScreenCursor::ScreenCursor() noexcept : + pos({-1, -1}), + visible(false), + backup(0) +{ + DisplayBuffer::addCursor(this); +} + +inline ScreenCursor::~ScreenCursor() +{ + DisplayBuffer::removeCursor(this); +} + +inline void ScreenCursor::show() noexcept +{ + if (!visible) + DisplayBuffer::changeCursor(); + visible = true; +} + +inline void ScreenCursor::hide() noexcept +{ + visible = false; +} + +inline bool ScreenCursor::isVisible() const noexcept +{ + return visible; +} + +inline void ScreenCursor::setPos(const TPoint &p) noexcept +{ + if (visible && p != pos) + DisplayBuffer::changeCursor(); + pos = p; +} + +inline const TPoint& ScreenCursor::getPos() const noexcept +{ + return pos; +} + +inline void ScreenCursor::apply(TColorAttr &attr) noexcept +{ + backup = attr; + draw(attr); +} + +inline void ScreenCursor::restore(TColorAttr &attr) const noexcept +{ + attr = backup; +} + +class ReverseScreenCursor : public ScreenCursor +{ + void draw(TColorAttr &attr) const noexcept override; +}; + +class NegativeScreenCursor : public ScreenCursor +{ + void draw(TColorAttr &attr) const noexcept override; +}; + +} // namespace tvision + +#endif // TVISION_CURSOR_H diff --git a/src/include/tvision/internal/dispbuff.h b/src/include/tvision/internal/dispbuff.h new file mode 100644 index 00000000..1f025e80 --- /dev/null +++ b/src/include/tvision/internal/dispbuff.h @@ -0,0 +1,114 @@ +#ifndef TVISION_DISPBUFF_H +#define TVISION_DISPBUFF_H + +#define Uses_TPoint +#include + +#include +#include + +namespace tvision +{ + +class ScreenCursor; +class DisplayStrategy; + +namespace +{ +struct FlushScreenAlgorithm; +} + +class DisplayBuffer +{ + friend FlushScreenAlgorithm; + + struct Range { + int begin, end; + }; + + std::vector buffer, flushBuffer; + std::vector rowDamage; + + const bool wideOverlapping; + bool screenTouched {true}; + bool caretMoved {false}; + TPoint caretPosition {-1, -1}; + int newCaretSize {0}; + + bool limitFPS; + std::chrono::microseconds flushDelay {}; + std::chrono::time_point lastFlush {}; + + static DisplayBuffer *instance; +#ifdef _WIN32 + static constexpr int defaultFPS = 120; // Just 60 feels notably slower on Windows, I don't know why. +#else + static constexpr int defaultFPS = 60; +#endif + + bool inBounds(int x, int y) const noexcept; + + void resizeBuffer() noexcept; + void setDirty(int x, int y, int len) noexcept; + void validateCell(TScreenCell &cell) const noexcept; + + std::vector cursors; + void drawCursors() noexcept; + void undrawCursors() noexcept; + + bool needsFlush() const noexcept; + bool timeToFlush() noexcept; + +public: + + TPoint size {}; + int caretSize {}; + + DisplayBuffer() noexcept; + ~DisplayBuffer(); + + void setCaretSize(int size) noexcept; + void setCaretPosition(int x, int y) noexcept; + void screenWrite(int x, int y, TScreenCell *buf, int len) noexcept; + void clearScreen(DisplayStrategy &) noexcept; + void redrawScreen(DisplayStrategy &) noexcept; + void flushScreen(DisplayStrategy &) noexcept; + TScreenCell *reloadScreenInfo(DisplayStrategy &) noexcept; + + static void addCursor(ScreenCursor *cursor) noexcept; + static void removeCursor(ScreenCursor *cursor) noexcept; + static void changeCursor() noexcept; +}; + +inline bool DisplayBuffer::inBounds(int x, int y) const noexcept +{ + return 0 <= x && x < size.x && + 0 <= y && y < size.y; +} + +inline void DisplayBuffer::addCursor(ScreenCursor *cursor) noexcept +{ + auto &cursors = instance->cursors; + for (auto it = cursors.begin(); it != cursors.end(); ++it) + if (*it == cursor) + return; + cursors.push_back(cursor); +} + +inline void DisplayBuffer::removeCursor(ScreenCursor *cursor) noexcept +{ + changeCursor(); + auto &cursors = instance->cursors; + for (auto it = cursors.begin(); it != cursors.end(); ++it) + if (*it == cursor) + return (void) cursors.erase(it); +} + +inline void DisplayBuffer::changeCursor() noexcept +{ + instance->caretMoved = true; +} + +} // namespace tvision + +#endif // TVISION_DISPBUFF_H diff --git a/src/include/tvision/internal/events.h b/src/include/tvision/internal/events.h new file mode 100644 index 00000000..c7f4a50a --- /dev/null +++ b/src/include/tvision/internal/events.h @@ -0,0 +1,177 @@ +#ifndef TVISION_EVENTS_H +#define TVISION_EVENTS_H + +#define Uses_TEvent +#include +#include +#include +#include + +#ifdef _TV_UNIX +#include +#else +#include +#endif + +namespace tvision +{ + +#ifdef _TV_UNIX +using SysHandle = int; +#else +using SysHandle = HANDLE; +#endif + +struct SysManualEvent +{ +#ifdef _TV_UNIX + using Handle = int[2]; + Handle fds; +#else + using Handle = HANDLE; + Handle hEvent; +#endif + + static bool createHandle(Handle &handle) noexcept; + static SysHandle getWaitableHandle(Handle handle) noexcept; + + SysManualEvent(Handle aHandle) noexcept; + ~SysManualEvent(); + void signal() noexcept; + void clear() noexcept; +}; + +inline SysManualEvent::SysManualEvent(Handle aHandle) noexcept : +#ifdef _TV_UNIX + fds {aHandle[0], aHandle[1]} +#else + hEvent {aHandle} +#endif +{ +} + +inline SysHandle SysManualEvent::getWaitableHandle(Handle handle) noexcept +{ +#ifdef _TV_UNIX + return handle[0]; +#else + return handle; +#endif +} + +class EventSource +{ +public: + + const SysHandle handle; + + EventSource(SysHandle handle) noexcept : + handle(handle) + { + } + + virtual ~EventSource() {} + + virtual bool hasPendingEvents() noexcept; + virtual bool getEvent(TEvent &) noexcept; +}; + +class WakeUpEventSource : public EventSource +{ + SysManualEvent sys; + bool (*callback) (void *, TEvent &) noexcept; + void *callbackArgs; + std::atomic signaled {false}; + + bool clear() noexcept; + +public: + + // Pre: if 'callback' or 'callbackArgs' are not null, their lifetime must + // exceed that of 'this'. 'callback' must be noexcept. + WakeUpEventSource( SysManualEvent::Handle aHandle, + bool (*aCallback) (void *, TEvent &), + void *aCallbackArgs ) noexcept; + + WakeUpEventSource &operator=(const WakeUpEventSource &) = delete; + + void signal() noexcept; // Multiple producers. + bool getEvent(TEvent &event) noexcept override; // Single consumer. +}; + +inline WakeUpEventSource::WakeUpEventSource( SysManualEvent::Handle aHandle, + bool (*aCallback) (void *, TEvent &), + void *aCallbackArgs ) noexcept : + EventSource(SysManualEvent::getWaitableHandle(aHandle)), + sys(aHandle), + callback((bool (*)(void *, TEvent &) noexcept) aCallback), + callbackArgs(aCallbackArgs) +{ +} + +#ifdef _TV_UNIX +using PollItem = struct pollfd; +static inline PollItem pollItem(SysHandle fd) noexcept { return {fd, POLLIN}; } +#else +using PollItem = HANDLE; +static inline PollItem pollItem(SysHandle h) noexcept { return h; } +#endif + +enum PollState : uint8_t +{ + psNothing, + psReady, + psDisconnect, +}; + +struct PollData +{ + std::vector items; + std::vector states; + + void push_back(SysHandle h) + { + items.push_back(pollItem(h)); + states.push_back(psNothing); + } + + void erase(size_t i) + { + items.erase(items.begin() + i); + states.erase(states.begin() + i); + } + + size_t size() + { + return items.size(); + } +}; + +class EventWaiter +{ + std::vector sources; + PollData pd; + std::unique_ptr wakeUp {nullptr}; + TEvent readyEvent; + bool readyEventPresent {false}; + + void removeSource(size_t i) noexcept; + void pollSources(int timeoutMs) noexcept; + bool hasReadyEvent() noexcept; + void getReadyEvent(TEvent &ev) noexcept; + +public: + + EventWaiter() noexcept; + + void addSource(EventSource &) noexcept; + void removeSource(EventSource &) noexcept; + + bool getEvent(TEvent &ev) noexcept; + void waitForEvent(int ms) noexcept; + void stopEventWait() noexcept; +}; + +} // namespace tvision + +#endif // TVISION_EVENTS_H diff --git a/src/include/tvision/internal/far2l.h b/src/include/tvision/internal/far2l.h new file mode 100644 index 00000000..1eae5da1 --- /dev/null +++ b/src/include/tvision/internal/far2l.h @@ -0,0 +1,27 @@ +#ifndef TVISION_FAR2L_H +#define TVISION_FAR2L_H + +#include + +namespace tvision +{ + +class EventSource; + +#define far2lEnableSeq "\x1B_far2l1\x1B\\" +#define far2lDisableSeq "\x1B_far2l0\x1B\\" +#define far2lPingSeq "\x1B_far2l:FAR=\x1B\\" + +enum { pingTimeout = 200 }; + +ParseResult parseFar2lAnswer(GetChBuf &, TEvent &, InputState &) noexcept; +ParseResult parseFar2lInput(GetChBuf &, TEvent &, InputState &) noexcept; + +bool setFar2lClipboard(StdioCtl &, TStringView, InputState &) noexcept; +bool requestFar2lClipboard(StdioCtl &, InputState &) noexcept; + +void waitFar2lPing(EventSource &, InputState &) noexcept; + +} // namespace tvision + +#endif // TVISION_FAR2L_H diff --git a/src/include/tvision/internal/findfrst.h b/src/include/tvision/internal/findfrst.h new file mode 100644 index 00000000..5c485229 --- /dev/null +++ b/src/include/tvision/internal/findfrst.h @@ -0,0 +1,87 @@ +#ifndef TVISION_FINDFRST_H +#define TVISION_FINDFRST_H + +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#endif + +namespace tvision +{ + +// A class implementing the behaviour of findfirst and findnext. +// allocate() assigns a FindFirstRec to the provided find_t struct and sets +// the search filters. get() simply retrieves the FindFirstRec that was +// assigned to a find_t struct. next() performs the actual search and +// automatically updates the find_t struct. + +class FindFirstRec +{ + +public: + + static FindFirstRec* allocate(struct find_t *, unsigned, const char *) noexcept; + static FindFirstRec* get(struct find_t *) noexcept; + + bool next() noexcept; + +private: + + struct find_t *finfo; + unsigned searchAttr; + +#ifndef _WIN32 + DIR *dirStream {0}; + std::string searchDir; + std::string wildcard; +#else + HANDLE hFindFile {INVALID_HANDLE_VALUE}; + std::string fileName; +#endif // _WIN32 + + bool open() noexcept; + void close() noexcept; + bool setParameters(unsigned, const char *) noexcept; + bool attrMatch(unsigned attrib) noexcept; + +#ifndef _WIN32 + bool setPath(const char*) noexcept; + bool matchEntry(struct dirent*) noexcept; + + static bool wildcardMatch(char const *wildcard, char const *filename) noexcept; + unsigned cvtAttr(const struct stat *st, const char* filename) noexcept; + static void cvtTime(const struct stat *st, struct find_t *fileinfo) noexcept; +#else + unsigned cvtAttr(const WIN32_FIND_DATAW *findData, const wchar_t* filename) noexcept; + static void cvtTime(const WIN32_FIND_DATAW *findData, struct find_t *fileinfo) noexcept; +#endif // _WIN32 + + // A vector of FindFirstRec that deallocates all directory streams + // on destruction. + class RecList : std::vector + { + friend class FindFirstRec; + using std::vector::vector; + ~RecList() + { + for (FindFirstRec &r : *this) + r.close(); + } + std::mutex m; + operator std::mutex&() + { + return m; + } + } static recList; +}; + +} // namespace tvision + +#endif // TVISION_FINDFRST_H diff --git a/src/include/tvision/internal/getenv.h b/src/include/tvision/internal/getenv.h new file mode 100644 index 00000000..f0bce552 --- /dev/null +++ b/src/include/tvision/internal/getenv.h @@ -0,0 +1,31 @@ +#ifndef TVISION_GETENV_H +#define TVISION_GETENV_H + +#include + +namespace tvision +{ + +template +inline T getEnv(const char* name, T def = T{}) noexcept +{ + const char* body = getenv(name); + return body ? body : def; +} + +template<> +inline int getEnv(const char* name, int def) noexcept +{ + const char* body = getenv(name); + if (body) { + char* end; + auto i = strtol(body, &end, 0); + if (body != end) + return i; + } + return def; +} + +} // namespace tvision + +#endif // TVISION_GETENV_H diff --git a/src/include/tvision/internal/gpminput.h b/src/include/tvision/internal/gpminput.h new file mode 100644 index 00000000..1e48d804 --- /dev/null +++ b/src/include/tvision/internal/gpminput.h @@ -0,0 +1,51 @@ +#ifndef TVISION_GPMINPUT_H +#define TVISION_GPMINPUT_H + +#include + +#ifdef HAVE_GPM + +#define Uses_TPoint +#define Uses_TEvent +#include + +#include +#include + +namespace tvision +{ + +class GpmInput final : public InputStrategy +{ + NegativeScreenCursor cursor; + uchar buttonState; + + static void fitEvent(Gpm_Event&) noexcept; + GpmInput() noexcept; + +public: + + static GpmInput *create() noexcept; + ~GpmInput(); + bool getEvent(TEvent &ev) noexcept; + int getButtonCount() noexcept; +}; + +} // namespace tvision + +#else + +namespace tvision +{ + +class GpmInput : public InputStrategy +{ +public: + static GpmInput *create() noexcept { return nullptr; } +}; + +} // namespace tvision + +#endif // HAVE_GPM + +#endif // TVISION_GPMINPUT_H diff --git a/src/include/tvision/internal/linuxcon.h b/src/include/tvision/internal/linuxcon.h new file mode 100644 index 00000000..9e0bcfec --- /dev/null +++ b/src/include/tvision/internal/linuxcon.h @@ -0,0 +1,66 @@ +#ifndef TVISION_LINUXCON_H +#define TVISION_LINUXCON_H + +#ifdef __linux__ + +#include + +struct TEvent; + +namespace tvision +{ + +class ScreenLifetime; +class SigwinchHandler; +class GpmInput; +struct InputState; + +struct LinuxConsoleInput final : public EventSource +{ + StdioCtl &io; + InputStrategy &input; + + LinuxConsoleInput(StdioCtl &aIo, InputStrategy &aInput) noexcept : + EventSource(aInput.handle), + io(aIo), + input(aInput) + { + } + + bool getEvent(TEvent &ev) noexcept override; + bool hasPendingEvents() noexcept override; + + static ushort getKeyboardModifiers(StdioCtl &io) noexcept; +}; + +class LinuxConsoleStrategy : public ConsoleStrategy +{ + ScreenLifetime &scrl; + InputState &inputState; + SigwinchHandler *sigwinch; + LinuxConsoleInput &wrapper; + GpmInput *gpm; + + LinuxConsoleStrategy( DisplayStrategy &, LinuxConsoleInput &, + ScreenLifetime &, InputState &, SigwinchHandler *, + GpmInput * ) noexcept; + +public: + + // Pre: 'io.isLinuxConsole()' returns 'true'. + // The lifetime of 'io' must exceed that of the returned object. + // Takes ownership over 'scrl', 'inputState', 'display' and 'input'. + static LinuxConsoleStrategy &create( StdioCtl &io, ScreenLifetime &scrl, + InputState &inputState, + DisplayStrategy &display, + InputStrategy &input ) noexcept; + ~LinuxConsoleStrategy(); + + static int charWidth(uint32_t) noexcept; +}; + +} // namespace tvision + +#endif // __linux__ + +#endif // TVISION_LINUXCON_H diff --git a/src/include/tvision/internal/ncurdisp.h b/src/include/tvision/internal/ncurdisp.h new file mode 100644 index 00000000..9d7db865 --- /dev/null +++ b/src/include/tvision/internal/ncurdisp.h @@ -0,0 +1,62 @@ +#ifndef TVISION_NCURDISP_H +#define TVISION_NCURDISP_H + +#include + +#ifdef HAVE_NCURSES + +#include +#include + +namespace tvision +{ + +class NcursesDisplay : public TerminalDisplay +{ + SCREEN *term; + + bool hasColors; + std::unordered_map pairIdentifiers; + ushort definedPairs; + + bool usesNcursesDraw; + + void getCaretPosition(int &x, int &y) noexcept; + uint translateAttributes(TColorAttr attr) noexcept; + uint getColorPair(uchar pairKey) noexcept; + +public: + + // The lifetime of 'aIo' exceeds that of 'this'. + NcursesDisplay(StdioCtl &io) noexcept; + ~NcursesDisplay(); + + void reloadScreenInfo() noexcept override; + TPoint getScreenSize() noexcept override; + int getCaretSize() noexcept override; + int getColorCount() noexcept override; + + void clearScreen() noexcept override; + +protected: + + void lowlevelWriteChars(TStringView chars, TColorAttr attr) noexcept override; + void lowlevelMoveCursor(uint x, uint y) noexcept override; + void lowlevelCursorSize(int size) noexcept override; + void lowlevelFlush() noexcept override; +}; + +} // namespace tvision + +#else + +namespace tvision +{ + +class NcursesDisplay : public DisplayStrategy {}; + +} // namespace tvision + +#endif // HAVE_NCURSES + +#endif // TVISION_NCURDISP_H diff --git a/src/include/tvision/internal/ncursinp.h b/src/include/tvision/internal/ncursinp.h new file mode 100644 index 00000000..4658d01f --- /dev/null +++ b/src/include/tvision/internal/ncursinp.h @@ -0,0 +1,51 @@ +#ifndef TVISION_NCURSINP_H +#define TVISION_NCURSINP_H + +#include + +#ifdef HAVE_NCURSES + +#define Uses_TKeys +#define Uses_TPoint +#define Uses_TEvent +#include + +namespace tvision +{ + +class NcursesDisplay; +struct InputState; + +class NcursesInput : public InputStrategy +{ + enum : char { KEY_ESC = '\x1B' }; + enum { readTimeout = 10 }; + + StdioCtl &io; + InputState &state; + bool mouseEnabled; + + static int getch_nb() noexcept; + void detectAlt(int keys[4], bool &Alt) noexcept; + void parsePrintableChar(TEvent &ev, int keys[4], int &num_keys) noexcept; + void readUtf8Char(int keys[4], int &num_keys) noexcept; + + bool parseCursesMouse(TEvent&) noexcept; + void consumeUnprocessedInput() noexcept; + +public: + + // Lifetimes of 'io', 'display' and 'state' must exceed that of 'this'. + NcursesInput(StdioCtl &io, NcursesDisplay &display, InputState &state, bool mouse) noexcept; + ~NcursesInput(); + + bool getEvent(TEvent &ev) noexcept; + int getButtonCount() noexcept; + bool hasPendingEvents() noexcept; +}; + +} // namespace tvision + +#endif // HAVE_NCURSES + +#endif // TVISION_NCURSINP_H diff --git a/src/include/tvision/internal/pathconv.h b/src/include/tvision/internal/pathconv.h new file mode 100644 index 00000000..b621e0d4 --- /dev/null +++ b/src/include/tvision/internal/pathconv.h @@ -0,0 +1,45 @@ +#ifndef TVISION_PATHCONV_H +#define TVISION_PATHCONV_H + +#include +#include +#include + +namespace tvision +{ + +inline bool isDriveLetter(char c) noexcept +{ + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); +} + +// path_dos2unix: replaces '\' with '/' and removes drive letter. + +inline void path_dos2unix(std::string &s, bool drive=true) noexcept { + std::replace(s.begin(), s.end(), '\\', '/'); + if (drive && s.size() > 1 && s[1] == ':' && isDriveLetter(s[0])) + s = s.substr(2); +} + +inline void path_dos2unix(char *c, bool drive=true) noexcept { + char *d = c; + while ((d = strchr(d, '\\'))) + *d = '/'; + if (drive && *c && c[1] == ':' && isDriveLetter(*c)) + memmove(c, c+2, strlen(c)-1); // Copies null terminator as well. +} + +// path_unix2dos: replaces '/' with '\'. + +inline void path_unix2dos(std::string &s) noexcept { + std::replace(s.begin(), s.end(), '/', '\\'); +} + +inline void path_unix2dos(char *c) noexcept { + while ((c = strchr(c, '/'))) + *c = '\\'; +} + +} // namespace tvision + +#endif // TVISION_PATHCONV_H diff --git a/src/include/tvision/internal/platform.h b/src/include/tvision/internal/platform.h new file mode 100644 index 00000000..4a7e4aa4 --- /dev/null +++ b/src/include/tvision/internal/platform.h @@ -0,0 +1,204 @@ +#ifndef TVISION_PLATFORM_H +#define TVISION_PLATFORM_H + +#define Uses_TPoint +#define Uses_TColorAttr +#include +#include +#include +#include +#include +#include + +struct TEvent; + +namespace tvision +{ + +class DisplayStrategy +{ +public: + + virtual ~DisplayStrategy() {} + + virtual TPoint getScreenSize() noexcept { return {}; } + virtual int getCaretSize() noexcept { return 0; } // Range [0, 100]. + virtual void clearScreen() noexcept {} + virtual ushort getScreenMode() noexcept { return 0; } + virtual void reloadScreenInfo() noexcept {} + virtual void lowlevelWriteChars(TStringView chars, TColorAttr attr) noexcept {} + virtual void lowlevelMoveCursor(uint x, uint y) noexcept {}; + virtual void lowlevelMoveCursorX(uint x, uint y) noexcept { lowlevelMoveCursor(x, y); } + virtual void lowlevelCursorSize(int size) noexcept {}; + virtual void lowlevelFlush() noexcept {}; + virtual bool screenChanged() noexcept { return false; } +}; + +class InputStrategy : public EventSource +{ +public: + + InputStrategy(SysHandle aHandle) noexcept : + EventSource(aHandle) + { + } + + virtual ~InputStrategy() {} + + virtual int getButtonCount() noexcept { return 0; } + virtual void cursorOn() noexcept {} + virtual void cursorOff() noexcept {} +}; + +struct ConsoleStrategy +{ + DisplayStrategy &display; + InputStrategy &input; + const std::vector sources; + + ConsoleStrategy( DisplayStrategy &aDisplay, InputStrategy &aInput, + std::vector &&aSources ) noexcept : + display(aDisplay), + input(aInput), + sources(std::move(aSources)) + { + } + + virtual ~ConsoleStrategy() {} + + virtual bool isAlive() noexcept { return true; } + virtual bool setClipboardText(TStringView) noexcept { return false; } + virtual bool requestClipboardText(void (&)(TStringView)) noexcept { return false; } +}; + +using ThreadId = const void *; + +struct ThisThread +{ + static ThreadId id() noexcept + { + static thread_local struct {} idBase; + return &idBase; + } +}; + +#if ATOMIC_POINTER_LOCK_FREE < 2 +#warning The code below assumes that atomic pointers are lock-free, but they are not. +#endif + +template +struct SignalThreadSafe +{ + T t; + std::atomic lockingThread {}; + + struct LockGuard + { + SignalThreadSafe *self; + LockGuard(SignalThreadSafe *aSelf) noexcept : self(aSelf) + { + ThreadId none {}; + // Use a spin lock because regular mutexes are not signal-safe. + if (self) + while (self->lockingThread.compare_exchange_weak(none, ThisThread::id())) + ; + } + ~LockGuard() + { + if (self) + self->lockingThread = ThreadId {}; + } + }; + + template + // 'func' takes a 'T &' by parameter. + auto lock(Func &&func) noexcept + { + LockGuard lk {lockedByThisThread() ? nullptr : this}; + return func(t); + } + + bool lockedByThisThread() const noexcept + { + return lockingThread == ThisThread::id(); + } +}; + +class Platform +{ +#ifdef _TV_UNIX + StdioCtl io; +#endif + EventWaiter waiter; + DisplayBuffer displayBuf; + DisplayStrategy dummyDisplay; + InputStrategy dummyInput {(SysHandle) 0}; + ConsoleStrategy dummyConsole {dummyDisplay, dummyInput, {}}; + // Invariant: 'console' contains either a non-owning reference to 'dummyConsole' + // or an owning reference to a heap-allocated ConsoleStrategy object. + SignalThreadSafe console {&dummyConsole}; + + Platform() noexcept; + ~Platform(); + + void setUpConsole(ConsoleStrategy *&) noexcept; + void restoreConsole(ConsoleStrategy *&) noexcept; + void checkConsole() noexcept; + bool sizeChanged(TEvent &ev) noexcept; + ConsoleStrategy &createConsole() noexcept; + + static int errorCharWidth(uint32_t) noexcept; + static void signalCallback(bool) noexcept; + + bool screenChanged() noexcept + { return console.lock([] (auto *c) { return c->display.screenChanged(); }); } + +public: + + static Platform instance; + static int (*charWidth)(uint32_t) noexcept; + + // Explicit 'this' required by GCC 5. + void setUpConsole() noexcept + { console.lock([&] (auto *&c) { this->setUpConsole(c); }); } + void restoreConsole() noexcept + { console.lock([&] (auto *&c) { this->restoreConsole(c); }); } + + bool getEvent(TEvent &ev) noexcept; + void waitForEvent(int ms) noexcept { checkConsole(); waiter.waitForEvent(ms); } + void stopEventWait() noexcept { waiter.stopEventWait(); } + + int getButtonCount() noexcept + { return console.lock([] (auto *c) { return c->input.getButtonCount(); }); } + void cursorOn() noexcept + { console.lock([] (auto *c) { c->input.cursorOn(); }); } + void cursorOff() noexcept + { console.lock([] (auto *c) { c->input.cursorOff(); }); } + + // Adjust the caret size to the range 1 to 100 because that's what the original + // THardwareInfo::getCaretSize() does and what TScreen expects. + int getCaretSize() noexcept { return min(max(displayBuf.caretSize, 1), 100); } + bool isCaretVisible() noexcept { return displayBuf.caretSize > 0; } + void clearScreen() noexcept + { console.lock([&] (auto *c) { displayBuf.clearScreen(c->display); }); } + int getScreenRows() noexcept { return displayBuf.size.y; } + int getScreenCols() noexcept { return displayBuf.size.x; } + void setCaretPosition(int x, int y) noexcept { displayBuf.setCaretPosition(x, y); } + ushort getScreenMode() noexcept + { return console.lock([] (auto *c) { return c->display.getScreenMode(); }); } + void setCaretSize(int size) noexcept { displayBuf.setCaretSize(size); } + void screenWrite(int x, int y, TScreenCell *b, int l) noexcept { displayBuf.screenWrite(x, y, b, l); } + void flushScreen() noexcept + { console.lock([&] (auto *c) { displayBuf.flushScreen(c->display); }); } + TScreenCell *reloadScreenInfo() noexcept + { return console.lock([&] (auto *c) { return displayBuf.reloadScreenInfo(c->display); }); } + + bool setClipboardText(TStringView text) noexcept + { return console.lock([&] (auto *c) { return c->setClipboardText(text); }); } + bool requestClipboardText(void (&accept)(TStringView)) noexcept + { return console.lock([&] (auto *c) { return c->requestClipboardText(accept); }); } +}; + +} // namespace tvision + +#endif // TVISION_PLATFORM_H diff --git a/src/include/tvision/internal/scrlife.h b/src/include/tvision/internal/scrlife.h new file mode 100644 index 00000000..787119fe --- /dev/null +++ b/src/include/tvision/internal/scrlife.h @@ -0,0 +1,31 @@ +#ifndef TVISION_SCRLIFE_H +#define TVISION_SCRLIFE_H + +#include + +#ifdef _TV_UNIX + +namespace tvision +{ + +class StderrRedirector +{ + int ttyFd {-1}; + int bufFd[2] {-1, -1}; + +public: + + StderrRedirector() noexcept; + ~StderrRedirector(); +}; + +class ScreenLifetime +{ + StderrRedirector sr; +}; + +} // namespace tvision + +#endif // _TV_UNIX + +#endif // TVISION_SCRLIFE_H diff --git a/src/include/tvision/internal/sighandl.h b/src/include/tvision/internal/sighandl.h new file mode 100644 index 00000000..2542cfaf --- /dev/null +++ b/src/include/tvision/internal/sighandl.h @@ -0,0 +1,81 @@ +#ifndef TVISION_SIGHANDL_H +#define TVISION_SIGHANDL_H + +#include + +#ifdef _TV_UNIX +#include +#include +#endif + +namespace tvision +{ + +using SignalHandlerCallback = void(bool enter); + +#ifdef _TV_UNIX + +class SignalHandler +{ + static std::atomic callback; + + enum HandledSignals + { + SigInt, SigQuit, SigIll, SigAbrt, SigFpe, SigSegv, SigTerm, SigTstp, + HandledSignalCount + }; + +public: + + static const int handledSignals[HandledSignalCount]; + +private: + + static constexpr struct sigaction makeDefaultAction() noexcept + { + struct sigaction sa = {}; + sa.sa_handler = SIG_DFL; + return sa; + } + + static struct sigaction makeHandlerAction() noexcept + { + struct sigaction sa = {}; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + sa.sa_sigaction = &handleSignal; + return sa; + } + + struct HandlerInfo + { + struct sigaction action {makeDefaultAction()}; + std::atomic running {false}; + }; + + static void handleSignal(int, siginfo_t *, void *); + static HandlerInfo &getHandlerInfo(int) noexcept; + static bool invokeHandlerOrDefault(int, struct sigaction &, siginfo_t *, void *) noexcept; + static bool invokeDefault(int, siginfo_t *) noexcept; + +public: + + // 'aCallback' must be noexcept and signal-safe. + static void enable(SignalHandlerCallback &aCallback) noexcept; + static void disable() noexcept; +}; + +#else + +class SignalHandler +{ +public: + + static void enable(SignalHandlerCallback &aCallback) noexcept {} + static void disable() noexcept {} +}; + +#endif // _TV_UNIX + +} // namespace tvision + +#endif // TVISION_SIGHANDL_H diff --git a/src/include/tvision/internal/sigwinch.h b/src/include/tvision/internal/sigwinch.h new file mode 100644 index 00000000..de58a2a3 --- /dev/null +++ b/src/include/tvision/internal/sigwinch.h @@ -0,0 +1,36 @@ +#ifndef TVISION_SIGWINCH_H +#define TVISION_SIGWINCH_H + +#include + +#ifdef _TV_UNIX +#include +#include + +struct TEvent; + +namespace tvision +{ + +class SigwinchHandler final : public WakeUpEventSource +{ + struct sigaction oldSa; + + static SigwinchHandler *instance; + static void handleSignal(int) noexcept; + static bool getEvent(void *, TEvent &) noexcept; + + SigwinchHandler( SysManualEvent::Handle handle, + const struct sigaction &aOldSa ) noexcept; + +public: + + static SigwinchHandler *create() noexcept; + ~SigwinchHandler(); +}; + +} // namespace tvision + +#endif // _TV_UNIX + +#endif // TVISION_SIGWINCH_H diff --git a/src/include/tvision/internal/stdioctl.h b/src/include/tvision/internal/stdioctl.h new file mode 100644 index 00000000..66b9148a --- /dev/null +++ b/src/include/tvision/internal/stdioctl.h @@ -0,0 +1,57 @@ +#ifndef TVISION_STDIOCTL_H +#define TVISION_STDIOCTL_H + +#include +#include + +#ifdef _WIN32 +#include +#endif + +namespace tvision +{ + +class StdioCtl final +{ +#ifdef _WIN32 + enum { input = 0, startupOutput = 1, activeOutput = 2 }; + struct + { + HANDLE handle {INVALID_HANDLE_VALUE}; + bool owning {false}; + } cn[3]; + bool ownsConsole {false}; +#else + int ttyfd {-1}; + int fds[2] {-1, -1}; + FILE *infile {nullptr}; + FILE *outfile {nullptr}; +#endif // _WIN32 + + +public: + + StdioCtl() noexcept; + ~StdioCtl(); + + void write(const char *data, size_t bytes) const noexcept; + TPoint getSize() const noexcept; + TPoint getFontSize() const noexcept; + +#ifdef _WIN32 + HANDLE in() const noexcept { return cn[input].handle; } + HANDLE out() const noexcept { return cn[activeOutput].handle; } +#else + int in() const noexcept { return fds[0]; } + int out() const noexcept { return fds[1]; } + FILE *fin() const noexcept { return infile; } + FILE *fout() const noexcept { return outfile; } +#ifdef __linux__ + bool isLinuxConsole() const noexcept; +#endif +#endif // _WIN32 +}; + +} //namespace tvision + +#endif // TVISION_STDIOCTL_H diff --git a/src/include/tvision/internal/strings.h b/src/include/tvision/internal/strings.h new file mode 100644 index 00000000..0cb8254e --- /dev/null +++ b/src/include/tvision/internal/strings.h @@ -0,0 +1,49 @@ +#ifndef TVISION_STRINGS_H +#define TVISION_STRINGS_H + +#ifndef _TV_VERSION +#include +#endif + +namespace tvision +{ + +template +inline constexpr Int string_as_int(TStringView s) noexcept +{ + Int res = 0; + for (size_t i = 0; i < min(s.size(), sizeof(res)); ++i) + // CAUTION: Assumes Little Endian. + res |= uint64_t(uint8_t(s[i])) << 8*i; + return res; +} + +char *fast_utoa(uint32_t value, char *buffer) noexcept; + +template +struct constarray; + +struct alignas(4) btoa_lut_elem_t +{ + char chars[3]; + uint8_t digits; +}; + +using btoa_lut_t = constarray; + +inline char *fast_btoa(uint8_t value, char *buffer) noexcept +{ + extern const btoa_lut_t btoa_lut; + const auto &lut = (btoa_lut_elem_t (&) [256]) btoa_lut; + // CAUTION: Assumes Little Endian. + // We can afford to write more bytes into 'buffer' than digits. + uint32_t asInt; + memcpy(&asInt, &lut[value], 4); + memcpy(buffer, &asInt, 4); + return buffer + (asInt >> 24); + static_assert(sizeof(btoa_lut_elem_t) == 4, ""); +} + +} // namespace tvision + +#endif // TVISION_STRINGS_H diff --git a/src/include/tvision/internal/termdisp.h b/src/include/tvision/internal/termdisp.h new file mode 100644 index 00000000..9b80ba19 --- /dev/null +++ b/src/include/tvision/internal/termdisp.h @@ -0,0 +1,66 @@ +#ifndef TVISION_TERMDISP_H +#define TVISION_TERMDISP_H + +#include + +namespace tvision +{ + +// Terminal quirk flags. + +const uint + qfBoldIsBright = 0x0001, + qfBlinkIsBright = 0x0002, + qfNoItalic = 0x0004, + qfNoUnderline = 0x0008; + +enum TermCapColors : uint8_t +{ + NoColor, + Indexed8, + Indexed16, + Indexed256, + Direct, + TermCapColorCount, +}; + +struct TermCap +{ + TermCapColors colors; + uint quirks; +}; + +// TerminalDisplay is a DisplayStrategy with knowledge of terminal capabilities. + +class TerminalDisplay : public DisplayStrategy +{ + TermCap getCapabilities() noexcept; + TPoint lastSize {}; + +protected: + + StdioCtl &io; + TermCap termcap; + + // The subclass must invoke this in the constructor. + void initCapabilities() noexcept + { + termcap = getCapabilities(); + } + +public: + + // The lifetime of 'aIo' exceeds that of 'this'. + TerminalDisplay(StdioCtl &aIo) noexcept : + io(aIo) + { + } + + virtual int getColorCount() noexcept = 0; + ushort getScreenMode() noexcept override; + bool screenChanged() noexcept override; +}; + +} // namespace tvision + +#endif // TVISION_TERMDISP_H diff --git a/src/include/tvision/internal/terminal.h b/src/include/tvision/internal/terminal.h new file mode 100644 index 00000000..9acfa898 --- /dev/null +++ b/src/include/tvision/internal/terminal.h @@ -0,0 +1,218 @@ +#ifndef TVISION_TERMINAL_H +#define TVISION_TERMINAL_H + +#define Uses_TPoint +#define Uses_TEvent +#include + +#include + +namespace tvision +{ + +class StdioCtl; +class EventSource; + +struct Far2lState +{ + bool enabled {false}; +}; + +struct InputState +{ + uchar buttons {0}; +#ifdef _WIN32 + wchar_t surrogate {0}; +#endif + Far2lState far2l; + bool hasFullOsc52 {false}; + bool bracketedPaste {false}; + void (*putPaste)(TStringView) {nullptr}; +}; + +class InputGetter +{ +public: + + virtual int get() noexcept = 0; + virtual void unget(int) noexcept = 0; +}; + +class GetChBuf +{ + enum { maxSize = 31 }; + + InputGetter ∈ + uint size {0}; + int keys[maxSize]; + +public: + + GetChBuf(InputGetter &aIn) noexcept : + in(aIn) + { + } + + int getUnbuffered() noexcept; + int get(bool keepErr) noexcept; + int last(size_t i) noexcept; + void unget() noexcept; + void reject() noexcept; + bool getNum(uint &) noexcept; + bool getInt(int &) noexcept; + bool readStr(TStringView) noexcept; + +}; + +inline int GetChBuf::getUnbuffered() noexcept +{ + return in.get(); +} + +inline int GetChBuf::get(bool keepErr=false) noexcept +{ + if (size < maxSize) + { + int k = in.get(); + if (keepErr || k != -1) + keys[size++] = k; + return k; + } + return -1; +} + +inline int GetChBuf::last(size_t i=0) noexcept +{ + if (i < size) + return keys[size - 1 - i]; + return -1; +} + +inline void GetChBuf::unget() noexcept +{ + int k; + if (size && (k = keys[--size]) != -1) + in.unget(k); +} + +inline void GetChBuf::reject() noexcept +{ + while (size) + unget(); +} + +// getNum, getInt: INVARIANT: the last non-digit read key (or -1) +// can be accessed with 'last()' and can also be ungetted. + +inline bool GetChBuf::getNum(uint &result) noexcept +{ + uint num = 0, digits = 0; + int k; + while ((k = get(true)) != -1 && '0' <= k && k <= '9') + { + num = 10 * num + (k - '0'); + ++digits; + } + if (digits) + return (result = num), true; + return false; +} + +inline bool GetChBuf::getInt(int &result) noexcept +{ + int num = 0, digits = 0, sign = 1; + int k = get(true); + if (k == '-') + { + sign = -1; + k = get(true); + } + while (k != -1 && '0' <= k && k <= '9') + { + num = 10 * num + (k - '0'); + ++digits; + k = get(true); + } + if (digits) + return (result = sign*num), true; + return false; +} + +inline bool GetChBuf::readStr(TStringView str) noexcept +{ + size_t origSize = size; + size_t i = 0; + while (i < str.size() && get() == str[i]) + ++i; + if (i == str.size()) + return true; + while (origSize < size) + unget(); + return false; +} + +enum ParseResult { Rejected = 0, Accepted, Ignored }; + +struct CSIData +{ + // Represents the data stored in a CSI escape sequence: + // \x1B [ val[0] sep[0] val[1] sep[1] ... + + // CSIs can be longer, but this is the largest we need for now. + enum { maxLength = 3 }; + + uint val[maxLength]; + uint sep[maxLength]; + uint length; + + bool readFrom(GetChBuf &buf) noexcept + { + length = 0; + for (uint i = 0; i < maxLength; ++i) + { + if (!buf.getNum(val[i])) + val[i] = 1; + int k = buf.last(); + if (k == -1) return false; + if ((sep[i] = (uint) k) != ';') + return (length = i + 1), true; + } + return false; + } + + uint terminator() const noexcept + { + return length ? sep[length - 1] : 0; + } +}; + +namespace TermIO +{ + void mouseOn(StdioCtl &) noexcept; + void mouseOff(StdioCtl &) noexcept; + void keyModsOn(StdioCtl &) noexcept; + void keyModsOff(StdioCtl &, EventSource &, InputState &) noexcept; + + void normalizeKey(KeyDownEvent &keyDown) noexcept; + + bool setClipboardText(StdioCtl &, TStringView, InputState &) noexcept; + bool requestClipboardText(StdioCtl &, void (&)(TStringView), InputState &) noexcept; + + ParseResult parseEvent(GetChBuf&, TEvent&, InputState&) noexcept; + ParseResult parseEscapeSeq(GetChBuf&, TEvent&, InputState&) noexcept; + ParseResult parseX10Mouse(GetChBuf&, TEvent&, InputState&) noexcept; + ParseResult parseSGRMouse(GetChBuf&, TEvent&, InputState&) noexcept; + ParseResult parseCSIKey(const CSIData &csi, TEvent&, InputState&) noexcept; + ParseResult parseFKeyA(GetChBuf&, TEvent&) noexcept; + ParseResult parseSS3Key(GetChBuf&, TEvent&) noexcept; + ParseResult parseArrowKeyA(GetChBuf&, TEvent&) noexcept; + ParseResult parseFixTermKey(const CSIData &csi, TEvent&) noexcept; + ParseResult parseDCS(GetChBuf&, InputState&) noexcept; + ParseResult parseOSC(GetChBuf&, InputState&) noexcept; + + char *readUntilBelOrSt(GetChBuf &) noexcept; +} + +} // namespace tvision + +#endif // TVISION_TERMINAL_H diff --git a/src/include/tvision/internal/unixcon.h b/src/include/tvision/internal/unixcon.h new file mode 100644 index 00000000..71b68dbf --- /dev/null +++ b/src/include/tvision/internal/unixcon.h @@ -0,0 +1,50 @@ +#ifndef TVISION_UNIXCON_H +#define TVISION_UNIXCON_H + +#include +#ifdef _TV_UNIX + +namespace tvision +{ + +class ScreenLifetime; +class SigwinchHandler; +struct InputState; +class DisplayBuffer; + +class UnixConsoleStrategy : public ConsoleStrategy +{ + StdioCtl &io; + DisplayBuffer &displayBuf; + ScreenLifetime &scrl; + InputState &inputState; + SigwinchHandler *sigwinch; + + UnixConsoleStrategy( DisplayStrategy &, InputStrategy &, StdioCtl &, + DisplayBuffer &, ScreenLifetime &, InputState &, + SigwinchHandler * ) noexcept; + +public: + + // The lifetime of 'io' and 'displayBuf' must exceed that of the returned object. + // Takes ownership over 'scrl', 'inputState', 'display' and 'input'. + static UnixConsoleStrategy &create( StdioCtl &io, + DisplayBuffer &displayBuf, + ScreenLifetime &scrl, + InputState &inputState, + DisplayStrategy &display, + InputStrategy &input ) noexcept; + + ~UnixConsoleStrategy(); + + bool setClipboardText(TStringView) noexcept override; + bool requestClipboardText(void (&)(TStringView)) noexcept override; + + static int charWidth(uint32_t) noexcept; +}; + +} // namespace tvision + +#endif // _TV_UNIX + +#endif // TVISION_UNIXCON_H diff --git a/src/include/tvision/internal/utf8.h b/src/include/tvision/internal/utf8.h new file mode 100644 index 00000000..2ea426fc --- /dev/null +++ b/src/include/tvision/internal/utf8.h @@ -0,0 +1,94 @@ +#ifndef TVISION_UTF8_H +#define TVISION_UTF8_H + +#include + +#include +#include +#include + +namespace tvision +{ + +inline constexpr uint Utf8BytesLeft(char first_byte) noexcept +{ + // https://en.wikipedia.org/wiki/UTF-8 + return (first_byte & 0b11100000) == 0b11000000 ? 1 : \ + (first_byte & 0b11110000) == 0b11100000 ? 2 : \ + (first_byte & 0b11111000) == 0b11110000 ? 3 : 0; +} + +template +inline std::array make_utf8int(const TStringView utf8[N]) noexcept +{ + std::array result {}; + for (size_t i = 0; i < N; ++i) + result[i] = string_as_int(utf8[i]); + return result; +} + +inline constexpr uint32_t utf8To32(TStringView s) noexcept +{ + // Precondition: s is a valid UTF-8 sequence. + switch (s.size()) { + case 1: + return s[0]; + case 2: + return ((s[0] & 0b00011111) << 6) | (s[1] & 0b00111111); + case 3: + return ((s[0] & 0b00001111) << 12) | ((s[1] & 0b00111111) << 6) | (s[2] & 0b00111111); + case 4: + return ((s[0] & 0b00001111) << 18) | ((s[1] & 0b00111111) << 12) | ((s[2] & 0b00111111) << 6) | (s[3] & 0b00111111); + } + return 0; +} + +inline size_t utf32To8(uint32_t u, char utf8[4]) noexcept +{ + union { + uint8_t asChars[4] {0}; + uint32_t asInt; + }; + if (u <= 0x007F) { + memcpy(&utf8[0], &u, 4); + return 1; + } else if (u <= 0x07FF) { + asChars[1] = (u & 0b00111111) | 0b10000000; + asChars[0] = ((u >> 6) & 0b00011111) | 0b11000000; + memcpy(&utf8[0], asChars, 4); + return 2; + } else if (u <= 0xFFFF) { + asChars[2] = (u & 0b00111111) | 0b10000000; + asChars[1] = ((u >> 6) & 0b00111111) | 0b10000000; + asChars[0] = ((u >> 12) & 0b00001111) | 0b11100000; + memcpy(&utf8[0], asChars, 4); + return 3; + } else { + asChars[3] = (u & 0b00111111) | 0b10000000; + asChars[2] = ((u >> 6) & 0b00111111) | 0b10000000; + asChars[1] = ((u >> 12) & 0b00111111) | 0b10000000; + asChars[0] = ((u >> 18) & 0b00000111) | 0b11110000; + memcpy(&utf8[0], asChars, 4); + return 4; + } +} + +inline int utf32To16(uint32_t u32, uint16_t u16[2]) noexcept +{ + if (u32 <= 0xFFFF && (u32 < 0xD800 || 0xDFFF < u32)) + { + u16[0] = uint16_t(u32); + return 1; + } + else if (u32 < 0x10FFFF) // Two surrogates. + { + u16[0] = uint16_t(((u32 - 0x10000) >> 10) + 0xD800); + u16[1] = uint16_t(((u32 - 0x10000) & 0x3FF) + 0xDC00); + return 2; + } + return -1; +} + +} // namespace tvision + +#endif // TVISION_UTF8_H diff --git a/src/include/tvision/internal/win32con.h b/src/include/tvision/internal/win32con.h new file mode 100644 index 00000000..36b3c8b5 --- /dev/null +++ b/src/include/tvision/internal/win32con.h @@ -0,0 +1,107 @@ +#ifndef WIN32CON_H +#define WIN32CON_H + +#include +#include +#include +#include +#include + +namespace tvision +{ + +bool getWin32Key(const KEY_EVENT_RECORD &, TEvent &, InputState &) noexcept; +void getWin32Mouse(const MOUSE_EVENT_RECORD &, TEvent &, InputState &) noexcept; + +#ifdef _WIN32 + +class Win32Input; +class Win32Display; + +class Win32ConsoleStrategy final : public ConsoleStrategy +{ + StdioCtl &io; + UINT cpInput, cpOutput; + + Win32ConsoleStrategy( StdioCtl &aIo, + UINT cpInput, UINT cpOutput, + DisplayStrategy &aDisplay, + InputStrategy &aInput ) noexcept : + ConsoleStrategy(aDisplay, aInput, {&aInput}), + io(aIo), + cpInput(cpInput), + cpOutput(cpOutput) + { + } + + ~Win32ConsoleStrategy(); + + bool isAlive() noexcept override; + bool setClipboardText(TStringView) noexcept override; + bool requestClipboardText(void (&)(TStringView)) noexcept override; + +public: + + static Win32ConsoleStrategy &create() noexcept; + static int charWidth(uint32_t) noexcept; +}; + +class Win32Input final : public InputStrategy +{ + StdioCtl &io; + InputState state; + + bool getEvent(const INPUT_RECORD &, TEvent &ev) noexcept; + bool getMouseEvent(MOUSE_EVENT_RECORD, TEvent &ev) noexcept; + +public: + + // The lifetime of 'aIo' must exceed that of 'this'. + Win32Input(StdioCtl &aIo) noexcept : + InputStrategy(aIo.in()), + io(aIo) + { + } + + bool getEvent(TEvent &ev) noexcept override; + int getButtonCount() noexcept override; + void cursorOn() noexcept override; + void cursorOff() noexcept override; +}; + +class Win32Display : public TerminalDisplay +{ + TPoint size {}; + uchar lastAttr {'\x00'}; + std::vector buf; + CONSOLE_FONT_INFO lastFontInfo {}; + +public: + + // The lifetime of 'aIo' must exceed that of 'this'. + Win32Display(StdioCtl &aIo) noexcept : + TerminalDisplay(aIo) + { + initCapabilities(); + } + + void reloadScreenInfo() noexcept override; + TPoint getScreenSize() noexcept override; + int getCaretSize() noexcept override; + int getColorCount() noexcept override; + void clearScreen() noexcept override; + bool screenChanged() noexcept override; + +protected: + + void lowlevelWriteChars(TStringView chars, TColorAttr attr) noexcept override; + void lowlevelMoveCursor(uint x, uint y) noexcept override; + void lowlevelCursorSize(int size) noexcept override; + void lowlevelFlush() noexcept override; +}; + +#endif // _WIN32 + +} // namespace tvision + +#endif // WIN32CON_H diff --git a/src/include/tvision/internal/winwidth.h b/src/include/tvision/internal/winwidth.h new file mode 100644 index 00000000..5cb4a764 --- /dev/null +++ b/src/include/tvision/internal/winwidth.h @@ -0,0 +1,56 @@ +#ifndef WINWIDTH_H +#define WINWIDTH_H + +#ifdef _WIN32 + +#include +#include +#include +#include + +namespace tvision +{ + +class WinWidth +{ + // Since there is no equivalent to wcwidth and the console API allows + // having buffers out of sight, character widths are measured by printing + // to a console buffer and taking the cursor position. + + // A separate state is stored for every thread so that mbcwidth() is both + // thread-safe and lock-free. + + static std::atomic lastReset; + static thread_local WinWidth localInstance; + + std::unordered_map results; + HANDLE cnHandle {INVALID_HANDLE_VALUE}; + size_t currentReset {lastReset}; + + int calcWidth(uint32_t) noexcept; + void setUp() noexcept; + void tearDown() noexcept; + + ~WinWidth(); + +public: + + static int width(uint32_t) noexcept; + static void reset() noexcept; +}; + +inline int WinWidth::width(uint32_t wc) noexcept +{ + return localInstance.calcWidth(wc); +} + +inline void WinWidth::reset() noexcept +{ + ++lastReset; +} + +} // namespace tvision + +#endif // _WIN32 + +#endif // WINWIDTH_H diff --git a/src/include/tvision/menus.h b/src/include/tvision/menus.h new file mode 100644 index 00000000..7d777220 --- /dev/null +++ b/src/include/tvision/menus.h @@ -0,0 +1,551 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* MENUS.H */ +/* */ +/* defines the classes TMenuItem, TMenu, TMenuView, TSubMenu, */ +/* TMenuBar, TMenuBox, TStatusItem, TStatusDef, and TStatusLine */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class _FAR TSubMenu; +class _FAR TMenuItem; +class _FAR TStatusDef; +class _FAR TStatusItem; + +TSubMenu& operator + ( TSubMenu& s, TMenuItem& i ) noexcept; +TSubMenu& operator + ( TSubMenu& s1, TSubMenu& s2 ) noexcept; +TMenuItem& operator + ( TMenuItem& i1, TMenuItem& i2 ) noexcept; +TStatusDef& operator + ( TStatusDef& s1, TStatusItem& s2 ) noexcept; +TStatusDef& operator + ( TStatusDef& s1, TStatusDef& s2 ) noexcept; + +#if defined( Uses_TMenuItem ) && !defined( __TMenuItem ) +#define __TMenuItem + +class _FAR TMenu; + +class TMenuItem +{ + +public: + + TMenuItem( TStringView aName, + ushort aCommand, + TKey aKey, + ushort aHelpCtx = hcNoContext, + TStringView p = 0, + TMenuItem *aNext = 0 + ) noexcept; + TMenuItem( TStringView aName, + TKey aKey, + TMenu *aSubMenu, + ushort aHelpCtx = hcNoContext, + TMenuItem *aNext = 0 + ) noexcept; + + ~TMenuItem(); + + void append( TMenuItem *aNext ) noexcept; + + TMenuItem *next; + const char *name; + ushort command; + Boolean disabled; + TKey keyCode; + ushort helpCtx; + union + { + const char *param; + TMenu *subMenu; + }; +}; + +inline void TMenuItem::append( TMenuItem *aNext ) noexcept +{ + next = aNext; +} + +inline TMenuItem &newLine() noexcept +{ + return *new TMenuItem( 0, 0, 0, hcNoContext, 0, 0 ); +} + +#endif // Uses_TMenuItem + +#if defined( Uses_TSubMenu ) && !defined( __TSubMenu ) +#define __TSubMenu + +class TSubMenu : public TMenuItem +{ + +public: + + TSubMenu( TStringView nm, TKey key, ushort helpCtx = hcNoContext ) noexcept; + +}; + +#endif // Uses_TSubMenu + +#if defined( Uses_TMenu ) && !defined( __TMenu ) +#define __TMenu + +class TMenu +{ + +public: + + TMenu() noexcept : items(0), deflt(0) {}; + TMenu( TMenuItem& itemList ) noexcept + { items = &itemList; deflt = &itemList; } + TMenu( TMenuItem& itemList, TMenuItem& TheDefault ) noexcept + { items = &itemList; deflt = &TheDefault; } + ~TMenu(); + + TMenuItem *items; + TMenuItem *deflt; + +}; + +#endif // Uses_TMenu + +/* ---------------------------------------------------------------------- */ +/* class TMenuView */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Disabled text */ +/* 3 = Shortcut text */ +/* 4 = Normal selection */ +/* 5 = Disabled selection */ +/* 6 = Shortcut selection */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TMenuView ) && !defined( __TMenuView ) +#define __TMenuView + +class _FAR TRect; +class _FAR TMenu; +struct _FAR TEvent; + +class TMenuView : public TView +{ + +public: + + TMenuView( const TRect& bounds, TMenu *aMenu, TMenuView *aParent = 0 ) noexcept; + TMenuView( const TRect& bounds ) noexcept; + + virtual ushort execute(); + TMenuItem *findItem( char ch ); + virtual TRect getItemRect( TMenuItem *item ); + virtual ushort getHelpCtx(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + TMenuItem *hotKey( TKey key ); + TMenuView *newSubView( const TRect& bounds, + TMenu *aMenu, + TMenuView *aParentMenu + ); + +protected: + + TMenuView *parentMenu; + TMenu *menu; + TMenuItem *current; + + Boolean putClickEventOnExit; + +private: + + void nextItem(); + void prevItem(); + void trackKey( Boolean findNext ); + Boolean mouseInOwner( TEvent& e ); + Boolean mouseInMenus( TEvent& e ); + void trackMouse( TEvent& e , Boolean& mouseActive); + TMenuView *topMenu(); + Boolean updateMenu( TMenu *menu ); + void do_a_select( TEvent& ); + TMenuItem *findHotKey( TMenuItem *p, TKey key ); + +private: + + virtual const char *streamableName() const + { return name; } + static void writeMenu( opstream&, TMenu * ); + static TMenu *readMenu( ipstream& ); + +protected: + + TMenuView( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TMenuView& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMenuView*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMenuView& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMenuView* cl ) + { return os << (TStreamable *)cl; } + +inline TMenuView::TMenuView( const TRect& bounds, + TMenu *aMenu, + TMenuView *aParent + ) noexcept : + TView(bounds), parentMenu( aParent ), menu( aMenu ), current( 0 ), + putClickEventOnExit( True ) +{ + eventMask |= evBroadcast; +} + +inline TMenuView::TMenuView( const TRect& bounds ) noexcept : + TView(bounds), parentMenu(0), menu(0), current(0), + putClickEventOnExit( True ) +{ + eventMask |= evBroadcast; +} + +#endif // Uses_TMenuView + +/* ---------------------------------------------------------------------- */ +/* class TMenuBar */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Disabled text */ +/* 3 = Shortcut text */ +/* 4 = Normal selection */ +/* 5 = Disabled selection */ +/* 6 = Shortcut selection */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TMenuBar ) && !defined( __TMenuBar ) +#define __TMenuBar + +class _FAR TRect; +class _FAR TMenu; + +class TMenuBar : public TMenuView +{ + +public: + + TMenuBar( const TRect& bounds, TMenu *aMenu ) noexcept; + TMenuBar( const TRect& bounds, TSubMenu &aMenu ) noexcept; + ~TMenuBar(); + + virtual void draw(); + virtual TRect getItemRect( TMenuItem *item ); + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TMenuBar( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TMenuBar& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMenuBar*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMenuBar& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMenuBar* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TMenuBar + +/* ---------------------------------------------------------------------- */ +/* class TMenuBox */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Disabled text */ +/* 3 = Shortcut text */ +/* 4 = Normal selection */ +/* 5 = Disabled selection */ +/* 6 = Shortcut selection */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TMenuBox ) && !defined( __TMenuBox ) +#define __TMenuBox + +class _FAR TRect; +class _FAR TMenu; +class _FAR TMenuView; +class _FAR TDrawBuffer; + +class TMenuBox : public TMenuView +{ + +public: + + TMenuBox( const TRect& bounds, TMenu *aMenu, TMenuView *aParentMenu) noexcept; + + virtual void draw(); + virtual TRect getItemRect( TMenuItem *item ); + +private: + + void frameLine( TDrawBuffer&, short n ); + void drawLine( TDrawBuffer& ); + + static const char * _NEAR frameChars; + virtual const char *streamableName() const + { return name; } + +protected: + + TMenuBox( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + + +inline ipstream& operator >> ( ipstream& is, TMenuBox& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TMenuBox*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TMenuBox& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TMenuBox* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TMenuBox + + +#if defined( Uses_TMenuPopup ) && !defined( __TMenuPopup ) +#define __TMenuPopup + +/* ---------------------------------------------------------------------- */ +/* class TMenuPopup */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Disabled text */ +/* 3 = Shortcut text */ +/* 4 = Normal selection */ +/* 5 = Disabled selection */ +/* 6 = Shortcut selection */ +/* ---------------------------------------------------------------------- */ + +class TMenuPopup : public TMenuBox +{ + +public: + + TMenuPopup(const TRect& bounds, TMenu *aMenu, TMenuView *aParent = 0) noexcept; + virtual ushort execute(); + virtual void handleEvent(TEvent&); + +protected: + + TMenuPopup( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + + +#endif // Uses_TMenuPopup + + + + +#if defined( Uses_TStatusItem ) && !defined( __TStatusItem ) +#define __TStatusItem + +class TStatusItem +{ + +public: + + TStatusItem( TStringView aText, + TKey aKey, + ushort cmd, + TStatusItem *aNext = 0 + ) noexcept; + ~TStatusItem(); + + TStatusItem *next; + char *text; + TKey keyCode; + ushort command; + +}; + +inline TStatusItem::TStatusItem( TStringView aText, + TKey aKey, + ushort cmd, + TStatusItem *aNext + ) noexcept : + next( aNext ), text( newStr(aText) ), keyCode( aKey ), command( cmd ) +{ +} + +inline TStatusItem::~TStatusItem() +{ + delete[] text; +} + +#endif // Uses_TStatusItem + +#if defined( Uses_TStatusDef ) && !defined( __TStatusDef ) +#define __TStatusDef + +class TStatusDef +{ + +public: + + TStatusDef( ushort aMin, + ushort aMax, + TStatusItem *someItems = 0, + TStatusDef *aNext = 0 + ) noexcept; + + TStatusDef *next; + ushort min; + ushort max; + TStatusItem *items; +}; + +inline TStatusDef::TStatusDef( ushort aMin, + ushort aMax, + TStatusItem *someItems, + TStatusDef *aNext + ) noexcept : + next( aNext ), min( aMin ), max( aMax ), items( someItems ) +{ +} + +#endif // Uses_TStatusDef + +/* ---------------------------------------------------------------------- */ +/* class TStatusLine */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Disabled text */ +/* 3 = Shortcut text */ +/* 4 = Normal selection */ +/* 5 = Disabled selection */ +/* 6 = Shortcut selection */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TStatusLine ) && !defined( __TStatusLine ) +#define __TStatusLine + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TPoint; + +class TStatusLine : public TView +{ + +public: + + TStatusLine( const TRect& bounds, TStatusDef& aDefs ) noexcept; + ~TStatusLine(); + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual const char* hint( ushort aHelpCtx ); + void update(); + +protected: + + TStatusItem *items; + TStatusDef *defs; + +private: + + void drawSelect( TStatusItem *selected ); + void findItems() noexcept; + TStatusItem *itemMouseIsIn( TPoint ); + void disposeItems( TStatusItem *item ); + + static const char * _NEAR hintSeparator; + + virtual const char *streamableName() const + { return name; } + + static void writeItems( opstream&, TStatusItem * ); + static void writeDefs( opstream&, TStatusDef * ); + static TStatusItem *readItems( ipstream& ); + static TStatusDef *readDefs( ipstream& ); + + +protected: + + TStatusLine( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TStatusLine& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TStatusLine*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TStatusLine& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TStatusLine* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TStatusLine + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/msgbox.h b/src/include/tvision/msgbox.h new file mode 100644 index 00000000..45329ac3 --- /dev/null +++ b/src/include/tvision/msgbox.h @@ -0,0 +1,87 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* MSGBOX.H */ +/* */ +/* defines the functions messageBox(), messageBoxRect(), */ +/* inputBox(), and inputBoxRect() */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( Uses_MsgBox ) && !defined( __MsgBox ) +#define __MsgBox + +#if !defined( __STDARG_H ) +#include +#endif // __STDARG_H + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class _FAR TRect; + +ushort messageBox( TStringView msg, ushort aOptions ) noexcept; +ushort messageBox( unsigned aOptions, const char *msg, ... ) noexcept; + +ushort messageBoxRect( const TRect &r, TStringView msg, ushort aOptions ) noexcept; +ushort messageBoxRect( const TRect &r, ushort aOptions, const char *msg, ... ) noexcept; + +ushort inputBox( TStringView Title, TStringView aLabel, char *s, uchar limit ) noexcept; + +ushort inputBoxRect( const TRect &bounds, TStringView title, + TStringView aLabel, char *s, uchar limit ) noexcept; + +const int + +// Message box classes + + mfWarning = 0x0000, // Display a Warning box + mfError = 0x0001, // Dispaly a Error box + mfInformation = 0x0002, // Display an Information Box + mfConfirmation = 0x0003, // Display a Confirmation Box + +// Message box button flags + + mfYesButton = 0x0100, // Put a Yes button into the dialog + mfNoButton = 0x0200, // Put a No button into the dialog + mfOKButton = 0x0400, // Put an OK button into the dialog + mfCancelButton = 0x0800, // Put a Cancel button into the dialog + + mfYesNoCancel = mfYesButton | mfNoButton | mfCancelButton, + // Standard Yes, No, Cancel dialog + mfOKCancel = mfOKButton | mfCancelButton; + // Standard OK, Cancel dialog + +class MsgBoxText +{ + +public: + + static const char * _NEAR yesText; + static const char * _NEAR noText; + static const char * _NEAR okText; + static const char * _NEAR cancelText; + static const char * _NEAR warningText; + static const char * _NEAR errorText; + static const char * _NEAR informationText; + static const char * _NEAR confirmText; +}; + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif + +#endif // Uses_MsgBox diff --git a/src/include/tvision/objects.h b/src/include/tvision/objects.h new file mode 100644 index 00000000..6339cf8f --- /dev/null +++ b/src/include/tvision/objects.h @@ -0,0 +1,296 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* OBJECTS.H */ +/* */ +/* defines the classes TPoint, TRect, TCollection, and TSortedCollection */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TPoint ) && !defined( __TPoint ) +#define __TPoint + +class TPoint +{ + +public: + + TPoint& operator+=( const TPoint& adder ) noexcept; + TPoint& operator-=( const TPoint& subber ) noexcept; + friend TPoint operator - ( const TPoint& one, const TPoint& two) noexcept; + friend TPoint operator + ( const TPoint& one, const TPoint& two) noexcept; + friend int operator == ( const TPoint& one, const TPoint& two) noexcept; + friend int operator != ( const TPoint& one, const TPoint& two) noexcept; + + int x,y; + +}; + +inline TPoint& TPoint::operator += ( const TPoint& adder ) noexcept +{ + x += adder.x; + y += adder.y; + return *this; +} + +inline TPoint& TPoint::operator -= ( const TPoint& subber ) noexcept +{ + x -= subber.x; + y -= subber.y; + return *this; +} + +inline TPoint operator - ( const TPoint& one, const TPoint& two ) noexcept +{ + TPoint result; + result.x = one.x - two.x; + result.y = one.y - two.y; + return result; +} + +inline TPoint operator + ( const TPoint& one, const TPoint& two ) noexcept +{ + TPoint result; + result.x = one.x + two.x; + result.y = one.y + two.y; + return result; +} + +inline int operator == ( const TPoint& one, const TPoint& two ) noexcept +{ + return one.x == two.x && one.y == two.y; +} + +inline int operator!= ( const TPoint& one, const TPoint& two ) noexcept +{ + return one.x != two.x || one.y != two.y; +} + +inline ipstream& operator >> ( ipstream& is, TPoint& p ) + { return is >> p.x >> p.y; } +inline ipstream& operator >> ( ipstream& is, TPoint*& p ) + { return is >> p->x >> p->y; } + +inline opstream& operator << ( opstream& os, TPoint& p ) + { return os << p.x << p.y; } +inline opstream& operator << ( opstream& os, TPoint* p ) + { return os << p->x << p->y; } + +#endif // Uses_TPoint + +#if defined( Uses_TRect ) && !defined( __TRect ) +#define __TRect + +class TRect +{ + +public: + + TRect( int ax, int ay, int bx, int by ) noexcept; + TRect( TPoint p1, TPoint p2 ) noexcept; + TRect() noexcept {} + + TRect& move( int aDX, int aDY ) noexcept; + TRect& grow( int aDX, int aDY ) noexcept; + TRect& intersect( const TRect& r ) noexcept; + TRect& Union( const TRect& r ) noexcept; + Boolean contains( const TPoint& p ) const noexcept; + Boolean operator == ( const TRect& r ) const noexcept; + Boolean operator != ( const TRect& r ) const noexcept; + Boolean isEmpty() noexcept; + + TPoint a, b; + +}; + +inline TRect::TRect( int ax, int ay, int bx, int by) noexcept +{ + a.x = ax; + a.y = ay; + b.x = bx; + b.y = by; +} + +inline TRect::TRect( TPoint p1, TPoint p2 ) noexcept +{ + a = p1; + b = p2; +} + +inline TRect& TRect::move( int aDX, int aDY ) noexcept +{ + a.x += aDX; + a.y += aDY; + b.x += aDX; + b.y += aDY; + return *this; +} + +inline TRect& TRect::grow( int aDX, int aDY ) noexcept +{ + a.x -= aDX; + a.y -= aDY; + b.x += aDX; + b.y += aDY; + return *this; +} + +inline TRect& TRect::intersect( const TRect& r ) noexcept +{ + a.x = max( a.x, r.a.x ); + a.y = max( a.y, r.a.y ); + b.x = min( b.x, r.b.x ); + b.y = min( b.y, r.b.y ); + return *this; +} + +inline TRect& TRect::Union( const TRect& r ) noexcept +{ + a.x = min( a.x, r.a.x ); + a.y = min( a.y, r.a.y ); + b.x = max( b.x, r.b.x ); + b.y = max( b.y, r.b.y ); + return *this; +} + +inline Boolean TRect::contains( const TPoint& p ) const noexcept +{ + return Boolean( + p.x >= a.x && p.x < b.x && p.y >= a.y && p.y < b.y + ); +} + +inline Boolean TRect::operator == ( const TRect& r) const noexcept +{ + return Boolean( a == r.a && b == r.b ); +} + +inline Boolean TRect::operator != ( const TRect& r ) const noexcept +{ + return Boolean( !(*this == r) ); +} + +inline Boolean TRect::isEmpty() noexcept +{ + return Boolean( a.x >= b.x || a.y >= b.y ); +} + +inline ipstream& operator >> ( ipstream& is, TRect& r ) + { return is >> r.a >> r.b; } +inline ipstream& operator >> ( ipstream& is, TRect*& r ) + { return is >> r->a >> r->b; } + +inline opstream& operator << ( opstream& os, TRect& r ) + { return os << r.a << r.b; } +inline opstream& operator << ( opstream& os, TRect* r ) + { return os << r->a << r->b; } + +#endif // Uses_TRect + +#if defined( Uses_TCollection ) && !defined( __TCollection ) +#define __TCollection + +class TCollection : public virtual TNSCollection, public TStreamable +{ + +public: + + TCollection( ccIndex aLimit, ccIndex aDelta ) noexcept + { delta = aDelta; setLimit( aLimit ); } + +private: + + virtual const char *streamableName() const + { return name; } + + virtual void *readItem( ipstream& ) = 0; + virtual void writeItem( void *, opstream& ) = 0; + + +protected: + + TCollection( StreamableInit ) noexcept; + virtual void *read( ipstream& ); + virtual void write( opstream& ); + +public: + + static const char * const _NEAR name; + +}; + +inline ipstream& operator >> ( ipstream& is, TCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TCollection* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TCollection + +#if defined( Uses_TSortedCollection ) && !defined( __TSortedCollection ) +#define __TSortedCollection + +class TSortedCollection : public TNSSortedCollection, public TCollection +{ + +public: + + TSortedCollection( ccIndex aLimit, ccIndex aDelta) noexcept : + TCollection( aLimit, aDelta ) {} + +private: + + virtual int compare( void *key1, void *key2 ) = 0; + + virtual const char *streamableName() const + { return name; } + virtual void *readItem( ipstream& ) = 0; + virtual void writeItem( void *, opstream& ) = 0; + +protected: + + TSortedCollection( StreamableInit ) noexcept; + virtual void *read( ipstream& ); + virtual void write( opstream& ); + +public: + + static const char * const _NEAR name; + +}; + +inline ipstream& operator >> ( ipstream& is, TSortedCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TSortedCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TSortedCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TSortedCollection* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TSortedCollection + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/outline.h b/src/include/tvision/outline.h new file mode 100644 index 00000000..91ed3afb --- /dev/null +++ b/src/include/tvision/outline.h @@ -0,0 +1,217 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* OUTLINE.H */ +/* */ +/* defines the classes TOutline, and TOutlineViewer. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TOutlineViewer ) && !defined( __TOutlineViewer ) +#define __TOutlineViewer + +const int + ovExpanded = 0x01, + ovChildren = 0x02, + ovLast = 0x04; + +const int + cmOutlineItemSelected = 301; + +class TNode +{ +public: + TNode(TStringView aText) noexcept; + TNode(TStringView aText, TNode* aChildren, TNode* aNext, Boolean initialState = True) noexcept; + virtual ~TNode(); + + TNode* next; + const char* text; + TNode* childList; + Boolean expanded; +}; + +inline TNode::TNode(TStringView aText) noexcept : + next(0), text(newStr(aText)), childList(0), expanded(True) +{ +} + +inline TNode::TNode( TStringView aText, TNode* aChildren, + TNode* aNext, Boolean initialState ) noexcept : + next(aNext), text(newStr(aText)), + childList(aChildren), expanded(initialState) +{ +} + +inline TNode::~TNode() { + delete [] (char *) text; +} + +/* ------------------------------------------------------------------------*/ +/* class TOutlineViewer */ +/* */ +/* Palette layout */ +/* 1 = Normal color */ +/* 2 = Focus color */ +/* 3 = Select color */ +/* 4 = Not expanded color */ +/* ------------------------------------------------------------------------*/ + +class _FAR TRect; +class _FAR TScrollBar; +class _FAR TOutlineViewer; +struct _FAR TEvent; + +// Callback types for TOutlineViewer's traverse functions. + +typedef Boolean (*TOutlineVisitor)( TOutlineViewer*, TNode*, + int, int, long, ushort, void* ); +typedef Boolean (*TOutlineVisitorNoArg)( TOutlineViewer*, TNode*, + int, int, long, ushort ); + +class TOutlineViewer : public TScroller +{ +public: + TOutlineViewer(const TRect& bounds, TScrollBar* aHScrollBar, + TScrollBar* aVScrollBar) noexcept; + TOutlineViewer(StreamableInit s) noexcept; + virtual void adjust(TNode* node, Boolean expand)=0; + virtual void draw(); + virtual void focused(int i); + virtual TNode* getNext(TNode* node)=0; + virtual TNode* getChild(TNode* node, int i)=0; + virtual char* getGraph(int level, long lines, ushort flags); + virtual int getNumChildren(TNode* node)=0; + virtual TNode* getNode(int i); + virtual TPalette& getPalette() const; + virtual TNode* getRoot()=0; + virtual const char* getText(TNode* node)=0; + virtual void handleEvent(TEvent& event); + virtual Boolean hasChildren(TNode* node)=0; + virtual Boolean isExpanded(TNode* node)=0; + virtual Boolean isSelected(int i); + virtual void selected(int i); + virtual void setState(ushort aState, Boolean enable); + + void update() noexcept; + void expandAll(TNode* node); + + TNode* firstThat(TOutlineVisitor test, void* arg) noexcept; + TNode* firstThat(TOutlineVisitorNoArg test) noexcept; + + TNode* forEach(TOutlineVisitor action, void* arg) noexcept; + TNode* forEach(TOutlineVisitorNoArg action) noexcept; + + char* createGraph(int level, long lines, ushort flags, int levWidth, + int endWidth, const char* chars) noexcept; + + int foc; + +protected: + static void disposeNode(TNode* node) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + static TStreamable *build(); + static const char * const _NEAR name; + +private: + void adjustFocus(int newFocus) noexcept; + TNode* iterate(TOutlineVisitor action, void *arg, Boolean checkResult) noexcept; +}; + +inline TOutlineViewer::TOutlineViewer( StreamableInit s) noexcept : + TScroller(s) +{ +} + +#endif // Uses_TOutlineViewer + +#if defined( Uses_TOutline ) && !defined( __TOutline ) +#define __TOutline + +/* ------------------------------------------------------------------------*/ +/* class TOutline */ +/* */ +/* Palette layout */ +/* 1 = Normal color */ +/* 2 = Focus color */ +/* 3 = Select color */ +/* 4 = Not expanded color */ +/* ------------------------------------------------------------------------*/ + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; + +class TOutline : public TOutlineViewer +{ +public: + TOutline(const TRect& bounds, TScrollBar* aHScrollBar, TScrollBar* aVScrollBar, + TNode* aRoot) noexcept; + ~TOutline(); + + virtual void adjust(TNode* node, Boolean expand); + virtual TNode* getRoot(); + virtual int getNumChildren(TNode* node); + virtual TNode* getNext(TNode *node); + virtual TNode* getChild(TNode* node, int i); + virtual const char* getText(TNode* node); + virtual Boolean isExpanded(TNode* node); + virtual Boolean hasChildren(TNode* node); + + TNode* root; + +protected: + virtual void write( opstream& ); + virtual void* read( ipstream& ); + virtual void writeNode( TNode*, opstream& ); + virtual TNode* readNode( ipstream& ); + TOutline( StreamableInit ) noexcept; + +public: + static TStreamable* build(); + static const char* const _NEAR name; + +private: + virtual const char *streamableName() const + { return name; } + +}; + +inline TOutline::TOutline( StreamableInit s ) noexcept : TOutlineViewer( s ) +{ +} + +inline ipstream& operator >> ( ipstream& is, TOutline& o ) + { return is >> (TStreamable&)o; } +inline ipstream& operator >> ( ipstream& is, TOutline*& o ) + { return is >> (void *&)o; } + +inline opstream& operator << ( opstream& os, TOutline& o ) + { return os << (TStreamable&)o; } +inline opstream& operator << ( opstream& os, TOutline* o ) + { return os << (TStreamable*)o; } + +#endif // Uses_TOutline + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/resource.h b/src/include/tvision/resource.h new file mode 100644 index 00000000..1192cac6 --- /dev/null +++ b/src/include/tvision/resource.h @@ -0,0 +1,278 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* RESOURCE.H */ +/* */ +/* defines the classes TStringCollection, TResourceCollection, */ +/* TResourceFile, TStrListMaker, and TStringList */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TStringCollection ) && !defined( __TStringCollection ) +#define __TStringCollection + +class TStringCollection : public TSortedCollection +{ + +public: + + TStringCollection( short aLimit, short aDelta ) noexcept; + +private: + + virtual int compare( void *key1, void *key2 ); + virtual void freeItem( void *item ); + + virtual const char *streamableName() const + { return name; } + virtual void *readItem( ipstream& ); + virtual void writeItem( void *, opstream& ); + +protected: + + TStringCollection( StreamableInit ) noexcept : TSortedCollection ( streamableInit ) {}; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TStringCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TStringCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TStringCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TStringCollection* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TStringCollection + +#if defined( Uses_TResourceItem ) && !defined( __TResourceItem ) +#define __TResourceItem + +struct TResourceItem +{ + + int32_t pos; + int32_t size; + char *key; +}; + +#endif // Uses_TResourceItem + +#if defined( Uses_TResourceCollection ) && !defined( __TResourceCollection ) +#define __TResourceCollection + +class TResourceCollection: public TStringCollection +{ + +public: + + TResourceCollection( StreamableInit) noexcept : TStringCollection( streamableInit ) {}; + TResourceCollection( short aLimit, short aDelta ) noexcept; + + virtual void *keyOf( void *item ); + +private: + + virtual void freeItem( void *item ); + + virtual const char *streamableName() const + { return name; } + virtual void *readItem( ipstream& ); + virtual void writeItem( void *, opstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TResourceCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TResourceCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TResourceCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TResourceCollection* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TResourceCollection + +#if defined( Uses_TResourceFile ) && !defined( __TResourceFile ) +#define __TResourceFile + +class _FAR TResourceCollection; +class _FAR fpstream; + +class TResourceFile: public TObject +{ + +public: + + TResourceFile( fpstream *aStream ); + ~TResourceFile(); + short count(); + void remove( const char *key ); + void flush(); + void *get( const char *key ); + const char *keyAt( short i ); + void put( TStreamable *item, const char *key ); + fpstream *switchTo( fpstream *aStream, Boolean pack ); + +protected: + + fpstream *stream; + Boolean modified; + int32_t basePos; + int32_t indexPos; + TResourceCollection *index; +}; + +#endif // Uses_TResourceFile + +#if defined( Uses_TStrIndexRec ) && !defined( __TStrIndexRec ) +#define __TStrIndexRec + +class TStrIndexRec +{ + +public: + + TStrIndexRec() noexcept; + + ushort key; + ushort count; + ushort offset; + +}; + +#endif // Uses_TStrIndexRec + +#if defined( Uses_TStringList ) && !defined( __TStringList ) +#define __TStringList + +class _FAR TStrIndexRec; + +class TStringList : public TObject, public TStreamable +{ + +public: + + ~TStringList(); + + void get( char *dest, ushort key ); + +private: + + ipstream *ip; + int32_t basePos; + short indexSize; + TStrIndexRec *index; + + virtual const char *streamableName() const + { return name; } + +protected: + + TStringList( StreamableInit ) noexcept; + virtual void write( opstream& ) {} + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TStringList& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TStringList*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TStringList& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TStringList* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TStringList + + +#if defined( Uses_TStrListMaker ) && !defined( __TStrListMaker ) +#define __TStrListMaker + +class TStrListMaker : public TObject, public TStreamable +{ + +public: + + TStrListMaker( ushort aStrSize, ushort aIndexSize ) noexcept; + ~TStrListMaker(); + + void put( ushort key, char *str ); + +private: + + ushort strPos; + ushort strSize; + char *strings; + ushort indexPos; + ushort indexSize; + TStrIndexRec *index; + TStrIndexRec cur; + void closeCurrent(); + + virtual const char *streamableName() const + { return TStringList::name; } + +protected: + + TStrListMaker( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ) { return 0; } + +public: + + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TStrListMaker& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TStrListMaker*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TStrListMaker& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TStrListMaker* cl ) + { return os << (TStreamable *)cl; } + + +#endif // Uses_TStrListMaker + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/scrncell.h b/src/include/tvision/scrncell.h new file mode 100644 index 00000000..43b7976e --- /dev/null +++ b/src/include/tvision/scrncell.h @@ -0,0 +1,281 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* SCRNCELL.H */ +/* */ +/* Defines the structs TCellChar and TScreenCell. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#ifndef TVISION_SCRNCELL_H +#define TVISION_SCRNCELL_H + +#ifdef __BORLANDC__ + +inline const TColorAttr &getAttr(const TScreenCell &cell) +{ + return ((uchar *) &cell)[1]; +} + +inline void setAttr(TScreenCell &cell, TColorAttr attr) +{ + ((uchar *) &cell)[1] = attr; +} + +inline const TCellChar &getChar(const TScreenCell &cell) +{ + return ((uchar *) &cell)[0]; +} + +inline void setChar(TScreenCell &cell, TCellChar ch) +{ + ((uchar *) &cell)[0] = ch; +} + +inline void setCell(TScreenCell &cell, TCellChar ch, TColorAttr attr) +{ + cell = ushort((attr << 8) | ch); +} + +#else + +//// TCellChar +// +// Represents text in a screen cell. You should usually not need to interact +// with this manually. In order to write text into a screen cell, just use +// the functions in the TText namespace. +// +// INVARIANT: +// * '_text' contains one of the following: +// 1. A single byte of ASCII or 'extended ASCII' text (1 column wide). +// 2. Up to 15 bytes of UTF-8 text (1 or 2 columns wide in total, +// meaning that it must not contain just zero-width characters). +// 3. A special value that marks it as wide char trail. + +struct TCellChar +{ + enum : uint8_t { fWide = 0x1, fTrail = 0x2 }; + + char _text[15]; + uint8_t _flags; + + TCellChar() = default; + inline void moveChar(char ch); + inline void moveInt(uint32_t mbc, bool wide=false); + inline void moveStr(TStringView mbc, bool wide=false); + inline void moveWideCharTrail(); + + constexpr inline bool isWide() const; + constexpr inline bool isWideCharTrail() const; + constexpr inline void appendZeroWidth(TStringView mbc); + constexpr inline TStringView getText() const; + constexpr inline size_t size() const; + + constexpr inline char& operator[](size_t i); + constexpr inline const char& operator[](size_t i) const; +}; + +inline void TCellChar::moveChar(char ch) +{ + moveInt((uchar) ch); +} + +inline void TCellChar::moveInt(uint32_t mbc, bool wide) +{ + memset(this, 0, sizeof(*this)); + // CAUTION: Assumes Little Endian. + memcpy(_text, &mbc, sizeof(mbc)); + _flags = -int(wide) & fWide; +} + +inline void TCellChar::moveStr(TStringView mbc, bool wide) +{ + static_assert(sizeof(_text) >= 4, ""); + if (mbc.size() <= 4) + { + memset(this, 0, sizeof(*this)); + switch (mbc.size()) + { + case 4: _text[3] = mbc[3]; + case 3: _text[2] = mbc[2]; + case 2: _text[1] = mbc[1]; + case 1: _text[0] = mbc[0]; + } + _flags |= -int(wide) & fWide; + } +} + +inline void TCellChar::moveWideCharTrail() +{ + memset(this, 0, sizeof(*this)); + _flags = fTrail; +} + +constexpr inline bool TCellChar::isWide() const +{ + return _flags & fWide; +} + +constexpr inline bool TCellChar::isWideCharTrail() const +{ + return _flags & fTrail; +} + +constexpr inline void TCellChar::appendZeroWidth(TStringView mbc) +// Pre: !isWideCharTrail(); +{ + size_t sz = size(); + if (mbc.size() <= sizeof(_text) - sz) + { + if (!mbc[0]) + _text[0] = ' '; + switch (mbc.size()) + { + case 4: _text[sz + 3] = mbc[3]; + case 3: _text[sz + 2] = mbc[2]; + case 2: _text[sz + 1] = mbc[1]; + case 1: _text[sz] = mbc[0]; + } + } +} + +constexpr inline TStringView TCellChar::getText() const +{ + return {_text, size()}; +} + +constexpr inline size_t TCellChar::size() const +{ + size_t i = 0; + while (++i < sizeof(_text) && _text[i]); + return i; +} + +constexpr inline char& TCellChar::operator[](size_t i) +{ + return _text[i]; +} + +constexpr inline const char& TCellChar::operator[](size_t i) const +{ + return _text[i]; +} + +//// TScreenCell +// +// Stores the text and color attributes in a screen cell. +// Please use the functions in the TText namespace in order to fill screen cells +// with text. +// +// Considerations: +// * '_wide' indicates the width of the text in '_ch' minus one. In practice, +// the only possible character widths are 0, 1 and 2, and the text in a +// TCellChar is at least one column wide. So 'wide' will be either 0 or 1. +// * In order for a double-width character to be displayed entirely, its cell +// must be followed by another containing a wide char trail. If it is not, +// or if a wide char trail is not preceded by a double-width character, +// we'll understand that a double-width character is being overlapped partially. + +struct TScreenCell +{ + TColorAttr attr; + TCellChar _ch; + + TScreenCell() = default; + inline TScreenCell(ushort bios); + TV_TRIVIALLY_ASSIGNABLE(TScreenCell) + + constexpr inline bool isWide() const; + + inline bool operator==(const TScreenCell &other) const; + inline bool operator!=(const TScreenCell &other) const; +}; + +inline const TColorAttr &getAttr(const TScreenCell &cell); +inline void setAttr(TScreenCell &cell, const TColorAttr &attr); +inline void setChar(TScreenCell &cell, char ch); +inline void setCell(TScreenCell &cell, char ch, const TColorAttr &attr); + +inline TScreenCell::TScreenCell(ushort bios) +{ + memset(this, 0, sizeof(*this)); + _ch.moveChar(char(bios)); + attr = uchar(bios >> 8); +} + +constexpr inline bool TScreenCell::isWide() const +{ + return _ch.isWide(); +} + +inline bool TScreenCell::operator==(const TScreenCell &other) const +{ + return memcmp(this, &other, sizeof(*this)) == 0; +} + +inline bool TScreenCell::operator!=(const TScreenCell &other) const +{ + return !(*this == other); +} + +inline const TColorAttr &getAttr(const TScreenCell &cell) +{ + return cell.attr; +} + +inline void setAttr(TScreenCell &cell, const TColorAttr &attr) +{ + cell.attr = attr; +} + +inline void setChar(TScreenCell &cell, char ch) +{ + cell._ch.moveChar(ch); +} + +inline void setCell(TScreenCell &cell, char ch, const TColorAttr &attr) +{ + memset(&cell, 0, sizeof(cell)); + ::setChar(cell, ch); + ::setAttr(cell, attr); +} + +#ifdef SCRNCELL_DEBUG +#include + +namespace scrncell +{ + template + inline void check_trivial() + { + static_assert(std::is_trivial(), ""); + } + + template + static void check_convertible() + { + scrncell::check_trivial(); + static_assert(sizeof(C) == sizeof(T), ""); + static_assert(alignof(C) == alignof(T), ""); + } + + inline void check_assumptions() + { + check_trivial(); + check_trivial(); + check_trivial(); + check_trivial(); + check_trivial(); + check_convertible(); + check_convertible(); + check_convertible(); + static_assert(sizeof(TScreenCell) == 24, ""); + static_assert(sizeof(TColorDesired) == 4, ""); + static_assert(sizeof(TColorAttr) == 8, ""); + } +} + +#endif // SCRNCELL_DEBUG + +#endif // __BORLANDC__ + +#endif // TVISION_SCRNCELL_H diff --git a/src/include/tvision/stddlg.h b/src/include/tvision/stddlg.h new file mode 100644 index 00000000..319d1138 --- /dev/null +++ b/src/include/tvision/stddlg.h @@ -0,0 +1,731 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* STDDLG.H */ +/* */ +/* defines the classes TFileInputLine, TFileCollection, TSortedListBox, */ +/* TFileList, TFileInfoPane, TFileDialog, TDirCollection, TDirListBox, */ +/* and TChDirDialog */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma warn -hid +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __FILE_CMDS ) +#define __FILE_CMDS + +const int + +// Commands + + cmFileOpen = 1001, // Returned from TFileDialog when Open pressed + cmFileReplace = 1002, // Returned from TFileDialog when Replace pressed + cmFileClear = 1003, // Returned from TFileDialog when Clear pressed + cmFileInit = 1004, // Used by TFileDialog internally + cmChangeDir = 1005, // + cmRevert = 1006, // Used by TChDirDialog internally + +// Messages + + cmFileFocused = 102, // A new file was focused in the TFileList + cmFileDoubleClicked // A file was selected in the TFileList + = 103; + +#endif // __FILE_CMDS + +#if defined( Uses_TSearchRec ) && !defined( __TSearchRec ) +#define __TSearchRec + +#if !defined( __DIR_H ) +#include +#endif // __DIR_H + +struct TSearchRec +{ + uchar attr; + int32_t time; + int32_t size; + char name[MAXFILE+MAXEXT-1]; +}; + +#endif // Uses_TSearchRec + +#if defined( Uses_TFileInputLine ) && !defined( __TFileInputLine ) +#define __TFileInputLine + +class _FAR TRect; +struct _FAR TEvent; + +class TFileInputLine : public TInputLine +{ + +public: + + TFileInputLine( const TRect& bounds, short aMaxLen ) noexcept; + + virtual void handleEvent( TEvent& event ); + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TFileInputLine( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileInputLine& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileInputLine*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileInputLine& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileInputLine* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TFileInputLine + +#if defined( Uses_TFileCollection ) && !defined( __TFileCollection ) +#define __TFileCollection + +struct _FAR TSearchRec; + +class TFileCollection: public TSortedCollection +{ + +public: + + TFileCollection( ccIndex aLimit, ccIndex aDelta) noexcept : + TSortedCollection( aLimit, aDelta ) {} + + TSearchRec *at( ccIndex index ) + { return (TSearchRec *)TSortedCollection::at( index ); } + virtual ccIndex indexOf( TSearchRec *item ) + { return TSortedCollection::indexOf( item ); } + + void remove( TSearchRec *item ) + { TSortedCollection::remove( item ); } + void free( TSearchRec *item ) + { TSortedCollection::free( item ); } + void atInsert( ccIndex index, TSearchRec *item ) + { TSortedCollection::atInsert( index, item ); } + void atPut( ccIndex index, TSearchRec *item ) + { TSortedCollection::atPut( index, item ); } + virtual ccIndex insert( TSearchRec *item ) + { return TSortedCollection::insert( item ); } + + TSearchRec *firstThat( ccTestFunc Test, void *arg ); + TSearchRec *lastThat( ccTestFunc Test, void *arg ); + +private: + + virtual void freeItem( void *item ) + { delete (TSearchRec *)item; } + + virtual int compare( void *key1, void *key2 ); + + virtual const char *streamableName() const + { return name; } + + virtual void *readItem( ipstream& ); + virtual void writeItem( void *, opstream& ); + +protected: + + TFileCollection( StreamableInit ) noexcept : TSortedCollection ( streamableInit ) {} + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileCollection* cl ) + { return os << (TStreamable *)cl; } + +inline TSearchRec *TFileCollection::firstThat( ccTestFunc func, void *arg ) +{ + return (TSearchRec *)TSortedCollection::firstThat( ccTestFunc(func), arg ); +} + +inline TSearchRec *TFileCollection::lastThat( ccTestFunc func, void *arg ) +{ + return (TSearchRec *)TSortedCollection::lastThat( ccTestFunc(func), arg ); +} + +#endif // Uses_TFileCollection + + +#if defined( Uses_TSortedListBox ) && !defined( __TSortedListBox ) +#define __TSortedListBox + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; + +class TSortedListBox: public TListBox +{ + +public: + + TSortedListBox( const TRect& bounds, + ushort aNumCols, + TScrollBar *aScrollBar + ) noexcept; + + virtual void handleEvent( TEvent& event ); + void newList( TSortedCollection *aList ); + + TSortedCollection *list(); + +protected: + + uchar shiftState; + +private: + + virtual void *getKey( const char *s ); + + short searchPos; + + virtual const char *streamableName() const + { return name; } + +protected: + + TSortedListBox( StreamableInit ) noexcept : TListBox ( streamableInit ) {} + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TSortedListBox& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TSortedListBox*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TSortedListBox& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TSortedListBox* cl ) + { return os << (TStreamable *)cl; } + +inline TSortedCollection *TSortedListBox::list() +{ + return (TSortedCollection *)TListBox::list(); +} + +#endif // Uses_TSortedListBox + +#if defined( Uses_TFileList ) && !defined( __TFileList ) +#define __TFileList + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; + +class TFileList : public TSortedListBox +{ + +public: + + TFileList( const TRect& bounds, + TScrollBar *aScrollBar + ) noexcept; + ~TFileList(); + + virtual void focusItem( short item ); + virtual void selectItem( short item ); + virtual void getText( char *dest, short item, short maxLen ); + void newList( TFileCollection *aList ); + void readDirectory( TStringView dir, TStringView wildCard ); + void readDirectory( TStringView wildCard ); + + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void setData( void *rec ); + + TFileCollection *list(); + +private: + + virtual void *getKey( const char *s ); + + static const char * _NEAR tooManyFiles; + + virtual const char *streamableName() const + { return name; } + +protected: + + TFileList( StreamableInit ) noexcept : TSortedListBox ( streamableInit ) {} + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileList& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileList*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileList& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileList* cl ) + { return os << (TStreamable *)cl; } + +inline void TFileList::newList( TFileCollection *f ) +{ + TSortedListBox::newList( f ); +} + +inline TFileCollection *TFileList::list() +{ + return (TFileCollection *)TSortedListBox::list(); +} + +#endif // Uses_TFileList + + +#if defined( Uses_TFileInfoPane ) && !defined( __TFileInfoPane ) +#define __TFileInfoPane + +class _FAR TRect; +struct _FAR TEvent; + +class TFileInfoPane : public TView +{ + +public: + + TFileInfoPane( const TRect& bounds ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + +private: + + TSearchRec file_block; + + static const char * const _NEAR months[13]; + static const char * _NEAR pmText; + static const char * _NEAR amText; + + virtual const char *streamableName() const + { return name; } + +protected: + + TFileInfoPane( StreamableInit ) noexcept : TView ( streamableInit ) {} + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileInfoPane& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileInfoPane*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileInfoPane& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileInfoPane* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TFileInfoPane + +#if defined( Uses_TFileDialog ) && !defined( __TFileDialog ) +#define __TFileDialog + +const int + fdOKButton = 0x0001, // Put an OK button in the dialog + fdOpenButton = 0x0002, // Put an Open button in the dialog + fdReplaceButton = 0x0004, // Put a Replace button in the dialog + fdClearButton = 0x0008, // Put a Clear button in the dialog + fdHelpButton = 0x0010, // Put a Help button in the dialog + fdNoLoadDir = 0x0100; // Do not load the current directory + // contents into the dialog at Init. + // This means you intend to change the + // WildCard by using SetData or store + // the dialog on a stream. + +#if !defined( __DIR_H ) +#include +#endif // __DIR_H + +struct _FAR TEvent; +class _FAR TFileInputLine; +class _FAR TFileList; + +class TFileDialog : public TDialog +{ + +public: + + TFileDialog( TStringView aWildCard, TStringView aTitle, + TStringView inputName, ushort aOptions, uchar histId ) noexcept; + ~TFileDialog(); + + virtual void getData( void *rec ); + void getFileName( char *s ) noexcept; + virtual void handleEvent( TEvent& event ); + virtual void setData( void *rec ); + virtual Boolean valid( ushort command ); + virtual void shutDown(); + virtual void sizeLimits( TPoint& min, TPoint& max ); + + TFileInputLine *fileName; + TFileList *fileList; + char wildCard[MAXPATH]; + const char *directory; + +private: + + void readDirectory(); + + Boolean checkDirectory( const char * ); + + static const char * _NEAR filesText; + static const char * _NEAR openText; + static const char * _NEAR okText; + static const char * _NEAR replaceText; + static const char * _NEAR clearText; + static const char * _NEAR cancelText; + static const char * _NEAR helpText; + static const char * _NEAR invalidDriveText; + static const char * _NEAR invalidFileText; + + virtual const char *streamableName() const + { return name; } + +protected: + + TFileDialog( StreamableInit ) noexcept : + TWindowInit( TFileDialog::initFrame ), TDialog ( streamableInit ) {} + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFileDialog& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFileDialog*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFileDialog& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFileDialog* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TFileDialog + + +#if defined( Uses_TDirEntry ) && !defined( __TDirEntry ) +#define __TDirEntry + +class TDirEntry +{ + +public: + + TDirEntry( TStringView, TStringView ) noexcept; + ~TDirEntry(); + char *dir() { return directory; } + char *text() { return displayText; } + +private: + + char *displayText; + char *directory; + +}; + +inline TDirEntry::TDirEntry( TStringView txt, TStringView dir ) noexcept : + displayText( newStr( txt ) ), directory( newStr( dir ) ) +{ +} + +inline TDirEntry::~TDirEntry() +{ + delete[] displayText; + delete[] directory; +} + +#endif // Uses_TDirEntry + +#if defined( Uses_TDirCollection ) && !defined( __TDirCollection ) +#define __TDirCollection + +class _FAR TDirEntry; + +class TDirCollection : public TCollection +{ + +public: + + TDirCollection( ccIndex aLimit, ccIndex aDelta) noexcept : + TCollection( aLimit, aDelta ) {} + + TDirEntry *at( ccIndex index ) + { return (TDirEntry *)TCollection::at( index );} + virtual ccIndex indexOf( TDirEntry *item ) + { return TCollection::indexOf( item ); } + + void remove( TDirEntry *item ) + { TCollection::remove( item ); } + void free( TDirEntry *item ) + { TCollection::free( item ); } + void atInsert( ccIndex index, TDirEntry *item ) + { TCollection::atInsert( index, item ); } + void atPut( ccIndex index, TDirEntry *item ) + { TCollection::atPut( index, item ); } + virtual ccIndex insert( TDirEntry *item ) + { return TCollection::insert( item ); } + + TDirEntry *firstThat( ccTestFunc Test, void *arg ); + TDirEntry *lastThat( ccTestFunc Test, void *arg ); + +private: + + virtual void freeItem( void *item ) + { delete (TDirEntry *)item; } + + virtual const char *streamableName() const + { return name; } + virtual void *readItem( ipstream& ); + virtual void writeItem( void *, opstream& ); + +protected: + + TDirCollection( StreamableInit ) noexcept : TCollection ( streamableInit ) {} + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TDirCollection& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TDirCollection*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TDirCollection& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TDirCollection* cl ) + { return os << (TStreamable *)cl; } + +inline TDirEntry *TDirCollection::firstThat( ccTestFunc func, void *arg ) +{ + return (TDirEntry *)TCollection::firstThat( ccTestFunc(func), arg ); +} + +inline TDirEntry *TDirCollection::lastThat( ccTestFunc func, void *arg ) +{ + return (TDirEntry *)TCollection::lastThat( ccTestFunc(func), arg ); +} + +#endif // Uses_TDirCollection + + +#if defined( Uses_TDirListBox ) && !defined( __TDirListBox ) +#define __TDirListBox + +#if !defined( __DIR_H ) +#include +#endif // __DIR_H + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; +class _FAR TDirCollection; + +class TDirListBox : public TListBox +{ + +public: + + TDirListBox( const TRect& bounds, TScrollBar *aScrollBar ) noexcept; + ~TDirListBox(); + + virtual void getText( char *, short, short ); +// virtual void handleEvent( TEvent& ); + virtual Boolean isSelected( short ); + virtual void selectItem( short item ); + void newDirectory( TStringView ); + virtual void setState( ushort aState, Boolean enable ); + + TDirCollection *list(); + +private: + + void showDrives( TDirCollection * ); + void showDirs( TDirCollection * ); + + char dir[MAXPATH]; + ushort cur; + + static const char * _NEAR pathDir; + static const char * _NEAR firstDir; + static const char * _NEAR middleDir; + static const char * _NEAR lastDir; + static const char * _NEAR drives; + static const char * _NEAR graphics; + + virtual const char *streamableName() const + { return name; } + +protected: + + TDirListBox( StreamableInit ) noexcept : TListBox( streamableInit ) {} + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TDirListBox& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TDirListBox*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TDirListBox& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TDirListBox* cl ) + { return os << (TStreamable *)cl; } + +inline TDirCollection *TDirListBox::list() +{ + return (TDirCollection *)TListBox::list(); +} + +#endif // Uses_TDirListBox + +#if defined( Uses_TChDirDialog ) && !defined( __TChDirDialog ) +#define __TChDirDialog + +const int + cdNormal = 0x0000, // Option to use dialog immediately + cdNoLoadDir = 0x0001, // Option to init the dialog to store on a stream + cdHelpButton = 0x0002; // Put a help button in the dialog + +struct _FAR TEvent; +class _FAR TInputLine; +class _FAR TDirListBox; +class _FAR TButton; + +class TChDirDialog : public TDialog +{ + +public: + + friend class TDirListBox; + + TChDirDialog( ushort aOptions, ushort histId ) noexcept; + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void handleEvent( TEvent& ); + virtual void setData( void *rec ); + virtual Boolean valid( ushort ); + virtual void shutDown(); + +private: + + void setUpDialog(); + + TInputLine *dirInput; + TDirListBox *dirList; + TButton *okButton; + TButton *chDirButton; + + static const char * _NEAR changeDirTitle; + static const char * _NEAR dirNameText; + static const char * _NEAR dirTreeText; + static const char * _NEAR okText; + static const char * _NEAR chdirText; + static const char * _NEAR revertText; + static const char * _NEAR helpText; + static const char * _NEAR drivesText; + static const char * _NEAR invalidText; + + virtual const char *streamableName() const + { return name; } + +protected: + + TChDirDialog( StreamableInit ) noexcept : + TWindowInit( TChDirDialog::initFrame ), TDialog( streamableInit ) {} + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TChDirDialog& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TChDirDialog*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TChDirDialog& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TChDirDialog* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TChDirDialog + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/surface.h b/src/include/tvision/surface.h new file mode 100644 index 00000000..255e5585 --- /dev/null +++ b/src/include/tvision/surface.h @@ -0,0 +1,88 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* SURFACE.H */ +/* */ +/* Defines the classes TDrawSurface and TSurfaceView. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TDrawSurface ) && !defined( __TDrawSurface ) +#define __TDrawSurface + +// A TDrawSurface holds a two-dimensional buffer of TScreenCells +// that can be freely written to. + +class TDrawSurface +{ + + size_t dataLength; + TScreenCell _FAR *data; + +public: + + TPoint size; + + TDrawSurface() noexcept; + TDrawSurface(TPoint aSize) noexcept; + ~TDrawSurface(); + + void resize(TPoint aSize); + void grow(TPoint aDelta); + void clear(); + + // Warning: no bounds checking. + TScreenCell _FAR &at(int y, int x); + const TScreenCell _FAR &at(int y, int x) const; + +}; + +inline void TDrawSurface::grow(TPoint aDelta) +{ + resize(size + aDelta); +} + +inline TScreenCell _FAR &TDrawSurface::at(int y, int x) +{ + return data[y*size.x + x]; +} + +inline const TScreenCell _FAR &TDrawSurface::at(int y, int x) const +{ + return data[y*size.x + x]; +} + +#endif + +/* ---------------------------------------------------------------------- */ +/* class TSurfaceView */ +/* */ +/* Palette layout */ +/* 1 = Empty area */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TSurfaceView ) && !defined( __TSurfaceView ) +#define __TSurfaceView + +// A TSurfaceView displays a region of a TDrawSurface between 'delta' and +// '{delta.x + size.x, delta.y + size.y}'. +// Out-of-bounds areas (or the whole view if 'surface' is null) are +// displayed as whitespaces. + +// The "empty area" color maps to TWindow's and TDialog's "frame passive" color. + +class TSurfaceView : public TView +{ + +public: + + const TDrawSurface _FAR *surface; + TPoint delta; + + TSurfaceView(const TRect &bounds, const TDrawSurface _FAR *aSurface=0) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + +}; + +#endif diff --git a/src/include/tvision/system.h b/src/include/tvision/system.h new file mode 100644 index 00000000..9ded1c1a --- /dev/null +++ b/src/include/tvision/system.h @@ -0,0 +1,558 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* SYSTEM.H */ +/* */ +/* defines the classes THWMouse, TMouse, TEventQueue, TDisplay, */ +/* TScreen, and TSystemError */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __EVENT_CODES ) +#define __EVENT_CODES + +/* Event codes */ + +const int evMouseDown = 0x0001; +const int evMouseUp = 0x0002; +const int evMouseMove = 0x0004; +const int evMouseAuto = 0x0008; +const int evMouseWheel= 0x0020; +const int evKeyDown = 0x0010; +const int evCommand = 0x0100; +const int evBroadcast = 0x0200; + +/* Event masks */ + +const int evNothing = 0x0000; +const int evMouse = 0x002f; +const int evKeyboard = 0x0010; +const int evMessage = 0xFF00; + +/* Mouse button state masks */ + +const int mbLeftButton = 0x01; +const int mbRightButton = 0x02; +const int mbMiddleButton= 0x04; + +/* Mouse wheel state masks */ + +const int mwUp = 0x01; +const int mwDown = 0x02; +const int mwLeft = 0x04; +const int mwRight = 0x08; + +/* Mouse event flags */ + +#if !defined( __FLAT__ ) +const int meMouseMoved = 0x01; +const int meDoubleClick = 0x02; +#else +#if !defined( __WINDOWS_H ) +#include +#endif +const int meMouseMoved = MOUSE_MOVED; // NT values from WINDOWS.H +const int meDoubleClick = DOUBLE_CLICK; +#endif +// 0x04 and 0x08 are reserved by NT (MOUSE_WHEELED, MOUSE_HWHEELED). +const int meTripleClick = 0x10; + +#endif // __EVENT_CODES + +#if defined( Uses_TEvent ) && !defined( __TEvent ) +#define __TEvent + +struct MouseEventType +{ + TPoint where; + ushort eventFlags; // Replacement for doubleClick. + ushort controlKeyState; + uchar buttons; + uchar wheel; +}; + +class THWMouse +{ + +protected: + + THWMouse() noexcept; + THWMouse( const THWMouse& ) noexcept {}; + ~THWMouse(); +public: + static void show() noexcept; + static void hide() noexcept; +protected: + static void setRange( ushort, ushort ) noexcept; + static void getEvent( MouseEventType& ) noexcept; + static Boolean present() noexcept; + +#if !defined( __FLAT__ ) + static void registerHandler( unsigned, void (_FAR *)() ); +#endif + + static void suspend() noexcept; + static void resume() noexcept; + static void inhibit() noexcept; + +protected: + + static uchar _NEAR buttonCount; + +private: + + static Boolean _NEAR handlerInstalled; + static Boolean _NEAR noMouse; + +}; + +inline Boolean THWMouse::present() noexcept +{ + return Boolean( buttonCount != 0 ); +} + +inline void THWMouse::inhibit() noexcept +{ + noMouse = True; +} + +class TMouse : public THWMouse +{ + +public: + + TMouse() noexcept; + ~TMouse(); + + static void show() noexcept; + static void hide() noexcept; + + static void setRange( ushort, ushort ) noexcept; + static void getEvent( MouseEventType& ) noexcept; + static Boolean present() noexcept; + +#if !defined( __FLAT__ ) + static void registerHandler( unsigned, void (_FAR *)() ); +#endif + + static void suspend() noexcept { THWMouse::suspend(); } + static void resume() noexcept { THWMouse::resume(); } + +}; + +inline void TMouse::show() noexcept +{ + THWMouse::show(); +} + +inline void TMouse::hide() noexcept +{ + THWMouse::hide(); +} + +inline void TMouse::setRange( ushort rx, ushort ry ) noexcept +{ + THWMouse::setRange( rx, ry ); +} + +inline void TMouse::getEvent( MouseEventType& me ) noexcept +{ + THWMouse::getEvent( me ); +} + +inline Boolean TMouse::present() noexcept +{ + return THWMouse::present(); +} + +#if !defined( __FLAT__ ) +inline void TMouse::registerHandler( unsigned mask, void (_FAR *func)() ) +{ + THWMouse::registerHandler( mask, func ); +} +#endif + +struct CharScanType +{ + uchar charCode; + uchar scanCode; +}; + +struct KeyDownEvent +{ + union + { + ushort keyCode; + CharScanType charScan; + }; + ushort controlKeyState; + char text[4]; // NOT null-terminated. + uchar textLength; + + TStringView getText() const; + operator TKey() const; +}; + +inline TStringView KeyDownEvent::getText() const +{ + return TStringView(text, textLength); +} + +inline KeyDownEvent::operator TKey() const +{ + return TKey(keyCode, controlKeyState); +} + +struct MessageEvent +{ + ushort command; + union + { + void *infoPtr; + int32_t infoLong; + ushort infoWord; + short infoInt; + uchar infoByte; + char infoChar; + }; +}; + +struct TEvent +{ + ushort what; + union + { + MouseEventType mouse; + KeyDownEvent keyDown; + MessageEvent message; + }; + + void getMouseEvent() noexcept; + void getKeyEvent() noexcept; + static void waitForEvent(int timeoutMs) noexcept; + static void putNothing() noexcept; +}; + +#endif // Uses_TEvent + +#if defined( Uses_TEventQueue ) && !defined( __TEventQueue ) +#define __TEventQueue + +class TEventQueue +{ +public: + TEventQueue() noexcept; + ~TEventQueue(); + + static void getMouseEvent( TEvent& ) noexcept; + static void getKeyEvent( TEvent& ) noexcept; + static void suspend() noexcept; + static void resume() noexcept; + static void waitForEvent( int ) noexcept; + + friend class TView; + friend class TProgram; + friend void genRefs(); + + static ushort _NEAR doubleDelay; + static Boolean _NEAR mouseReverse; + + static void putPaste( TStringView ) noexcept; + +private: + + static TMouse * _NEAR mouse; + static Boolean getMouseState( TEvent& ) noexcept; + static Boolean getPasteEvent( TEvent& ) noexcept; + static void getKeyOrPasteEvent( TEvent& ) noexcept; + static Boolean readKeyPress( TEvent& ) noexcept; + +#if !defined( __FLAT__ ) +#if !defined( __DPMI16__ ) +#define __MOUSEHUGE huge +#else +#define __MOUSEHUGE +#endif + static void __MOUSEHUGE mouseInt(); +#endif + + static MouseEventType _NEAR lastMouse; +public: + static MouseEventType _NEAR curMouse; +private: + static MouseEventType _NEAR downMouse; + static ushort _NEAR downTicks; + +#if !defined( __FLAT__ ) + static TEvent _NEAR eventQueue[ eventQSize ]; + static TEvent * _NEAR eventQHead; + static TEvent * _NEAR eventQTail; +public: + static Boolean _NEAR mouseIntFlag; +private: + static ushort _NEAR eventCount; +#endif + + static Boolean _NEAR mouseEvents; + static Boolean _NEAR pendingMouseUp; + + static ushort _NEAR repeatDelay; + static ushort _NEAR autoTicks; + static ushort _NEAR autoDelay; + + static char * _FAR pasteText; + static size_t _NEAR pasteTextLength; + static size_t _NEAR pasteTextIndex; + + static TEvent _NEAR keyEventQueue[ keyEventQSize ]; + static size_t _NEAR keyEventCount; + static size_t _NEAR keyEventIndex; + static Boolean _NEAR keyPasteState; +}; + +inline void TEvent::getMouseEvent() noexcept +{ + TEventQueue::getMouseEvent( *this ); +} + +#endif // Uses_TEventQueue + +#if defined( Uses_TTimerQueue ) && !defined( __TTimerQueue ) +#define __TTimerQueue + +#ifdef __BORLANDC__ +typedef uint32_t TTimePoint; +#else +typedef uint64_t TTimePoint; +#endif + +struct _FAR TTimer; + +class TTimerQueue +{ +public: + + TTimerQueue() noexcept; + TTimerQueue(TTimePoint (&getTimeMs)()) noexcept; + ~TTimerQueue(); + + TTimerId setTimer(uint32_t timeoutMs, int32_t periodMs = -1); + void killTimer(TTimerId id); + void collectTimeouts(void (&func)(TTimerId, void *), void *args); + int32_t timeUntilTimeout(); + +private: + + TTimePoint (&getTimeMs)(); + TTimer *first; +}; + +#endif // Uses_TTimerQueue + +#if defined( Uses_TClipboard ) && !defined( __TClipboard ) +#define __TClipboard + +class TClipboard +{ +public: + + ~TClipboard(); + + static void setText(TStringView text) noexcept; + static void requestText() noexcept; + +private: + + TClipboard(); + + static TClipboard instance; + static char *localText; + static size_t localTextLength; +}; + +#endif + +#if defined( Uses_TScreen ) && !defined( __TScreen ) +#define __TScreen + + +class TDisplay +{ + +public: + + friend class TView; + + enum videoModes + { + smBW80 = 0x0002, + smCO80 = 0x0003, + smMono = 0x0007, + smFont8x8 = 0x0100, + smColor256 = 0x0200, + smColorHigh = 0x0400, + smChanged = 0x1000 + }; + + static void clearScreen( uchar, uchar ) noexcept; + + static void setCursorType( ushort ) noexcept; + static ushort getCursorType() noexcept; + + static ushort getRows() noexcept; + static ushort getCols() noexcept; + + static void setCrtMode( ushort ) noexcept; + static ushort getCrtMode() noexcept; + +#if !defined( __FLAT__ ) + static int isEGAorVGA(); +#endif + +protected: + + TDisplay() noexcept { updateIntlChars(); }; + TDisplay( const TDisplay& ) noexcept { updateIntlChars(); }; + ~TDisplay() {}; + +private: + +#if !defined( __FLAT__ ) + static void videoInt(); +#endif + + static void updateIntlChars() noexcept; + +}; + +class TScreen : public TDisplay +{ + +public: + + TScreen() noexcept; + ~TScreen(); + + static void setVideoMode( ushort mode ) noexcept; + static void clearScreen() noexcept; + static void flushScreen() noexcept; + + static ushort _NEAR startupMode; + static ushort _NEAR startupCursor; + static ushort _NEAR screenMode; + static ushort _NEAR screenWidth; + static ushort _NEAR screenHeight; + static Boolean _NEAR hiResScreen; + static Boolean _NEAR checkSnow; + static TScreenCell * _NEAR screenBuffer; + static ushort _NEAR cursorLines; + static Boolean _NEAR clearOnSuspend; + + static void setCrtData() noexcept; + static ushort fixCrtMode( ushort ) noexcept; + + static void suspend() noexcept; + static void resume() noexcept; + +}; + +#endif // Uses_TScreen + +#if defined( Uses_TSystemError ) && !defined( __TSystemError ) +#define __TSystemError + +class _FAR TDrawBuffer; + +struct TPMRegs +{ + unsigned long di, si, bp, dummy, bx, dx, cx, ax; + unsigned flags, es, ds, fs, gs, ip, cs, sp, ss; +}; + +class TSystemError +{ + +public: + + TSystemError() noexcept; + ~TSystemError(); + + static Boolean _NEAR ctrlBreakHit; + + static void suspend() noexcept; + static void resume() noexcept; + +#if !defined( __FLAT__ ) + static short ( _FAR *sysErrorFunc )( short, uchar ); +#endif + +private: + + static Boolean _NEAR saveCtrlBreak; + +#if !defined( __FLAT__ ) + static ushort _NEAR sysColorAttr; + static ushort _NEAR sysMonoAttr; + static Boolean _NEAR sysErrActive; + + static void swapStatusLine( TDrawBuffer _FAR & ); + static ushort selectKey(); + static short sysErr( short, uchar ); + + static const char * const _NEAR errorString[22]; + static const char * _NEAR sRetryOrCancel; + + static Boolean _NEAR inIDE; + + static void interrupt Int24PMThunk(); + static void setupDPMI(); + static void shutdownDPMI(); + + static TPMRegs Int24Regs; + static void (interrupt far *Int24RMThunk)(); + static void (interrupt far *Int24RMCallback)(); + static unsigned Int24RMThunkSel; + + friend class Int11trap; +#endif + +}; + +#if !defined( __FLAT__ ) +class Int11trap +{ + +public: + + Int11trap(); + ~Int11trap(); + +private: + + static void interrupt handler(...); + static void interrupt (_FAR * _NEAR oldHandler)(...); + +}; +#endif + +#endif // Uses_TSystemError + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/textview.h b/src/include/tvision/textview.h new file mode 100644 index 00000000..e6dfeb1a --- /dev/null +++ b/src/include/tvision/textview.h @@ -0,0 +1,129 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TEXTVIEW.H */ +/* */ +/* defines the classes TTextDevice and TTerminal */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TTextDevice ) && !defined( __TTextDevice ) +#define __TTextDevice + +#include +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class _FAR TRect; +class _FAR TScrollBar; + +class TTextDevice : public TScroller, public streambuf +{ + +public: + + TTextDevice( const TRect& bounds, + TScrollBar *aHScrollBar, + TScrollBar *aVScrollBar, + ushort aBufSize = 256 + ) noexcept; + ~TTextDevice(); + + virtual int do_sputn( const char *s, int count ) = 0; + virtual int overflow( int = EOF ); + +protected: + + virtual int sync(); + +}; + +#endif // Uses_TTextDevice + +#if defined( Uses_TTerminal ) && !defined( __TTerminal ) +#define __TTerminal + +class _FAR TRect; +class _FAR TScrollBar; + +class TTerminal: public TTextDevice +{ + +public: + + friend void genRefs(); + + TTerminal( const TRect& bounds, + TScrollBar *aHScrollBar, + TScrollBar *aVScrollBar, + ushort aBufSize + ) noexcept; + ~TTerminal(); + + virtual int do_sputn( const char *s, int count ); + + void bufInc( ushort& val ); + Boolean canInsert( ushort amount ); + short calcWidth(); + virtual void draw(); + ushort nextLine( ushort pos ); + ushort prevLines( ushort pos, ushort lines ); + Boolean queEmpty(); + +protected: + + ushort bufSize; + char *buffer; + ushort queFront, queBack; + void bufDec(ushort& val); +}; + +#endif // Uses_TTerminal + +#if defined( Uses_otstream ) && !defined( __otstream ) +#define __otstream + +#include +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + + +class otstream : public ostream +{ + +public: + + otstream( TTerminal * ); + +}; + + +#endif + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/tkeys.h b/src/include/tvision/tkeys.h new file mode 100644 index 00000000..614b1a86 --- /dev/null +++ b/src/include/tvision/tkeys.h @@ -0,0 +1,216 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TKEYS.H */ +/* */ +/* defines constants for all control key combinations */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( Uses_TKeys ) && !defined( __TKeys ) +#define __TKeys + +#if defined( __FLAT__ ) && !defined( __WINDOWS_H ) +#include +#endif + +//// Key codes +// +// The following constants can be used to define menu hotkeys and to +// examine the 'keyCode' field of 'evKeyDown' event records. +// +// Not all key combinations can be used in all platforms. In particular: +// +// * In 16-bit mode, keystrokes corresponding to the 'additional extended +// key codes' are not reported. +// +// * Keystrokes corresponding to system shortcuts (e.g. Alt+F4 for 'close +// window' in graphical environments) are not reported either. +// +// * In Unix, support for key combinations varies among terminal emulators. +// Ctrl+H, Ctrl+I, Ctrl+J and Ctrl+M are not likely to work since they +// usually represent Backspace, Tab and Enter. +// +// These constants do not cover all possible combinations of the Shift, Ctrl +// and Alt modifiers. For that purpose, see the TKey class below. + +const ushort + +// Control keys + + kbCtrlA = 0x0001, kbCtrlB = 0x0002, kbCtrlC = 0x0003, + kbCtrlD = 0x0004, kbCtrlE = 0x0005, kbCtrlF = 0x0006, + kbCtrlG = 0x0007, kbCtrlH = 0x0008, kbCtrlI = 0x0009, + kbCtrlJ = 0x000a, kbCtrlK = 0x000b, kbCtrlL = 0x000c, + kbCtrlM = 0x000d, kbCtrlN = 0x000e, kbCtrlO = 0x000f, + kbCtrlP = 0x0010, kbCtrlQ = 0x0011, kbCtrlR = 0x0012, + kbCtrlS = 0x0013, kbCtrlT = 0x0014, kbCtrlU = 0x0015, + kbCtrlV = 0x0016, kbCtrlW = 0x0017, kbCtrlX = 0x0018, + kbCtrlY = 0x0019, kbCtrlZ = 0x001a, + +// Extended key codes + + kbEsc = 0x011b, kbAltSpace = 0x0200, kbCtrlIns = 0x0400, + kbShiftIns = 0x0500, kbCtrlDel = 0x0600, kbShiftDel = 0x0700, + kbBack = 0x0e08, kbCtrlBack = 0x0e7f, kbShiftTab = 0x0f00, + kbTab = 0x0f09, kbAltQ = 0x1000, kbAltW = 0x1100, + kbAltE = 0x1200, kbAltR = 0x1300, kbAltT = 0x1400, + kbAltY = 0x1500, kbAltU = 0x1600, kbAltI = 0x1700, + kbAltO = 0x1800, kbAltP = 0x1900, kbCtrlEnter = 0x1c0a, + kbEnter = 0x1c0d, kbAltA = 0x1e00, kbAltS = 0x1f00, + kbAltD = 0x2000, kbAltF = 0x2100, kbAltG = 0x2200, + kbAltH = 0x2300, kbAltJ = 0x2400, kbAltK = 0x2500, + kbAltL = 0x2600, kbAltZ = 0x2c00, kbAltX = 0x2d00, + kbAltC = 0x2e00, kbAltV = 0x2f00, kbAltB = 0x3000, + kbAltN = 0x3100, kbAltM = 0x3200, kbF1 = 0x3b00, + kbF2 = 0x3c00, kbF3 = 0x3d00, kbF4 = 0x3e00, + kbF5 = 0x3f00, kbF6 = 0x4000, kbF7 = 0x4100, + kbF8 = 0x4200, kbF9 = 0x4300, kbF10 = 0x4400, + kbHome = 0x4700, kbUp = 0x4800, kbPgUp = 0x4900, + kbGrayMinus = 0x4a2d, kbLeft = 0x4b00, kbRight = 0x4d00, + kbGrayPlus = 0x4e2b, kbEnd = 0x4f00, kbDown = 0x5000, + kbPgDn = 0x5100, kbIns = 0x5200, kbDel = 0x5300, + kbShiftF1 = 0x5400, kbShiftF2 = 0x5500, kbShiftF3 = 0x5600, + kbShiftF4 = 0x5700, kbShiftF5 = 0x5800, kbShiftF6 = 0x5900, + kbShiftF7 = 0x5a00, kbShiftF8 = 0x5b00, kbShiftF9 = 0x5c00, + kbShiftF10 = 0x5d00, kbCtrlF1 = 0x5e00, kbCtrlF2 = 0x5f00, + kbCtrlF3 = 0x6000, kbCtrlF4 = 0x6100, kbCtrlF5 = 0x6200, + kbCtrlF6 = 0x6300, kbCtrlF7 = 0x6400, kbCtrlF8 = 0x6500, + kbCtrlF9 = 0x6600, kbCtrlF10 = 0x6700, kbAltF1 = 0x6800, + kbAltF2 = 0x6900, kbAltF3 = 0x6a00, kbAltF4 = 0x6b00, + kbAltF5 = 0x6c00, kbAltF6 = 0x6d00, kbAltF7 = 0x6e00, + kbAltF8 = 0x6f00, kbAltF9 = 0x7000, kbAltF10 = 0x7100, + kbCtrlPrtSc = 0x7200, kbCtrlLeft = 0x7300, kbCtrlRight = 0x7400, + kbCtrlEnd = 0x7500, kbCtrlPgDn = 0x7600, kbCtrlHome = 0x7700, + kbAlt1 = 0x7800, kbAlt2 = 0x7900, kbAlt3 = 0x7a00, + kbAlt4 = 0x7b00, kbAlt5 = 0x7c00, kbAlt6 = 0x7d00, + kbAlt7 = 0x7e00, kbAlt8 = 0x7f00, kbAlt9 = 0x8000, + kbAlt0 = 0x8100, kbAltMinus = 0x8200, kbAltEqual = 0x8300, + kbCtrlPgUp = 0x8400, kbNoKey = 0x0000, + +// Additional extended key codes + + kbAltEsc = 0x0100, kbAltBack = 0x0e00, kbF11 = 0x8500, + kbF12 = 0x8600, kbShiftF11 = 0x8700, kbShiftF12 = 0x8800, + kbCtrlF11 = 0x8900, kbCtrlF12 = 0x8a00, kbAltF11 = 0x8b00, + kbAltF12 = 0x8c00, kbCtrlUp = 0x8d00, kbCtrlDown = 0x9100, + kbCtrlTab = 0x9400, kbAltHome = 0x9700, kbAltUp = 0x9800, + kbAltPgUp = 0x9900, kbAltLeft = 0x9b00, kbAltRight = 0x9d00, + kbAltEnd = 0x9f00, kbAltDown = 0xa000, kbAltPgDn = 0xa100, + kbAltIns = 0xa200, kbAltDel = 0xa300, kbAltTab = 0xa500, + kbAltEnter = 0xa600, + +//// Keyboard state and shift masks +// +// The following constants can be used when examining the 'controlKeyState' +// field of an 'evKeyDown' event record. +// +// Distinguishing between the left and right Shift keys is only supported in +// 16-bit mode, while distinguishing between the left and right Ctrl and Alt +// keys is only supported in 32-bit DPMI and on Windows. +// +// The kbScrollState, kbNumState, kbCapsState and kbEnhanced flags are only +// reported on DOS and Windows. + +#if !defined( __FLAT__ ) + kbLeftShift = 0x0001, + kbRightShift = 0x0002, + kbShift = kbLeftShift | kbRightShift, + kbLeftCtrl = 0x0004, + kbRightCtrl = 0x0004, + kbCtrlShift = kbLeftCtrl | kbRightCtrl, + kbLeftAlt = 0x0008, + kbRightAlt = 0x0008, + kbAltShift = kbLeftAlt | kbRightAlt, + kbScrollState = 0x0010, + kbNumState = 0x0020, + kbCapsState = 0x0040, + kbInsState = 0x0080, + kbPaste = 0x0100; +#else + kbLeftShift = SHIFT_PRESSED, + kbRightShift = SHIFT_PRESSED, + kbShift = kbLeftShift | kbRightShift, + kbLeftCtrl = LEFT_CTRL_PRESSED, + kbRightCtrl = RIGHT_CTRL_PRESSED, + kbCtrlShift = kbLeftCtrl | kbRightCtrl, + kbLeftAlt = LEFT_ALT_PRESSED, + kbRightAlt = RIGHT_ALT_PRESSED, + kbAltShift = kbLeftAlt | kbRightAlt, + kbScrollState = SCROLLLOCK_ON, + kbNumState = NUMLOCK_ON, + kbCapsState = CAPSLOCK_ON, + kbEnhanced = ENHANCED_KEY, + kbInsState = 0x200, // Ensure this doesn't overlap above values + kbPaste = 0x400; +#endif + +#endif // __TKeys + +#if !defined( __TKey ) +#define __TKey + +//// TKey +// +// This class provides the ability to define new key combinations by +// specifying a key code and a mask of key modifiers. These key combinations +// can then be used to define menu hotkeys and examine 'evKeyDown' event +// records. +// +// The only modifiers taken into account are Shift, Ctrl and Alt, making no +// distinction between the left and right key on platforms that support it. +// +// Given that some key code constants already imply the presence of a key +// modifier, there are key combinations which can be defined in multiple +// ways. TKey ensures equality between all of them. For example: +// +// assert(kbCtrlA == TKey('A', kbCtrlShift)); +// assert(TKey(kbCtrlTab, kbShift) == TKey(kbTab, kbShift | kbCtrlShift)); +// assert(TKey(kbAltDel, kbCtrlShift) == TKey(kbCtrlDel, kbAltShift)); + +class TKey +{ +public: + + constexpr TKey() noexcept; + TKey(ushort keyCode, ushort shiftState = 0) noexcept; + + ushort code; + ushort mods; +}; + +inline constexpr TKey::TKey() noexcept : + code(0), + mods(0) +{ +} + +inline constexpr Boolean operator==(TKey a, TKey b) noexcept +{ + return Boolean( + (a.code | ((int32_t) a.mods << 16)) == (b.code | ((int32_t) b.mods << 16)) + ); +} + +inline constexpr Boolean operator!=(TKey a, TKey b) noexcept +{ + return Boolean( !(a == b) ); +} + +inline ipstream& operator >> ( ipstream& is, TKey& p ) + { return is >> p.code >> p.mods; } +inline ipstream& operator >> ( ipstream& is, TKey*& p ) + { return is >> p->code >> p->mods; } + +inline opstream& operator << ( opstream& os, TKey& p ) + { return os << p.code << p.mods; } +inline opstream& operator << ( opstream& os, TKey* p ) + { return os << p->code << p->mods; } + +#endif // __TKey diff --git a/src/include/tvision/tobjstrm.h b/src/include/tvision/tobjstrm.h new file mode 100644 index 00000000..4aa9ca50 --- /dev/null +++ b/src/include/tvision/tobjstrm.h @@ -0,0 +1,665 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TOBJSTRM.H */ +/* */ +/* defines the classes TStreamable, TStreamableClass, pstream, */ +/* ipstream, opstream, iopstream, ifpstream, ofpstream, and fpstream. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +typedef unsigned P_id_type; + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TStreamable */ +/* */ +/* This is the base class for all storable objects. It provides */ +/* three member functions, streamableName(), read(), and write(), which */ +/* must be overridden in every derived class. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#ifdef __DLL__ +#define _FAR far +#else +#define _FAR +#endif + +#if defined( __BORLANDC__ ) +#pragma warn -nst +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __fLink_def ) +#define __fLink_def + +struct fLink +{ + fLink _NEAR *f; + class TStreamableClass _NEAR *t; + static class TStreamableClass * volatile forceLink; +}; + +#ifndef __COUNTER__ + +#define __link( s ) \ + extern TStreamableClass s; \ + static fLink force ## s = \ + { (fLink _NEAR *)&force ## s, (fLink::forceLink = &s, (TStreamableClass _NEAR *)&s) }; + +#else + +// Take advantage of the __COUNTER__ macro so that linking the same object twice +// doesn't trigger a compilation error. + +#define __link_declare( s, n ) \ + extern TStreamableClass s; \ + static void * const force ## s ## n = ((void) force ## s ## n, fLink::forceLink = &s, nullptr); + +#define __link_expand( s, ... ) __link_declare( s, __VA_ARGS__ ) +#define __link( s ) __link_expand( s, __COUNTER__ ) + +#endif // __COUNTER__ + +#endif // __fLink_def + +#if defined( Uses_TStreamable ) && !defined( __TStreamable ) +#define __TStreamable + +class TStreamable +{ + + friend class pstream; + friend class opstream; + friend class ipstream; + +private: + + virtual const char *streamableName() const = 0; + +protected: + + virtual void *read( ipstream& ) = 0; + virtual void write( opstream& ) = 0; + +}; + +#endif // Uses_TStreamable + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TStreamableClass */ +/* */ +/* Used internally by TStreamableTypes and pstream. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TStreamableClass ) && !defined( __TStreamableClass ) +#define __TStreamableClass + +#include +#include +#include + +const P_id_type P_id_notFound = UINT_MAX; + +typedef TStreamable *(*BUILDER)(); + +// This is now computed at runtime by ipstream. +#define __DELTA( d ) 0 + +class TStreamableClass +{ + + friend TStreamableTypes; + friend opstream; + friend ipstream; + +public: + + TStreamableClass( const char *n, BUILDER b, int /* unused */ = 0 ) noexcept; + +private: + + const char *name; + BUILDER build; + +}; + +#endif // Uses_TStreamableClass + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TStreamableTypes */ +/* */ +/* Maintains a database of all registered types in the application. */ +/* Used by opstream and ipstream to find the functions to read and */ +/* write objects. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TStreamableTypes ) && !defined( __TStreamableTypes ) +#define __TStreamableTypes + +class TStreamableTypes : private TNSSortedCollection +{ + +public: + + TStreamableTypes() noexcept; + ~TStreamableTypes(); + + void registerType( const TStreamableClass * ); + const TStreamableClass *lookup( const char * ); + + void *operator new( size_t sz ) { return ::operator new( sz ); } + void *operator new( size_t, void * ); + +private: + + virtual void *keyOf( void * ); + int compare( void *, void * ); + +}; + +#endif // Uses_TStreamableTypes + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TPWrittenObjects */ +/* */ +/* Maintains a database of all objects that have been written to the */ +/* current object stream. */ +/* */ +/* Used by opstream when it writes a pointer onto a stream to determine */ +/* whether the object pointed to has already been written to the stream. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TPWrittenObjects ) && !defined( __TPWrittenObjects ) +#define __TPWrittenObjects + +class TPWrittenObjects : public TNSSortedCollection +{ + + friend opstream; + +public: + + void removeAll() { curId = 0; TNSSortedCollection::freeAll(); } + +private: + + TPWrittenObjects() noexcept; + ~TPWrittenObjects(); + + void registerObject( const void *adr ); + P_id_type find( const void *adr ); + + void *keyOf( void * ); + int compare( void *, void * ); + + P_id_type curId; + +}; + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TPWObj */ +/* */ +/* Used internally by TPWrittenObjects. */ +/* */ +/* ------------------------------------------------------------------------*/ + +class TPWObj +{ + + friend TPWrittenObjects; + +private: + + TPWObj( const void *adr, P_id_type id ) noexcept; + + const void *address; + P_id_type ident; + +}; + +#endif // Uses_TPWrittenObjects + +/* ------------------------------------------------------------------------*/ +/* */ +/* class TPReadObjects */ +/* */ +/* Maintains a database of all objects that have been read from the */ +/* current persistent stream. */ +/* */ +/* Used by ipstream when it reads a pointer from a stream to determine */ +/* the address of the object being referred to. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TPReadObjects ) && !defined( __TPReadObjects ) +#define __TPReadObjects + +class TPReadObjects : public TNSCollection +{ + + friend ipstream; + +public: + + void removeAll() { curId = 0; TNSCollection::removeAll(); } + +private: + + TPReadObjects() noexcept; + ~TPReadObjects(); + + void registerObject( const void *adr ); + const void *find( P_id_type id ); + + P_id_type curId; + +}; + +#endif // Uses_TPReadObjects + +/* ------------------------------------------------------------------------*/ +/* */ +/* class pstream */ +/* */ +/* Base class for handling streamable objects. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_pstream ) && !defined( __pstream ) +#define __pstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class _FAR TStreamableTypes; + +class pstream +{ + + friend TStreamableTypes; + +public: + + enum StreamableError { peNotRegistered, peInvalidType }; + enum PointerTypes { ptNull, ptIndexed, ptObject }; + + _Cdecl pstream( streambuf _FAR * ) noexcept; + virtual _Cdecl ~pstream(); + + typedef int openmode; + typedef int seekdir; + + int _Cdecl rdstate() const noexcept; + int _Cdecl eof() const noexcept; + int _Cdecl fail() const noexcept; + int _Cdecl bad() const noexcept; + int _Cdecl good() const noexcept; + void _Cdecl clear( int = 0 ) noexcept; + _Cdecl operator void *() const noexcept; + int _Cdecl operator ! () const noexcept; + + streambuf _FAR * _Cdecl rdbuf() const noexcept; + + static void initTypes() noexcept; + static void registerType( TStreamableClass *ts ) noexcept; + +protected: + + _Cdecl pstream() noexcept; + + void _Cdecl error( StreamableError ) noexcept; + void _Cdecl error( StreamableError, const TStreamable& ) noexcept; + + streambuf _FAR *bp; + int state; + + void _Cdecl init( streambuf _FAR * ) noexcept; + void _Cdecl setstate( int ) noexcept; + + static TStreamableTypes * _NEAR types; + +}; + +#endif // Uses_pstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class ipstream */ +/* */ +/* Base class for reading streamable objects */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_ipstream ) && !defined( __ipstream ) +#define __ipstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class _FAR TStreamableClass; + +class ipstream : virtual public pstream +{ + +public: + + _Cdecl ipstream( streambuf _FAR * ) noexcept; + _Cdecl ~ipstream(); + + streampos _Cdecl tellg(); + ipstream& _Cdecl seekg( streampos ); + ipstream& _Cdecl seekg( streamoff, pstream::seekdir ); + + uchar _Cdecl readByte(); + void _Cdecl readBytes( void _FAR *, size_t ); + ushort _Cdecl readWord(); + char _FAR * _Cdecl readString(); + char _FAR * _Cdecl readString( char _FAR *, unsigned ); + + friend ipstream& _Cdecl operator >> ( ipstream&, TStreamable& ); + friend ipstream& _Cdecl operator >> ( ipstream&, void _FAR *& ); + +protected: + + _Cdecl ipstream() noexcept; + + const TStreamableClass _FAR * _Cdecl readPrefix(); + void _FAR * _Cdecl readData( const TStreamableClass _FAR *, + TStreamable _FAR * ); + void _Cdecl readSuffix(); + + const void _FAR * _Cdecl find( P_id_type ); + void _Cdecl registerObject( const void _FAR *adr ); + +private: + + TPReadObjects objs; + +}; + +#endif // Uses_ipstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class opstream */ +/* */ +/* Base class for writing streamable objects */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_opstream ) && !defined( __opstream ) +#define __opstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + + +class _FAR TStreamableClass; + +class opstream : virtual public pstream +{ + +public: + + _Cdecl opstream( streambuf _FAR * ) noexcept; + _Cdecl ~opstream(); + + streampos _Cdecl tellp(); + opstream& _Cdecl seekp( streampos ); + opstream& _Cdecl seekp( streamoff, pstream::seekdir ); + opstream& _Cdecl flush(); + + void _Cdecl writeByte( uchar ); + void _Cdecl writeBytes( const void _FAR *, size_t ); + void _Cdecl writeWord( ushort ); + void _Cdecl writeString( const char _FAR * ); + void _Cdecl writeString( TStringView ); + + friend opstream& _Cdecl operator << ( opstream&, TStreamable& ); + friend opstream& _Cdecl operator << ( opstream&, TStreamable _FAR * ); + +protected: + + _Cdecl opstream() noexcept; + + void _Cdecl writePrefix( const TStreamable& ); + void _Cdecl writeData( TStreamable& ); + void _Cdecl writeSuffix( const TStreamable& ); + + P_id_type _Cdecl find( const void _FAR *adr ); + void _Cdecl registerObject( const void _FAR *adr ); + +private: + + TPWrittenObjects *objs; + +}; + +#endif // Uses_opstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class iopstream */ +/* */ +/* Base class for reading and writing streamable objects */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_iopstream ) && !defined( __iopstream ) +#define __iopstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class iopstream : public ipstream, public opstream +{ + +public: + + _Cdecl iopstream( streambuf _FAR * ) noexcept; + _Cdecl ~iopstream(); + +protected: + + _Cdecl iopstream() noexcept; + +}; + +#endif // Uses_iopstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class fpbase */ +/* */ +/* Base class for handling streamable objects on file streams */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_fpbase ) && !defined( __fpbase ) +#define __fpbase + +#if !defined( __FSTREAM_H ) +#include +#endif // __FSTREAM_H + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class fpbase : virtual public pstream +{ + +public: + + _Cdecl fpbase() noexcept; + _Cdecl fpbase( const char _FAR *, pstream::openmode); + _Cdecl ~fpbase(); + + void _Cdecl open( const char _FAR *, pstream::openmode); + void _Cdecl close(); + filebuf _FAR * _Cdecl rdbuf() noexcept; + +private: + + filebuf buf; + +}; + +#endif // Uses_fpbase + +/* ------------------------------------------------------------------------*/ +/* */ +/* class ifpstream */ +/* */ +/* Base class for reading streamable objects from file streams */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_ifpstream ) && !defined( __ifpstream ) +#define __ifpstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class ifpstream : public fpbase, public ipstream +{ + +public: + + _Cdecl ifpstream() noexcept; + _Cdecl ifpstream( const char _FAR *, + pstream::openmode = ios::in + ); + _Cdecl ~ifpstream(); + + filebuf _FAR * _Cdecl rdbuf() noexcept; + void _Cdecl open( const char _FAR *, + pstream::openmode = ios::in + ); + +}; + +#endif // Uses_ifpstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class ofpstream */ +/* */ +/* Base class for writing streamable objects to file streams */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_ofpstream ) && !defined( __ofpstream ) +#define __ofpstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + + +class ofpstream : public fpbase, public opstream +{ + +public: + + _Cdecl ofpstream() noexcept; + _Cdecl ofpstream( const char _FAR *, + pstream::openmode = ios::out + ); + _Cdecl ~ofpstream(); + + filebuf _FAR * _Cdecl rdbuf() noexcept; + void _Cdecl open( const char _FAR *, + pstream::openmode = ios::out + ); + +}; + +#endif // Uses_ofpstream + +/* ------------------------------------------------------------------------*/ +/* */ +/* class fpstream */ +/* */ +/* Base class for reading and writing streamable objects to */ +/* bidirectional file streams */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_fpstream ) && !defined( __fpstream ) +#define __fpstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +class fpstream : public fpbase, public iopstream +{ + +public: + + _Cdecl fpstream() noexcept; + _Cdecl fpstream( const char _FAR *, pstream::openmode); + _Cdecl ~fpstream(); + + filebuf _FAR * _Cdecl rdbuf() noexcept; + void _Cdecl open( const char _FAR *, pstream::openmode); + +}; + + +#endif // Uses_fpstream + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/tspan.h b/src/include/tvision/tspan.h new file mode 100644 index 00000000..b25d5980 --- /dev/null +++ b/src/include/tvision/tspan.h @@ -0,0 +1,125 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TSPAN.H */ +/* */ +/* Defines the class TSpan and its member functions. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#ifndef TVISION_TSPAN_H +#define TVISION_TSPAN_H + +template +class TSpan { + + // This is actually a generalization of TStringView for any kind of element + // type (and without enforcing the 'const' qualifier). + // It exists for compatibility with Borland C++ and because std::span (C++ 20) + // may not be widely available yet. + + T _FAR *ptr; + size_t len; + +public: + + // These are defined inline because otherwise they trigger + // a bug in Borland C++ when T is const. + + constexpr TSpan() : + ptr(0), + len(0) + { + } + + constexpr TSpan(T _FAR *first, size_t n) : + ptr(first), + len(n) + { + } + +#ifndef __BORLANDC__ + constexpr TSpan(decltype(nullptr)) : + TSpan() + { + } + + template + constexpr TSpan(T (&array)[N]) : + TSpan(array, N) + { + } +#endif + + constexpr operator TSpan() const + { + return TSpan(ptr, len); + } + + constexpr T _FAR * data() const + { + return ptr; + } + + constexpr size_t size() const + { + return len; + } + + constexpr size_t size_bytes() const + { + return size()*sizeof(T); + } + + constexpr Boolean empty() const + { + return Boolean( size() == 0 ); + } + + constexpr T _FAR & operator[](size_t pos) const + { + return ptr[pos]; + } + + constexpr T _FAR & front() const + { + return ptr[0]; + } + + constexpr T _FAR & back() const + { + return ptr[len - 1]; + } + + constexpr TSpan subspan(size_t pos) const + { + return TSpan(ptr + pos, len - pos); + } + + constexpr TSpan subspan(size_t pos, size_t n) const + { + return TSpan(ptr + pos, n <= len - pos ? n : len - pos); + } + + constexpr T _FAR * begin() const + { + return &ptr[0]; + } + + constexpr const T _FAR * cbegin() const + { + return &ptr[0]; + } + + constexpr T _FAR * end() const + { + return &ptr[len]; + } + + constexpr const T _FAR * cend() const + { + return &ptr[len]; + } + +}; + +#endif // TVISION_TSPAN_H diff --git a/src/include/tvision/tstrview.h b/src/include/tvision/tstrview.h new file mode 100644 index 00000000..5dc9a0a4 --- /dev/null +++ b/src/include/tvision/tstrview.h @@ -0,0 +1,248 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TSTRVIEW.H */ +/* */ +/* Defines the class TStringView and its member functions. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#ifndef TVISION_TSTRVIEW_H +#define TVISION_TSTRVIEW_H + +#include +#include + +#ifdef TVISION_STL +#include + +#if __cplusplus >= 201703L || __cpp_lib_string_view +#include +#endif +#endif // TVISION_STL + +class TStringView +{ + + // This class exists only to compensate for the lack of std::string_view + // in Borland C++. Unless you are programming for that compiler, you should + // always use std::string_view. + // Unlike std::string_view, TStringView can be constructed from a null pointer, + // for backward compatibility. + // TStringView is intercompatible with std::string_view, std::string and + // TSpan. + + const char _FAR *str; + size_t len; + +public: + + constexpr TStringView(); +#if defined(TVISION_STL) && (__cplusplus >= 201703L || __cpp_lib_constexpr_char_traits) + constexpr +#endif + TStringView(const char _FAR *str); + constexpr TStringView(const char _FAR *str, size_t len); + constexpr TStringView(TSpan span); + constexpr TStringView(TSpan span); +#ifdef TVISION_STL +#if __cplusplus >= 201703L || __cpp_lib_string_view + constexpr TStringView(std::string_view text); + constexpr operator std::string_view() const; +#endif + TStringView(const std::string &text); + operator std::string() const; +#endif // TVISION_STL + constexpr operator TSpan() const; + + constexpr const char _FAR * data() const; + constexpr size_t size() const; + constexpr Boolean empty() const; + constexpr const char _FAR & operator[](size_t pos) const; + constexpr const char _FAR & front() const; + constexpr const char _FAR & back() const; + + constexpr TStringView substr(size_t pos) const; + constexpr TStringView substr(size_t pos, size_t n) const; + + constexpr const char _FAR * begin() const; + constexpr const char _FAR * cbegin() const; + constexpr const char _FAR * end() const; + constexpr const char _FAR * cend() const; + +}; + +inline constexpr TStringView::TStringView() : + str(0), + len(0) +{ +} + +#if defined(TVISION_STL) && (__cplusplus >= 201703L || __cpp_lib_constexpr_char_traits) +constexpr +inline TStringView::TStringView(const char _FAR *str) : + str(str), + len(str ? std::char_traits::length(str) : 0) +{ +} +#else +inline TStringView::TStringView(const char _FAR *str) : + str(str), + len(str ? strlen(str) : 0) +{ +} +#endif + +inline constexpr TStringView::TStringView(const char _FAR *str, size_t len) : + str(str), + len(len) +{ +} + +inline constexpr TStringView::TStringView(TSpan span) : + str(span.data()), + len(span.size()) +{ +} + +inline constexpr TStringView::TStringView(TSpan span) : + str(span.data()), + len(span.size()) +{ +} + +#ifdef TVISION_STL +#if __cplusplus >= 201703L || __cpp_lib_string_view +inline constexpr TStringView::TStringView(std::string_view text) : + str(text.data()), + len(text.size()) +{ +} + +inline constexpr TStringView::operator std::string_view() const +{ + return {str, len}; +} +#endif + +inline TStringView::TStringView(const std::string &text) : + str(text.data()), + len(text.size()) +{ +} + +inline TStringView::operator std::string() const +{ + return {str, len}; +} +#endif // TVISION_STL + +inline constexpr TStringView::operator TSpan() const +{ + return TSpan(str, len); +} + +inline constexpr const char _FAR * TStringView::data() const +{ + return str; +} + +inline constexpr size_t TStringView::size() const +{ + return len; +} + +inline constexpr Boolean TStringView::empty() const +{ + return Boolean( size() == 0 ); +} + +inline constexpr const char _FAR & TStringView::operator[](size_t pos) const +{ + return str[pos]; +} + +inline constexpr const char _FAR & TStringView::front() const +{ + return str[0]; +} + +inline constexpr const char _FAR & TStringView::back() const +{ + return str[len - 1]; +} + +inline constexpr TStringView TStringView::substr(size_t pos) const +{ + return TStringView(str + pos, len - pos); +} + +inline constexpr TStringView TStringView::substr(size_t pos, size_t n) const +{ + return TStringView(str + pos, n <= len - pos ? n : len - pos); +} + +inline constexpr const char _FAR * TStringView::begin() const +{ + return &str[0]; +} + +inline constexpr const char _FAR * TStringView::cbegin() const +{ + return &str[0]; +} + +inline constexpr const char _FAR * TStringView::end() const +{ + return &str[len]; +} + +inline constexpr const char _FAR * TStringView::cend() const +{ + return &str[len]; +} + +#if defined(TVISION_STL) && (__cplusplus >= 201703L || __cpp_lib_constexpr_char_traits) +inline constexpr Boolean operator==(TStringView a, TStringView b) +{ + return a.size() == b.size() + ? std::char_traits::compare(a.data(), b.data(), b.size()) == 0 + : False; +} +#else +inline Boolean operator==(TStringView a, TStringView b) +{ + if (a.size() == b.size()) + return Boolean( memcmp(a.data(), b.data(), b.size()) == 0 ); + return False; +} +#endif + +#if defined(TVISION_STL) && (__cplusplus >= 201703L || __cpp_lib_constexpr_char_traits) +constexpr +#endif +inline Boolean operator!=(TStringView a, TStringView b) +{ + return Boolean( !(a == b) ); +} + +#if defined(TVISION_STL) && __cplusplus >= 201103L + +#include + +namespace std { +#if __cplusplus >= 201703L || __cpp_lib_string_view + template<> + struct hash : public std::hash + { + }; +#else + template<> + struct hash : public std::hash + { + }; +#endif +} // namespace std + +#endif // TVISION_STL && __cplusplus >= 201103L + +#endif // TVISION_TSTRVIEW_H diff --git a/src/include/tvision/ttext.h b/src/include/tvision/ttext.h new file mode 100644 index 00000000..938460b5 --- /dev/null +++ b/src/include/tvision/ttext.h @@ -0,0 +1,490 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TTEXT.H */ +/* */ +/* Defines functions related to multibyte string manipulation. */ +/* */ +/* ------------------------------------------------------------------------*/ + +#if defined( Uses_TText ) && !defined( __TText ) +#define __TText + +struct TTextMetrics +{ + uint width; + uint characterCount; + uint graphemeCount; // Number of non-combining characters. +}; + +class TText +{ +public: + + // Returns the width of 'text'. + static size_t width(TStringView text) noexcept; + + // Returns the width, the character count and the grapheme count of 'text'. + static TTextMetrics measure(TStringView text) noexcept; + + // Returns the length in bytes of the first character in 'text'. + static size_t next(TStringView text) noexcept; + + // Increases 'index' by the length in bytes of the character starting at + // position 'index' of 'text'. + // (variant 2): Increases 'width' by the width of the character. + // Returns whether 'index' was increased at all. + static Boolean next(TStringView text, size_t &index) noexcept; + static Boolean next(TStringView text, size_t &index, size_t &width) noexcept; + + // Returns the length in bytes of the character in 'text' right before + // position 'index'. + static size_t prev(TStringView text, size_t index) noexcept; + + // Converts the first character in 'text' to the current code page. + // If there is no possible converion or 'text' is empty, returns '\0'. + static char toCodePage(TStringView text) noexcept; + + // Returns the length in bytes of a leading substring of 'text' which is + // 'count' columns wide. If 'text' is less than 'count' columns wide, + // returns 'text.size()'. Negative values of 'count' are treated as 0. + // (variant 2): the length and width of the substring are returned via the + // output parameters 'length' and 'width', + // When column 'count' is in the middle of a double-width character in 'text', + // 'includeIncomplete' determines whether the double-width character must + // be included in the result. + static size_t scroll(TStringView text, int count, Boolean includeIncomplete) noexcept; + static void scroll( TStringView text, int count, Boolean includeIncomplete, + size_t &length, size_t &width ) noexcept; + + // Fills 'cells' with the character 'c'. + // (variant 2): also sets the color attribute to 'attr'. + static void drawChar(TSpan cells, char c) noexcept; + static void drawChar(TSpan cells, char c, TColorAttr attr) noexcept; + + // Copies text from 'text' into 'cells', starting at position 'indent' of + // 'cells' and at column 'textIndent' of 'text'. Returns the number of cells + // that were filled with text. + // (variants 2, 4): also sets the color attribute to 'attr'. + // (variants 3, 4): uses 'indent = 0' and 'textIndent = 0'. + // When column 'textIndent' of 'text' is in the middle of a double-width + // character, a whitespace is copied in its place. + static size_t drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent ) noexcept; + static size_t drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent, + TColorAttr attr ) noexcept; + static size_t drawStr(TSpan cells, TStringView text) noexcept; + static size_t drawStr(TSpan cells, TStringView text, TColorAttr attr) noexcept; + + // Reads a single character from a multibyte-encoded string, and writes it into + // a screen cell. + // + // * cells: range of TScreenCells to write to. + // * i (input/output parameter): index into 'cells'. Gets increased by + // the number of cells that have been updated. + // * text: input text. + // * j (input/output parameter): index into 'text'. Gets increased by + // the number of bytes read from 'text'. + // * (variant 2) attr: color attribute to set in the cell. + // + // Returns false when 'i >= cells.size() && j >= text.size()'. + // A screen cell may contain one printable character (of width 1 or more) + // and several combining characters appended to it (of width 0). + // When a zero-width character is found in 'text', it is combined with the + // previous cell, i.e. cells[i - 1], if 'i > 0'. In this case, 'i' is not + // increased and the color attribute is not set. + static Boolean drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j ) noexcept; + static Boolean drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j, + TColorAttr attr ) noexcept; + +#ifndef __BORLANDC__ + // Variants of the functions above which use a '(TColorAttr &) -> void' + // callback to change the color attribute of each cell (rather than + // setting it to a fixed value). + template + static void drawCharEx(TSpan cells, char c, Func &&transformAttr) noexcept; + template + static size_t drawStrEx( TSpan cells, size_t indent, + TStringView text, int textIndent, + Func &&transformAttr ) noexcept; + + // UTF-32 variants of some of the functions above. + static Boolean next(TSpan text, size_t &index, size_t &width) noexcept; + static void scroll( TSpan text, int count, Boolean includeIncomplete, + size_t &length, size_t &width ) noexcept; + static size_t drawStr( TSpan cells, size_t indent, + TSpan text, int textIndent ) noexcept; + static size_t drawStr( TSpan cells, size_t indent, + TSpan text, int textIndent, + TColorAttr attr ) noexcept; + template + static size_t drawStrEx( TSpan cells, size_t indent, + TSpan text, int textIndent, + Func &&transformAttr ) noexcept; + static Boolean drawOne( TSpan cells, size_t &i, + TSpan text, size_t &j ) noexcept; + static Boolean drawOne( TSpan cells, size_t &i, + TSpan text, size_t &j, + TColorAttr ) noexcept; +private: + + struct Lw { size_t length, width; }; + static Lw nextImpl(TStringView) noexcept; + static Lw nextImpl(TSpan) noexcept; + static Lw scrollImpl(TStringView, int, Boolean) noexcept; + static Lw scrollImpl(TSpan, int, Boolean) noexcept; + static Lw drawOneImpl(TSpan, size_t, TStringView, size_t) noexcept; + static Lw drawOneImpl(TSpan, size_t, TSpan, size_t) noexcept; + + template + static Lw scrollImplT(Text text, int, Boolean) noexcept; + template + static size_t drawStrExT(TSpan, size_t, Text, int, Func &&) noexcept; + template + static Boolean drawOneT(TSpan, size_t &i, Text, size_t &, Func &&) noexcept; +#endif // __BORLANDC__ +}; + +#ifdef __BORLANDC__ + +inline size_t TText::width(TStringView text) +{ + return text.size(); +} + +#pragma warn -inl + +inline TTextMetrics TText::measure(TStringView text) +{ + TTextMetrics metrics = {text.size(), text.size(), text.size()}; + return metrics; +} + +#pragma warn .inl + +inline size_t TText::next(TStringView text) +{ + return text.size() ? 1 : 0; +} + +inline Boolean TText::next(TStringView text, size_t &index) +{ + if (index < text.size()) + return ++index, True; + return False; +} + +inline Boolean TText::next(TStringView text, size_t &index, size_t &width) +{ + if (index < text.size()) + return ++index, ++width, True; + return False; +} + +inline size_t TText::prev(TStringView text, size_t index) +{ + return 0 < index && index <= text.size(); +} + +inline char TText::toCodePage(TStringView text) +{ + if (text.empty()) + return '\0'; + return text[0]; +} + +inline size_t TText::scroll(TStringView text, int count, Boolean) +{ + return count > 0 ? min(count, text.size()) : 0; +} + +inline void TText::scroll( TStringView text, int count, Boolean, + size_t &length, size_t &width ) +{ + length = width = (size_t) scroll(text, count, False); +} + +#pragma warn -inl + +inline void TText::drawChar(TSpan cells, char c) +{ + for (size_t i = 0; i < cells.size(); ++i) + ::setChar(cells[i], c); +} + +inline void TText::drawChar(TSpan cells, char c, TColorAttr attr) +{ + for (size_t i = 0; i < cells.size(); ++i) + { + ::setChar(cells[i], c); + ::setAttr(cells[i], attr); + } +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent ) +{ + if (indent < cells.size() && textIndent < text.size()) + { + cells = cells.subspan(indent); + text = text.substr(textIndent); + size_t count = min(cells.size(), text.size()); + for (size_t i = 0; i < count; ++i) + ::setChar(cells[i], text[i]); + return count; + } + return 0; +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent, + TColorAttr attr ) +{ + if (indent < cells.size() && textIndent < text.size()) + { + cells = cells.subspan(indent); + text = text.substr(textIndent); + size_t count = min(cells.size(), text.size()); + for (size_t i = 0; i < count; ++i) + ::setCell(cells[i], text[i], attr); + return count; + } + return 0; +} + +#pragma warn .inl + +inline size_t TText::drawStr(TSpan cells, TStringView text) +{ + return drawStr(cells, 0, text, 0); +} + +inline size_t TText::drawStr( TSpan cells, TStringView text, + TColorAttr attr ) +{ + return drawStr(cells, 0, text, 0, attr); +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j ) +{ + if (i < cells.size() && j < text.size()) + { + ::setChar(cells[i++], text[j++]); + return True; + } + return False; +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j, + TColorAttr attr ) +{ + if (i < cells.size() && j < text.size()) + { + ::setCell(cells[i++], text[j++], attr); + return True; + } + return False; +} + +#else + +inline Boolean TText::next(TStringView text, size_t &index) noexcept +{ + size_t len = TText::next(text.substr(index)); + index += len; + return len != 0; +} + +inline Boolean TText::next(TStringView text, size_t &index, size_t &width) noexcept +{ + auto result = TText::nextImpl(text.substr(index)); + index += result.length; + width += result.width; + return result.length != 0; +} + +inline Boolean TText::next(TSpan text, size_t &index, size_t &width) noexcept +{ + auto result = TText::nextImpl(text.subspan(index)); + index += result.length; + width += result.width; + return result.length != 0; +} + +inline size_t TText::scroll(TStringView text, int count, Boolean includeIncomplete) noexcept + +{ + size_t length = 0, width = 0; + scroll(text, count, includeIncomplete, length, width); + return length; +} + +inline void TText::scroll( TStringView text, int count, Boolean includeIncomplete, + size_t &length, size_t &width ) noexcept + +{ + auto result = scrollImpl(text, count, includeIncomplete); + length = result.length; + width = result.width; +} + +inline void TText::scroll( TSpan text, int count, Boolean includeIncomplete, + size_t &length, size_t &width ) noexcept + +{ + auto result = scrollImpl(text, count, includeIncomplete); + length = result.length; + width = result.width; +} + +inline void TText::drawChar(TSpan cells, char c) noexcept +{ + drawCharEx(cells, c, [] (auto &) {}); +} + +inline void TText::drawChar(TSpan cells, char c, TColorAttr attr) noexcept +{ + TScreenCell aCell; + ::setCell(aCell, c, attr); + for (auto &cell : cells) + cell = aCell; +} + +template +inline void TText::drawCharEx(TSpan cells, char ch, Func &&transformAttr) noexcept +{ + for (auto &c : cells) + { + ::setChar(c, ch); + transformAttr(c.attr); + } +} + +inline size_t TText::drawStr(TSpan cells, TStringView text) noexcept +{ + return drawStr(cells, 0, text, 0); +} + +inline size_t TText::drawStr( TSpan cells, TStringView text, + TColorAttr attr ) noexcept +{ + return drawStr(cells, 0, text, 0, attr); +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent ) noexcept +{ + return drawStrEx(cells, indent, text, textIndent, [] (auto &) {}); +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TSpan text, int textIndent ) noexcept +{ + return drawStrEx(cells, indent, text, textIndent, [] (auto &) {}); +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TStringView text, int textIndent, + TColorAttr aAttr ) noexcept +{ + return drawStrEx(cells, indent, text, textIndent, [&] (auto &attr) { + attr = aAttr; + }); +} + +inline size_t TText::drawStr( TSpan cells, size_t indent, + TSpan text, int textIndent, + TColorAttr aAttr ) noexcept +{ + return drawStrEx(cells, indent, text, textIndent, [&] (auto &attr) { + attr = aAttr; + }); +} + +template +inline size_t TText::drawStrEx( TSpan cells, size_t indent, + TStringView text, int textIndent, + Func &&transformAttr ) noexcept +{ + return drawStrExT(cells, indent, text, textIndent, (Func &&) transformAttr); +} + +template +inline size_t TText::drawStrEx( TSpan cells, size_t indent, + TSpan text, int textIndent, + Func &&transformAttr ) noexcept +{ + return drawStrExT(cells, indent, text, textIndent, (Func &&) transformAttr); +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j ) noexcept +{ + return drawOneT(cells, i, text, j, [] (auto &) {}); +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TSpan text, size_t &j ) noexcept +{ + return drawOneT(cells, i, text, j, [] (auto &) {}); +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TStringView text, size_t &j, + TColorAttr aAttr ) noexcept +{ + return drawOneT(cells, i, text, j, [&] (auto &attr) { + attr = aAttr; + }); +} + +inline Boolean TText::drawOne( TSpan cells, size_t &i, + TSpan text, size_t &j, + TColorAttr aAttr ) noexcept +{ + return drawOneT(cells, i, text, j, [&] (auto &attr) { + attr = aAttr; + }); +} + +template +inline size_t TText::drawStrExT( TSpan cells, size_t indent, + Text text, int textIndent, + Func &&transformAttr ) noexcept +{ + size_t i = indent, j = 0; + if (textIndent > 0) + { + size_t leadWidth; + TText::scroll(text, textIndent, True, j, leadWidth); + if (leadWidth > (size_t) textIndent && i < cells.size()) + { + ::setChar(cells[i], ' '); + transformAttr(cells[i++].attr); + } + } + while (TText::drawOneT(cells, i, text, j, (Func &&) transformAttr)); + return i - indent; +} + +template +inline Boolean TText::drawOneT( TSpan cells, size_t &i, + Text text, size_t &j, Func &&transformAttr ) noexcept +{ + auto result = drawOneImpl(cells, i, text, j); + if (result.width) + transformAttr(cells[i].attr); + if (result.width > 1) + transformAttr(cells[i + 1].attr); + i += result.width; + j += result.length; + return result.length != 0; +} + +#endif // __BORLANDC__ + +#endif // Uses_TText diff --git a/src/include/tvision/ttypes.h b/src/include/tvision/ttypes.h new file mode 100644 index 00000000..cdb85f91 --- /dev/null +++ b/src/include/tvision/ttypes.h @@ -0,0 +1,177 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TTYPES.H */ +/* */ +/* provides miscellaneous types used throughout Turbo Vision */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __TTYPES_H ) +#define __TTYPES_H + +#if !defined(_NEAR) +#define _NEAR near +#endif + +#include + +#ifdef __BORLANDC__ +#define I asm +#endif + + +#ifdef __BORLANDC__ +enum Boolean { False, True }; +#else +typedef bool Boolean; +enum { False, True }; +#endif + +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; + +#include + +#ifndef __BORLANDC__ +#include +#else +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef uchar uint8_t; +typedef ushort uint16_t; +typedef ulong uint32_t; +#endif + +#ifdef __BORLANDC__ +typedef ushort TScreenCell; +typedef uchar TCellChar; +typedef uchar TColorDesired; +typedef uchar TColorAttr; +typedef ushort TAttrPair; +#else +struct TScreenCell; +struct TCellChar; +struct TColorDesired; +struct TColorAttr; +struct TAttrPair; +#endif + +const char EOS = '\0'; + +enum StreamableInit { streamableInit }; + +class _FAR ipstream; +class _FAR opstream; +class _FAR TStreamable; +class _FAR TStreamableTypes; + +ipstream& _Cdecl operator >> ( ipstream&, char& ); +ipstream& _Cdecl operator >> ( ipstream&, signed char& ); +ipstream& _Cdecl operator >> ( ipstream&, unsigned char& ); +ipstream& _Cdecl operator >> ( ipstream&, signed short& ); +ipstream& _Cdecl operator >> ( ipstream&, unsigned short& ); +ipstream& _Cdecl operator >> ( ipstream&, signed int& ); +ipstream& _Cdecl operator >> ( ipstream&, unsigned int& ); +ipstream& _Cdecl operator >> ( ipstream&, signed long& ); +ipstream& _Cdecl operator >> ( ipstream&, unsigned long& ); +ipstream& _Cdecl operator >> ( ipstream&, float& ); +ipstream& _Cdecl operator >> ( ipstream&, double& ); +ipstream& _Cdecl operator >> ( ipstream&, long double& ); +ipstream& _Cdecl operator >> ( ipstream&, TStreamable& ); +ipstream& _Cdecl operator >> ( ipstream&, void _FAR *& ); + +opstream& _Cdecl operator << ( opstream&, char ); +opstream& _Cdecl operator << ( opstream&, signed char ); +opstream& _Cdecl operator << ( opstream&, unsigned char ); +opstream& _Cdecl operator << ( opstream&, signed short ); +opstream& _Cdecl operator << ( opstream&, unsigned short ); +opstream& _Cdecl operator << ( opstream&, signed int ); +opstream& _Cdecl operator << ( opstream&, unsigned int ); +opstream& _Cdecl operator << ( opstream&, signed long ); +opstream& _Cdecl operator << ( opstream&, unsigned long ); +opstream& _Cdecl operator << ( opstream&, float ); +opstream& _Cdecl operator << ( opstream&, double ); +opstream& _Cdecl operator << ( opstream&, long double ); +opstream& _Cdecl operator << ( opstream&, TStreamable& ); +opstream& _Cdecl operator << ( opstream&, TStreamable _FAR * ); + +#include +class TStringView; +ostream _FAR & _Cdecl operator<<(ostream _FAR &, TStringView); + +typedef void _FAR *TTimerId; + +typedef int ccIndex; +typedef Boolean (*ccTestFunc)( void *, void * ); +typedef void (*ccAppFunc)( void *, void * ); + +const int ccNotFound = -1; + +extern const uchar specialChars[]; + +#if !defined ( __FLAT__ ) +#define _genInt(i) __int__(i) +#endif + +// Reserve future keywords +#if __cplusplus < 201103L +#define constexpr +#define noexcept +#define thread_local +#endif + +// Do not include unnecessary STL headers if TVISION_NO_STL is defined. +// This speeds up compilation when building the library. +#if !defined( __BORLANDC__ ) && !defined( TVISION_NO_STL ) +#define TVISION_STL +#endif + +// In types with user-defined constructors, the default assignment operator +// creates a temporary object. If the type is large enough, the compiler +// may not be able to optimize out the temporary object. This has been observed +// with GCC, Clang, MSVC. +// +// To work around this in performance-critical types, we define a template +// assignment operator which just invokes the type constructor with the +// assigned object, so that the initialization is done in-place instead of in a +// temporary location. +// +// In order to use placement new, 'operator new(size_t, void*)' has to be defined. +// Usually this would be accomplished by including the header, but due to +// compilation performance it is more convenient to define a class-overloaded +// operator new. We also define operator delete to avoid a warning in some compilers. +// +// This macro is intended to be used in the definition of types with trivial +// destructors, so there is no need to invoke the destructor before placement +// new nor guard against self-assignment. +// +// This solution is incompatible with non-template assignment operators, +// because of the following: +// +// "Note that, if a non-template assignment operator from some non-class +// type is available, it is preferred over the copy/move assignment in +// 'E1 = {}' because '{}' to non-class is an identity conversion, which +// outranks the user-defined conversion from '{}' to a class type." +// (From https://en.cppreference.com/w/cpp/language/operator_assignment). +// +// This means that if we define a custom 'T& operator=(int)', the assignment +// 't = {}' will be equivalent to 't = 0' instead of 't = T()'. This would +// break the programmer's expectations completely. +#define TV_TRIVIALLY_ASSIGNABLE(S) \ + void* operator new(size_t, void *p) noexcept { return p; } \ + void operator delete(void *, void *) noexcept {}; \ + template \ + S& operator=(const T &t) { return *new (this) S(t); } + + +#endif // __TTYPES_H diff --git a/src/include/tvision/tv.h b/src/include/tvision/tv.h new file mode 100644 index 00000000..2e420146 --- /dev/null +++ b/src/include/tvision/tv.h @@ -0,0 +1,778 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TV.H */ +/* */ +/* includes other header files based on which Uses_XXXX symbols are */ +/* defined. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __BORLANDC__ ) +#define __FLAT__ + +#if !defined( _WIN32 ) +#define __cdecl +#define __stdcall +#define _TV_UNIX +#endif + +#endif + +#if defined( __FLAT__ ) +#define _NEAR +#define _FAR +#else +#define _NEAR near +#endif + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif +#if defined( _MSC_VER ) +#pragma warning(push) +#pragma warning(disable: 4250) +#endif +#if defined( __clang__ ) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-virtual" +#endif + +#if !defined( __FLAT__ ) +#if !defined ( __LARGE__ ) +#error TV needs the large memory model +#endif +#endif + +#if defined( _RTLDLL ) +#error TV must use the RTL in static form only +#endif + +#define _TV_VERSION 0x0200 + +#define Uses_EventCodes +#define Uses_ViewCommands +#define __INC_TKEYS_H +#define __INC_STDDLG_H + +#if defined( Uses_TApplication ) +#define Uses_TProgram +#define __INC_APP_H +#endif + +#if defined( Uses_TProgram ) +#define Uses_TEvent +#define Uses_TGroup +#define __INC_APP_H +#endif + +#if defined( Uses_TDeskTop ) +#define Uses_TGroup +#define __INC_APP_H +#endif + +#if defined( Uses_TBackground ) +#define Uses_TView +#define __INC_APP_H +#endif + +#if defined( Uses_TReplaceDialogRec ) +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TFindDialogRec ) +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TEditWindow ) +#define Uses_TWindow +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TFileEditor ) +#define Uses_TEditor +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TMemo ) +#define Uses_TEditor +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TEditor ) +#define Uses_TView +#define Uses_TPoint +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TIndicator ) +#define Uses_TView +#define Uses_TPoint +#define __INC_EDITORS_H +#endif + +#if defined( Uses_TTerminal ) +#define Uses_TTextDevice +#define __INC_TEXTVIEW_H +#endif + +#if defined( Uses_TOutline ) +#define Uses_TOutlineViewer +#endif + +#if defined( Uses_TOutlineViewer ) +#define Uses_TScroller +#define Uses_TScrollBar +#define __INC_OUTLINE_H +#endif + +#if defined( Uses_TSurfaceView ) +#define Uses_TView +#define Uses_TDrawSurface +#endif + +#if defined( Uses_TDrawSurface ) +#define Uses_TScreenCell +#define Uses_TPoint +#define __INC_SURFACE_H +#endif + +#if defined( Uses_TTextDevice ) +#define Uses_TScroller +#define __INC_TEXTVIEW_H +#endif + +#if defined( Uses_TStatusLine ) +#define Uses_TView +#define __INC_MENUS_H +#endif + +#if defined( Uses_TStatusDef ) +#define __INC_MENUS_H +#endif + +#if defined( Uses_TStatusItem ) +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenuPopup ) +#define Uses_TMenuBox +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenuBox ) +#define Uses_TMenuView +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenuBar ) +#define Uses_TMenuView +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenuView ) +#define Uses_TView +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenu ) +#define __INC_MENUS_H +#endif + +#if defined( Uses_TSubMenu ) +#define Uses_TMenuItem +#define __INC_MENUS_H +#endif + +#if defined( Uses_TMenuItem ) +#define __INC_MENUS_H +#endif + +#if defined( Uses_TColorDialog ) +#define Uses_TColorGroup +#define Uses_TDialog +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorItemList ) +#define Uses_TListViewer +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorGroupList ) +#define Uses_TListViewer +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorDisplay ) +#define Uses_TView +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TMonoSelector ) +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TMonoSelector ) +#define Uses_TCluster +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorSelector ) +#define Uses_TView +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorGroup ) +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TColorItem ) +#define __INC_COLORSEL_H +#endif + +#if defined( Uses_TChDirDialog ) +#define Uses_TDialog +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TDirListBox ) +#define Uses_TListBox +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TDirCollection ) +#define Uses_TCollection +#define Uses_TDirEntry +#define __INC_STDDLG_H +#endif + +#if defined ( Uses_TRangeValidator ) +#define Uses_TFilterValidator +#endif + +#if defined ( Uses_TFilterValidator ) +#define Uses_TValidator +#endif + +#if defined ( Uses_TStringLookupValidator ) +#define Uses_TLookupValidator +#define Uses_TStringCollection +#endif + +#if defined ( Uses_TLookupValidator ) +#define Uses_TValidator +#endif + +#if defined ( Uses_TPXPictureValidator ) +#define Uses_TValidator +#endif + +#if defined ( Uses_TValidator ) +#define Uses_TObject +#define Uses_TStreamable +#define __INC_VALIDATOR_H +#endif + +#if defined( Uses_TDirEntry ) +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TFileDialog ) +#define Uses_TDialog +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TFileInfoPane ) +#define Uses_TView +#define Uses_TSearchRec +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TFileList ) +#define Uses_TSortedListBox +#define Uses_TFileCollection +#define Uses_TSearchRec +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TSortedListBox ) +#define Uses_TListBox +#define Uses_TSortedCollection +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TFileCollection ) +#define Uses_TSortedCollection +#define Uses_TSearchRec +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TFileInputLine ) +#define Uses_TInputLine +#define __INC_STDDLG_H +#endif + +#if defined( Uses_TSearchRec ) +#define __INC_STDDLG_H +#endif + +#if defined( Uses_THistory ) +#define Uses_TView +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_THistoryWindow ) +#define Uses_TWindow +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_THistoryViewer ) +#define Uses_TListViewer +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TLabel ) +#define Uses_TStaticText +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TParamText ) +#define Uses_TStaticText +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TStaticText ) +#define Uses_TView +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TListBox ) +#define Uses_TListViewer +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TCheckBoxes ) +#define Uses_TCluster +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TMultiCheckBoxes ) +#define Uses_TCluster +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TRadioButtons ) +#define Uses_TCluster +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TCluster ) +#define Uses_TView +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TSItem ) +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TButton ) +#define Uses_TView +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TInputLine ) +#define Uses_TView +#define Uses_TValidator +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TDialog ) +#define Uses_TWindow +#define __INC_DIALOGS_H +#endif + +#if defined( Uses_TVMemMgr ) +#define __INC_BUFFERS_H +#endif + +#if defined( Uses_TWindow ) +#define Uses_TGroup +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TGroup ) +#define Uses_TView +#define Uses_TRect +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TListViewer ) +#define Uses_TView +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TScroller ) +#define Uses_TView +#define Uses_TPoint +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TScrollBar ) +#define Uses_TView +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TFrame ) +#define Uses_TView +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TView ) +#define Uses_TObject +#define Uses_TStreamable +#define Uses_TCommandSet +#define Uses_TPoint +#define Uses_TDrawBuffer +#define Uses_TPalette +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TPalette ) +#define Uses_TColorAttr +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TCommandSet ) +#define __INC_VIEWS_H +#endif + +#if defined( Uses_ViewCommands ) +#define __INC_VIEWS_H +#endif + +#if defined( Uses_TStrListMaker ) +#define Uses_TObject +#define Uses_TStreamable +#define Uses_TStrIndexRec +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TStringList ) +#define Uses_TObject +#define Uses_TStreamable +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TStrIndexRec ) +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TResourceFile ) +#define Uses_TObject +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TResourceItem ) +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TResourceCollection ) +#define Uses_TStringCollection +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_TStringCollection ) +#define Uses_TSortedCollection +#define __INC_RESOURCE_H +#endif + +#if defined( Uses_MsgBox ) +#define __INC_MSGBOX_H +#endif + +#if defined( Uses_TSystemError ) +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TScreen ) +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TClipboard ) +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TTimerQueue ) +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TEventQueue ) +#define Uses_TEvent +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TEvent ) +#define Uses_TPoint +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_THardwareInfo ) +#define Uses_TScreenCell +#define __INC_HARDWARE_H +#endif + +#if defined( Uses_EventCodes ) +#define __INC_SYSTEM_H +#endif + +#if defined( Uses_TSortedCollection ) +#define Uses_TNSSortedCollection +#define Uses_TCollection +#define __INC_OBJECTS_H +#endif + +#if defined( Uses_TCollection ) +#define Uses_TNSCollection +#define Uses_TStreamable +#define __INC_OBJECTS_H +#endif + +#if defined( Uses_TRect ) +#define Uses_TPoint +#define __INC_OBJECTS_H +#endif + +#if defined( Uses_TPoint ) +#define __INC_OBJECTS_H +#endif + +#if defined( Uses_TDrawBuffer ) +#define Uses_TScreenCell +#define __INC_DRAWBUF_H +#endif + +#if defined( Uses_fpstream ) +#define Uses_fpbase +#define Uses_iopstream +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_ofpstream ) +#define Uses_fpbase +#define Uses_opstream +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_ifpstream ) +#define Uses_fpbase +#define Uses_ipstream +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_fpbase ) +#define Uses_pstream +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_iopstream ) +#define Uses_ipstream +#define Uses_opstream +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_opstream ) +#define Uses_pstream +#define Uses_TPWrittenObjects +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_ipstream ) +#define Uses_pstream +#define Uses_TPReadObjects +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_pstream ) +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TPReadObjects ) +#define Uses_TNSCollection +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TPWrittenObjects ) +#define Uses_TNSSortedCollection +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TStreamableTypes ) +#define Uses_TNSSortedCollection +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TStreamableClass ) +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TStreamable ) +#define __INC_TOBJSTRM_H +#endif + +#if defined( Uses_TNSSortedCollection ) +#define Uses_TNSCollection +#define __INC_TVOBJS_H +#endif + +#if defined( Uses_TNSCollection ) +#define Uses_TObject +#define __INC_TVOBJS_H +#endif + +#if defined( Uses_TObject ) +#define __INC_TVOBJS_H +#endif + +#if defined( Uses_TKeys ) +#define __INC_TKEYS_H +#endif + +#if defined( Uses_TText ) +#define Uses_TScreenCell +#define __INC_TTEXT_H +#endif + +#if defined( Uses_TScreenCell ) +#define Uses_TColorAttr +#define __INC_SCRNCELL_H +#endif + +#if defined( Uses_TColorAttr ) +#define __INC_COLORS_H +#endif + +#include +#include +#include + +#include +#include + +#if defined( __INC_COLORS_H ) +#include +#endif + +#if defined( __INC_SCRNCELL_H ) +#include +#endif + +#if defined( __INC_HARDWARE_H ) +#include +#endif + +#if defined( __INC_TKEYS_H ) +#include +#endif + +#if defined( __INC_TTEXT_H ) +#include +#endif + +#if defined( __INC_TVOBJS_H ) +#include +#endif + +#if defined( __INC_TOBJSTRM_H ) +#include +#endif + +#if defined( __INC_DRAWBUF_H ) +#include +#endif + +#if defined( __INC_OBJECTS_H ) +#include +#endif + +#if defined( __INC_SYSTEM_H ) +#include +#endif + +#if defined( __INC_MSGBOX_H ) +#include +#endif + +#if defined( __INC_RESOURCE_H ) +#include +#endif + +#if defined( __INC_VIEWS_H ) +#include +#endif + +#if defined( __INC_BUFFERS_H ) +#include +#endif + +#if defined( __INC_DIALOGS_H ) +#include +#endif + +#if defined( __INC_VALIDATOR_H ) +#include +#endif + +#if defined( __INC_STDDLG_H ) +#include +#endif + +#if defined( __INC_COLORSEL_H ) +#include +#endif + +#if defined( __INC_MENUS_H ) +#include +#endif + +#if defined( __INC_TEXTVIEW_H ) +#include +#endif + +#if defined( __INC_EDITORS_H ) +#include +#endif + +#if defined( __INC_OUTLINE_H ) +#include +#endif + +#if defined( __INC_SURFACE_H ) +#include +#endif + +#if defined( __INC_APP_H ) +#include +#endif + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif +#if defined( _MSC_VER ) +#pragma warning(pop) +#endif +#if defined( __clang__ ) +#pragma clang diagnostic pop +#endif diff --git a/src/include/tvision/tvobjs.h b/src/include/tvision/tvobjs.h new file mode 100644 index 00000000..0825a0df --- /dev/null +++ b/src/include/tvision/tvobjs.h @@ -0,0 +1,152 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* TVOBJS.H */ +/* */ +/* defines the classes TObject, TNSCollection, and TNSSortedCollection. */ +/* */ +/* The NS variants of collections are Not Streamable. These are */ +/* needed for internal use in the stream manager. There are */ +/* streamable variants of each of these classes for use by the */ +/* rest of the library. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if defined( Uses_TObject ) && !defined( __TObject ) +#define __TObject + +#if !defined( __STDDEF_H ) +#include +#endif // __STDDEF_H + +class TObject +{ + +public: + + virtual ~TObject() {} + + static void destroy( TObject * ); + virtual void shutDown(); + +private: + +}; + +inline void TObject::destroy( TObject *o ) +{ + if( o != 0 ) + o->shutDown(); + delete o; +} + +#endif // Uses_TObject + +#if defined( Uses_TNSCollection ) && !defined( __TNSCollection ) +#define __TNSCollection + +class TNSCollection : public TObject +{ + +public: + + TNSCollection( ccIndex aLimit, ccIndex aDelta ) noexcept; + ~TNSCollection(); + + virtual void shutDown(); + + void *at( ccIndex index ); + virtual ccIndex indexOf( void *item ); + + void atFree( ccIndex index ); + void atRemove( ccIndex index ); + void remove( void *item ); + void removeAll(); + void free( void *item ); + void freeAll(); + + void atInsert( ccIndex index, void *item ); + void atPut( ccIndex index, void *item ); + virtual ccIndex insert( void *item ); + + virtual void error( ccIndex code, ccIndex info ); + + void *firstThat( ccTestFunc Test, void *arg ); + void *lastThat( ccTestFunc Test, void *arg ); + void forEach( ccAppFunc action, void *arg ); + + void pack(); + virtual void setLimit( ccIndex aLimit ); + + ccIndex getCount() + { return count; } + +protected: + + TNSCollection() noexcept; + + void **items; + ccIndex count; + ccIndex limit; + ccIndex delta; + Boolean shouldDelete; + +private: + + virtual void freeItem( void *item ); + +}; + +#endif // Uses_TNSCollection + +#if defined( Uses_TNSSortedCollection ) && !defined( __TNSSortedCollection ) +#define __TNSSortedCollection + +class TNSSortedCollection: public virtual TNSCollection +{ + +public: + + TNSSortedCollection( ccIndex aLimit, ccIndex aDelta) noexcept : + TNSCollection( aLimit, aDelta ), duplicates(False) + { delta = aDelta; setLimit( aLimit ); } + + virtual Boolean search( void *key, ccIndex& index ); + + virtual ccIndex indexOf( void *item ); + virtual ccIndex insert( void *item ); + + Boolean duplicates; + virtual void *keyOf( void *item ); + +protected: + + TNSSortedCollection() noexcept : duplicates(False) {} + +private: + + virtual int compare( void *key1, void *key2 ) = 0; + +}; + +#endif // Uses_TNSSortedCollection + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/include/tvision/util.h b/src/include/tvision/util.h new file mode 100644 index 00000000..a738fffc --- /dev/null +++ b/src/include/tvision/util.h @@ -0,0 +1,105 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* UTIL.H */ +/* */ +/* defines various utility functions used throughout Turbo Vision */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if !defined( __UTIL_H ) +#define __UTIL_H + +#include + +inline constexpr int min( int a, int b ) +{ + return a < b ? a : b; +} + +inline constexpr int max( int a, int b ) +{ + return a > b ? a : b; +} + +#if !defined( __MINMAX_DEFINED ) // Also defined in Borland C++'s stdlib.h. +#define __MINMAX_DEFINED +template +inline constexpr const T& min( const T& a, const T& b ) +{ + return a < b ? a : b; +} + +template +inline constexpr const T& max( const T& a, const T& b ) +{ + return a > b ? a : b; +} +#endif // __MINMAX_DEFINED + +void fexpand( char *rpath ) noexcept; +void fexpand( char *rpath, const char *relativeTo ) noexcept; + +char hotKey( const char *s ) noexcept; +ushort ctrlToArrow( ushort ) noexcept; +char getAltChar( ushort keyCode ) noexcept; +ushort getAltCode( char ch ) noexcept; +char getCtrlChar(ushort) noexcept; +ushort getCtrlCode(uchar) noexcept; + +ushort historyCount( uchar id ) noexcept; +const char *historyStr( uchar id, int index ) noexcept; +void historyAdd( uchar id, TStringView ) noexcept; + +int cstrlen( TStringView ) noexcept; +int strwidth( TStringView ) noexcept; + +class _FAR TView; +void *message( TView *receiver, ushort what, ushort command, void *infoPtr ); + +class _FAR TPoint; +class _FAR TGroup; +class _FAR TMenu; +class _FAR TMenuItem; +ushort popupMenu(TPoint where, TMenuItem &aMenu, TGroup * = 0); + +Boolean lowMemory() noexcept; + +char *newStr( TStringView ) noexcept; + +Boolean driveValid( char drive ) noexcept; +Boolean isDir( const char *str ) noexcept; +Boolean pathValid( const char *path ) noexcept; +Boolean validFileName( const char *fileName ) noexcept; +void getCurDir( char *dir, char drive=-1 ) noexcept; +Boolean getHomeDir( char *drive, char *dir ) noexcept; +Boolean isWild( const char *f ) noexcept; + +size_t strnzcpy( char *dest, TStringView src, size_t n ) noexcept; +size_t strnzcat( char *dest, TStringView src, size_t n ) noexcept; + +void printKeyCode(ostream _FAR &, ushort keyCode); +void printControlKeyState(ostream _FAR &, ushort controlKeyState); +void printEventCode(ostream _FAR &, ushort eventCode); +void printMouseButtonState(ostream _FAR &, ushort buttonState); +void printMouseWheelState(ostream _FAR &, ushort wheelState); +void printMouseEventFlags(ostream _FAR &, ushort eventFlags); + +#if !defined( __BORLANDC__ ) && !defined( _WIN32 ) + +int stricmp( const char *s1, const char *s2 ) noexcept; +int strnicmp( const char *s1, const char *s2, size_t maxlen ) noexcept; +char *strupr(char *s) noexcept; +char *itoa( int value, char *buffer, int radix ) noexcept; +char *ltoa( long value, char *buffer, int radix ) noexcept; +char *ultoa( ulong value, char *buffer, int radix ) noexcept; + +#endif + +#endif // __UTIL_H diff --git a/src/include/tvision/validate.h b/src/include/tvision/validate.h new file mode 100644 index 00000000..6917e42d --- /dev/null +++ b/src/include/tvision/validate.h @@ -0,0 +1,303 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* VALIDATE.H */ +/* */ +/* defines the classes TValidator, TPXPictureValidator, TRangeValidator, */ +/* TFilterValidator, TLookupValidator, and TStringLookupValidator. */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined(Uses_TValidator) && !defined(__TValidator) +#define __TValidator + +// TValidator Status constants + +static const int + vsOk = 0, + vsSyntax = 1, // Error in the syntax of either a TPXPictureValidator + // or a TDBPictureValidator + +// Validator option flags + voFill = 0x0001, + voTransfer = 0x0002, + voReserved = 0x00FC; + +// TVTransfer constants + + +enum TVTransfer {vtDataSize, vtSetData, vtGetData}; + +// Abstract TValidator object + + +class TValidator : public TObject, public TStreamable +{ +public: + TValidator() noexcept; + virtual void error(); + virtual Boolean isValidInput(char* s, Boolean suppressFill); + virtual Boolean isValid(const char* s); + virtual ushort transfer(char *s, void* buffer, TVTransfer flag); + Boolean validate(const char* s); + + ushort status; + ushort options; + +protected: + TValidator( StreamableInit ) noexcept; + virtual void write( opstream& os ); + virtual void* read( ipstream& is ); + +private: + virtual const char *streamableName() const {return name;}; + +public: + static TStreamable *build(); + static const char * const _NEAR name; +}; + +#endif + + +#if defined(Uses_TPXPictureValidator) && !defined(__TPXPictureValidator) +#define __TPXPictureValidator + +// TPXPictureValidator result type + +enum TPicResult {prComplete, prIncomplete, prEmpty, prError, prSyntax, + prAmbiguous, prIncompNoFill}; + +// TPXPictureValidator + + +class TPXPictureValidator : public TValidator +{ + + static const char * _NEAR errorMsg; + +public: + TPXPictureValidator(TStringView aPic, Boolean autoFill); + ~TPXPictureValidator(); + virtual void error(); + virtual Boolean isValidInput(char* s, Boolean suppressFill); + virtual Boolean isValid(const char* s); + virtual TPicResult picture(char* input, Boolean autoFill); + + +protected: + TPXPictureValidator( StreamableInit ) noexcept; + virtual void write( opstream& os ); + virtual void* read( ipstream& is ); + + char* pic; + +private: + void consume(char ch, char* input); + void toGroupEnd(int& i, int termCh); + Boolean skipToComma(int termCh); + int calcTerm(int); + TPicResult iteration(char* input, int termCh); + TPicResult group(char* input, int termCh); + TPicResult checkComplete(TPicResult rslt, int termCh); + TPicResult scan(char* input, int termCh); + TPicResult process(char* input, int termCh); + Boolean syntaxCheck(); + virtual const char *streamableName() const {return name;}; + + int index, jndex; + +public: + static TStreamable *build(); + static const char * const _NEAR name; +}; + +inline ipstream& operator >> ( ipstream& is, TValidator& v ) + { return is >> (TStreamable&)v; } +inline ipstream& operator >> ( ipstream& is, TValidator*& v ) + { return is >> (void *&)v; } + +inline opstream& operator << ( opstream& os, TValidator& v ) + { return os << (TStreamable&)v; } +inline opstream& operator << ( opstream& os, TValidator* v ) + { return os << (TStreamable *)v; } + +#endif + + +#if defined(Uses_TFilterValidator) && !defined(__TFilterValidator) +#define __TFilterValidator + +// TFilterValidator + +class TFilterValidator : public TValidator +{ + + static const char * _NEAR errorMsg; + +public: + TFilterValidator(TStringView aValidChars) noexcept; + ~TFilterValidator(); + virtual void error(); + virtual Boolean isValidInput(char* s, Boolean suppressFill); + virtual Boolean isValid(const char* s); + +protected: + TFilterValidator( StreamableInit ) noexcept; + virtual void write( opstream& os); + virtual void* read( ipstream& is ); + + char* validChars; + +private: + virtual const char *streamableName() const {return name;}; + +public: + static TStreamable *build(); + static const char * const _NEAR name; +}; + +inline ipstream& operator >> ( ipstream& is, TFilterValidator& v ) + { return is >> (TStreamable&)v; } +inline ipstream& operator >> ( ipstream& is, TFilterValidator*& v ) + { return is >> (void *&)v; } + +inline opstream& operator << ( opstream& os, TFilterValidator& v ) + { return os << (TStreamable&)v; } +inline opstream& operator << ( opstream& os, TFilterValidator* v ) + { return os << (TStreamable *)v; } + +#endif + + +#if defined(Uses_TRangeValidator) && !defined(__TRangeValidator) +#define __TRangeValidator + +// TRangeValidator + + +class TRangeValidator : public TFilterValidator +{ + + static const char * _NEAR validUnsignedChars; + static const char * _NEAR validSignedChars; + static const char * _NEAR errorMsg; + +public: + TRangeValidator(int32_t aMin, int32_t aMax) noexcept; + virtual void error(); + virtual Boolean isValid(const char* s); + virtual ushort transfer(char* s, void* buffer, TVTransfer flag); + +protected: + int32_t min; + int32_t max; + + TRangeValidator( StreamableInit ) noexcept; + virtual void write( opstream& os ); + virtual void* read( ipstream& is ); + +private: + virtual const char *streamableName() const {return name;}; + +public: + static TStreamable *build(); + static const char * const _NEAR name; + +}; + +inline ipstream& operator >> ( ipstream& is, TRangeValidator& v ) + { return is >> (TStreamable&)v; } +inline ipstream& operator >> ( ipstream& is, TRangeValidator*& v ) + { return is >> (void *&)v; } + +inline opstream& operator << ( opstream& os, TRangeValidator& v ) + { return os << (TStreamable&)v; } +inline opstream& operator << ( opstream& os, TRangeValidator* v ) + { return os << (TStreamable *)v; } + +#endif + +#if defined(Uses_TLookupValidator) && !defined(__TLookupValidator) +#define __TLookupValidator + +// TLookupValidator + +class TLookupValidator : public TValidator +{ +public: + TLookupValidator() noexcept {}; + virtual Boolean isValid(const char* s); + virtual Boolean lookup(const char* s); + static TStreamable *build(); + static const char * const _NEAR name; +protected: + TLookupValidator( StreamableInit ) noexcept; +private: + virtual const char *streamableName() const {return name;}; +}; + +inline ipstream& operator >> ( ipstream& is, TLookupValidator& v ) + { return is >> (TStreamable&)v; } +inline ipstream& operator >> ( ipstream& is, TLookupValidator*& v ) + { return is >> (void *&)v; } + +inline opstream& operator << ( opstream& os, TLookupValidator& v ) + { return os << (TStreamable&)v; } +inline opstream& operator << ( opstream& os, TLookupValidator* v ) + { return os << (TStreamable *)v; } + +#endif + + +#if defined(Uses_TStringLookupValidator) && !defined(__TStringLookupValidator) +#define __TStringLookupValidator + +// TStringLookupValidator + +class TStringLookupValidator : public TLookupValidator +{ + + static const char * _NEAR errorMsg; + +public: + TStringLookupValidator(TStringCollection* aStrings) noexcept; + ~TStringLookupValidator(); + virtual void error(); + virtual Boolean lookup(const char* s); + +protected: + TStringLookupValidator( StreamableInit ) noexcept; + virtual void write( opstream& os ); + virtual void* read( ipstream& is ); + + TStringCollection* strings; + +private: + virtual const char *streamableName() const {return name;}; + +public: + void newStringList(TStringCollection* aStrings); + static TStreamable *build(); + static const char * const _NEAR name; +}; + + +inline ipstream& operator >> ( ipstream& is, TStringLookupValidator& v ) + { return is >> (TStreamable&)v; } +inline ipstream& operator >> ( ipstream& is, TStringLookupValidator*& v ) + { return is >> (void *&)v; } + +inline opstream& operator << ( opstream& os, TStringLookupValidator& v ) + { return os << (TStreamable&)v; } +inline opstream& operator << ( opstream& os, TStringLookupValidator* v ) + { return os << (TStreamable *)v; } + + +#endif diff --git a/src/include/tvision/views.h b/src/include/tvision/views.h new file mode 100644 index 00000000..e9c29837 --- /dev/null +++ b/src/include/tvision/views.h @@ -0,0 +1,1045 @@ +/* ------------------------------------------------------------------------*/ +/* */ +/* VIEWS.H */ +/* */ +/* defines the classes TView, TFrame, TScrollBar, TScroller, */ +/* TListViewer, TGroup, and TWindow */ +/* */ +/* ------------------------------------------------------------------------*/ +/* + * Turbo Vision - Version 2.0 + * + * Copyright (c) 1994 by Borland International + * All Rights Reserved. + * + */ + +#if defined( __BORLANDC__ ) +#pragma option -Vo- +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po- +#endif + +#if !defined( __COMMAND_CODES ) +#define __COMMAND_CODES + +const ushort + +// Standard command codes + + cmValid = 0, + cmQuit = 1, + cmError = 2, + cmMenu = 3, + cmClose = 4, + cmZoom = 5, + cmResize = 6, + cmNext = 7, + cmPrev = 8, + cmHelp = 9, + +// TDialog standard commands + + cmOK = 10, + cmCancel = 11, + cmYes = 12, + cmNo = 13, + cmDefault = 14, + +// Standard application commands + + cmNew = 30, + cmOpen = 31, + cmSave = 32, + cmSaveAs = 33, + cmSaveAll = 34, + cmChDir = 35, + cmDosShell = 36, + cmCloseAll = 37, + +// TView State masks + + sfVisible = 0x001, + sfCursorVis = 0x002, + sfCursorIns = 0x004, + sfShadow = 0x008, + sfActive = 0x010, + sfSelected = 0x020, + sfFocused = 0x040, + sfDragging = 0x080, + sfDisabled = 0x100, + sfModal = 0x200, + sfDefault = 0x400, + sfExposed = 0x800, + +// TView Option masks + + ofSelectable = 0x001, + ofTopSelect = 0x002, + ofFirstClick = 0x004, + ofFramed = 0x008, + ofPreProcess = 0x010, + ofPostProcess = 0x020, + ofBuffered = 0x040, + ofTileable = 0x080, + ofCenterX = 0x100, + ofCenterY = 0x200, + ofCentered = 0x300, + ofValidate = 0x400, + +// TView GrowMode masks + + gfGrowLoX = 0x01, + gfGrowLoY = 0x02, + gfGrowHiX = 0x04, + gfGrowHiY = 0x08, + gfGrowAll = 0x0f, + gfGrowRel = 0x10, + gfFixed = 0x20, + +// TView DragMode masks + + dmDragMove = 0x01, + dmDragGrow = 0x02, + dmDragGrowLeft = 0x04, + dmLimitLoX = 0x10, + dmLimitLoY = 0x20, + dmLimitHiX = 0x40, + dmLimitHiY = 0x80, + dmLimitAll = dmLimitLoX | dmLimitLoY | dmLimitHiX | dmLimitHiY, + +// TView Help context codes + + hcNoContext = 0, + hcDragging = 1, + +// TScrollBar part codes + + sbLeftArrow = 0, + sbRightArrow = 1, + sbPageLeft = 2, + sbPageRight = 3, + sbUpArrow = 4, + sbDownArrow = 5, + sbPageUp = 6, + sbPageDown = 7, + sbIndicator = 8, + +// TScrollBar options for TWindow.StandardScrollBar + + sbHorizontal = 0x000, + sbVertical = 0x001, + sbHandleKeyboard = 0x002, + +// TWindow Flags masks + + wfMove = 0x01, + wfGrow = 0x02, + wfClose = 0x04, + wfZoom = 0x08, + +// TView inhibit flags + + noMenuBar = 0x0001, + noDeskTop = 0x0002, + noStatusLine = 0x0004, + noBackground = 0x0008, + noFrame = 0x0010, + noViewer = 0x0020, + noHistory = 0x0040, + +// TWindow number constants + + wnNoNumber = 0, + +// TWindow palette entries + + wpBlueWindow = 0, + wpCyanWindow = 1, + wpGrayWindow = 2, + +// Application command codes + + cmCut = 20, + cmCopy = 21, + cmPaste = 22, + cmUndo = 23, + cmClear = 24, + cmTile = 25, + cmCascade = 26, + cmRedo = 27, + +// Standard messages + + cmReceivedFocus = 50, + cmReleasedFocus = 51, + cmCommandSetChanged = 52, + cmTimeout = 58, + +// TScrollBar messages + + cmScrollBarChanged = 53, + cmScrollBarClicked = 54, + +// TWindow select messages + + cmSelectWindowNum = 55, + +// TListViewer messages + + cmListItemSelected = 56, + +// TProgram messages + + cmScreenChanged = 57, + +// Event masks + + positionalEvents = evMouse & ~evMouseWheel, + focusedEvents = evKeyboard | evCommand; + +#endif // __COMMAND_CODES + +#if defined( Uses_TCommandSet ) && !defined( __TCommandSet ) +#define __TCommandSet + +class TCommandSet +{ + +public: + + TCommandSet() noexcept; + TCommandSet( const TCommandSet& ) noexcept; + + Boolean has( int cmd ) noexcept; + + void disableCmd( int cmd ) noexcept; + void enableCmd( int cmd ) noexcept; + void operator += ( int cmd ) noexcept; + void operator -= ( int cmd ) noexcept; + + void disableCmd( const TCommandSet& ) noexcept; + void enableCmd( const TCommandSet& ) noexcept; + void operator += ( const TCommandSet& ) noexcept; + void operator -= ( const TCommandSet& ) noexcept; + + Boolean isEmpty() noexcept; + + TCommandSet& operator &= ( const TCommandSet& ) noexcept; + TCommandSet& operator |= ( const TCommandSet& ) noexcept; + + friend TCommandSet operator & ( const TCommandSet&, const TCommandSet& ) noexcept; + friend TCommandSet operator | ( const TCommandSet&, const TCommandSet& ) noexcept; + + friend int operator == ( const TCommandSet& tc1, const TCommandSet& tc2 ) noexcept; + friend int operator != ( const TCommandSet& tc1, const TCommandSet& tc2 ) noexcept; + +private: + + int loc( int ) noexcept; + int mask( int ) noexcept; + + static int _NEAR masks[8]; + + uchar cmds[32]; + +}; + +inline void TCommandSet::operator += ( int cmd ) noexcept +{ + enableCmd( cmd ); +} + +inline void TCommandSet::operator -= ( int cmd ) noexcept +{ + disableCmd( cmd ); +} + +inline void TCommandSet::operator += ( const TCommandSet& tc ) noexcept +{ + enableCmd( tc ); +} + +inline void TCommandSet::operator -= ( const TCommandSet& tc ) noexcept +{ + disableCmd( tc ); +} + +inline int operator != ( const TCommandSet& tc1, const TCommandSet& tc2 ) noexcept +{ + return !operator == ( tc1, tc2 ); +} + +inline int TCommandSet::loc( int cmd ) noexcept +{ + return cmd / 8; +} + +inline int TCommandSet::mask( int cmd ) noexcept +{ + return masks[ cmd & 0x07 ]; +} + +#endif // Uses_TCommandSet + +#if defined( Uses_TPalette ) && !defined( __TPalette ) +#define __TPalette + +class TPalette +{ + +public: + + TPalette( const char *, ushort ) noexcept; +#ifndef __BORLANDC__ + TPalette( const TColorAttr *, ushort ) noexcept; + template + TPalette( const TColorAttr (&array) [N] ) noexcept : + TPalette(array, (ushort) N) + { + } +#endif + TPalette( const TPalette& ) noexcept; + ~TPalette(); + + TPalette& operator = ( const TPalette& ) noexcept; + + TColorAttr& operator[]( int ) const noexcept; + + TColorAttr *data; + +}; + +inline TColorAttr& TPalette::operator[]( int index ) const noexcept +{ + return data[index]; +} + +#endif // Uses_TPalette + +#if defined( Uses_TView ) && !defined( __TView ) +#define __TView + +struct write_args +{ + void _FAR *self; + void _FAR *target; + void _FAR *buf; + ushort offset; +}; + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TGroup; + +class TView : public TObject, public TStreamable +{ + +public: + + friend void genRefs(); + + enum phaseType { phFocused, phPreProcess, phPostProcess }; + enum selectMode{ normalSelect, enterSelect, leaveSelect }; + + TView( const TRect& bounds ) noexcept; + ~TView(); + + virtual void sizeLimits( TPoint& min, TPoint& max ); + TRect getBounds() const noexcept; + TRect getExtent() const noexcept; + TRect getClipRect() const noexcept; + Boolean mouseInView( TPoint mouse ) noexcept; + Boolean containsMouse( TEvent& event ) noexcept; + + void locate( TRect& bounds ); + virtual void dragView( TEvent& event, uchar mode, // temporary fix + TRect& limits, TPoint minSize, TPoint maxSize ); // for Miller's stuff + virtual void calcBounds( TRect& bounds, TPoint delta ); + virtual void changeBounds( const TRect& bounds ); + void growTo( short x, short y ); + void moveTo( short x, short y ); + void setBounds( const TRect& bounds ) noexcept; + + virtual ushort getHelpCtx(); + + virtual Boolean valid( ushort command ); + + void hide(); + void show(); + virtual void draw(); + void drawView() noexcept; + Boolean exposed() noexcept; + Boolean focus(); + void hideCursor(); + void drawHide( TView *lastView ); + void drawShow( TView *lastView ); + void drawUnderRect( TRect& r, TView *lastView ); + void drawUnderView( Boolean doShadow, TView *lastView ); + + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void setData( void *rec ); + + virtual void awaken(); + void blockCursor(); + void normalCursor(); + virtual void resetCursor(); + void setCursor( int x, int y ) noexcept; + void showCursor(); + void drawCursor() noexcept; + + void clearEvent( TEvent& event ) noexcept; + Boolean eventAvail(); + virtual void getEvent( TEvent& event ); + virtual void handleEvent( TEvent& event ); + virtual void putEvent( TEvent& event ); + + static Boolean commandEnabled( ushort command ) noexcept; + static void disableCommands( TCommandSet& commands ) noexcept; + static void enableCommands( TCommandSet& commands ) noexcept; + static void disableCommand( ushort command ) noexcept; + static void enableCommand( ushort command ) noexcept; + static void getCommands( TCommandSet& commands ) noexcept; + static void setCommands( TCommandSet& commands ) noexcept; + static void setCmdState( TCommandSet& commands, Boolean enable ) noexcept; + + virtual void endModal( ushort command ); + virtual ushort execute(); + + TAttrPair getColor( ushort color ) noexcept; + virtual TPalette& getPalette() const; + virtual TColorAttr mapColor( uchar ) noexcept; + + Boolean getState( ushort aState ) const noexcept; + void select(); + virtual void setState( ushort aState, Boolean enable ); + + void getEvent( TEvent& event, int timeoutMs ); + void keyEvent( TEvent& event ); + Boolean mouseEvent( TEvent& event, ushort mask ); + Boolean textEvent( TEvent &event, TSpan dest, size_t &length ); + + virtual TTimerId setTimer( uint timeoutMs, int periodMs = -1 ); + virtual void killTimer( TTimerId id ); + + TPoint makeGlobal( TPoint source ) noexcept; + TPoint makeLocal( TPoint source ) noexcept; + + TView *nextView() noexcept; + TView *prevView() noexcept; + TView *prev() noexcept; + TView *next; + + void makeFirst(); + void putInFrontOf( TView *Target ); + TView *TopView() noexcept; + + void writeBuf( short x, short y, short w, short h, const void _FAR* b ) noexcept; + void writeBuf( short x, short y, short w, short h, const TDrawBuffer& b ) noexcept; + void writeChar( short x, short y, char c, uchar color, short count ) noexcept; + void writeLine( short x, short y, short w, short h, const TDrawBuffer& b ) noexcept; + void writeLine( short x, short y, short w, short h, const void _FAR *b ) noexcept; + void writeStr( short x, short y, const char *str, uchar color ) noexcept; +#ifndef __BORLANDC__ + void writeBuf( short x, short y, short w, short h, const TScreenCell *b ) noexcept; + void writeLine( short x, short y, short w, short h, const TScreenCell *b ) noexcept; +#endif + + TPoint size; + ushort options; + ushort eventMask; + ushort state; + TPoint origin; + TPoint cursor; + uchar growMode; + uchar dragMode; + ushort helpCtx; + static Boolean _NEAR commandSetChanged; +#ifndef GENINC + static TCommandSet _NEAR curCommandSet; +#endif + TGroup *owner; + + static Boolean _NEAR showMarkers; + static uchar _NEAR errorAttr; + + virtual void shutDown(); + +private: + + void moveGrow( TPoint p, + TPoint s, + TRect& limits, + TPoint minSize, + TPoint maxSize, + uchar mode + ); + void change( uchar, TPoint delta, TPoint& p, TPoint& s, ushort ctrlState ) noexcept; + static void writeView( write_args ); + void writeView( short x, short y, short count, const void _FAR* b ) noexcept; +#ifndef __BORLANDC__ + void writeView( short x, short y, short count, const TScreenCell* b ) noexcept; +#endif + + TPoint resizeBalance; + + virtual const char *streamableName() const + { return name; } + +protected: + + TView( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +protected: + + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +}; + +inline ipstream& operator >> ( ipstream& is, TView& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TView*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TView& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TView* cl ) + { return os << (TStreamable *)cl; } + +inline void TView::writeBuf( short x, short y, short w, short h, + const TDrawBuffer& b ) noexcept +{ + writeBuf( x, y, min(w, short(b.length() - x)), h, &b.data[0] ); +} + +inline void TView::writeLine( short x, short y, short w, short h, + const TDrawBuffer& b ) noexcept +{ + writeLine( x, y, min(w, short(b.length() - x)), h, &b.data[0] ); +} + +#endif // Uses_TView + +/* ---------------------------------------------------------------------- */ +/* class TFrame */ +/* */ +/* Palette layout */ +/* 1 = Passive frame */ +/* 2 = Passive title */ +/* 3 = Active frame */ +/* 4 = Active title */ +/* 5 = Icons */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TFrame ) && !defined( __TFrame ) +#define __TFrame + +class _FAR TRect; +struct _FAR TEvent; +class _FAR TDrawBuffer; + +class TFrame : public TView +{ + +public: + + TFrame( const TRect& bounds ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual void setState( ushort aState, Boolean enable ); + +private: + + void frameLine( TDrawBuffer& frameBuf, short y, short n, TColorAttr color ); + void dragWindow( TEvent& event, uchar dragMode ); + + friend class TDisplay; + static const char _NEAR initFrame[19]; + static char _NEAR frameChars[33]; + static const char * _NEAR closeIcon; + static const char * _NEAR zoomIcon; + static const char * _NEAR unZoomIcon; + static const char * _NEAR dragIcon; + static const char * _NEAR dragLeftIcon; + + virtual const char *streamableName() const + { return name; } + +protected: + + TFrame( StreamableInit ) noexcept; + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TFrame& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TFrame*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TFrame& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TFrame* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TFrame + +/* ---------------------------------------------------------------------- */ +/* class TScrollBar */ +/* */ +/* Palette layout */ +/* 1 = Page areas */ +/* 2 = Arrows */ +/* 3 = Indicator */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TScrollBar ) && !defined( __TScrollBar ) +#define __TScrollBar + +class _FAR TRect; +struct _FAR TEvent; + +typedef char TScrollChars[5]; + +class TScrollBar : public TView +{ + +public: + + TScrollBar( const TRect& bounds ) noexcept; + + virtual void draw(); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual void scrollDraw(); + virtual int scrollStep( int part ); + void setParams( int aValue, int aMin, int aMax, + int aPgStep, int aArStep ) noexcept; + void setRange( int aMin, int aMax ) noexcept; + void setStep( int aPgStep, int aArStep ) noexcept; + void setValue( int aValue ) noexcept; + + void drawPos( int pos ) noexcept; + int getPos() noexcept; + int getSize() noexcept; + + int value; + + TScrollChars chars; + int minVal; + int maxVal; + int pgStep; + int arStep; + +private: + + int getPartCode(void) noexcept; + + static TScrollChars _NEAR vChars; + static TScrollChars _NEAR hChars; + + virtual const char *streamableName() const + { return name; } + +protected: + + TScrollBar( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TScrollBar& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TScrollBar*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TScrollBar& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TScrollBar* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TScrollBar + +/* ---------------------------------------------------------------------- */ +/* class TScroller */ +/* */ +/* Palette layout */ +/* 1 = Normal text */ +/* 2 = Selected text */ +/* ---------------------------------------------------------------------- */ + +#if defined( Uses_TScroller ) && !defined( __TScroller ) +#define __TScroller + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; + +class TScroller : public TView +{ + +public: + + TScroller( const TRect& bounds, + TScrollBar *aHScrollBar, + TScrollBar *aVScrollBar + ) noexcept; + + virtual void changeBounds( const TRect& bounds ); + virtual TPalette& getPalette() const; + virtual void handleEvent( TEvent& event ); + virtual void scrollDraw(); + void scrollTo( int x, int y ) noexcept; + void setLimit( int x, int y ) noexcept; + virtual void setState( ushort aState, Boolean enable ); + void checkDraw() noexcept; + virtual void shutDown(); + TPoint delta; + +protected: + + uchar drawLock; + Boolean drawFlag; + TScrollBar *hScrollBar; + TScrollBar *vScrollBar; + TPoint limit; + +private: + + void showSBar( TScrollBar *sBar ); + + virtual const char *streamableName() const + { return name; } + +protected: + + TScroller( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TScroller& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TScroller*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TScroller& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TScroller* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TScroller + +#if defined( Uses_TListViewer ) && !defined( __TListViewer ) +#define __TListViewer + +class _FAR TRect; +class _FAR TScrollBar; +struct _FAR TEvent; + +class TListViewer : public TView +{ + + static const char * _NEAR emptyText; + +public: + + TListViewer( const TRect& bounds, + ushort aNumCols, + TScrollBar *aHScrollBar, + TScrollBar *aVScrollBar + ) noexcept; + + virtual void changeBounds( const TRect& bounds ); + virtual void draw(); + virtual void focusItem( short item ); + virtual TPalette& getPalette() const; + virtual void getText( char *dest, short item, short maxLen ); + virtual Boolean isSelected( short item ); + virtual void handleEvent( TEvent& event ); + virtual void selectItem( short item ); + void setRange( short aRange ); + virtual void setState( ushort aState, Boolean enable ); + + virtual void focusItemNum( short item ); + virtual void shutDown(); + + TScrollBar *hScrollBar; + TScrollBar *vScrollBar; + short numCols; + short topItem; + short focused; + short range; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TListViewer( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TListViewer& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TListViewer*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TListViewer& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TListViewer* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TListViewer + +#if defined( Uses_TGroup ) && !defined( __TGroup ) +#define __TGroup + +class _FAR TView; + +class TGroup : public TView +{ + +public: + + friend void genRefs(); + + TGroup( const TRect& bounds ) noexcept; + ~TGroup(); + + virtual void shutDown(); + + ushort execView( TView *p ) noexcept; + virtual ushort execute(); + virtual void awaken(); + + void insertView( TView *p, TView *Target ) noexcept; + void remove( TView *p ); + void removeView( TView *p ) noexcept; + void resetCurrent(); + void setCurrent( TView *p, selectMode mode ); + void selectNext( Boolean forwards ); + TView *firstThat( Boolean (*func)( TView *, void * ), void *args ); + Boolean focusNext(Boolean forwards); + void forEach( void (*func)( TView *, void * ), void *args ); + void insert( TView *p ) noexcept; + void insertBefore( TView *p, TView *Target ); + TView *current; + TView *at( short index ) noexcept; + TView *firstMatch( ushort aState, ushort aOptions ) noexcept; + short indexOf( TView *p ) noexcept; + TView *first() noexcept; + + virtual void setState( ushort aState, Boolean enable ); + + virtual void handleEvent( TEvent& event ); + + void drawSubViews( TView *p, TView *bottom ) noexcept; + + virtual void changeBounds( const TRect& bounds ); + + virtual ushort dataSize(); + virtual void getData( void *rec ); + virtual void setData( void *rec ); + + virtual void draw(); + void redraw() noexcept; + void lock() noexcept; + void unlock() noexcept; + virtual void resetCursor(); + + virtual void endModal( ushort command ); + + virtual void eventError( TEvent& event ); + + virtual ushort getHelpCtx(); + + virtual Boolean valid( ushort command ); + + void freeBuffer() noexcept; + void getBuffer() noexcept; + + TView *last; + + TRect clip; + phaseType phase; + + TScreenCell *buffer; + uchar lockFlag; + ushort endState; + +private: + + void focusView( TView *p, Boolean enable ); + void selectView( TView *p, Boolean enable ); + TView* findNext(Boolean forwards) noexcept; + + virtual const char *streamableName() const + { return name; } + +protected: + + TGroup( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TGroup& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TGroup*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TGroup& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TGroup* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TGroup + +#if defined( Uses_TWindow ) && !defined( __TWindow ) +#define __TWindow + +#define cpBlueWindow "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" +#define cpCyanWindow "\x10\x11\x12\x13\x14\x15\x16\x17" +#define cpGrayWindow "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + +class _FAR TFrame; +class _FAR TRect; +class _FAR TPoint; +struct _FAR TEvent; +class _FAR TFrame; +class _FAR TScrollBar; + +class TWindowInit +{ + +public: + + TWindowInit( TFrame *(*cFrame)( TRect ) ) noexcept; + +protected: + + TFrame *(*createFrame)( TRect ); + +}; + +/* ---------------------------------------------------------------------- */ +/* class TWindow */ +/* */ +/* Palette layout */ +/* 1 = Frame passive */ +/* 2 = Frame active */ +/* 3 = Frame icon */ +/* 4 = ScrollBar page area */ +/* 5 = ScrollBar controls */ +/* 6 = Scroller normal text */ +/* 7 = Scroller selected text */ +/* 8 = Reserved */ +/* ---------------------------------------------------------------------- */ + +class TWindow: public TGroup, public virtual TWindowInit +{ + +public: + + TWindow( const TRect& bounds, + TStringView aTitle, + short aNumber + ) noexcept; + ~TWindow(); + + virtual void close(); + virtual TPalette& getPalette() const; + virtual const char *getTitle( short maxSize ); + virtual void handleEvent( TEvent& event ); + static TFrame *initFrame( TRect ); + virtual void setState( ushort aState, Boolean enable ); + virtual void sizeLimits( TPoint& min, TPoint& max ); + TScrollBar *standardScrollBar( ushort aOptions ) noexcept; + virtual void zoom(); + virtual void shutDown(); + + uchar flags; + TRect zoomRect; + short number; + short palette; + TFrame *frame; + const char *title; + +private: + + virtual const char *streamableName() const + { return name; } + +protected: + + TWindow( StreamableInit ) noexcept; + virtual void write( opstream& ); + virtual void *read( ipstream& ); + +public: + + static const char * const _NEAR name; + static TStreamable *build(); + +}; + +inline ipstream& operator >> ( ipstream& is, TWindow& cl ) + { return is >> (TStreamable&)cl; } +inline ipstream& operator >> ( ipstream& is, TWindow*& cl ) + { return is >> (void *&)cl; } + +inline opstream& operator << ( opstream& os, TWindow& cl ) + { return os << (TStreamable&)cl; } +inline opstream& operator << ( opstream& os, TWindow* cl ) + { return os << (TStreamable *)cl; } + +#endif // Uses_TWindow + +#if defined( __BORLANDC__ ) +#pragma option -Vo. +#endif +#if defined( __BCOPT__ ) && !defined (__FLAT__) +#pragma option -po. +#endif diff --git a/src/win32api.cc b/src/win32api.cc index c9577601..bfbc5c33 100644 --- a/src/win32api.cc +++ b/src/win32api.cc @@ -42,7 +42,7 @@ void Parser::ASM_Code::init_win32api() char * buffer = new char[20480]; sprintf(buffer, - "; T 0x%p MessageBoxA" "\n" + "; T 0x%p extern_MessageBoxA" "\n" "; T 0x%p Lv_Entry__lpText" "\n" "; T 0x%p Lv_Entry__lpCapt" "\n" "; T 0x%p Lv_Entry__lpMsgM" "\n" @@ -123,8 +123,8 @@ bool Parser::ASM_Code::user32_MessageBox() // ------------------------------------------- char * buffer = new char[1024]; sprintf(buffer, - "; T 0x%p MessageBoxA\n" - "MessageBoxA:\n\tdq 0x%p\n", + "; T 0x%p extern_MessageBoxA\n" + "extern_MessageBoxA:\n\tdq 0x%p\n", ::MessageBoxA, ::MessageBoxA );