0

I would like to have some advice about how to port an old C++ program written for MS-DOS in the early 90s.

This program implements a quite complex text-user interface. The interface code is well separated from the logic, and I don't think it would be too difficult to make it use ncurses.

Being a complete novice, I have a few questions:

  1. The DOS program intercepts interrupt 0x33 to handle mouse events. The interrupt handler store events in a FIFO, which the main program pools periodically. (Every element in the FIFO is a C structure containing information about the nature of the event, the position of the mouse and the state of its buttons.) To keep the logic of the code unchanged, I was thinking of firing a thread which calls getch() asynchronously within an infinite loop and fills the FIFO in the same way the old program did. My idea is that this thread, and only this thread, should access stdin, while the main thread would only have the responsibility to access stdout (through add_wch() and similar). Is ncurses safe to use in this way, or do stdin/stdout accesses need to be always done within the same thread?

  2. The way colors are set in this app is quite byzantine, as it uses the concept of "inherited palettes". Basically, a window usually specifies the background and foreground colors, and every widget within that window sets the foreground only (but a few widgets redefine both fg/bg). I understand that ncurses' attr() always wants to specify colors using pairs, which must be initialized using initp(), and this doesn't play nicely with the logic of this program. I am therefore thinking of using tiparm() to directly send setaf/setbf sequences when the program wants to change the fg/bg color, respectively. (I would lose the ability to run the code on terminals which do not support setaf/setbf, but this would not be a huge loss.) Is it safe to send setaf/setbf control sequences and then call functions like add_wch(), or should the latter be used only in association with attr()?

    I could write a few test scripts to check that my ideas work, but I would not be sure that this approach is supposed to work always.

Thanks for any help!

Community
  • 1
  • 1
Maurizio Tomasi
  • 474
  • 4
  • 11

1 Answers1

1

There's a lot of possibilities - but the approach described sounds like terminfo (low-level) rather than curses, except for the mention of add_wch. Rather than tiparm, a curses application would use wattr_set, init_pair, start_color, etc.

ncurses I/O has to be in one thread; while ncurses can be compiled to help (by using mutexes in some places), packagers have generally ignored that (and even with that configuration, application developers still would have work to do).

Further reading:

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • Your comment about terminfo is true, in fact I am mainly interested in ncurses' `getch` function. Its implementation seems far from being trivial. If I understand your comment, using low-level terminfo functions and `printf` in the main thread and `getch` in the event thread would be ok, as all ncurses functions (just this one, in fact) would be called in the same thread. Is this correct? – Maurizio Tomasi Mar 29 '17 at 02:26
  • `getch` is not a low-level function (it's part of the curses library, and has to be initiialized with `initscr` or `newterm`, and will update the screen using the other curses-library functions). Even with the ncurses configuration which *helps* with threading, there is still the low-level data used by `tparm`, `tputs`, etc. requiring a mutex. – Thomas Dickey Mar 29 '17 at 08:03
  • Thank you a lot Thomas, this was exactly the information I needed (although it was not what I was hoping…). – Maurizio Tomasi Mar 29 '17 at 08:33