PDCurses for "real" Windows
Screen shot of 'newtest'

The above screen shot shows some of the things this flavor of PDCurses can do, such as display of bold, italic, underlined, overlined, 'strikeout', blinking text, and 256 colors. (The actual window does have blinking text as indicated; I didn't try to replicate that in the screen shot!)

Last updated 2012 May 14

Description of this version:

PDCurses currently comes in several flavors: DOS, Win32 console, XCurses, OS/2, and SDL. These each have merits and demerits, but none actually implements all PDCurses capabilities. For example, only XCurses and SDL allow for underlined and left/right lined text. Most versions don't implement italic or blinking text, and "bold" text usually just means "brighter color" text. The machines may support lots of colors, but PDCurses usually supports 16 or 8. Mouse wheel events and double-clicks aren't always handled. I wanted a full-capability, no-compromises version of PDCurses.

One possibility would have been to modify the SDL version. That would have made some sense; I'd have had to add bold and italic fonts, blinking text, and revised it to support 256 colors. This is still a tempting idea, especially since I'd have a cross-platform solution (though since Win32a works perfectly with Wine, it really is cross-platform). However, I thought it wouldn't take too long to make a for-real Windows version. Silly me! (Despite the fact that one can run Win32a apps using Wine, I'm still mildly tempted to modify the X11 flavor of PDCurses to support all the things this flavor supports. But I probably won't do that unless somebody pays me for it, which seems unlikely.)

In any case, to bring SDL up to par with Win32a, I'd now have to revise SDL to support Unicode, triple mouse clicks, a more advanced concept of cursor display, cutting and pasting to clipboard, hotkeys to change the font size, resizable windows, and more.

Anyway... it does look as if this flavor of PDCurses now supports absolutely everything known to Curses, even nearly useless features such as triple mouse clicks. All display attributes work, and all mouse and keyboard events are detected. The window can be resized, programmatically or by the user, and font sizes can be chosen. The user can click and drag a rectangle and have it copied to the clipboard, and/or paste from the clipboard to the input stream.

I have made some extensions to PDCurses, but backward compatibility has been key. None of the original features of PDCurses has been broken. You should be able to compile your legacy PDCurses apps with this new library, and all should work Just Fine *.

This flavor is currently known as Win32a, just to distinguish it from the "real", console-based Win32 version.

* The only caveats I can think of are that your app will now be resizable like any other Windows window; and that you might get certain unexpected input, such as triple-clicks or left/right-wheel events on tilt-wheel mice. I'd think the resizing might confuse some apps that expect a fixed 80-column, 25-row screen and no messing. If that's a big deal, it would be possible to add a "no user resizing" feature. (Which would probably also come in handy with the SDL and XCurses flavors.)

Licensing

Like the rest of PDCurses, Win32a is in the public domain. I hope to get it merged as a flavor of PDCurses. I've e-mailed the maintainers of PDCurses, and am awaiting a reply. But the "mainstream" PDCurses project appears to be mostly inactive; I have doubts this will ever join "mainstream" PDCurses.

Download the source code

Click here to download the source code (about 191 KBytes). Make a folder such as c:\pdcurses and and unZIP the source into it. You should then be able to change to the c:\pdcurses\win32a folder and compile it, using the various make files for MinGW, Visual C/C++, or OpenWATCOM (or possibly the others; those are the three compilers I've used.)

I have maintained the basic form of the standard PDCurses distribution. The file/directory layout is almost identical, except with the Win32a folder and no X11, OS2, DOS, etc. folders. The Win32a folder is new, of course. The other files are either exact copies of those supplied with standard PDCurses, or incorporate small changes required to get things working with Win32a (but which do not "break" the other flavors of PDCurses.) The pdcurses folder has a file, diff.txt, which explains what got changed in existing files and why.

I was providing a DLL for a while, and one could swap it in for an existing PDCurses DLL so that current PDCurses apps (if linked to a DLL) would suddenly become Win32a ones. Unfortunately, when I extended Win32a to support five-button mice, it made it impossible to do this sort of swapping. The addition of tilt-wheel mouse support further breaks binary compatibility.

Soft Label Key (SLK) improvements

This is being provided as part of Win32a, but can be applied to any flavor of PDCurses. In fact, you could download standard PDCurses and simply replace the slk.c file provided in that distribution with the one provided in this distribution, and you'd have the new SLK features described below.

Soft Label Keys are shown at the bottom of the screen shot at the top of this page: they provide a simple way to make sure that there are a few buttons, which can be user-labelled, at the bottom of the window. A line or two has to be sacrificed to accommodate them. Click on the buttons, and it's as if you hit a function key.

As provided in current PDCurses, you can have only certain configurations of buttons: "3-2-3" format (three buttons on the left and right sides and two in the middle), "4-4" format (four on each side), "4-4-4", "5-5", and "4-4-4 with index", in which above each button is a label giving the corresponding function key. You can't get any other format, nor can you change formats in mid-program.

The revised slk.c in Win32a fixes both limitations. As is described in the code itself, you can get essentially any label layout you want. (This actually resulted in somewhat simpler code. The original version treated each layout as a special case, without recognizing that they could be handled in a common manner.) I also found that by adding a couple of lines of code, I was able to allow changes in format in mid-program; see newtest.cpp (part of the Win32a source code) for an example. You do still have to set up soft label keys before the window is initialized. Turning SLKs on (or off) after the window was created would mean adding (or removing) lines from the main window, and I've not seen a good way to do that.

Changes:

Fixes (2012 May 14) :

Fixes (2011 November 1) :

Fixes (2011 September 14) :

Fixes (2011 June 12) :

Fixes (2011 January 20) :

Fixes (2010 December 26) :

Fixes (2010 November 29) :

Fixes (2010 November 12) :

Fixes (2010 September 26) :

Fixes (2010 August 5) :

Fixes (2010 May 24) :

Fixes (2010 May 9) :

Fixes (2010 May 4) :

Fixes (2010 May 3) :

Fixes (2010 Apr 30) :

Fixes (2010 Apr 29) :

Fixes (2010 Apr 26) :

Fixes (2010 Apr 23) :

Fixes (2010 Apr 19) :

Fixes (2010 Apr 15) :

Fixes (2010 Apr 14) :

Fixes (2010 Apr 13) :

Fixes (2010 Apr 12) :

Fixes (2010 Apr 11) :

Fixes (2010 Apr 7) :

Fixes (2010 Apr 6) :

Fixes (2010 Apr 5) :

Fixes (2010 Apr 4) :

Fixes (2010 Apr 3) :

Fixes (2010 Apr 1) :

Fixes (2010 Mar 30) :

Known Problems:

• As is described above, I'm not totally confident that all thread-collision problems have been resolved. (In fact, I'm sure some remain; PDCurses is liberally salted with globals, and making it truly thread-safe seems unlikely. The question is if the problems are of merely theoretical interest, or could cause realistic trouble. I'm inclined to think the former, but am not sure.) The problem is that people rely on those globals, so making it truly re-entrant doesn't appear to be an option.

• In the input test part of 'testcurs', mouse move events are reported if a button is pressed. Looking at the definition of ALL_MOUSE_EVENTS in curses.h, this makes sense; all bits are set, except for the REPORT_MOUSE_POSITION button. I turned that one on, too, thinking it would cause 'testcurs' to report all mouse movement, whether buttons were pressed or not. That doesn't happen, with either the SDL or "standard" Win32 libraries. This is probably a matter of my not understanding how PDCurses is supposed to work.

• At certain font sizes, junk can be left behind on the screen. Probably the way around this will involve just not using those sizes. (I think this happens because sometimes, a "fixed-width" TrueType font has a non-integral width/height. It may also have to do with TrueType fonts not necessarily staying within the character block size. The way around this may be to force bitmapped fonts.)

• Wide-character support fails (compiles cleanly, but testcurs locks when run). Also, if you aim for a DLL version, certain functions aren't exported (not declared in pdcurses.def.)

• At present, you can have any font you want as long as it's Courier. I tried others. The problem is that the other fixed fonts (at least on my system) don't come with bold, italic, and bold italic variants. So either you get 'normal' text where you wouldn't want it, or the system looks for a bold font... and finds one that doesn't match the size of the normal one, so you get garbage.

• Also at certain font sizes, Windoze decides that normal = bold. That is to say, its font mapper can't be persuaded to provide two different fonts for certain sizes. The only way around this (at present) is to hit "Larger" until they become different.

Notes/Possible Improvements:

• Menu options to print the current screen, and/or save it as an HTML file, could be useful. Neither would be difficult to do. PostScript output would be nearly trivial (mostly because I already know a lot about PS). The functions for PS and HTML export would even be platform-independent. PDF would be a little tougher. One could just use ps2pdf, but I'd rather avoid the dependency.

• Functions should be provided to specify maximum and minimum dimensions. In many cases, these might be the same (a legacy app that expects 80 columns and 25 rows, for example, and which has no provisions for resizing events). In such cases, the dialog style might change from "resizable window" to "fixed window".

• A fix for SDL: in the course of testing PDC_set_line_color, I noticed that it only 'sort of' works in SDL: it'll change the line color for subsequently drawn lines. If you run newtest with the SDL library, for example, when you click to change the line color, nothing happens. But resize the window (triggering a redraw), and hey presto, the lines are redrawn in the correct color.

• A conversation with Mark Hessling caused me to realize that being able to configure the menu programmatically could be helpful, and might not even be all that tough to do.

• Mark also pointed out that some sort of drag-and-drop functionality could be useful. He's currently doing this when in the Win32 console flavor of PDCurses, but in Win32a, you don't have the same direct access to the window. Doing this would require some relatively simple extensions to PDCurses, which would realistically speaking probably only occur in Win32a; the other flavors are not under much active development.

• There are currently 32 ACS_ alternate character set #defines in curses.h. As best I can tell, there's nothing preventing us from having up to 128 such. It would be nice, in my humble opinion, if the double-line variants of the box characters ACS_RTEE and such were supported; perhaps also ACS_CHECKMARK, perhaps some of the block/half-block characters... If one did this, would there be backward-compatibility issues? (I see none.) As best I can tell, only the behaviour of those 32 ACS items is specified; we're still free to play around with anything else. (I've added some possible #defines to pdcwin.h to illustrate. Note that these should be available on other systems, too.)

• At present, all flavors of PDCurses support one display window, called stdscr. At least in theory, it would be possible for Win32a to support multiple display windows. That'd be really nifty (and useful), but probably more effort than I'll go to unless I can get somebody to pay me to do it. (It would involve a new 'switch stdscr' function, which would have to store all the many static/external variables associated with the current stdscr, then create a new one; or, restore all the static/external variables. Plus some other annoying bits and pieces.)

• A full-screen option might be useful. This would basically enlarge the window so that the borders and menu and such were just outside the actual screen (something I've done with the astronomy software that is my "day job", so I'm familiar with the process.)

• If you drag open an area with the left mouse button pressed, it marks that area and then copies it to the clipboard when you release the mouse button. To me, this makes a certain amount of intuitive sense. Almost all the time, if you drag open an area on-screen in a PDCurses window, you're doing it to copy it to the clipboard. It may be useful to provide a menu option to disable mark/copy, for those probably very few apps wherein one might drag the mouse for another reason.

• At present, when you mark an area with the mouse, it's assumed to be a rectangle. However, you might prefer to mark a series of lines, as in

      <-  From here, keep marking text until it wr
aps around,  then keep on marking some more text t
o be copied to clipboard until you get here-> 

...i.e., the way things usually get marked in most word processors. (Thus, one might mark a rectangle, or series of words, or, as described in the previous paragraph, not mark at all. A three-way switch.) I started work on this, ran into some issues, and didn't finish.

• There are three menu options at present: make the font bigger, make it smaller, paste from the clipboard. (With this last, if you've text in the clipboard, it's fed through getch( ) to your program.) These probably should be icons rather than text. All three, incidentally, default to being available through Ctrl-Plus, Ctrl-Minus, and Ctrl-V respectively.

• Mice are almost totally supported (five buttons, and up to triple clicks.) For the wheel, we really ought to be keeping track of total wheel motion, which isn't necessarily an integral number of wheel clicks. Vista, in particular, added support for continuously varying wheels:

 
http://social.msdn.microsoft.com/Forums/en/gametechnologiesgeneral/thread/1deb5f7e-95ee-40ac-84db-58d636f601c7
 

The issues described therein, of the need to accumulate mouse motion, are handled properly in the code now; 'wheel up' and 'wheel down' messages are generated as needed, after the mouse has moved far enough. But there's no way to signal "mouse wheel moved just a little bit".

• This version supports COLORS=256 and COLOR_PAIRS=256. Compile with the testcurs that's part of the win32a.zip file, and go to Color Test, and you'll see this demonstrated. (Or you can see it in the Newtest demo at the top of this page.)

• Italic, reverse, and under/left/right-lined text has been added, as has blinking, using timer events to trigger a reversal in color. (Compile and link the testcurs included with the win32a.zip file, and look at the 'color test' portion, and you should see all attribute combinations.) Those would be all the attributes we can probably get with a 32-bit chtype. With a 64-bit chtype, we could, if desired, get a slew of additional attributes, and could set up non-palette-based RGB background and foreground colors for each character cell. This last would require some (backward-compatible) extensions to PDCurses, and would be easy enough to do. One currently unused attribute bit would, when set, indicate that the existing eight palette bits, plus 22 currently unused bits, would specify five bits each of R, G, and B for the foreground and background colors (30 bits total). Whether anyone would actually want to do this is another matter; 256 colors appears, at least at present, to be enough for anybody.

With the 64-bit flavor, we could set A_INVIS to some different value. I assume its purpose would be that if you set that attribute, the text disappears (i.e., that character cell is just filled with the background color).

• The 64-bit flavor could also support Unicode characters beyond 64K. If you look at the Unicode code charts, you'll see that, for example, (Cretan) Linear B, Old Italic, Phaistos Disc, Shavian, Phoenician, and so on require more than a 16-bit character size. My guess would be that these are rarely needed. But it would be easy enough, in the 64-bit flavor, to provide a few extra bits to the character size.

• The above comments on 64-bit improvements would also apply to SDL and XCurses.

• Currently, key_modifiers includes Alt, Shift, Control, and Numlock. Why not Capslock and Scroll lock?

• I don't really like the way key modifiers are handled (using GetAsyncKey). The code I wrote does work, but if, for some reason, there's a significant delay between the key being hit and the WM_KEYDOWN message getting to WndProc, the user may no longer be pressing the Ctrl or Shift key, and those modifiers will have been lost. I've not actually seen that happen, and it seems unlikely. But it seems as if in theory, it ought to be possible. Proper fixing of this, though, would require having a queue of mouse events, and I think might break existing Curses programs that assume no queue. Or maybe it's assumed that the program checks for input on a frequent basis.

• I've tested this (to varying degrees) with Visual C, OpenWATCOM, Digital Mars, and MinGW. On latter, I'm getting problems with finding libgdi32.a and libuser32.a unless I specify their locations explicitly, but that may just reflect my (lack of) knowledge.

Contact info

I can be reached at plüto@prôjéctplutö.cöm (obviously, removing diacritical marks inserted in hopes of confusing spammers!)

Should you send me code for a "problem" case, it would be nice (but not essential) if it compiles to use the DLL flavor of PDCurses. The advantage of this is that I can swap the Win32 console flavor DLL for the SDL flavor DLL, or the Win32a flavor DLL, without needing to recompile anything. Also, that way, I can just recompile Win32a and immediately test it with your app.