PDCurses for "real" Windows
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.)
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) :
- Alexander Nilsson
pointed out that when using a Swedish keyboard layout, hitting
Shift-2 produced @ (as expected with a US layout) instead of ".
A bit of testing on my end revealed other problems: the
å, ö and ä keys failed, as well as combinations
used to produce the Euro sign (€) and some others. Display
was also sometimes strange or just wrong.
I think this is now all fixed. In the Unicode version (compiled
with PDC_WIDE defined), characters are simply assumed to
be in Unicode and all works "logically". In the non-wide version,
the current locale is used. (Previously, output was always in
Latin-1.)
- In testing the above, I found a long
list of problems with the Unicode version (I must confess I'd not
done much with this before) and fixed them. As with anything else
you find wrong in this flavor of PDCurses, I would very much
appreciate any bug reports. Except when testing, I am almost
always using Win32a with a US-Dvorak layout and in non-Unicode
mode. So there are certain bugs I'd be very unlikely to spot;
your help is appreciated.
- Roald Ribe suggested that the "junk
pixel" problems that were sometimes seen with some font sizes could
be fixed using the ExtTextOut( ) function. He was right.
ExtTextOut( ) allows one to specify a clipping rectangle
that is also used to fill in backgrounds, as well as the inter-character
spacing. It does not appear to be a total solution, for reasons I
don't currently understand (some characters at some font sizes extend
beyond the rectangle, yet are not clipped). But it definitely has
improved matters greatly.
Fixes (2011 November 1) :
- I've revised the
curs_set( ) function so that one can now set any of a vast
array of cursors, and set their shape for each half of the blink cycle.
If you set the cursor to have the same shape at each half of the blink
cycle, then it appears not to blink at all. Set it to be invisible for
half the blink cycle, and you get "standard"-type blinking. As before,
curs_set( 0) will turn off the cursor,
curs_set( 1) will give a blinking underline, and
curs_set( 2) will give a blinking solid block cursor;
but, as is described in pdcwin.h, one can now set
a caret cursor, outlined-block cursor, half-block cursor, and
some others; and the cursor can be set to blink between any two
styles, not just between any style and invisible.
Fixes (2011 September 14) :
- A long list of previously
unrecognized characters are now recognized, such as
Ctl-semicolon, Ctl-0 through Ctl-9, PrintScreen, ScrollLock,
and the "extended" buttons provided at the top of some keyboards
such as "Mail", "Mute", "Favorites", and so on. See
curses.h and look after the "2011 Sep 14" comment
for the full list. Basically, just about every key hit is
now recognized.
- Fixed a bug wherein,
if the "Larger/Smaller/Paste" menu was turned off and the
font size was smaller than the menu bar height, a line was
added to the window each time you shut that program down and
then re-started it. (Caused by an assumption on one line that
the menu would always be on.)
Fixes (2011 June 12) :
- Following some comments from
Thomas Cool, I found a bug in the window-closing procedure.
Basically, the SP pointer was being freed, then
accessed. This presumably caused the crashing that some
have reported when PDCurses closes down.
- I noticed that "current"
PDCurses, at least in the SDL, Win32, and X11 flavors,
provides for tilt mice, adding "wheel left" and "wheel right"
events to the existing "wheel up" and "wheel down" ones. It
was easy enough to add those events to Win32a as well.
- Previously, I just posted a ZIP
with the contents of the win32a sub-folder and relied on
the user to also get the
standard PDCurses
files and put it all together. That caused trouble, especially
once I started making tweaks in parts of standard PDCurses. So
win32a.zip file now contains everything you need, in
"standalone" fashion.
Fixes (2011 January 20) :
- I added a section on
licensing to make it clear that yes,
this is public domain, like the rest of PDCurses.
- Previously, Win32a supported
three mouse buttons (like any other flavor of PDCurses) and a
mouse wheel. However, I recently got a Logitech MX700. This
has five buttons detected by Windows (plus three more that I've
not been able to persuade Windows to detect yet). I've revised
the code slightly to handle the additional two buttons, with
"future-proofing" added to curses.h to allow for up
to nine (see the PDC_MAX_MOUSE_BUTTONS macro). As
Bill Gates might have put it, "nine mouse buttons ought to
be enough for anybody."
Important safety tip: adding these buttons meant
that the MOUSE_STATUS structure had to change (to
add six new short integers). Which in turn, sadly, means you
have to recompile everything; you can't just recompile PDCurses
and link to the library. It also means you can't swap PDCurses
DLLs to change your app from a console one, to a Win32a one,
to an SDL one, and back. If that idea distresses you, edit
curses.h and re-define PDC_MAX_MOUSE_BUTTONS
back to 3 and delete the xbutton array, and give up
on the ability to access more than three mouse buttons.
(But note that the recent addition of
tilt-wheel mouse support means you'd need to recompile
everything anyway.)
Fixes (2010 December 26) :
- This flavor of PDCurses now
supports triple mouse clicks. (Double clicks have been supported
almost from the beginning. I ignored triples as being borderline
useless. But then I read something pointing out their use in
Firefox: a single click selects your location with a page,
a double-click highlights the word under the cursor, and a
triple-click highlights the entire line. I can see situations
wherein this could be useful... and supporting triple clicks
requires only a very small addition to the code.)
Subsequent clicks are also treated as triple; i.e., if you
make a long series of clicks, they're detected as single, double,
triple, triple, triple... Were it desired, it would be easy
enough to add a "click count" function; you'd still get a triple
click event, but could call some other function to get the
actual number of clicks. But I don't know of
anything that uses quadruple or quintuple clicks.
Fixes (2010 November 29) :
- Wilhelm R. Stanzl suggested that
it would be nice to have a way to turn off cursor blinking. To do this,
I revised the way curs_set( ) works... and have since
revised curs_set( ) again
so that one can have a tremendous variety of cursor behavior.
- Hitting Ctrl-= now defaults to decreasing
the font size. Hitting Ctrl-- defaults to enlarging it. These can be
reset using PDC_set_function_key( ), as discussed in
pdcwin.h.
- As described
below, I revised things so that by default, bold text is shown
"intensified". Mark Hessling suggested a slightly different intensification
level; I've now revised the intensified_color( ) function in
pdcdisp.c to accommodate this.
- In the course of this project, I've identified
some new candidates for the alternate character set; added macros for the
different cursor types (including the new non-blinking type of cursor)
and for a lot of character codes that could, if we wished, be returned
from getch( ); and made certain fixes that really ought to make
their way back into curses.h. For the nonce, though, I've put
them into pdcwin.h. Eventually, if this becomes an "official"
PDCurses flavor, I fully expect those changes will be integrated into
curses.h where they belong.
- At certain font sizes, there was
a tendency for garbage to appear on the screen. I've made a small fix,
described in comments above PDC_transform_line_given_hdc( )
in pdcdisp.c, that eliminates this problem at most font sizes.
Fixes (2010 November 12) :
- It's long been possible to paste into a window
using a 'paste' menu option. One can now do so by hitting Ctrl-V. It is
also possible to reset the key used for pasting, via
PDC_set_function_key( ), as described in pdcwin.h.
Fixes (2010 September 26) :
- A while back,
Mark Hessling pointed out some problems in the way blinking is handled.
Basically, if PDC_set_blink( ) is called with TRUE,
we'd like "real" blinking; with FALSE, the default, we want it to
look pretty much the way things do in the standard Windows and DOS flavors
of PDCurses: blinking text is shown with an intensified background, but
otherwise unchanged. I'd made three key mistakes: I'd changed the font to
bold, and I'd intensified both the background and foreground
colors, and the level of intensification was too great. All three were easy
fixes.
- Actually, there was also a fourth problem: in the Win32 and DOS
versions, bold text is showed with the foreground color intensified. I've
revised Win32a to behave similarly. It's not entirely necessary, because
in Win32a we have bold fonts with which to make the text stand out; we
don't really need to use color the way Win32/DOS do. But it helps with
certain extended characters that lack a "real" bold-font version.
- I revised testcurs a bit so I
could explore what bold and blinking text looked like with different
fore/background colors, running the Win32 and Win32a versions side by
side.
Fixes (2010 August 5) :
- Characters in the ranges 0-31 and 128-257
were drawn using the Windows character set. Thus, if you'd relied on the
idea that character 132 should appear as ä (lowercase a with umlaut),
you were out of luck. This is almost entirely fixed, by the expedient
of remapping those characters to their Unicode equivalents. The downside
to this is that the Courier font on your system may not support all of the
glyphs (mine, for instance, lacks the "eighth note" symbol for ASCII 13
and the "barred pair of sixteenth notes" symbol for ASCII 14, plus some
others.)
Technically speaking, one shouldn't be relying on such
behavior anyway, since I don't think the appearance of such characters is
"standard". But I think it's standard amongst the DOS, Windows, and X11
ports, and I wanted Win32a to match.
- The size of the window for a given app was
stored in the Windows registry, but not its location. The result was that
if you closed your app and restarted, it would wander around the screen in
a most annoying way. This is fixed. (A remaining problem: maximize on a
second monitor, shut your program down and restart, and it's maximized on
the first monitor. I've found a fix for this -- the use of the
Get/SetWindowPlacement() functions -- but haven't had time to
implement it yet.)
Fixes (2010 May 24) :
- If you clicked on the "Paste" option
with an empty clipboard, the program crashed. Important Safety Tip:
Always check return values. This is fixed.
Fixes (2010 May 9) :
- When calling init_pair( ),
"real" DOS and Windows curses are using a truly-palette based scheme. So
if you reset, say, color pair 3, then all text that's using that color
pair changes color automatically. That isn't the case in Win32a; the
program needs to sweep through and redraw all that text in the new color.
I finally got around to revising PDC_init_pair( ) so it
would do this.
- I just installed Ubuntu 10.04, and noticed that when a terminal
window loses focus, the cursor turns into a filled block and stops
blinking. This seemed desirable behavior, and I revised Win32a to
do the same.
Fixes (2010 May 4) :
-
Mark Hessling provided some code to cause the icon
to match the one stored in the currently-running app.
-
I tried recompiling with short (16-bit) chtypes. Use of
certain attributes broke; I realized I'd made some 32-bit specific
decisions in pdcdisp.c and fixed them. I dunno if anyone
actually uses short chtypes, but assume there may be
legacy apps out there that do. Anyway... the code now appears to
work Just Fine with 16, 32, and 64-bit
chtypes.
Fixes (2010 May 3) :
-
Mark also pointed out that programmatic resizing, such as that done
in the 'resizing test' part of testcurs, was broken. Fixing that
proved troublesome. The logic for resizing had become so convoluted that
I had to rewrite a lot of it. Good news is that it's far less bizarre
now; I could even make a decent case that it's Done Right.
- Handling of the key_code parameter in
PDC_get_key( ) was completely wrong, causing output
sometimes not to be echoed when it ought to have been.
- When dragging open a box with the mouse to mark text and copy
it to the clipboard, it was possible to get invalid text appended.
I hadn't realized this, but despite the fact that PDC_setclipboard( )
takes a length parameter, it also assumes a null-terminated string.
(This has been fixed in the Win32a flavor, and the change really
should be mirrored back to the Win32 flavor. It's a one-line fix.)
Fixes (2010 Apr 30) :
-
I just realized that A_LEFTLINE caused lines on the right
side of each character. A_RIGHTLINE caused lines on the
left side. I swapped 'em back.
- PDC_set_line_color( ) now works (it
previously had no effect). I know this largely because...
- There is a new newtest.cpp program included.
I needed something to verify that A_OVERLINE and
A_STRIKEOUT (attributes available with the
64-bit chtype modification)
worked, and that PDC_set_line_color( ) and
PDC_set_blink( ) worked properly. (See the
screen shot at the top of this page.)
- newtest also includes some testing of the (not
very well documented) SLK (Soft Label Key)
functions, which caused me to realize that Win32a never set
the SP->key_code flag to TRUE. I must
confess that I don't really know what SP->key_code is
supposed to do. But leaving it FALSE after a key hit
meant that SLK clicks were just treated as plain old mouse
clicks. This is now fixed.
Fixes (2010 Apr 29) :
-
I made some modifications to allow for a 64-bit chtype.
This turned out to be very straightforward; worst part was
that Microsoft VC has non-standard defines for 64-bit types.
(By default, the code will still compile with good ol' 32-bit
chtypes. To get the 64-bit flavor, set CHTYPE_LONG
equal to 2 in curses.h.) This could allow for expanding
a variety of fields. Color is currently stored in eight bits;
that could be expanded to 32 (sixteen-bit foreground and 16-bit
background color, no palette), though this would break the way
colors currently work. The character value is stored in 16 bits,
which is a minor problem in a world where there are more than 2^16
defined Unicode characters; we might want to add a few bits
there.
The only thing I've tried doing with this extension, though, is
adding an A_OVERLINE and A_STRIKEOUT attribute.
I consider the former to be somewhat useful; it lets you have
"outlined text". If one showed the word 'word' with all letters
having A_OVERLINE|A_UNDERLINE, with the 'w' also having
the A_LEFTLINE attribute and the 'd' having the
A_RIGHTLINE attribute, you could put that text in a handy
box.
Fixes (2010 Apr 26) :
-
If one has called PDC_set_function_key( )
to set a key for FUNCTION_KEY_SHUT_DOWN,
a kill option is now added to the system menu of the window. This
addresses a nasty little issue with setting a shutdown key. Suppose you set
the shutdown key to be, say, 'q' (which ought to cause your app to close).
And suppose that, for some reason, the app is no longer responding to input
(the most common reason you'd hit the Close box in the first place).
In such a case, a kill option, which shuts the program down
gracelessly (without asking if you'd like to save your work and such) would
be convenient. So I added one. As before, if you've not set a shutdown key
in your program (the default situation), the Close button will just result
in exit( ) being called... i.e., the same graceless exit as
before.
- (Incidentally, I'd think that PDC_set_function_key( )
and the associated kill option ought to be available, in
a similar manner, in SDL Curses and XCurses... in my humble opinion.)
- If the window was minimized and then maximized, a crash usually
occurred. I fixed this.
Fixes (2010 Apr 23) :
-
I realized that when you started up a program using this library
in maximized mode, you would get a redraw right away: when the
menu was added, the screen resized, you lost a line, and a
KEY_RESIZE was triggered. This is now fixed. You should
be able to start any PDCurses-using program with this library, and
not get a resize until you actually trigger one, either programmatically
with resize_term( ); or by dragging the window frame or
hitting the maximize button.
Fixes (2010 Apr 19) :
- Alt-L, Alt-P, and Alt-S no longer act as
hotkeys causing the font to expand/shrink, or paste from the clipboard
to the PDCurses input stream. (Previously, they did act as hotkeys,
which was annoying if you really wanted them to do something in your
own program.)
Fixes (2010 Apr 15) :
- I've "sort of" fixed a crash caused intermittently
by resizing. It occurred because the window is controlled in a separate
thread. You can get a situation wherein the screen is being repainted
(perhaps due to resizing the window), happily reading data from
curscr->_y, whilst in the main thread, resize_term( )
is reallocating curscr->_y (reasonably enough, because the screen
size has changed). I "fixed" this using a mutex: if a paint message is in
process, the resizing is suspended until it's all done. (My fix isn't a pure
one: the mutex is held through PDC_resize_screen( ) , when it
really ought to be held through the entire resize_term( )
function. That wouldn't be too hard to implement, but would require
Win32a-specific code in initscr.c.)
This is the most blatantly obvious case of threads colliding. In
practice, I think the fix will eliminate crashes. But in theory,
at least, we'd need mutexes all over the place, mostly to keep
curscr->_y and certain other globals from being used in the
window thread while they're being changed outside the thread.
- I've added several possible #defines
for new ACS_* characters in pdcwin.h. No actual changes
to the functions, but I wanted to note some characters we might someday
add. I restricted myself to a selection that could also be used in the
other PDCurses libraries. These should, eventually, really be in
curses.h.
- Indentation now matches the PDCurses standards.
Fixes (2010 Apr 14) :
- PDC_return_key_modifiers( )
now works correctly. (It doesn't work entirely correctly in "vanilla"
Win32a, by the way. Under Win9x, left and right ctrl/alt/shift keys are
not differentiated; they're all considered to be right-handed. The SDL
library does handle this correctly. Borrowing from that code got me key
values that match the correct side of the keyboard, even on Win9x
systems... with the warning that, with some keyboards on Win9x boxes,
the left and right Shift keys may not be properly differentiated.)
Fixes (2010 Apr 13) :
- PDC_set_blink( ) actually
functions correctly now. Called with TRUE, text with the
A_BLINK attribute actually blinks. Called with FALSE
(the default), such text is shown as bold, with both foreground and
background brighter than they otherwise would be (the RGB values are
averaged with pure white). Note that since both types of display are
supported (unlike on other platforms), OK is always returned.
(Every other flavor of PDCurses returns OK for one input and
ERR for the other.) Also in contrast to most other flavors,
the number of colors isn't affected by this function.
Fixes (2010 Apr 12) :
- The window title defaults to the name and command
line arguments of the application, instead of defaulting to be blank.
You can still override it using PDC_set_title( ).
Fixes (2010 Apr 11) :
- The number of lines and columns, and font size, are now stored in the
Windoze registry. Like most programmers, I regard the registry with
disgust, but this is actually a reasonable use for it, I think.
The data is stored on an application-by-application basis, so that
the screen/font sizes for, say, testcurs will be maintained
separately from those for, say, firework.
- The system menu now has a "Menu" option. It's checked by default,
meaning that the menu bar (with its 'enlarge', 'shrink', and 'paste'
options) are displayed. Toggle it, and the menu vanishes. If the
window is maximized, this may result in the screen getting an extra
line. If it's not, then the window just shrinks by the size of the
menu bar, and from the viewpoint of Curses, no resizing happens;
if you had, say, thirty columns on-screen, you'll still have
exactly thirty columns. I did this because I thought it best for
programs that don't handle resizing of windows.
- For similar reasons, 'enlarge' and 'shrink' normally change
the font and window size, but not the number of rows/columns in Curses,
so that again, no KEY_RESIZE is sent and SP->resized remains FALSE.
But for a maximized window, this didn't seem very sensible. In that
case, it makes more sense for the window to remain its existing size,
but the number of row/columns to increase (if the font is 'shrunk') or
decrease (if the font is 'enlarged'). That is now the library's behavior.
- With a maximized window, it's possible for the window not to be
an even multiple of the character size, so that there is a fractional
character size of space on the right and bottom margins. This is now
filled in with black.
Fixes (2010 Apr 7) :
-
Mark Hessling turned up an issue
with the use of 'leftline' and 'rightline' attributes, which could
leave lines running all over the place. This sprang from a line in
curses.h,
# define PDC_ATTR_SHIFT 19
which leaves out the left- and right-line attributes. Not a problem
on most flavors of PDCurses, since most don't support these attributes.
(The macro was previously used only in the DOS, OS/2, and Win32
flavors, where it didn't matter, since they didn't support side-lining
anyway.) I was reluctant to alter curses.h, so I made suitable
changes in pdcdisp.c wherein I used
#define REAL_PDC_ATTR_SHIFT 17.
- My decision to have
the 'close' button add a KEY_EXIT to the queue was flawed;
plenty of existing code doesn't expect that. I've set the default
behavior back to just exiting, but added a PDC_set_function_key( )
to pdcwin.h. The use of this key is described in that file.
Fixes (2010 Apr 6) :
-
Mark Hessling kindly sent me a copy of
THE
linked with the DLL version of PDCurses, so that I could swap
in my DLL in place of the SDL or "usual" Win32 one. That enabled me
to track down a bug in window sizing. Fixing that bug was rather
complicated; it turned out that I hadn't really understood how
PDCurses is supposed to handle certain situations. But it appears
that all functions correctly now.
- Cursor display appears to also be fixed. I
thought cursor visibility was set only via the
cur_set( ) function, but it apparently can be set elsewhere;
to evade this issue, one has to ensure that when the cursor is moved, the
underlying text is simply redrawn, without making assumptions about what
shape any cursor might have had. The code now does this, and everything
appears to be OK now.
Fixes (2010 Apr 5) :
- With a few changes, I was able to get the code to
compile with wide-character support (WIDE=Y). Unfortunately, it doesn't
work; testcurs locks up, both with the DLL build and static
build. (Since fixed.) For the .dll version, five functions were undefined
until I added them to pdcurses.def. Those functions were
add_wch, addnwstr, addwstr, get_wstr,
and mvaddwstr. Same problem occurs when attempting to make a
wide-char version of the "standard" Win32 flavor of PDCurses, though, so I
dunno where the problem is.
- Tracked down many spurious KEY_RESIZE events. (For example,
clicking on 'larger' or 'smaller' really shouldn't trigger a resize, but
it was doing just that. Also, there was a spurious resize when the
window was first drawn.)
- It was pointed out to me that is_termresized( ) was
returning spurious results. (It would be set to TRUE and just
stay that way; it's supposed to revert to FALSE after the user
handles the resizing event.) I think I've fixed this.
Fixes (2010 Apr 4) :
- When you click on the 'close' box in the window, a
KEY_EXIT is placed in the input queue
(this behavior has been modified). Therefore, unlike with
the SDL and XCurses versions, the program doesn't necessarily shut down
when the window is closed. Instead, the program has to catch the
KEY_EXIT and act accordingly. I did this because it's graceless
(in my humble opinion) for Curses to just shut things down, rather than
letting the application clean things up and possibly ask are-you-sure
or do-you-want-to-save-your-changes type questions.
- When invoking a program using Win32a from a console, the
focus didn't go back to the console when the program was done. I'm not
entirely sure why this is the case. But, by having the PDCurses thread
find out which window had the focus when it started (using
GetForegroundWindow()) and resetting that focus when the window
is closed (using SetForegroundWindow()), it at least appears
that the problem is fixed. (SDL has the same issue, possibly
fixable in the same way.)
- Clicking the 'maximize' button didn't work. Curses drew to
the same size window as before, leaving junk in the rest of the window.
This is fixed.
Fixes (2010 Apr 3) :
- The cursor now blinks. (The same timer event -- one every half
second -- that controls blinking text is used to blink the cursor
at the same time.)
Fixes (2010 Apr 1) :
- Dragging an area with the left mouse button pressed (to copy it to the
clipboard, see below) flickered. I added some logic to the
show_mouse_rect( ) function in pdcscrn.c to fix this
(mostly).
- Before, if you tried to drag an area with the left mouse button pressed,
and the text underneath was updated while you did it, garbage
resulted. This is fixed.
Fixes (2010 Mar 30) :
- Mouse movement was not handled. (You could set the mask and so on,
but no events would ever get reported to the app.) Now it is.
- Buttons 2 and 3 (i.e., the middle and right buttons) were swapped.
To me, it seemed "logical" that a two-button mouse would have
buttons 1 and 2, but it's actually buttons 1 and 3.
- When resizing, the window is forced to remain a multiple of the
character size in width and height. You can't get a partial
character sliver at the edges of the window. I also fixed
an oddity in which this worked well when dragging from below or
the right, but not from above or the left.
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.