Apparently, if you don't specify GDK_SMOOTH_SCROLL_MASK in a widget's
event mask, then you don't receive "scroll_event" signals at all, even
of the non-smooth variety that was all GTK2 had. Hence, neither mouse
scroll wheels nor touchpad scroll gestures seem to generate any
response.
Adding GDK_SMOOTH_SCROLL_MASK brings the old scroll events back again,
so this is at least no worse than GTK2 was. But in GTK3 we _ought_ to
be able to do better still, by supporting smooth scrolling from
touchpads; this commit doesn't do that.
Forgot to remove this after debugging a development-time problem with
the new EPIPE special case. One of these days I'm going to have to set
up an automated way to protect against this kind of mistake...
If you use the new 'plink -shareexists' feature, then on Unix at least
it's possible for the upstream to receive EPIPE, because the
downstream makes a test connection and immediately closes it, so that
upstream fails to write its version string.
This looks a bit ugly in the upstream's Event Log, so I'm making a
special case: an error of 'broken pipe' type, which occurs on a socket
from a connection sharing downstream, before we've received a version
string from that downstream, is treated as an unusual kind of normal
connection termination and not logged as an error.
A Plink invocation of the form 'plink -shareexists <session>' tests
for a currently live connection-sharing upstream for the session in
question. <session> can be any syntax you'd use with Plink to make the
actual connection (a host/port number, a bare saved session name,
-load, whatever).
I envisage this being useful for things like adaptive proxying - e.g.
if you want to connect to host A which you can't route to directly,
and you might already have a connection to either of hosts B or C
which are viable proxies, then you could write a proxy shell script
which checks whether you already have an upstream for B or C and goes
via whichever one is currently active.
Testing for the upstream's existence has to be done by actually
connecting to its socket, because on Unix the mere existence of a
Unix-domain socket file doesn't guarantee that there's a process
listening to it. So we make a test connection, and then immediately
disconnect; hence, that shows up in the upstream's event log.
For each connection to a downstream I had a flag indicating that we'd
sent a version string to that downstream, and one indicating that we'd
received one in return. But I never actually set the latter to TRUE -
which was OK, as it turned out, because I never used it for anything
either.
Now I do want to use it, so I'd better actually set it :-)
This is the part of ssh.c's connect_to_host() which figures out the
host name and port number that logically identify the connection -
i.e. not necessarily where we physically connected to, but what we'll
use to look up the saved session cache, put in the window title bar,
and give to the connection sharing code to identify other connections
to share with.
I'm about to want to use it for another purpose, so it needs to be
moved out into a separate function.
This is the part of ssh_connection_sharing_init() which decides on the
identifying string to pass to the platform sharing setup. I'm about to
want to use it for another purpose, so it needs to be moved into a
separate function.
When I abandoned GtkDialog for GtkWindow (in dc11417ae), I manually
added a horizontal GtkSeparator between the content and action areas.
Or rather, I tried to - but I forgot that gtk_box_pack_end works in
the opposite order, so that you have to add the bottom-most element
first and then the one you want to appear above it. So my separator
was below the action area, rather than between it and the content
area.
In GTK 3, it was impossible to resize the window smaller than it
started off, because the size request on the drawing area was taken as
a minimum. (I can't actually remember how the GTK 2 version doesn't
have this problem too.)
Fixed by instead setting the initial window size using
gtk_window_set_default_geometry() (having first set up the geometry
hints to reflect the character cell size).
On Windows, colons are illegal in filenames, because they're part of
the path syntax. But colons can appear in automatically constructed
log file names, if an IPv6 address is expanded from the &H placeholder.
Now we coerce any such illegal characters to '.', which is a bit of a
bodge but should at least cause a log file to be generated.
A user points out that logging fopen failures to the Event Log is a
bit obscure, and it's possible to proceed for months in the assumption
that your sessions are being correctly logged when in fact the
partition was full or you were aiming them at the wrong directory. Now
we produce output visibly in the PuTTY window.
I noticed that Unix PSCP was unwantedly renaming downloaded files
which had a backslash in their names, because pscp.c's stripslashes()
treated \ as a path component separator, since it hadn't been modified
since PSCP ran on Windows only.
It also turns out that pscp.c, psftp.c and winsftp.c all had a
stripslashes(), and they didn't all have quite the same prototype. So
now there's one in winsftp.c and one in uxsftp.c, with appropriate
OS-dependent behaviour, and the ones in pscp.c and psftp.c are gone.
Log files, especially SSH packet logs, are often things you want to
generate in unusual circumstances, so it's good to have lots of ways
to ask for them. Particularly, it's especially painful to have to set
up a custom saved session to get diagnostics out of the command-line
tools.
I've added options '-sessionlog', '-sshlog' and '-sshrawlog', each of
which takes a filename argument. I think the fourth option (session
output but filtered down to the printable subset) is not really a
_debugging_ log in the same sense, so it's not as critical to have an
option for it.
In any DRAWTYPE_CAIRO mode, we now do all our Cairo drawing to a Cairo
image surface which lives on the client; then we either blit directly
from that to the window (if we're in GTK3 mode, or GTK2 without
deprecated pieces of API), or else we blit from the Cairo surface to
the server-side pixmap and then from there to the actual window.
In DRAWTYPE_GDK mode, nothing much has changed: we still draw directly
to the server-side pixmap using the GDK drawing API, then blit from
there to the window. But there is one change, namely that the blit is
no longer done proactively - instead, we queue a redraw of the
affected rectangle, and wait until we're called back by the expose
handler.
The main aim of all this is to arrange that the only time we ever draw
to the real window is in response to expose/draw events. The
experimental GTK3 OS X port stopped working a week or two ago (I
presume in response to an OS update) with the symptoms that attempts
to draw on the window outside the context of a "draw" event handler
just didn't seem to work any more; this change fixes it.
In addition to that benefit, this change also has obvious performance
advantages in principle. No more expensive text rendering in response
to an expose event - just re-copy to the window from the bitmap we
already have, from wherever it's stored that's nearest.
Moreover, this seems to have fixed the significant performance problem
with X server-side fonts under GTK. I didn't expect _that_! I'd
guessed that the approach of downloading character bitmaps and
rendering them manually via Cairo was just inherently slow for some
reason. I've no real idea _why_ this change improves matters so much;
my best guess is that perhaps there's an overhead in each drawing
operation to a GDK Cairo surface, so we win by doing lots of
operations to a much faster image surface and then batching them up
into one GDK Cairo operation. But whyever it is, I'm certainly not
complaining!
(In fact, it now seems to be noticeably _faster_, at least on my usual
local X displays, to draw server-side fonts using that technique than
using the old GDK approach. I may yet decide to switch over...)
Plink sets standard input into nonblocking mode, meaning that read()
from fd 0 in an interactive context will typically return -1 EAGAIN.
But the prompt functions in uxcons.c, used for verifying SSH host keys
and suchlike, were doing an unguarded read() from fd 0, and then
panicking and aborting the session when they got EAGAIN.
Fixed by inventing a wrapper around read(2) which handles EAGAIN but
passes all other errors back to the caller. (Seemed slightly less
dangerous than the stateful alternative of temporarily re-blockifying
the file descriptor.)
If we've chosen the ChaCha20-Poly1305 option for a cipher, then that
forces the use of its associated MAC. In that situation, we should
avoid even _trying_ to figure out a MAC by examining the MAC string
from the server's KEXINIT, because we won't use the MAC selected by
that method anyway, so there's no point imposing the requirement on
servers to present a MAC we believe in just so we know it's there.
This was breaking interoperation with tinysshd, and is in violation of
OpenSSH's spec for the "chacha20-poly1305@openssh.com" cipher.
The revamp of key generation in commit e460f3083 made the assumption
that you could decide how many bytes of key material to generate by
converting cipher->keylen from bits to bytes. This is a good
assumption for all ciphers except DES/3DES: since the SSH DES key
setup ignores one bit in every byte of key material it's given, you
need more bytes than its keylen field would have you believe. So
currently the DES ciphers aren't being keyed correctly.
The original keylen field is used for deciding how big a DH group to
request, and on that basis I think it still makes sense to keep it
reflecting the true entropy of a cipher key. So it turns out we need
two _separate_ key length fields per cipher - one for the real
entropy, and one for the much more obvious purpose of knowing how much
data to ask for from ssh2_mkkey.
A compensatory advantage, though, is that we can now measure the
latter directly in bytes rather than bits, so we no longer have to
faff about with dividing by 8 and rounding up.
The Xcode icon composer doesn't seem to exist any more in modern
versions of Xcode, or at least if it does then it's well hidden and
certainly doesn't live at the top-level path at /Developer where web
pages still claim it can be found.
There is a free software 'libicns' and associated command-line tools,
but they're large, complicated, picky about the exact format of PNGs
they get as input, and in any case a needless extra build dependency
when it turns out the important parts of the file format can be done
in a few dozen lines of Python. So here's a new macicon.py, and
icons/Makefile additions to build a demo icon for OS X PuTTY, as and
when I finally get it working.
Also I've deleted the static icon file in the neglected 'macosx'
source directory, because this one is better anyway - the old one was
appalling quality, and must have been autogenerated from a single
image in some way.
When I introduced the KEY_EVENT_DIAGNOSTICS system last month in
commit 769600b22, I somehow didn't notice that it sat next to an
existing system of ifdefs labelled KEY_DEBUGGING, which did some
things worse but some things better.
Now I've expanded both of those into a fairly complete system of
diagnostics (keeping the newer name of KEY_EVENT_DIAGNOSTICS), and
made them use debug() rather than printf() so that in situations where
no standard output is available I can still retrieve the diagnostics
from debug.log.
I turned it into Shift-Return, because I was trying to find out why
the former didn't work on OS X and replaced it with something else
random to see if the code was even being reached. And then, like an
utter doofus, I committed that change as part of a50da0e30.
On OS X GTK, when you click in a pterm that wasn't the active window,
the first click activates it but is swallowed by the windowing system
- but a subsequent tiny drag can still be taken as part of a selection
action, making it difficult to activate the window in order to paste
into it.
Fixed by ignoring mouse drags when the terminal.c mouse state was
NO_SELECTION; if we've seen one prior click then it should be
ABOUT_TO, or DRAGGING if we saw a double or triple click.
The build script generates the .htaccess files that go in each
individual build and redirect generic names like 'putty.tar.gz' to the
real filenames including that build's version number. Those .htaccess
files redirect the corresponding signatures as well, so they need
updating now that we're generating signature files with a different
extension.
Rather than trying to get my existing hugely complicated X-style
clipboard code to somehow work with the Quartz GTK back end, I've
written an entirely new and much simpler alternative clipboard handler
usnig the higher-leve GtkClipboard interface. It assumes all clipboard
text can be converted to and from UTF-8 sensibly (which isn't a good
assumption on all front ends, but on OS X I think it's reasonable),
and it talks to GDK_SELECTION_CLIPBOARD rather than PRIMARY, which is
the only clipboard OS X has.
I had to do a fiddly thing to cope with the fact that each call to
gtk_clipboard_set_with_data caused a call to the clipboard clear
function left over from the previous set of data, so I had to avoid
mistaking that for a clipboard-clear for the _new_ data and
immediately deselecting it. I did that by allocating a distinct
placeholder object in memory for each instance of the copy operation,
so that I can tell whether a clipboard-clear is for the current copy
or a previous one.
This is only very basic support which demonstrates successful copying
and pasting is at least possible. For a sensible OS X implementation
we'll need a more believable means of generating a paste UI action
(it's quite easy to find a Mac on which neither Shift-Ins nor the
third mouse button even exists!). Also, after the trouble I had with
the clipboard-clear event, it's a bit annoying to find that it
_doesn't_ seem to get called when another application becomes the
clipboard owner. That may just be something we have to put up with, if
I can't find any reason why it's failing.
The original version of the xterm mouse tracking protocol did not
support character-cell coordinates greater than 223. If term_mouse()
got one, it would fail to construct an escape sequence for the mouse
event, and would then call ldisc_send() with a zero-length string -
which fails an assertion that I added in November (c269dd0135) on the
occasion of moving ldisc_echoedit_update() into its own function. So
the corresponding operation before that change would have done a
gratuitous ldisc_echoedit_update(), which is exactly the sort of thing
the assertion was there to catch :-)
Later extensions to the mouse tracking protocol support larger
coordinates anyway (try ESC[?1006h or ESC[?1015h in addition to the
ESC[?1000h that turns the whole system on in the first place). It's
only clients that don't use one of those extensions which would have
had the problem.
Thanks to Mirko Wolle for the report.
sign.sh's command-line syntax has changed, so I've updated the sample
command line in CHECKLST as well. Also the file extensions of the
signatures have changed, so I've updated the pre-release verification
command line in CHECKLST too.
If I'm using Option as the Meta key, I want to suppress OS X GTK's
default behaviour of treating it as an AltGr-oid which changes the
keyval and Unicode translation of alphabetic keys. So on OS X I enable
a somewhat bodgy workaround which retranslates from the hardware
keycode as if the Option modifier had not been active at the time, and
use that as the character to prefix Esc to.
This is a bit nasty because I have to hardwire group = 0 in the call
to gdk_keymap_translate_keyboard_state(), whereas in principle what I
wanted was group = (whatever would have resulted from everything else
in the key event other than MOD1). However, in practice, they seem to
be the same, so this will do for the moment.
Personally I like using Command as the Esc-prefixing Meta key in
terminal sessions, because it occupies the same physical keyboard
position as the Alt key that I'm used to using on non-Macs. OS X
Terminal uses Option for that purpose (freeing up Command for the
conventional Mac keyboard shortcuts, of course), so I anticipate
differences of opinion.
Hence, here's a pair of OSX-specific config options which permit a
user to set either, or neither, or both of those modifier keys to
function as the terminal Meta key.
On OS X, apparently, we can't do termios setup on the pty master, so
instead we have to leave it until we've opened the slave fd in the
child process. That works on Linux too, so let's leave it here rather
than having another cumbersome ifdef.
In a UTF-8 pterm, it makes sense to set the IUTF8 flag (on systems
that have one) on the pty device, so that line editing will take
account of UTF-8 multibyte characters.
By retrieving characters' widths using get_extents and not
get_pixel_extents, we can spot when they're not actually an exact
multiple of a pixel, and avoid getting confused by the overall width
of a long string being off by up to a pixel per character.
The Pty that we created in pty_pre_init had its bufchain properly
initialised, but if that one didn't get created, then the one we
create in pty_init did not. Now both should go through the same init
routine.
Now I've moved align_label_left() into gtkmisc.c where gtkask.c can
get at it, we can use it to fix the alignment of the prompt label.
Also, use gtk_label_set_width_chars() to give the label a more or less
sensible width.
Several utility functions I've written over the last few weeks were in
rather random places because I didn't have a central gtkmisc.c to put
them in. Now I've got one, put them there!
They've now deprecated gtk_dialog_get_action_area, because they really
want a dialog box's action area to be filled with nothing but buttons
controlled by GTK which end the dialog with a response code. But we're
accustomed to putting all sorts of other things in our action area -
non-buttons, buttons that don't end the dialog, and sub-widgets that
do layout - and so I think it's no longer sensible to be trying to
coerce our use cases into GtkDialog.
Hence, I'm introducing a set of wrapper functions which equivocate
between a GtkDialog for GTK1 and GTK2, and a GtkWindow with a vbox in
it for GTK3, and I'll lay out the action area by hand.
(Not everything has sensible layout and margins in the new GTK3 system
yet, but I can sort that out later.)
Because the new functions are needed by gtkask.c, which doesn't link
against gtkdlg.c or include putty.h, I've put them in a new source
file and header file pair gtkmisc.[ch] which is common to gtkask and
the main GTK edifice.
When NULL appears in variadic argument lists, it should be cast to the
pointer type that the function will be expecting, because otherwise it
might end up as a type not even the same size as a pointer.
This is a much simpler way to display simple message-box type dialogs,
whose absence I've previously been working around by laboriously
constructing something in my usual style.
We were using it in the main config box to ensure everything expanded
on window resize, but in GTK3 that's the default anyway. And we were
using it to put padding around the edges of the font selector, which
is now done using the "margin" property.
I'm using a slightly more up-to-date GTK version for testing on MacOS,
and it's marked a few more functions as deprecated, among which is
gdk_color_parse(). So now parsing -fg and -bg options has to be done
by two different calls and an ugly #ifdef, depending on GTK version.
If we're not supporting server-side fonts, it's utterly silly to set
one as the default! Instead, we use Pango's guarantee that some
reasonably sensible monospaced font will be made available under the
name "Monospace", and use that at a reasonable default size of 12pt.
Using GTK to run on OS X is going to require several workarounds and
behaviour tweaks to be enabled at various points in the code, and it's
already getting cumbersome to remember what they all are to put on the
command line. Here's a central #define (OSX_GTK) that enables them all
in one go, and a configure option (--with-quartz) that sets it.
As part of this commit, I've also rearranged the #include order in the
GTK source files, so that they include unix.h (which now might be
where NOT_X_WINDOWS gets defined) before they test NOT_X_WINDOWS to
decide whether to include X11 headers.
The Quartz GDK back end, if you press (say) Ctrl-A, will generate a
GdkKeyEvent with keyval='a' and state=CONTROL, but it'll have a
translated string of "a" where the X back end would have returned
"\001". So we have to do our own translation, which fortunately isn't
hard.
OS X for some reason doesn't let my usual fcntl approach (wrapped in
nonblock()) work on pty masters - the fcntl(F_SETFL) fails, with the
(in this context) hilariously inappropriate error code ENOTTY. Work
around it by instead passing O_NONBLOCK to posix_openpt.
OS X dislikes us calling the setuid or setgid syscalls when not
privileged, even if we try to set ourselves to the _same_ uid/gid.
Since I don't anticipate this code needing to run setuid on OS X, and
since I do anticipate wanting to handle multiple ptys in a single
process so that pty_pre_init would be useless anyway, the simplest fix
seems to me to be just conditioning out the whole of pty_pre_init
completely.