Turbo Vision 2.0 - आधुनिक पोर्ट
(github.com/magiblot)- क्लासिक text UI framework को Linux और Windows पर फिर से उपयोग करने लायक पोर्ट करते हुए, UTF-8 और extended color तक शामिल करने वाला एक साझा development base प्रदान करता है
- मौजूदा Turbo Vision apps के source code level compatibility को अधिकतम बनाए रखते हुए भी
char-based API को जारी रखता है, ताकि platform-specific terminal differences को library के भीतर absorb किया जा सके - Unicode input और display को पूरे framework में integrate करके double-width characters, combining characters, multibyte shortcuts, UTF-8-आधारित editing और drawing को साथ में संभाला जा सकता है
- overlapping windows, menus, dialogs, input boxes, scrollbars जैसे basic widgets के साथ, event loop, timer, clipboard, mouse wheel, resize, large file editing जैसी आधुनिक क्षमताएँ भी support करता है
- पुराने 16-color API से आगे बढ़कर 24-bit color, xterm-256 palette, system clipboard, और कई console environments के support को एक साथ जोड़ता है, जिससे पुराना TUI code और modern terminal environments के बीच पुल बनता है
प्रोजेक्ट का स्वरूप और मुख्य दिशा
- Turbo Vision 2.0 का आधुनिक पोर्ट, जो क्लासिक text UI framework को Linux और Windows पर फिर से उपयोग करने लायक बनाता है और UTF-8 व extended color support भी जोड़ता है
- शुरुआती चरण में Linux support जोड़ने, मौजूदा DOS/Windows behavior को बनाए रखने, और पुराने Turbo Vision apps की source code level compatibility को सुरक्षित रखने पर ध्यान दिया गया
- इस compatibility के लिए कुछ Borland C++ RTL functions भी सीधे implement किए गए
- 2020 के जुलाई-अगस्त के बीच मौजूदा संरचना में पूर्ण Unicode support integrate किया गया, और उसी प्रक्रिया में Turbo text editor भी बनाया गया
- applications को terminal feature differences या direct terminal I/O handling को खुद bypass न करना पड़े, इसके लिए उन्हें wrap किया जाता है, ताकि platform-specific differences को library की तरफ absorb किया जा सके
- Linux और Windows पर एक ही code से text UI लिखने पर फोकस है, और
wchar_tयाTCHARकी जगहchar-based API को जारी रखा गया है
यह उपयोगी क्यों है
- कई widget classes देता है, जिनसे resizable overlapping windows, pulldown menus, dialogs, buttons, scrollbars, input boxes, checkboxes, radio buttons आदि सीधे इस्तेमाल किए जा सकते हैं
- अपने widget बनाते समय भी event dispatch या full-width Unicode character rendering जैसी common processing को दोबारा लिखने का बोझ कम हो जाता है
- हर environment में जहाँ तक संभव हो एक जैसा परिणाम देने की कोशिश करता है
- Linux console में अगर bright background color blink attribute पर निर्भर हो, तो उसे भी library खुद संभाल लेती है
- Microsoft RTL के
setlocaleUTF-8 support का उपयोग करके Windows पर भीstd::ifstream f("コンピュータ.txt");जैसे code को अपेक्षित तरीके से चलाया जा सकता है- Windows में RTL file names को तुरंत system encoding में convert कर देता है
Unicode डिज़ाइन और text processing
- UTF-8 को input और display की default encoding के रूप में अपनाया गया है
- यह मौजूदा
char *data type के साथ compatible है और terminal I/O encoding के समान होने से अनावश्यक conversion कम करता है - इसकी दिशा UTF-8 Everywhere Manifesto से भी मेल खाती है
- यह मौजूदा
- Borland C++ से build करते समय Unicode support नहीं मिलता, लेकिन API extensions को encoding-independent code लिखने योग्य बनाने के लिए design किया गया है
KeyDownEventमें मौजूदाcharScan.charCodeके अलावाtext[4]औरtextLengthजोड़े गए हैं, ताकि UTF-8 input byte sequence सीधे दी जा सके- backward compatibility के लिए
charScan.charCodeमें अब भी CP437-आधारित character आता है getText()से string view लेकर उपयोग करने का तरीका recommended है
- backward compatibility के लिए
- input examples Unicode और legacy code के साथ काम करने के तरीके को वैसे ही दिखाते हैं
ñinput करने परcharCode=164 ('ñ'),text={'\xC3','\xB1'},textLength=2होता है€input करने पर, क्योंकि वह CP437 में नहीं है,keyCode=0x0,charCode=0,text={'\xE2','\x82','\xAC'},textLength=3होता है- shortcut input के समय
textLength=0होकर खाली रहता है
- TScreenCell UTF-8 codepoints के साथ bold, underline, italic जैसी extended attributes को भी रख सकता है
- ASCII control characters को code page characters की तरह संभाला जाता है
- valid UTF-8 को वैसे ही display किया जाता है, और invalid UTF-8 को code page characters की तरह treat किया जाता है
- extended ASCII और UTF-8 को मिलाकर इस्तेमाल किया जा सकता है, जो backward compatibility के लिए फायदेमंद है, लेकिन अप्रत्याशित परिणाम भी दे सकता है
- double-width characters और combining characters के लिए भी अलग handling है
- combining characters पिछले character के ऊपर overlay हो जाते हैं
ZERO WIDTH JOINERU+200Dको हमेशा छोड़ दिया जाता है- अगर terminal
wcwidthके अनुसार character width को मानता है, तो दिखाई देने वाली graphic corruption लगभग नहीं होती - उदाहरण Wide character display में देखा जा सकता है
Unicode API और standard view support
-
Unicode-aware drawing API
TDrawBuffer::moveChar,putCharमेंchar cको code page character के रूप में हैंडल किया जाता हैmoveStr,moveCStrTStringViewलेते हैं और Unicode rules के अनुसार string को प्रोसेस करते हैंmaxStrWidthbytes की संख्या नहीं बल्कि columns की संख्या पर आधारित हैstrIndentभी bytes नहीं बल्कि columns की संख्या पर आधारित है, इसलिए इसे horizontal scroll में इस्तेमाल किया जा सकता है- return value कॉपी किए गए text की display width होती है
moveBufTStringViewआने से पहले null-terminated न होने वाली string को हैंडल करने वाला function था, इसलिए इसे बनाए रखा गया हैcstrlen(TStringView s)~को छोड़कर display length लौटाता है, औरstrwidth(TStringView s)~को शामिल करके display length लौटाता है
-
draw() का सरलीकरण और bug में कमी
- पहले
TFileViewer::draw()partial substring को temporary buffer में कॉपी करने के बादmoveStrकॉल करता था, लेकिन इस तरीके में buffer overrun का जोखिम और multibyte boundary की समस्या थी - संशोधन के बाद इसे
b.moveStr(0, p, c, size.x, delta.x);की एक लाइन से हैंडल किया गया, जिससे बीच की कॉपी हट गईdelta.xको सीधे column आधार पर लागू किया जा सकता है- अधिकतम
size.xcolumns ही कॉपी होते हैं, इसलिए bytes की संख्या और boundary conditions को सीधे calculate करने की जरूरत कम हो जाती है
- पहले
-
Unicode display को support करने वाले standard views
TStaticText,TFrame,TStatusLine,THistoryViewer,THelpViewer,8c7dac2a,20f331e3,TListViewer,TMenuBox,TTerminal,TOutlineViewer,tvdemoकेTFileViewer,tvdirकेTFilePaneमें Unicode display support है- कुछ views horizontal scroll और word wrapping भी साथ में हैंडल करते हैं
-
Unicode input तक हैंडल करने वाले views
TInputLine,cb489d42,TEditor,TMenuViewके shortcut keys में Unicode user input भी हैंडल किया जाता हैTEditorinstance default रूप से UTF-8 mode में होता है औरCtrl+Pसे single-byte mode में स्विच किया जा सकता है- यह switch document content को बदले बिना सिर्फ display method और input encoding बदलता है
TStatusLine,TButtonआदि के highlighted key shortcuts support नहीं किए जाते
-
menu और status line के multilingual strings
~Ñ~ello,階~毎~料入報最...,五劫~の~擦り切れ,העברית ~א~ינטרנט,~Alt-Ç~ Exitजैसी strings को menu और status line में वैसे ही इस्तेमाल किया जा सकता है- result screen को Unicode Hello में देखा जा सकता है
प्लेटफ़ॉर्म के अनुसार संचालन मॉडल
-
Unix
- Ncurses-आधारित टर्मिनल सपोर्ट का उपयोग करता है
- X10, SGR माउस एन्कोडिंग, xterm का modifyOtherKeys, Paul Evans का fixterms, Kitty का keyboard protocol, WSL Conpty का
win32-input-mode, far2l, Linux console केTIOCLINUXmodifiers और GPM mouse को सपोर्ट करता है - प्रोग्राम के असामान्य रूप से बंद होने से पहले टर्मिनल स्थिति को बहाल करने के लिए custom signal handler मौजूद है
- अगर
stderrtty हो, तो स्क्रीन खराब होने से बचाने के लिए आउटपुट को बफ़र में रखता है और exit या suspend के समय प्रिंट करता है- बफ़र आकार की सीमा होने के कारण, भर जाने पर
stderrwrite विफल हो सकता है - सब कुछ सुरक्षित रखने के लिए
2>redirection की सिफारिश की जाती है
- बफ़र आकार की सीमा होने के कारण, भर जाने पर
TERM,COLORTERM,ESCDELAY,TVISION_USE_STDIOenvironment variables को पढ़ता है- अगर
COLORTERM=truecolorया24bitहो, तो 24-bit color माना जाता है ESCDELAYका default मान10ms है- अगर
TVISION_USE_STDIOखाली नहीं है, तो/dev/ttyकी जगहstdinऔरstdoutसे I/O किया जाता है
- अगर
-
Windows
- केवल Win32 Console API के साथ compatible है
- इसे सपोर्ट न करने वाले terminal emulators में अलग console window अपने-आप खोलता है
- application layout console buffer नहीं, बल्कि console window size के आधार पर होता है, और exit या suspend पर console buffer को restore करता है
- Borland C++ न होने पर startup में console code page को UTF-8 में बदलता है और exit पर restore करता है
- Microsoft C runtime को भी UTF-8 mode में बदलता है ताकि डेवलपर को
wchar_tvariants सीधे इस्तेमाल करने की ज़रूरत कम हो - legacy mode और bitmap font के संयोजन में Unicode display टूट सकता है, और इसे detect करने पर font को
ConsolasयाLucida Consoleमें बदलने की कोशिश करता है- उदाहरण photo में देखा जा सकता है
-
सामान्य व्यवहार सुधार
- 24-bit color,
stdin/stdout/stderrredirection के साथ सह-अस्तित्व, और 32-bit help file compatibility प्रदान करता है TVISION_MAX_FPSenvironment variable से अधिकतम refresh rate नियंत्रित करता है- default मान
60है 0सीमा को disable करता है-1हरTHardwareInfo::screenWritecall पर तुरंत draw करता है
- default मान
- middle mouse button, mouse wheel, अधिकतम 32767 पंक्ति/स्तंभ screen size, और resize events को सपोर्ट करता है
- window को नीचे-बाएँ कोने से भी resize किया जा सकता है, और middle button से खाली क्षेत्र को पकड़कर drag किया जा सकता है
- menu को parent item पर दोबारा क्लिक करके बंद किया जा सकता है, और scrollbar drag के दौरान page scroll तथा wheel input पर प्रतिक्रिया देता है
TInputLinefocus बदलने पर टेक्स्ट को अनावश्यक रूप से scroll नहीं करताTFileViewerऔरTEditorLF line ending को सपोर्ट करते हैं, औरTEditorsave करते समय मौजूदा line ending बनाए रखता है तथा नई files में default रूप से CRLF का उपयोग करता हैTEditorमें right-click menu, middle-button drag scroll, word-unit delete key, बेहतर Home key, और 64 KiB से बड़ी files का सपोर्ट भी शामिल हैtvdemoमें event viewer applet और background pattern बदलने का option शामिल है
- 24-bit color,
इवेंट लूप और API परिवर्तन
- screen write buffering का उपयोग करता है, और सामान्यतः हर active event loop iteration में एक बार टर्मिनल पर भेजता है
- अगर busy loop में तुरंत refresh चाहिए, तो
TScreen::flushScreen()call किया जा सकता है TEventQueue::waitForEvents(int timeoutMs)input events का इंतज़ार करता है, और wait के दौरान भीTScreen::flushScreen()से screen refresh करता हैTProgram::getEvent()इसे default20वालेeventTimeoutMsके साथ call करता है ताकि 100% CPU busy loop से बचा जा सकेTEventQueue::wakeUp()दूसरे thread से event loop को जगाने के लिए thread-safe method हैTView::getEvent(TEvent &, int timeoutMs)से view-स्तर पर timeout wait रखा जा सकता हैsetTimer,killTimerजोड़े गए हैं, जो timer expire होने परevBroadcastऔरcmTimerExpiredउत्पन्न करते हैं- अगर
periodMsनकारात्मक हो, तो यह one-shot timer बनकर अपने-आप साफ हो जाता है - timer events
TProgram::idle()में बनते हैं और केवल तब process होते हैं जब keyboard या mouse events न हों
- अगर
TDrawBufferअब fixed-length array नहीं है, और out-of-range access को रोकता हैTRectकेmove,grow,intersect,UnionTRect&लौटाते हैं, जिससे chaining संभव होती हैTApplicationडिफ़ॉल्ट रूप सेdosShell(),cascade(),tile()प्रदान करता है औरcmDosShell,cmCascade,cmTileको default रूप से handle करता हैTStringView,TSpan<T>,TDrawSurface,TSurfaceView,TClipboardजैसे types जोड़े गए हैंTHardwareInfo,TScreen,TEventQueueका initializationmainसे पहले नहीं, बल्कि पहलेTApplicationके निर्माण पर होता है- input extensions भी शामिल हैं
evMouseWheel,mwUp,mwDown,mwLeft,mwRightmbMiddleButton,meTripleClickevMouseUp.buttonsमें छोड़े गए button की जानकारी बनी रहती हैhotKeyStr,getAltCharStr,getCtrlCharStrसे multibyte shortcuts लागू किए जा सकते हैंTKeyसेShift+Alt+Upजैसे नए key combinations परिभाषित किए जा सकते हैंTInputLineilMaxBytes,ilMaxWidth,ilMaxCharsके limitMode को सपोर्ट करता है
क्लिपबोर्ड इंटीग्रेशन
-
सिस्टम क्लिपबोर्ड इंटीग्रेशन
- पहले केवल
TEditor::clipboardstatic member के जरिए आंतरिक क्लिपबोर्ड उपलब्ध था, और इसका उपयोग सिर्फTEditorकर सकता था - नया
TClipboardclass सिस्टम क्लिपबोर्ड तक पहुंचता है, और अगर पहुंच संभव न हो तो आंतरिक क्लिपबोर्ड का उपयोग करता है
- पहले केवल
-
समर्थित वातावरण
- Windows, WSL, macOS में यह डिफ़ॉल्ट रूप से समर्थित है
- macOS को छोड़कर Unix में external dependency की आवश्यकता होती है
- remote execution में
ssh -Xकी X11 forwarding, far2l और putty4far2l, तथा OSC 52 सपोर्ट वाले टर्मिनल में यह काम कर सकता है - कुछ अन्य टर्मिनल केवल copy को सपोर्ट करते हैं
- टर्मिनल emulator का
Ctrl+Shift+VयाCmd+Vpaste अलग से हमेशा संभव है
-
API और paste handling
<tvision/tv.h>शामिल करने से पहलेUses_TClipboarddefine करने परTClipboardका उपयोग किया जा सकता हैsetText(TStringView text)सिस्टम क्लिपबोर्ड की सामग्री सेट करता है, और पहुंच संभव न हो तो आंतरिक क्लिपबोर्ड का उपयोग करता हैrequestText()सिस्टम क्लिपबोर्ड की सामग्री के लिए asynchronous request भेजता है, और बाद में सामान्यevKeyDownevent के रूप में उसे प्राप्त करता है- paste किया गया text,
keyDown.controlKeyStateकेkbPasteflag से सामान्य key input से अलग पहचाना जा सकता है - लंबे paste को हजारों key input की तरह process करने वाली inefficiency को कम करने के लिए
TView::textEvent(...)जोड़ा गया है- लगातार आने वाले
evKeyDowntext को user buffer में इकट्ठा करके पढ़ता है - जब वह आगे text न रहे, तो
putEvent()के जरिए अगले loop में भेज देता है
- लगातार आने वाले
-
standard command integration
TEditorऔरTInputLine,cmCut,cmCopy,cmPastecommands पर प्रतिक्रिया देते हैं- application को status bar आदि में
kbCtrlX,kbCtrlC,kbCtrlVको संबंधित commands से जोड़ना चाहिए - focus और selection state के अनुसार संबंधित commands अपने-आप enable या disable हो जाते हैं
विस्तारित रंग मॉडल और compatibility
- Turbo Vision API पारंपरिक 16 रंगों से आगे बढ़कर extended colors को सपोर्ट करता है
- 4-bit BIOS color attributes
- 24-bit RGB
- 8-bit xterm-256color palette index
- terminal default color
- अगर टर्मिनल किसी खास color format को सपोर्ट नहीं करता, तो Turbo Vision उसे quantize करके दिखाता है
- आधुनिक platforms पर
ucharकी जगह TColorAttr औरushortकी जगह TAttrPair पेश किए गए हैंTPaletteभीTColorAttrarray का उपयोग करता हैTView::mapColorअबvirtualहै, जिससे hierarchical palette system को bypass करके color specify किया जा सकता है
TColorBIOS,TColorRGB,TColorXTerm,TColorDesiredके जरिए color representation की परतें बांटी गई हैंTColorAttrमेंforeground,background,stylebitmask होते हैं- style में
slBold,slItalic,slUnderline,slBlink,slReverse,slStrikeशामिल हैं slReverseकी विश्वसनीयता कम है, इसलिएreverseAttribute(TColorAttr attr)का उपयोग recommended है
TViewमें extended colors इस्तेमाल करने के तीन तरीके हैंmapColorको override करके index के हिसाब से hardcode करनाdraw()मेंTDrawBufferको सीधेTColorAttrदेना- application palette को ही modify करना
TScreen::screenModedisplay capability को expose करता हैsmMonomonocolor हैsmBW80grayscale हैsmCO80कम-से-कम 16 रंग हैंsmColor256कम-से-कम 256 रंग हैंsmColorHighउससे भी अधिक रंगों को दर्शाता है, जैसे 24-bit color
- backward compatibility को
#ifdefरहित common API बनाए रखने के हिसाब से डिज़ाइन किया गया है- Borland C++ में
TColorAttr,TAttrPairक्रमशःuchar,ushortके typedef हैं - आधुनिक platforms पर ये पुराने
uchar,ushortकी जगह ले सकते हैं - legacy code वैसे ही compile हो जाता है, लेकिन non-BIOS color attributes
ucharयाushortमें implicit conversion होते ही खो सकते हैं
- Borland C++ में
drawmethod मेंushortको palette index pair और color attribute pair दोनों के लिए इस्तेमाल करने वाला code वैसे ही काम करता है, लेकिन extended colors बनाए रखने के लिए variable declaration कोushortसे TAttrPair में बदलना पर्याप्त हैTColorDialogको फिर से redesign नहीं किया गया है, इसलिए runtime के extended color picker के रूप में इसका उपयोग नहीं किया जा सकता
बिल्ड, डिप्लॉयमेंट, इंटीग्रेशन
-
Linux और Unix परिवार
- CMake और GCC/Clang के साथ static library
libtvision.aबिल्ड की जा सकती है hello,tvdemo,tvedit,tvdir,mmenu,palette,tvhcHelp Compiler भी साथ में जनरेट होते हैं- आवश्यकताएँ हैं C++14 सपोर्ट करने वाला compiler,
libncursesw, और वैकल्पिकlibgpm - runtime clipboard integration के लिए
xsel,xclip,wl-clipboardका उपयोग होता है - कुछ environments में
-ltinfowकी ज़रूरत पड़ सकती है, नहीं तो रनटाइम पर segmentation fault हो सकता है- संबंधित issue: #11
- CMake और GCC/Clang के साथ static library
-
Windows और अन्य toolchains
- MSVC बिल्ड target architecture के अनुसार अलग build directory का उपयोग करता है, और output
tvision.libतथा example apps के रूप में बनता है TV_USE_STATIC_RTLविकल्प से Microsoft runtime की static linking संभव है/MTऔर/MD, debug और non-debug binaries को आपस में मिलाकर link नहीं किया जा सकता<tvision/tv.h>के उपयोग के लिए/permissive-,/Zc:__cplusplusflags चाहिए, और CMake submodule तरीके में यह अपने-आप सक्षम हो जाता है- इसमें लिखा है कि उचित MSVC version और settings के साथ Windows XP भी संभव है
- MinGW भी Linux की तरह CMake से बिल्ड होता है, और यदि compiler सपोर्ट करे तो Windows XP या उसके बाद के संस्करणों पर चल सकता है
- Borland C++ से भी DOS या Windows library बिल्ड की जा सकती है, लेकिन Unicode का समर्थन नहीं है
- Borland C++ environment में winevdm के उपयोग को एक विकल्प के रूप में सुझाया गया है
- MSVC बिल्ड target architecture के अनुसार अलग build directory का उपयोग करता है, और output
-
प्रोजेक्ट इंटीग्रेशन के तरीके और डिप्लॉयमेंट स्थिति
- CMake में
find_package(tvision CONFIG)याadd_subdirectory(tvision)ये दो तरीके दिए गए हैं - दोनों तरीके include paths और Ncurses, GPM जैसी आवश्यक links को अपने-आप संभालते हैं
- vcpkg में
tvisionport उपलब्ध है - अभी कोई stable release नहीं है, और नवीनतम commits के आधार पर upgrade के दौरान मिलने वाली समस्याओं की रिपोर्ट करने की सिफारिश की गई है
- Unix परिवार में demo apps को सीधे बिल्ड करना पड़ता है
- Windows binaries Actions में उपलब्ध हैं
examples-dos32.zip: Borland C++ बिल्ड 32-bit executable, Unicode सपोर्ट नहींexamples-x86.zip: MSVC बिल्ड 32-bit executable, Windows Vista या उसके बाद के संस्करण की आवश्यकताexamples-x64.zip: MSVC बिल्ड 64-bit executable, x64 Windows Vista या उसके बाद के संस्करण की आवश्यकता
- CMake में
उदाहरण, दस्तावेज़, उपयोग के मामले
- शुरुआत के लिए Turbo Vision For C++ User's Guide की सिफारिश की गई है
- बुनियादी बातें सीखने के बाद Turbo Vision 2.0 Programming Guide को संदर्भ के रूप में देखा जा सकता है
- उदाहरणों में
hello,tvdemo,tvedit,paletteआदि दिए गए हैं - screenshots का संग्रह here में देखा जा सकता है
- उपयोग में मौजूद applications के रूप में ये दिए गए हैं
1 टिप्पणियां
Hacker News टिप्पणियाँ
इस repository को front page पर देखना सच में बहुत अच्छा लगा, और मैं अभी इसी repository के लिए अपना wrapper खुद बना रहा हूँ
.Net के ऊपर macOS पर Turbo Vision चला रहा हूँ, और यह काफ़ी जादुई लगता है
मैं एक higher-level API दे रहा हूँ, काफ़ी पुरानी palette API को wrap या बेहतर कर रहा हूँ, और layout भी जोड़ रहा हूँ
अभी यह सब private repository में ज़ोरों से चल रहा काम है, और आज surface के हिसाब से palette सेट कर रहा हूँ जहाँ controls रखे गए हैं, कल किसी और हिस्से को polish करूँगा—ऐसे ही लगातार सुधार रहा हूँ
layout को साफ़-सुथरा करना, और आज के हिसाब से missing basic controls जोड़ना जैसे काम अभी बाकी हैं
पहले Terminal.Gui भी इस्तेमाल किया था, लेकिन शायद v2 transition की वजह से उसे bugs के बिना संभालना काफ़ी मुश्किल था, और Claude ने भी यह अच्छी तरह दिखा दिया कि अगर असली terminal को ध्यान में रखे बिना TUI library बनाई जाए तो क्या नहीं करना चाहिए
इसलिए मैं सोच ही रहा था कि Turbo Vision का कोई आधुनिक रूप होना चाहिए, तभी यह repository मिली, और इसमें Unicode support देखकर सच में बहुत आभार महसूस हुआ
https://www.remobjects.com/elements/oxygene/
https://www.remobjects.com/elements/
मैं भी एक .NET wrapper बना रहा हूँ, और शायद मेरी प्रगति कम हुई है, लेकिन मैं Windows Forms API को जितना हो सके उतना नज़दीक से mimic करना चाहता हूँ, यहाँ तक कि drag-and-drop TUI designer भी जोड़ना चाहता हूँ
उदाहरण यहाँ है: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
C++ वाली मुश्किल integration का ज़्यादातर हिस्सा मैंने यहाँ संभाला है: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
मैंने simple C functions export किए हैं ताकि उन्हें P/Invoke से बुलाया जा सके, और C# side को मुख्यतः class structure पर फ़ोकस करने दिया
शुरुआत में मैंने ज़ोर दिया था कि C++ में जो कुछ संभव है वह सब C# में भी संभव होना चाहिए, लेकिन वह बहुत जटिल हो गया, और placement new से C++ objects को C# buffers के अंदर रखकर लगभग यह स्थिति आ गई कि C# side से C++ classes inherit की जा रही हों—फिर design ही टूट गया
आख़िर में मैंने एक ज़्यादा सीधा, कम flexible लेकिन बहुत सरल approach अपनाया, और flexibility C# side पर छोड़ दी
आपका P/Invoke system कैसे बना है, यह जानने की जिज्ञासा है
शायद इसी वजह से GEOS के लिए app बनाने या one-man Hurd team में शामिल होने जैसी बेकार कोशिशों से बच गया हूँ
Terminal.Gui इस्तेमाल किया था, लेकिन TV side ज़्यादा आकर्षक लगी, इसलिए wrapper के बारे में सोच रहा था, और अगर यह public हो तो मैं ज़रूर देखना चाहूँगा
मेरा programming career सचमुच 90s में कूड़ेदान से शुरू हुआ था
किसी के फेंके हुए Turbo Vision book मिली थी, और मैं उन नीले रंग की TUI screens पर तुरंत फ़िदा हो गया जिन्हें कोई भी बना सकता था
मूल version Turbo Pascal 6 में था, और C++ port बाद में आया
इसलिए इसे port का आधुनिक port कहना ठीक होगा
Borland के दूसरे frameworks में भी यही पैटर्न था; OWL भी मूल रूप से Turbo Pascal for Windows 1.5 side पर पहले था, और C++ Builder के काफ़ी tools असल में Delphi में लिखे गए थे
Turbo Pascal 5.5 का Object Pascal, और 6 का Turbo Vision—यही मेरे लिए OOP की शुरुआत थे, और मुझे लगता है कि उस रास्ते पर जाना मेरी किस्मत थी
MS-DOS जैसे environment में भी OOP और Turbo Vision के framework फ़ायदे सचमुच अच्छे से सीखे जा सकते थे
जब Borland ने Turbo Pascal, Turbo C++, और TurboVision जारी किए, तो लगा जैसे संभावनाओं का पूरा ब्रह्मांड खुल गया हो
compiler performance भी शानदार थी और manuals कला-कृतियों जैसे थे; काश वे किताबें अभी भी मेरे पास होतीं
यह बस एक सांस्कृतिक ख़ज़ाना है
90s की शुरुआत में मैंने लगभग सिर्फ़ Turbo C++ के साथ आने वाली Borland की किताबों के ढेर को पढ़कर खुद C/C++ सीखा था, और आज यह कल्पना करना भी मुश्किल है कि कोई सिर्फ़ reference books पढ़कर इस तरह सीख सकता है
नए TUI frameworks में हमेशा कुछ न कुछ कमी लगती थी, और अब इसे फिर से इस्तेमाल करके देखूँगा कि वह सिर्फ़ nostalgia था या नहीं
मैं इसे अपने अगले tool में डालने वाला हूँ, और इसे बनाने वालों के लिए ज़ोरदार तालियाँ हैं
GW-BASIC और MS-DOS को छोड़ दें तो Turbo BASIC, Turbo Pascal, Turbo C++ for MS-DOS and Windows 3.x, Turbo Vision, OWL—सब कुछ Borland ही था
VC++ मैंने शायद version 5 के आसपास इस्तेमाल किया, लेकिन MFC हमेशा Borland products की तुलना में बहुत फीका लगा
आज भी C++ Builder की RAD capabilities का सही मुकाबला कम ही चीज़ें कर पाती हैं, और .NET को भी Delphi जैसी low-level coding और AOT story को ठीक करने में काफ़ी समय लगा
मेरा मानना है कि Go, C++, और Rust developers को MS-DOS के लिए Turbo Pascal 7 और आधुनिक Delphi की कुछ-कुछ copies पकड़ाई जानी चाहिए
Turbo Vision 2.0 आज भी काफ़ी practical है, और मैंने एक साल पहले prototyping के काम में इसे सीधे इस्तेमाल किया था
मैंने LLDB debugger के लिए एक Turbo Vision frontend बनाने की कोशिश की थी ताकि वह Borland के Turbo Debugger जैसा काम करे, और ज़्यादातर चीज़ें मनचाहे तरीके से चलीं
यह देखकर हैरानी हुई कि यह 199x में जहाँ रुका था वहीं से जैसे आगे बढ़ गया हो, और 1993 का code भी बिना बड़ी समस्या के compile और run हो गया
एक बेहतर built-in editor का Scintilla-based version भी है, जिसमें syntax highlighting जैसी सुविधाएँ हैं, लेकिन जिस तरह मैं उसे modify करना चाहता था, वह ठीक से नहीं हुआ, इसलिए शायद author से मदद माँगनी पड़ेगी
हालाँकि आज के साझा ज्ञान वाले अर्थ में documentation की कमी है, इसलिए Stack Overflow या AI से पूछना आसान नहीं था; मुझे example code देखकर सीखना पड़ा और Turbo Vision की कुछ किताबें बार-बार पढ़ने वाली पुरानी शैली अपनानी पड़ी
manual layout काफ़ी झंझटभरा है, इसलिए Qt जैसी auto layout सुविधा होती तो अच्छा होता, और splitter भी याद आता है, हालाँकि उसे implement करना मुश्किल नहीं लगता
एक और हैरानी की बात यह थी कि TV असल में काफ़ी छोटा और compact है. 90s में यह बहुत विशाल लगता था
कुल मिलाकर modernization का काम बहुत अच्छे से हुआ है, और मुझे यह बेहद पसंद है
Turbo Vision मूल रूप से बहुत बड़ी मात्रा में high-quality documentation के साथ आता था
उल्टा मुझे लगता है कि ऐसी documentation की कमी आज की चीज़ों में ज़्यादा है
https://archive.org/details/bitsavers_borlandTurrogrammingGuide1992_25707423
इतनी सारी cmake directives देखकर बेवजह अतीत में लौटने का मन करता है
Turbo C या Pascal में तो बस F9 दबाते ही सब चल पड़ता था
दूसरी तरफ़, यह हमारी toolchain की अक्षम्यता भी दिखाता है
आज के ज़माने में तो बस किसी online compiler की ओर इशारा करो और तुरंत चला दो, या download करके एक folder खोलो और run कर दो—इतना काफ़ी होना चाहिए; यह tools नहीं, किसी ritual जैसी प्रक्रिया बन गई है
./configure && make && make install अब भी gold standard होना चाहिए
यह बस Turbo Vision ports/clones में से एक है
C++ side पर यह भी है: https://github.com/kloczek/tvision
FreePascal/Lazarus में शामिल version Pascal में लिखा गया है, और एक Rust version भी है, हालाँकि वह थोड़ा vibe-coded जैसा लगता है: https://github.com/aovestdipaperino/turbo-vision-4-rust
terminal में इसे चलाने पर वह मूल text-mode screen mouse वाली अहम अनुभूति थोड़ी खो जाती है
असली text-mode screen पर यह mouse pointer जैसा नहीं दिखता था, बल्कि mouse से हिलने वाला एक पीला block जैसा लगता था
जानना चाहूँगा कि किसी ने इसे high-resolution Linux text mode में GPM के साथ चलाया है या नहीं
यह ऊपर ढके हुए cell के रंगों को invert करके दिखाता था, और क्योंकि स्क्रीन का ज़्यादातर हिस्सा भरने वाली main window गहरे नीले रंग की होती थी, इसलिए नतीजा अक्सर चमकीले पीले block जैसा दिखता था
हाल की Wookash podcast में Chuck Jazdzewski वाला episode recommend करता हूँ
वह मूल Turbo Vision बनाने वाली team का हिस्सा था, और पूरे ecosystem के बारे में भी काफ़ी बातें करता है
मैं आज भी C++ version से ज़्यादा असल Turbo Vision, यानी Pascal version, चाहता हूँ
C++ version आख़िरकार Pascal version का एक अनुवाद ही ज़्यादा लगता है
उदाहरण के लिए Pascal में
usesएक keyword है, जबकि#defineसे modules include करने का तरीका थोड़ा hack जैसा लगता हैहालाँकि अब शायद यह कोई बहुत बड़ा फ़र्क न हो
text-mode IDE भी Free Vision का इस्तेमाल करता है
https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
लेकिन मुख्य फ़र्क यह है कि Free Vision और Turbo Vision, Delphi के
classकी जगह Turbo Pascal 5.5 के दौर वालेobjecttype का इस्तेमाल करते हैंclassमें RTTI की वजह से automatic serialization जैसी चीज़ें implement करना आसान होता है, लेकिनobjectमें वह नहीं होता, इसलिए runtime पर अलग-अलग types पहचानने के लिए object pointer के एक fixed offset पर मौजूद VMT pointer को register करके manual serialization करनी पड़ती हैFree Pascal ने
objectमें private/protected/public, property जैसी कुछ सुविधाजनक extensions जोड़ी हैं, लेकिन Free Vision मूल Turbo Vision API को implement करने के लिए उन extensions का इस्तेमाल नहीं करता