将旧的 DOS TUI 移植到 ncurses
Porting an old DOS TUI to ncurses
我想就如何移植 90 年代初为 MS-DOS 编写的旧 C++ 程序提出一些建议。
这个程序实现了一个相当复杂的文本用户界面。界面代码和逻辑分离的很好,我觉得用ncurses做起来也不会太难。
作为一个完全的新手,我有几个问题:
DOS程序拦截中断0x33来处理鼠标事件。中断处理程序将事件存储在 FIFO 中,主程序会定期收集这些事件。 (FIFO 中的每个元素都是一个 C 结构,包含有关事件性质、鼠标位置及其按钮状态的信息。)为了保持代码的逻辑不变,我正在考虑触发一个调用的线程getch() 在无限循环中异步运行,并以与旧程序相同的方式填充 FIFO。我的想法是这个线程,而且只有这个线程,应该访问 stdin,而主线程只负责访问 stdout(通过 add_wch() 和类似的)。以这种方式使用 ncurses 是否安全,或者 stdin/stdout 访问是否需要始终在同一线程内完成?
此应用中设置颜色的方式非常复杂,因为它使用了“继承调色板”的概念。基本上,window 通常指定背景和前景颜色,并且 window 中的每个小部件仅设置前景(但一些小部件重新定义两者 fg/bg)。我知道 ncurses 的 attr() 总是想使用对来指定颜色,这必须使用 initp() 进行初始化,这与该程序的逻辑不相符。因此,我正在考虑在程序想要分别更改 fg/bg 颜色时使用 tiparm() 直接发送 setaf/setbf 序列。 (我会失去 运行 不支持 setaf/setbf 的终端上的代码的能力,但这不会是一个巨大的损失。)发送 setaf/setbf 控制序列然后然后发送是否安全调用像 add_wch() 这样的函数,或者后者应该只与 attr() 结合使用?
我可以编写一些测试脚本来检查我的想法是否有效,但我不确定这种方法是否应该始终有效。
感谢您的帮助!
有很多可能性 - 但描述的方法听起来像 terminfo(低级)而不是 curses,除了提到 add_wch
。 curses 应用程序将使用 wattr_set
、init_pair
、start_color
等
而不是 tiparm
ncurses I/O 必须在一个线程中;虽然可以编译 ncurses 来提供帮助(通过在某些地方使用互斥锁),但打包者通常忽略了这一点(即使使用这种配置,应用程序开发人员仍然有工作要做)。
延伸阅读:
我想就如何移植 90 年代初为 MS-DOS 编写的旧 C++ 程序提出一些建议。
这个程序实现了一个相当复杂的文本用户界面。界面代码和逻辑分离的很好,我觉得用ncurses做起来也不会太难。
作为一个完全的新手,我有几个问题:
DOS程序拦截中断0x33来处理鼠标事件。中断处理程序将事件存储在 FIFO 中,主程序会定期收集这些事件。 (FIFO 中的每个元素都是一个 C 结构,包含有关事件性质、鼠标位置及其按钮状态的信息。)为了保持代码的逻辑不变,我正在考虑触发一个调用的线程getch() 在无限循环中异步运行,并以与旧程序相同的方式填充 FIFO。我的想法是这个线程,而且只有这个线程,应该访问 stdin,而主线程只负责访问 stdout(通过 add_wch() 和类似的)。以这种方式使用 ncurses 是否安全,或者 stdin/stdout 访问是否需要始终在同一线程内完成?
此应用中设置颜色的方式非常复杂,因为它使用了“继承调色板”的概念。基本上,window 通常指定背景和前景颜色,并且 window 中的每个小部件仅设置前景(但一些小部件重新定义两者 fg/bg)。我知道 ncurses 的 attr() 总是想使用对来指定颜色,这必须使用 initp() 进行初始化,这与该程序的逻辑不相符。因此,我正在考虑在程序想要分别更改 fg/bg 颜色时使用 tiparm() 直接发送 setaf/setbf 序列。 (我会失去 运行 不支持 setaf/setbf 的终端上的代码的能力,但这不会是一个巨大的损失。)发送 setaf/setbf 控制序列然后然后发送是否安全调用像 add_wch() 这样的函数,或者后者应该只与 attr() 结合使用?
我可以编写一些测试脚本来检查我的想法是否有效,但我不确定这种方法是否应该始终有效。
感谢您的帮助!
有很多可能性 - 但描述的方法听起来像 terminfo(低级)而不是 curses,除了提到 add_wch
。 curses 应用程序将使用 wattr_set
、init_pair
、start_color
等
tiparm
ncurses I/O 必须在一个线程中;虽然可以编译 ncurses 来提供帮助(通过在某些地方使用互斥锁),但打包者通常忽略了这一点(即使使用这种配置,应用程序开发人员仍然有工作要做)。
延伸阅读: