9 पॉइंट द्वारा GN⁺ 3 일 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • क्लासिक 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 के setlocale UTF-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 है
  • 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 JOINER U+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, moveCStr TStringView लेते हैं और Unicode rules के अनुसार string को प्रोसेस करते हैं
      • maxStrWidth bytes की संख्या नहीं बल्कि columns की संख्या पर आधारित है
      • strIndent भी bytes नहीं बल्कि columns की संख्या पर आधारित है, इसलिए इसे horizontal scroll में इस्तेमाल किया जा सकता है
      • return value कॉपी किए गए text की display width होती है
    • moveBuf TStringView आने से पहले 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.x columns ही कॉपी होते हैं, इसलिए bytes की संख्या और boundary conditions को सीधे calculate करने की जरूरत कम हो जाती है
  • Unicode display को support करने वाले standard views

  • Unicode input तक हैंडल करने वाले views

    • TInputLine, cb489d42, TEditor, TMenuView के shortcut keys में Unicode user input भी हैंडल किया जाता है
    • TEditor instance 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 के TIOCLINUX modifiers और GPM mouse को सपोर्ट करता है
    • प्रोग्राम के असामान्य रूप से बंद होने से पहले टर्मिनल स्थिति को बहाल करने के लिए custom signal handler मौजूद है
    • अगर stderr tty हो, तो स्क्रीन खराब होने से बचाने के लिए आउटपुट को बफ़र में रखता है और exit या suspend के समय प्रिंट करता है
      • बफ़र आकार की सीमा होने के कारण, भर जाने पर stderr write विफल हो सकता है
      • सब कुछ सुरक्षित रखने के लिए 2> redirection की सिफारिश की जाती है
    • TERM, COLORTERM, ESCDELAY, TVISION_USE_STDIO environment 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_t variants सीधे इस्तेमाल करने की ज़रूरत कम हो
    • legacy mode और bitmap font के संयोजन में Unicode display टूट सकता है, और इसे detect करने पर font को Consolas या Lucida Console में बदलने की कोशिश करता है
      • उदाहरण photo में देखा जा सकता है
  • सामान्य व्यवहार सुधार

    • 24-bit color, stdin/stdout/stderr redirection के साथ सह-अस्तित्व, और 32-bit help file compatibility प्रदान करता है
    • TVISION_MAX_FPS environment variable से अधिकतम refresh rate नियंत्रित करता है
      • default मान 60 है
      • 0 सीमा को disable करता है
      • -1 हर THardwareInfo::screenWrite call पर तुरंत draw करता है
    • middle mouse button, mouse wheel, अधिकतम 32767 पंक्ति/स्तंभ screen size, और resize events को सपोर्ट करता है
    • window को नीचे-बाएँ कोने से भी resize किया जा सकता है, और middle button से खाली क्षेत्र को पकड़कर drag किया जा सकता है
    • menu को parent item पर दोबारा क्लिक करके बंद किया जा सकता है, और scrollbar drag के दौरान page scroll तथा wheel input पर प्रतिक्रिया देता है
    • TInputLine focus बदलने पर टेक्स्ट को अनावश्यक रूप से scroll नहीं करता
    • TFileViewer और TEditor LF line ending को सपोर्ट करते हैं, और TEditor save करते समय मौजूदा 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 शामिल है

इवेंट लूप और 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() इसे default 20 वाले 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, Union TRect& लौटाते हैं, जिससे chaining संभव होती है
  • TApplication डिफ़ॉल्ट रूप से dosShell(), cascade(), tile() प्रदान करता है और cmDosShell, cmCascade, cmTile को default रूप से handle करता है
  • TStringView, TSpan<T>, TDrawSurface, TSurfaceView, TClipboard जैसे types जोड़े गए हैं
  • THardwareInfo, TScreen, TEventQueue का initialization main से पहले नहीं, बल्कि पहले TApplication के निर्माण पर होता है
  • input extensions भी शामिल हैं
    • evMouseWheel, mwUp, mwDown, mwLeft, mwRight
    • mbMiddleButton, meTripleClick
    • evMouseUp.buttons में छोड़े गए button की जानकारी बनी रहती है
    • hotKeyStr, getAltCharStr, getCtrlCharStr से multibyte shortcuts लागू किए जा सकते हैं
    • TKey से Shift+Alt+Up जैसे नए key combinations परिभाषित किए जा सकते हैं
    • TInputLine ilMaxBytes, ilMaxWidth, ilMaxChars के limitMode को सपोर्ट करता है

क्लिपबोर्ड इंटीग्रेशन

  • सिस्टम क्लिपबोर्ड इंटीग्रेशन

    • पहले केवल TEditor::clipboard static member के जरिए आंतरिक क्लिपबोर्ड उपलब्ध था, और इसका उपयोग सिर्फ TEditor कर सकता था
    • नया TClipboard class सिस्टम क्लिपबोर्ड तक पहुंचता है, और अगर पहुंच संभव न हो तो आंतरिक क्लिपबोर्ड का उपयोग करता है
  • समर्थित वातावरण

    • Windows, WSL, macOS में यह डिफ़ॉल्ट रूप से समर्थित है
    • macOS को छोड़कर Unix में external dependency की आवश्यकता होती है
    • remote execution में ssh -X की X11 forwarding, far2l और putty4far2l, तथा OSC 52 सपोर्ट वाले टर्मिनल में यह काम कर सकता है
    • कुछ अन्य टर्मिनल केवल copy को सपोर्ट करते हैं
    • टर्मिनल emulator का Ctrl+Shift+V या Cmd+V paste अलग से हमेशा संभव है
  • API और paste handling

    • <tvision/tv.h> शामिल करने से पहले Uses_TClipboard define करने पर TClipboard का उपयोग किया जा सकता है
    • setText(TStringView text) सिस्टम क्लिपबोर्ड की सामग्री सेट करता है, और पहुंच संभव न हो तो आंतरिक क्लिपबोर्ड का उपयोग करता है
    • requestText() सिस्टम क्लिपबोर्ड की सामग्री के लिए asynchronous request भेजता है, और बाद में सामान्य evKeyDown event के रूप में उसे प्राप्त करता है
    • paste किया गया text, keyDown.controlKeyState के kbPaste flag से सामान्य key input से अलग पहचाना जा सकता है
    • लंबे paste को हजारों key input की तरह process करने वाली inefficiency को कम करने के लिए TView::textEvent(...) जोड़ा गया है
      • लगातार आने वाले evKeyDown text को user buffer में इकट्ठा करके पढ़ता है
      • जब वह आगे text न रहे, तो putEvent() के जरिए अगले loop में भेज देता है
  • standard command integration

    • TEditor और TInputLine, cmCut, cmCopy, cmPaste commands पर प्रतिक्रिया देते हैं
    • 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 भी TColorAttr array का उपयोग करता है
    • TView::mapColor अब virtual है, जिससे hierarchical palette system को bypass करके color specify किया जा सकता है
  • TColorBIOS, TColorRGB, TColorXTerm, TColorDesired के जरिए color representation की परतें बांटी गई हैं
    • TColorAttr में foreground, background, style bitmask होते हैं
    • 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::screenMode display capability को expose करता है
    • smMono monocolor है
    • smBW80 grayscale है
    • 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 होते ही खो सकते हैं
  • draw method में 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, tvhc Help Compiler भी साथ में जनरेट होते हैं
    • आवश्यकताएँ हैं C++14 सपोर्ट करने वाला compiler, libncursesw, और वैकल्पिक libgpm
    • runtime clipboard integration के लिए xsel, xclip, wl-clipboard का उपयोग होता है
    • कुछ environments में -ltinfow की ज़रूरत पड़ सकती है, नहीं तो रनटाइम पर segmentation fault हो सकता है
      • संबंधित issue: #11
  • 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:__cplusplus flags चाहिए, और CMake submodule तरीके में यह अपने-आप सक्षम हो जाता है
    • इसमें लिखा है कि उचित MSVC version और settings के साथ Windows XP भी संभव है
    • MinGW भी Linux की तरह CMake से बिल्ड होता है, और यदि compiler सपोर्ट करे तो Windows XP या उसके बाद के संस्करणों पर चल सकता है
    • Borland C++ से भी DOS या Windows library बिल्ड की जा सकती है, लेकिन Unicode का समर्थन नहीं है
    • Borland C++ environment में winevdm के उपयोग को एक विकल्प के रूप में सुझाया गया है
  • प्रोजेक्ट इंटीग्रेशन के तरीके और डिप्लॉयमेंट स्थिति

    • CMake में find_package(tvision CONFIG) या add_subdirectory(tvision) ये दो तरीके दिए गए हैं
    • दोनों तरीके include paths और Ncurses, GPM जैसी आवश्यक links को अपने-आप संभालते हैं
    • vcpkg में tvision port उपलब्ध है
    • अभी कोई 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 या उसके बाद के संस्करण की आवश्यकता

उदाहरण, दस्तावेज़, उपयोग के मामले

  • शुरुआत के लिए Turbo Vision For C++ User's Guide की सिफारिश की गई है
  • बुनियादी बातें सीखने के बाद Turbo Vision 2.0 Programming Guide को संदर्भ के रूप में देखा जा सकता है
  • उदाहरणों में hello, tvdemo, tvedit, palette आदि दिए गए हैं
  • screenshots का संग्रह here में देखा जा सकता है
  • उपयोग में मौजूद applications के रूप में ये दिए गए हैं
    • Turbo: proof-of-concept text editor
    • tvterm: proof-of-concept terminal emulator
    • TMBASIC: console applications बनाने के लिए programming language

1 टिप्पणियां

 
GN⁺ 3 일 전
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 देखकर सच में बहुत आभार महसूस हुआ

    • Oxygene RemObjects के Elements product family का हिस्सा है, इसलिए Pascal-आधारित Oxygene के अलावा भी आप कई लोकप्रिय languages को मिलाकर Windows, macOS, Linux, Android वगैरह पर ले जा सकते हैं
      https://www.remobjects.com/elements/oxygene/
      https://www.remobjects.com/elements/
    • मैंने भी इस tvision port के साथ काम किया है, और जब भी कोई नया TUI framework छूता हूँ तो आख़िर में यही लगता है कि Turbo Vision ज़्यादा बेहतर है
      मैं भी एक .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 कैसे बना है, यह जानने की जिज्ञासा है
    • इस TV library के साथ काम करने में nostalgia का मज़ा भरपूर मिलता है
      शायद इसी वजह से 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 फ़ायदे सचमुच अच्छे से सीखे जा सकते थे

    • मज़ेदार बात यह है कि Free Vision कभी public domain में छोड़े गए C++ version का किसी ने हाथ से अनुवाद करके उसे फिर Object/Free Pascal में वापस ले जाने का नतीजा है
    • OWL सच में अपने समय से बहुत आगे था
  • जब Borland ने Turbo Pascal, Turbo C++, और TurboVision जारी किए, तो लगा जैसे संभावनाओं का पूरा ब्रह्मांड खुल गया हो
    compiler performance भी शानदार थी और manuals कला-कृतियों जैसे थे; काश वे किताबें अभी भी मेरे पास होतीं
    यह बस एक सांस्कृतिक ख़ज़ाना है

    • वे manuals सच में कमाल के थे
      90s की शुरुआत में मैंने लगभग सिर्फ़ Turbo C++ के साथ आने वाली Borland की किताबों के ढेर को पढ़कर खुद C/C++ सीखा था, और आज यह कल्पना करना भी मुश्किल है कि कोई सिर्फ़ reference books पढ़कर इस तरह सीख सकता है
    • Turbo Vision लंबे समय तक मेरे लिए gold standard जैसा था
      नए TUI frameworks में हमेशा कुछ न कुछ कमी लगती थी, और अब इसे फिर से इस्तेमाल करके देखूँगा कि वह सिर्फ़ nostalgia था या नहीं
      मैं इसे अपने अगले tool में डालने वाला हूँ, और इसे बनाने वालों के लिए ज़ोरदार तालियाँ हैं
    • एक समय था जब मैं पूरी तरह Borland all-in था
      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 जैसी प्रक्रिया बन गई है

    • आधुनिक Unix में software compile करना एक समय पहले से हल की गई समस्या था
      ./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 जैसा लगता है
    हालाँकि अब शायद यह कोई बहुत बड़ा फ़र्क न हो

    • Free Pascal के साथ शामिल Free Vision लगभग वही भूमिका निभाता है
      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 के दौर वाले object type का इस्तेमाल करते हैं
      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 का इस्तेमाल नहीं करता