Turbo Vision is a character-mode text user interface framework.
Turbo Vision C++ is a framework developed by Borland. It is a text-based user interface framework created in the early 1990s by Borland.
Turbo Vision was integrated into Borland Pascal, Turbo Pascal, and Borland C++ and was used to create integrated development environments (IDEs) for these programming languages.
The framework offers various user interface elements such as edit fields, list boxes, checkboxes, radio buttons, and menus, all of which have mouse support.
Turbo Vision was originally written in Pascal and C++ and was intended for MS-DOS and IBM PC compatible systems.
It was later discontinued in favor of the Object Windows Library, the Win16 API, and the GUI tools of Borland Delphi. In 1997, Borland released the C++ source code into the public domain.
Although Turbo Vision was later released into the public domain and further developed by an open-source community, there are no known ports to Perl.
Most further developments and ports focused on other platforms, such as Unix systems.
Starting in 2025, I made the previously private project public after successfully porting the Turbo Vision C++ framework to Perl for the target platform Windows 10 and 11 (after two failed attempts, see commits history for details).
This port is based on the original codebase of Borland C++ 4.02 (Turbo Vision 2.0 sources including bug fixes by Eric Woodruff: tv2fixed.zip). In addition, assembler routines that have been ported to C++ come from magiblot's implementation "A modern port of Turbo Vision 2.0.".
Perl TVision wanted to enable developers to use the powerful text-based user interfaces of Turbo Vision in Perl.
lib/TV/
+-- App/ - TProgram, TApplication, TDeskTop, TBackground, etc.
+-- Dialogs/ - TDialog, TButton, TInputLine, TLabel, etc.
+-- Drivers/ - TEvent, TScreen, TEventQueue, THardwareInfo, etc.
+-- Editors/ - TEditor, TMemo, TFileEditor, TIndicator, etc.
+-- Gadgets/ - TClickTester, TEventViewer, THeapView, etc.
+-- Help/ - THelpFile, THelpTopic, THelpViewer, etc.
+-- Memory/ - Memory manager
+-- Menus/ - TMenuBar, TMenuBox, TStatusLine, etc.
+-- Objects/ - TObject, TPoint, TRect, TCollection, TSortedCollection, etc.
+-- StdDlg/ - TFileDialog, TChDirDialog, TDirListBox, etc.
+-- TextView/ - TTextDevice, TTerminal, etc.
+-- toolkit/ - Object toolkit
+-- Validate/ - TValidator, TFilterValidator, TPXPictureValidator, etc.
+-- Views/ - TDrawBuffer, TView, TGroup, TFrame, TScroller, TWindow, etc.This following checklist maps all Borland Turbo Vision classes to their Perl equivalents in the TVision port. It reflects the actual state of the repository as observed from the module tree.
Each entry includes:
Borland class name
Perl module name (if present)
Porting status
[x] = implemented [ ] = missing [o] = partial
+----------------+---------------------------+-----------+
| TPoint | TV::Objects::Point | [x] |
| TRect | TV::Objects::Rect | [x] |
| TDrawBuffer | TV::Views::DrawBuffer | [x] |
| TPalette | TV::Views::Palette | [x] |
| TCommandSet | TV::Views::CommandSet | [x] |
+----------------+---------------------------+-----------++----------------+---------------------------+-----------+
| TEvent | TV::Drivers::Event | [x] |
| KeyDownEvent | TV::Drivers::Event | [x] |
| MouseEvent | TV::Drivers::Event | [x] |
| MessageEvent | TV::Drivers::Event | [x] |
| TEventQueue | TV::Drivers::EventQueue | [x] |
+----------------+---------------------------+-----------++----------------+---------------------------+-----------+
| THWMouse | TV::Drivers::HWMouse | [o] |
| TMouse | TV::Drivers::Mouse | [x] |
| TSystemError | TV::Drivers::SystemError | [o] |
| TScreen | TV::Drivers::Screen | [o] |
| TDisplay | TV::Drivers::Display | [o] |
| THardwareInfo | TV::Drivers::HardwareInfo | [o] |
+----------------+---------------------------+-----------+Win32 Console Driver, implemented in TV::Drivers::HardwareInfo::Win32.
+----------------+---------------------------+-----------+
| TObject | TV::Objects::Object | [x] |
| TView | TV::Views::View | [x] |
| TGroup | TV::Views::Group | [x] |
| TFrame | TV::Views::Frame | [x] |
| TScrollBar | TV::Views::ScrollBar | [x] |
| TScroller | TV::Views::Scroller | [x] |
| TListViewer | TV::Views::ListViewer | [x] |
| TBackground | TV::App::Background | [x] |
+----------------+---------------------------+-----------+Hierarchical screen write system, implemented in TV::Views::View::Write.
+----------------+---------------------------+-----------+
| TDeskInit | TV::App::DeskInit | [x] |
| TDeskTop | TV::App::DeskTop | [x] |
| TProgInit | TV::App::ProgInit | [x] |
| TProgram | TV::App::Program | [x] |
| TApplication | TV::App::Application | [x] |
| TWindowInit | TV::Views::WindowInit | [x] |
| TWindow | TV::Views::Window | [x] |
| TDialog | TV::Dialogs::Dialog | [x] |
+----------------+---------------------------+-----------+Buttons and Clusters
+------------------+------------------------------+-----------+
| TButton | TV::Dialogs::Button | [x] |
| TSItem | TV::Dialogs::StrItem | [x] |
| TCluster | TV::Dialogs::Cluster | [x] |
| TRadioButtons | TV::Dialogs::RadioButtons | [x] |
| TCheckBoxes | TV::Dialogs::CheckBoxes | [x] |
| TMultiCheckBoxes | TV::Dialogs::MultiCheckBoxes | [x] |
+------------------+------------------------------+-----------+Input and Text
+----------------+---------------------------+-----------+
| TInputLine | TV::Dialogs::InputLine | [x] |
| TStaticText | TV::Dialogs::StaticText | [x] |
| TParamText | TV::Dialogs::ParamText | [x] |
| TLabel | TV::Dialogs::Label | [x] |
+----------------+---------------------------+-----------+Lists and History
+----------------+--------------------------------------+-----------+
| TListBox | TV::Dialogs::ListBox | [x] |
| TListBoxRec | TV::Dialogs::ListBox | [x] |
| TSortedListBox | TV::StdDlg::SortedListBox | [x] |
| HistRec | TV::Dialogs::HistoryViewer::HistList | [x] |
| THistoryViewer | TV::Dialogs::HistoryViewer | [x] |
| THistInit | TV::Dialogs::HistInit | [x] |
| THistoryWindow | TV::Dialogs::HistoryWindow | [x] |
| THistory | TV::Dialogs::History | [x] |
+----------------+--------------------------------------+-----------++-----------------+----------------------------+-----------+
| ffblk/find_t | TV::StdDlg::Dos | [x] |
| FindFirstRec | TV::StdDlg::FindFirstRec | [o] |
| TFileDialog | (missing) | [ ] |
| TChDirDialog | (missing) | [ ] |
| TFileInputLine | TV::StdDlg::FileInputLine | [x] |
| TFileList | (missing) | [ ] |
| TFileInfoPane | (missing) | [ ] |
| TDirListBox | (missing) | [ ] |
| TDirEntry | (missing) | [ ] |
| TDirCollection | (missing) | [ ] |
| TFileCollection | TV::StdDlg::FileCollection | [x] |
| TSearchRec | TV::StdDlg::FileCollection | [x] |
+-----------------+----------------------------+-----------+Win32 FindFirstRec class, implemented in TV::Drivers::FindFirstRec::Win32.
+----------------+---------------------------+-----------+
| TMenuItem | TV::Menus::MenuItem | [x] |
| TMenu | TV::Menus::Menu | [x] |
| TMenuView | TV::Menus::MenuView | [x] |
| TMenuBar | TV::Menus::MenuBar | [x] |
| TMenuBox | TV::Menus::MenuBox | [x] |
| TMenuPopup | (missing) | [ ] |
| TSubMenu | TV::Menus::SubMenu | [x] |
| TStatusLine | TV::Menus::StatusLine | [x] |
| TStatusItem | TV::Menus::StatusItem | [x] |
| TStatusDef | TV::Menus::StatusDef | [x] |
+----------------+---------------------------+-----------++------------------+-------------------------+-----------+
| messageBox() | TV::MsgBox::MsgBoxText | [x] |
| messageBoxRect() | TV::MsgBox::MsgBoxText | [x] |
| inputBox() | TV::MsgBox::MsgBoxText | [x] |
| inputBoxRect() | TV::MsgBox::MsgBoxText | [x] |
+------------------+-------------------------+-----------++------------------------+-------------------+-----------+
| TValidator | (missing) | [ ] |
| TFilterValidator | (missing) | [ ] |
| TRangeValidator | (missing) | [ ] |
| TLookupValidator | (missing) | [ ] |
| TStringLookupValidator | (missing) | [ ] |
| TPXPictureValidator | (missing) | [ ] |
+------------------------+-------------------+-----------++----------------------+---------------------------------+-----------+
| TNSCollection | TV::Objects::NSCollection | [x] |
| TNSSortedCollection | TV::Objects::NSSortedCollection | [x] |
| TCollection | TV::Objects::Collection | [x] |
| TSortedCollection | TV::Objects::SortedCollection | [x] |
| TStringCollection | TV::Objects::StringCollection | [x] |
| TStringList | (missing) | [ ] |
| TStrListMaker | (missing) | [ ] |
| TResourceCollection | (missing) | [ ] |
| TResourceFile | (missing) | [ ] |
+----------------------+---------------------------------+-----------++----------------+---------------------------+-----------+
| TEditor | (missing) | [ ] |
| TMemo | (missing) | [ ] |
| TFileEditor | (missing) | [ ] |
| TEditWindow | (missing) | [ ] |
| TIndicator | (missing) | [ ] |
| TTextDevice | TV::TextView::TextDevice | [x] |
| TTerminal | TV::TextView::Terminal | [x] |
+----------------+---------------------------+-----------++-----------------+--------------------------+-----------+
| TCalcDisplay | (missing) | [ ] |
| TCalendarView | (missing) | [ ] |
| TClickTester | (missing) | [ ] |
| TClockView | TV::Gadgets::ClockView | [x] |
| TEventViewer | TV::Gadgets::EventViewer | [x] |
| THeapView | TV::Gadgets::HeapView | [o] |
| TLineCollection | (missing) | [ ] |
| TPuzzleView | (missing) | [ ] |
+-----------------+--------------------------+-----------+Win32 THeapView, implemented in TV::Gadgets::HeapView::Win32.
These following areas represent the bulk of Turbo Vision's higher-level UI framework.
The project has completed the foundational subsystems:
Core primitives
Event system
Platform layer (partial)
View hierarchy (core)
Menu system
Status system
TextView subsystem
Dialog controls
The remaining work is concentrated in:
File/Directory dialogs
Validators
Editors
Gadgets
Resource/collection extensions
Standard dialogs
Summary
Total Borland classes/items tracked: 141
Implemented: 73
Partial: 8
Missing: 60Notes: Calculated from the full inventory of ~140 Turbo Vision classes, dialogs, widgets, validators, and subsystems as defined in the mapping list.
Languages with automatic garbage collection (like Perl) have complementary problems compared to languages without garbage collection (like C/C++). For every issue, there is a bug characteristic of non-GC languages and a bug characteristic of GC languages, along with programmer responsibilities in both types.
Perl programmers might think they are relieved from freeing objects, but objects hold other resources besides memory that often need to be released appropriately. Where a C++ programmer might have a dangling reference (often not a bug due to some flag or state marking it as not to be used), a Perl programmer has a memory leak. Thus, the C++ programmer is responsible for ensuring free/delete is called appropriately, while the Perl programmer must ensure unwanted references are nulled or otherwise disposed of properly.
Perl 5 supports weak references so that programmers can deliberately avoid creating reference cycles. If data structures contain reference cycles, these are only reclaimed by the Perl runtime when the parent thread is switched off. This is seen as a welcome compromise, as opposed to implementing overhead cycle detection, which would slow down execution time.
It is claimed that a few calls to weaken or using Proxy Objects can handle this. This might be true, but Turbo Vision sources use many dangling references in various tree structures or collections. To break all these cycles and ensure timely disposal of garbage memory, the Perl implementation must have an intelligent scheme.
Turbo Vision C++ code relies heavily on the convention of resource allocation and ensures reliable and timely destructor calls. This is not possible in Perl, which works with cycles. This poses some challenges during implementation. If you interrupt a garbage cycle, you can't know which destructor to call first without causing dependency problems - it might even be impossible, since there are more cyclic dependencies than just memory references. All other resources have to be cleaned up manually, like in Pascal or C++, without the advantages of Perl.
When porting C++ code to Perl, one common pitfall is accidentally replacing an object reference instead of copying data into the existing object. In C++, passing by reference ensures that assignments modify the caller's object, while in Perl the same assignment simply rebinds a local scalar and discards the caller's reference. This difference can silently break control flow, especially in event-driven systems where modified objects must propagate back to the caller.
- Compatibility
-
The port supports 32-bit and 64-bit Strawberry Perl versions >= 5.10 and covers a wide range of Windows systems (Please note that not all combinations of Windows versions and Perl versions could be checked by me).
- User Interfaces
-
All original user interface elements such as edit fields, list boxes, checkboxes, radio buttons, and menus are available in Perl and offer full mouse support (in the future, so please don't be angry that this is in progress; see Coverage).
- Extensibility
-
A Moo/s/e based toolkit was used to ensure that the applications remain efficient and portable. The toolkit enables developers to extend the functionality of Perl TVision easily and efficiently. The Moos package (by default), Moo and Moose are currently supported.
Moo and Moose are widely used libraries with a well-known API. It is important to note that Moo and Moose are not required as prerequisites! The default toolkit Moos is compatible with this API and implemented in pure Perl.
It's up to you what you want to use. Simply
use Mooin your application, instead ofuse TV::toolkitif you want to use Moo. Perl TVision will then use Moo in its entirety (the same applies to Moose, of course).
The port can be installed via CPAN (Comprehensive Perl Archive Network). Simply run the following command:
cpan install TurboVisionA simple example to create an application with Turbo Vision in Perl:
use TV::App;
my $app = TApplication->new();
$app->run();Detailed documentation and examples can be found in the CPAN or GitHub repository of this port.
Please note that this is a very recent version of the port of the Turbo Vision C++ framework to Perl. Although I have done my best to create a stable and functional version, there may still be bugs and instabilities.
However, I do my best to answer questions and bug fixes quickly and reliably. Your feedback is extremely valuable to continuously improve the quality and stability of this port. Please do not hesitate to contact me if you have any problems or questions. For this use the GitHub issue tracker and the Github discussion channel.
I hope this port will facilitate the development of text-based applications in Perl on Windows systems and look forward to feedback and contributions from the developer community.
Copyright (c) 1990-1994, 1997 by Borland International
Copyright (c) 2021-2026 the AUTHORS and CONTRIBUTORS as listed in the sources.
This software is licensed under the MIT license (see the LICENSE file, which is part of the distribution).