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 full colors. (The actual window
does have blinking text as indicated; I didn't try to replicate
that in the screen shot!)
Last updated 2013 January 26
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 (now full RGB). 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 fonts and font sizes can be
chosen. The user can click and drag a rectangle or paragraph 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.
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.
"Public domain" does mean that you can do whatever you want with the
code; you don't need to release your changes, for example. However,
I do appreciate any bug reports, fixes, suggestions for improvements,
etc. You can contact me.
Download the source code
Click here to download the source code (about
197 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:
- 2013 January 26 (font selection dialogue, recognition of Shift-Ctrl keys)
- 2012 November 10 (bug fix for Win7)
- 2012 October 31 (still better handling of resizing)
- 2012 October 18 (better handling of resizing, mouse capture)
- 2012 June 11 (Code cleanup, full RGB, bug fixes)
- 2012 June 2 (No threads, Xinitscr, paragraph selection, etc.)
- 2012 May 14 (Internationalization, Unicode, stray pixel fixes)
- 2011 November 1 (Improvements to cursor display)
- 2011 September 14 (Recognizing more keystrokes; fix to window sizing)
- 2011 June 12 (Crashing bug fixed; tilt-mouse support added)
- 2011 January 20 (Public domain licence, five-button mouse support)
- 2010 December 26 (Triple clicking support added)
- 2010 November 29 (Non-blinking cursors, font size hotkeys, blink state fix, junk pixel cleanup)
- 2010 November 12 (Ctrl-V to paste from clipboard)
- 2010 September 26
- 2010 August 5
- 2010 May 24
- 2010 May 9
- 2010 May 4
- 2010 May 3
- 2010 Apr 30
- 2010 Apr 29
- 2010 Apr 26
- 2010 Apr 23
- 2010 Apr 19
- 2010 Apr 15
- 2010 Apr 14
- 2010 Apr 13
- 2010 Apr 12
- 2010 Apr 11
- 2010 Apr 7
- 2010 Apr 6
- 2010 Apr 5
- 2010 Apr 4
- 2010 Apr 3
- 2010 Apr 1
- 2010 Mar 30
Fixes (2013 Jan 26):
• The
'enlarge font' and 'shrink font' options are now missing from the
menu, and a new 'Font' option has been added. Click on this,
and you can choose the font used in the window (size and type).
You can also hit Ctrl-Comma to access this dialog.
Note that while you can now select
any font you want, not all fonts will work equally well. The
display is fixed-pitch; non-proportional fonts will usually
look pretty weird. Not all fonts support the box-and-lines type
alternative characters. I originally chose Courier New because
it supports absolutely everything, including non-Latin alphabets.
Still, for a lot of purposes, you'll find that other fonts work
Just Fine.
•
Jason Foley pointed out that Win32a didn't register most
Ctrl-Shift key combinations as events, and didn't recognize
Ctrl-Alt anything. I was able to fix the former easily enough.
The latter is a stickier wicket, now described in comments
in pdcscrn.c. Basically, some keyboards consider
Ctrl-Alt to be a modifier to get characters not otherwise
available. For example, on a Swedish keyboard, Shift-2
gets a " (double quote) mark, and Ctrl-Alt-2 gets a @.
We really should, when using a Swedish layout, return
a key for Ctrl-Alt-1, but not for Ctrl-Alt-2; Windows
will "convert" that into an at-sign, and we'd feed two
characters to the user.
At least for the nonce, therefore,
Win32a still doesn't return Ctrl-Alt combinations, unless
one sets the new external variable PDC_show_ctrl_alts
to a non-zero value.
Fixes (2012 Nov 10):
• Roald Ribe
pointed out that the most recent version failed when run in Windows
7. I borrowed a Win7 machine and replicated the failure. It turned
out that the window style used for non-resizable windows was wrong.
This is now fixed. I also rearranged the newtest demo
program's screen (as shown in the image at the top of this page)
so that it would be useable in the default 25-line/80-column mode.
Fixes (2012 Oct 31 and 2012 Oct 18):
• Xavier
Wang found and fixed bugs occurring when apps didn't handle user
resizing messages. This is quite common, because only the X11,
Win32a, and SDL platforms support user resizing at all. When apps
written for the DOS, OS/2 or Windows versions are linked to Win32a
and the user changes the window size, you could get garbage on the
screen, or crashes. Xavier fixed this.
Thinking about this caused me to change the behavior of Win32a. There
is no way for Win32a to know in advance if an application has been
written to handle user resizing correctly. So Win32a now defaults to
non-user-resizable windows, with two ways to get resizable windows.
You can, before calling initscr( ) or
Xinitscr( ), signal to Win32a that the window can be
resized from 20 to 55 lines, and 70 to 100 columns, by calling
PDC_set_resize_limits( 20, 55, 70, 100);
The above has only one slight flaw: the
PDC_set_resize_limits( ) function exists, at present,
only in Win32a. If you try to use it with other flavors of PDCurses,
you'll get unresolved external function errors. Eventually, the
function may exist in other flavors; in X11, it could actually be
"functional" (other flavors of PDCurses don't support resizing, so
this would be a do-nothing function for them.)
Alternatively, you can (again, before calling
initscr( ) or Xinitscr( )) set the
following:
ttytype[0] = 20; /* Window must have at least 20 lines in Win32a */
ttytype[1] = 55; /* Window can have a max of 55 lines in Win32a */
ttytype[2] = 70; /* Window must have at least 70 columns in Win32a */
ttytype[3] = (unsigned char)200; /* Window can have a max of 200 columns in Win32a */
...which won't cause trouble with other flavors (they'll
just ignore it), but which is inelegant and limits you to 255x255 windows.
Though arguably, 255x255 windows should be big enough for anyone.
My thanks to Anatoly Techtonik for pointing out some
problems in my original version of this feature.
• Xavier also pointed out that the window
didn't capture mouse events. You could get strange behavior if you
clicked within the Win32a window, dragged the mouse, and released
the button somewhere outside the window. A few calls to
SetCapture( ) and ReleaseCapture( )
fixed this.
• Xavier also pointed out
that certain Chinese characters really should be drawn "wide",
occupying twice the space of other characters. I don't have an
answer for that problem yet; the code assumes a fixed-width font,
and things would get very strange indeed if we changed that assumption.
Fixes (2012 Jun 11):
• Roald Ribe
provided a patch that made the WndProc( ) function in
pdcdisp.c considerably cleaner. That function had become too
large to be easily managed; the new arrangement is a little easier to
follow.
• As is shown in the
screen shot at the top of this page, one can get text to appear with any
desired foreground and background colors; you aren't limited to the
256-color palette. You can just specify a foreground RGB and a background
RGB for each character. For an example of how this is done, see
newtest.cpp. Note that this works only when using
64-bit chtypes.
• I found
that if you maximized a Win32a window, exited, and restarted the program,
it would hang. Also, attempting to check for a key press wouldn't
necessarily work, now that we aren't multi-threading:
PDC_check_key( ) must explicitly check for new messages sent
to the PDCurses window, in order to make sure that all keyboard events have
been processed. Both bugs are now fixed.
Fixes (2012 Jun 2) :
• Previously, the window had been handled in a
separate thread. This made the code somewhat more complicated than it had to
be. More seriously, there were issues caused by the lack of re-entrancy in
PDCurses. It was at least theoretically possible to have the window thread
and the "main" outside-the-window-thread accessing variables simultaneously.
A mutex helped to avoid this problem, sort of, but it wasn't a perfect fix.
However, Roald Ribe figured out a nice way to avoid the need to
multi-thread. The code is much saner and safer as a result.
• Roald also
pointed out that a lot of code uses Xinitscr( )
when compiled for XCurses and initscr( ) otherwise.
There is no good need for this. On non-XCurses platforms,
initscr( ) simply calls
Xinitscr( 0, NULL), and the argc and argv parameters
are then ignored. So Xinitscr( ) is now enabled for all
platforms. Use of it is actually a Good Thing; it makes it slightly
more likely that the correct command line arguments will get to the
library, which can then use them for setting the window title and
getting the previous window state from the Registry.
• Roald also pointed
out that it would be nice to be able to select in
"paragraph style" instead of the default "block style". So you could
mark things like
<- From here, keep marking text until it wrap
s around, then keep on marking some more lines to b
e copied to clipboard until you've had enough, right
here->
...i.e., the way things usually get marked in most
word processors. This is now enabled. Drag with the left mouse button
pressed, and a paragraph will be highlighted and copied to the Windows
clipboard when you let go of the button. (Hold down Shift when you
press that mouse button, and you can get the previous block-marking and
copying behavior.)
• Roald also provided some fixes to
OpenWATCOM
compilation to get proper symbols in the debugger and smooth out a few
problems with that compiler.
• I made some changes
in curses.h so that, when using 64-bit
chtypes, one can specify Unicode characters up to 20 bits.
Almost all "normal" Unicode characters fit within 16 bits -- hence
the widespread use of UTF-16 -- but 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 a seventeenth
bit. It does appear as if Unicode can
require 21 bits, if one makes use of the
"Private
Use Area". But 20 bits appears to be overkill for all practical
purposes. I also extended the color field within chtype to
consume 31 bits. See newtest.c for an example of the use
of this (or look at the screen shot at the top of this page).
Basically, five bits each specify the foreground and background R, G,
and B, plus one more "signal" bit to indicate that the color is to
be treated in this manner, instead of as an index within a palette...
that brings us up to 31 bits.
This color specification system could also apply to
the SDL and XCurses flavors of PDCurses.
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. (See newtest.cpp
for an example of this use.)
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. (More recently:
Ctrl-, lets you choose the font from a dialog.) 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 New font (or any font you've chosen to use) 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.) As of 2012 June 2, this has
allowed for allowed for Unicode characters
beyond 64K and RGB-coloring (as opposed to the usual
palette-based coloring.)
It also has allowed 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. (See newtest for an example of this use.)
We also have a few attribute bits left over for future use. These
might provide a choice of font and enable the A_DIM attribute
(currently unused in all flavors of PDCurses).
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 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 now, when
PDCurses starts up, it finds out which window has the focus (using
GetForegroundWindow()) and returns focus when PDCurses shuts
down (using SetForegroundWindow()). That seems to have fixed
the problem. (SDL has the same issue, probably 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:
• 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.)
• The default Courier New font always works. You can choose
other fonts, but they may have shortcomings. You can use
Lucida, Verdana, Courier, and other fixed-size fonts if you wish;
you'll just find that italic and/or bold text may not work. Which,
for most existing applications, won't matter; other flavors of
PDCurses didn't support those things anyway. Also, if you try to
display characters not included in the font, you'll get blanks or
boxes or question marks. (Again, not an issue for the many apps
that use only Latin-1 anyway.) For that matter, you can even use
Times or other proportional fonts, though you may find that the
result looks a little weird.
• 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 choose a different or larger font.
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.
• There are two menu options at present: select the font, and
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. Both functions are
available via Ctrl-Comma 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. This also shows how, when
using 64-bit chtypes, one can get
full RGB coloring.
• 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 are all the
attributes we can probably get with a 32-bit chtype. With
a 64-bit chtype, one can also get
strike-out text and full RGB coloring. All of this is backward
compatible (always a key consideration with PDCurses).
With the 64-bit chtype 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).
• 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 the 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. (This is at least partly fixed now.)
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.