Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
/*
|
|
|
|
* gtkmain.c: the common main-program code between the straight-up
|
|
|
|
* Unix PuTTY and pterm, which they do not share with the
|
|
|
|
* multi-session gtkapp.c.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#if !GTK_CHECK_VERSION(3,0,0)
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if GTK_CHECK_VERSION(2,0,0)
|
|
|
|
#include <gtk/gtkimmodule.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define MAY_REFER_TO_GTK_IN_HEADERS
|
|
|
|
|
|
|
|
#include "putty.h"
|
|
|
|
#include "terminal.h"
|
|
|
|
#include "gtkcompat.h"
|
|
|
|
#include "gtkfont.h"
|
|
|
|
#include "gtkmisc.h"
|
|
|
|
|
|
|
|
#ifndef NOT_X_WINDOWS
|
|
|
|
#include <gdk/gdkx.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xatom.h>
|
Basic support for running under GDK Wayland back end.
GTK 3 PuTTY/pterm has always assumed that if it was compiled with
_support_ for talking to the raw X11 layer underneath GTK and GDK,
then it was entitled to expect that raw X11 layer to exist at all
times, i.e. that GDK_DISPLAY_XDISPLAY would return a meaningful X
display that it could do useful things with. So if you ran it over the
GDK Wayland backend, it would immediately segfault.
Modern GTK applications need to cope with multiple GDK backends at run
time. It's fine for GTK PuTTY to _contain_ the code to find and use
underlying X11 primitives like the display and the X window id, but it
should be prepared to find that it's running on Wayland (or something
else again!) so those functions don't return anything useful - in
which case it should degrade gracefully to the subset of functionality
that can be accessed through backend-independent GTK calls.
Accordingly, I've centralised the use of GDK_DISPLAY_XDISPLAY into a
support function get_x_display() in gtkmisc.c, which starts by
checking that there actually is one first. All previous direct uses of
GDK_*_XDISPLAY now go via that function, and check the result for NULL
afterwards. (To save faffing about calling that function too many
times, I'm also caching the display pointer in more places, and
passing it as an extra argument to various subfunctions, mostly in
gtkfont.c.)
Similarly, the get_windowid() function that retrieves the window id to
put in the environment of pterm's child process has to be prepared for
there not to be a window id.
This isn't a complete fix for all Wayland-related problems. The other
one I'm currently aware of is that the default font is "server:fixed",
which is a bad default now that it won't be available on all backends.
And I expect that further problems will show up with more testing. But
it's a start.
2018-05-09 08:18:20 +00:00
|
|
|
#include "x11misc.h"
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static char *progname, **gtkargvstart;
|
|
|
|
static int ngtkargs;
|
|
|
|
|
|
|
|
extern char **pty_argv; /* declared in pty.c */
|
|
|
|
extern int use_pty_argv;
|
|
|
|
|
|
|
|
static const char *app_name = "pterm";
|
|
|
|
|
|
|
|
char *x_get_default(const char *key)
|
|
|
|
{
|
|
|
|
#ifndef NOT_X_WINDOWS
|
Basic support for running under GDK Wayland back end.
GTK 3 PuTTY/pterm has always assumed that if it was compiled with
_support_ for talking to the raw X11 layer underneath GTK and GDK,
then it was entitled to expect that raw X11 layer to exist at all
times, i.e. that GDK_DISPLAY_XDISPLAY would return a meaningful X
display that it could do useful things with. So if you ran it over the
GDK Wayland backend, it would immediately segfault.
Modern GTK applications need to cope with multiple GDK backends at run
time. It's fine for GTK PuTTY to _contain_ the code to find and use
underlying X11 primitives like the display and the X window id, but it
should be prepared to find that it's running on Wayland (or something
else again!) so those functions don't return anything useful - in
which case it should degrade gracefully to the subset of functionality
that can be accessed through backend-independent GTK calls.
Accordingly, I've centralised the use of GDK_DISPLAY_XDISPLAY into a
support function get_x_display() in gtkmisc.c, which starts by
checking that there actually is one first. All previous direct uses of
GDK_*_XDISPLAY now go via that function, and check the result for NULL
afterwards. (To save faffing about calling that function too many
times, I'm also caching the display pointer in more places, and
passing it as an extra argument to various subfunctions, mostly in
gtkfont.c.)
Similarly, the get_windowid() function that retrieves the window id to
put in the environment of pterm's child process has to be prepared for
there not to be a window id.
This isn't a complete fix for all Wayland-related problems. The other
one I'm currently aware of is that the default font is "server:fixed",
which is a bad default now that it won't be available on all backends.
And I expect that further problems will show up with more testing. But
it's a start.
2018-05-09 08:18:20 +00:00
|
|
|
Display *disp;
|
|
|
|
if ((disp = get_x11_display()) == NULL)
|
|
|
|
return NULL;
|
|
|
|
return XGetDefault(disp, app_name, key);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void fork_and_exec_self(int fd_to_close, ...)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Re-execing ourself is not an exact science under Unix. I do
|
|
|
|
* the best I can by using /proc/self/exe if available and by
|
|
|
|
* assuming argv[0] can be found on $PATH if not.
|
|
|
|
*
|
|
|
|
* Note that we also have to reconstruct the elements of the
|
|
|
|
* original argv which gtk swallowed, since the user wants the
|
|
|
|
* new session to appear on the same X display as the old one.
|
|
|
|
*/
|
|
|
|
char **args;
|
|
|
|
va_list ap;
|
|
|
|
int i, n;
|
|
|
|
int pid;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Collect the arguments with which to re-exec ourself.
|
|
|
|
*/
|
|
|
|
va_start(ap, fd_to_close);
|
|
|
|
n = 2; /* progname and terminating NULL */
|
|
|
|
n += ngtkargs;
|
|
|
|
while (va_arg(ap, char *) != NULL)
|
|
|
|
n++;
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
args = snewn(n, char *);
|
|
|
|
args[0] = progname;
|
|
|
|
args[n-1] = NULL;
|
|
|
|
for (i = 0; i < ngtkargs; i++)
|
|
|
|
args[i+1] = gtkargvstart[i];
|
|
|
|
|
|
|
|
i++;
|
|
|
|
va_start(ap, fd_to_close);
|
|
|
|
while ((args[i++] = va_arg(ap, char *)) != NULL);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
assert(i == n);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do the double fork.
|
|
|
|
*/
|
|
|
|
pid = fork();
|
|
|
|
if (pid < 0) {
|
|
|
|
perror("fork");
|
|
|
|
sfree(args);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pid == 0) {
|
|
|
|
int pid2 = fork();
|
|
|
|
if (pid2 < 0) {
|
|
|
|
perror("fork");
|
|
|
|
_exit(1);
|
|
|
|
} else if (pid2 > 0) {
|
|
|
|
/*
|
|
|
|
* First child has successfully forked second child. My
|
|
|
|
* Work Here Is Done. Note the use of _exit rather than
|
|
|
|
* exit: the latter appears to cause destroy messages
|
|
|
|
* to be sent to the X server. I suspect gtk uses
|
|
|
|
* atexit.
|
|
|
|
*/
|
|
|
|
_exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we reach here, we are the second child, so we now
|
|
|
|
* actually perform the exec.
|
|
|
|
*/
|
|
|
|
if (fd_to_close >= 0)
|
|
|
|
close(fd_to_close);
|
|
|
|
|
|
|
|
execv("/proc/self/exe", args);
|
|
|
|
execvp(progname, args);
|
|
|
|
perror("exec");
|
|
|
|
_exit(127);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
int status;
|
|
|
|
sfree(args);
|
|
|
|
waitpid(pid, &status, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void launch_duplicate_session(Conf *conf)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* For this feature we must marshal conf and (possibly) pty_argv
|
|
|
|
* into a byte stream, create a pipe, and send this byte stream
|
|
|
|
* to the child through the pipe.
|
|
|
|
*/
|
2018-05-24 09:48:20 +00:00
|
|
|
int i, ret;
|
|
|
|
strbuf *serialised;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
char option[80];
|
|
|
|
int pipefd[2];
|
|
|
|
|
|
|
|
if (pipe(pipefd) < 0) {
|
|
|
|
perror("pipe");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-24 09:48:20 +00:00
|
|
|
serialised = strbuf_new();
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
2018-05-24 09:48:20 +00:00
|
|
|
conf_serialise(BinarySink_UPCAST(serialised), conf);
|
|
|
|
if (use_pty_argv && pty_argv)
|
|
|
|
for (i = 0; pty_argv[i]; i++)
|
|
|
|
put_asciz(serialised, pty_argv[i]);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
2018-05-24 09:48:20 +00:00
|
|
|
sprintf(option, "---[%d,%d]", pipefd[0], serialised->len);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
noncloexec(pipefd[0]);
|
|
|
|
fork_and_exec_self(pipefd[1], option, NULL);
|
|
|
|
close(pipefd[0]);
|
|
|
|
|
|
|
|
i = ret = 0;
|
2018-05-24 09:48:20 +00:00
|
|
|
while (i < serialised->len &&
|
|
|
|
(ret = write(pipefd[1], serialised->s + i,
|
|
|
|
serialised->len - i)) > 0)
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
i += ret;
|
|
|
|
if (ret < 0)
|
|
|
|
perror("write to pipe");
|
|
|
|
close(pipefd[1]);
|
2018-05-24 09:48:20 +00:00
|
|
|
strbuf_free(serialised);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void launch_new_session(void)
|
|
|
|
{
|
|
|
|
fork_and_exec_self(-1, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void launch_saved_session(const char *str)
|
|
|
|
{
|
|
|
|
fork_and_exec_self(-1, "-load", str, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int read_dupsession_data(Conf *conf, char *arg)
|
|
|
|
{
|
2018-05-28 14:36:15 +00:00
|
|
|
int fd, i, ret, size;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
char *data;
|
2018-05-28 14:36:15 +00:00
|
|
|
BinarySource src[1];
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
|
|
|
if (sscanf(arg, "---[%d,%d]", &fd, &size) != 2) {
|
|
|
|
fprintf(stderr, "%s: malformed magic argument `%s'\n", appname, arg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
data = snewn(size, char);
|
|
|
|
i = ret = 0;
|
|
|
|
while (i < size && (ret = read(fd, data + i, size - i)) > 0)
|
|
|
|
i += ret;
|
|
|
|
if (ret < 0) {
|
|
|
|
perror("read from pipe");
|
|
|
|
exit(1);
|
|
|
|
} else if (i < size) {
|
|
|
|
fprintf(stderr, "%s: unexpected EOF in Duplicate Session data\n",
|
|
|
|
appname);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2018-05-28 14:36:15 +00:00
|
|
|
BinarySource_BARE_INIT(src, data, size);
|
|
|
|
if (!conf_deserialise(conf, src)) {
|
|
|
|
fprintf(stderr, "%s: malformed Duplicate Session data\n", appname);
|
|
|
|
exit(1);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
}
|
2018-05-28 14:36:15 +00:00
|
|
|
if (use_pty_argv) {
|
|
|
|
int pty_argc = 0;
|
|
|
|
size_t argv_startpos = src->pos;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
2018-05-28 14:36:15 +00:00
|
|
|
while (get_asciz(src), !get_err(src))
|
|
|
|
pty_argc++;
|
|
|
|
|
|
|
|
src->err = BSE_NO_ERROR;
|
|
|
|
|
|
|
|
if (pty_argc > 0) {
|
|
|
|
src->pos = argv_startpos;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
2018-05-28 14:36:15 +00:00
|
|
|
pty_argv = snewn(pty_argc + 1, char *);
|
|
|
|
pty_argv[pty_argc] = NULL;
|
|
|
|
for (i = 0; i < pty_argc; i++)
|
|
|
|
pty_argv[i] = dupstr(get_asciz(src));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (get_err(src) || get_avail(src) > 0) {
|
|
|
|
fprintf(stderr, "%s: malformed Duplicate Session data\n", appname);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sfree(data);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void help(FILE *fp) {
|
|
|
|
if(fprintf(fp,
|
|
|
|
"pterm option summary:\n"
|
|
|
|
"\n"
|
|
|
|
" --display DISPLAY Specify X display to use (note '--')\n"
|
|
|
|
" -name PREFIX Prefix when looking up resources (default: pterm)\n"
|
|
|
|
" -fn FONT Normal text font\n"
|
|
|
|
" -fb FONT Bold text font\n"
|
|
|
|
" -geometry GEOMETRY Position and size of window (size in characters)\n"
|
|
|
|
" -sl LINES Number of lines of scrollback\n"
|
|
|
|
" -fg COLOUR, -bg COLOUR Foreground/background colour\n"
|
|
|
|
" -bfg COLOUR, -bbg COLOUR Foreground/background bold colour\n"
|
|
|
|
" -cfg COLOUR, -bfg COLOUR Foreground/background cursor colour\n"
|
|
|
|
" -T TITLE Window title\n"
|
|
|
|
" -ut, +ut Do(default) or do not update utmp\n"
|
|
|
|
" -ls, +ls Do(default) or do not make shell a login shell\n"
|
|
|
|
" -sb, +sb Do(default) or do not display a scrollbar\n"
|
|
|
|
" -log PATH, -sessionlog PATH Log all output to a file\n"
|
|
|
|
" -nethack Map numeric keypad to hjklyubn direction keys\n"
|
|
|
|
" -xrm RESOURCE-STRING Set an X resource\n"
|
|
|
|
" -e COMMAND [ARGS...] Execute command (consumes all remaining args)\n"
|
|
|
|
) < 0 || fflush(fp) < 0) {
|
|
|
|
perror("output error");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void version(FILE *fp) {
|
2017-01-21 14:55:53 +00:00
|
|
|
char *buildinfo_text = buildinfo("\n");
|
|
|
|
if(fprintf(fp, "%s: %s\n%s\n", appname, ver, buildinfo_text) < 0 ||
|
|
|
|
fflush(fp) < 0) {
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
perror("output error");
|
|
|
|
exit(1);
|
|
|
|
}
|
2017-01-21 14:55:53 +00:00
|
|
|
sfree(buildinfo_text);
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *geometry_string;
|
|
|
|
|
2017-11-27 19:40:13 +00:00
|
|
|
void cmdline_error(const char *p, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
fprintf(stderr, "%s: ", appname);
|
|
|
|
va_start(ap, p);
|
|
|
|
vfprintf(stderr, p, ap);
|
|
|
|
va_end(ap);
|
|
|
|
fputc('\n', stderr);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2017-11-27 20:09:54 +00:00
|
|
|
void window_setup_error(const char *errmsg)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s: %s\n", appname, errmsg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
Centralise PuTTY and Plink's non-option argument handling.
This is another piece of long-overdue refactoring similar to the
recent commit e3796cb77. But where that one dealt with normalisation
of stuff already stored _in_ a Conf by whatever means (including, in
particular, handling a user typing 'username@host.name' into the
Hostname box of the GUI session dialog box), this one deals with
handling argv entries and putting them into the Conf.
This isn't exactly a pure no-functional-change-at-all refactoring. On
the other hand, it isn't a full-on cleanup that completely
rationalises all the user-visible behaviour as well as the code
structure. It's somewhere in between: I've preserved all the behaviour
quirks that I could imagine a reason for having intended, but taken
the opportunity to _not_ faithfully replicate anything I thought was
clearly just a bug.
So, for example, the following inconsistency is carefully preserved:
the command 'plink -load session nextword' treats 'nextword' as a host
name if the loaded session hasn't provided a hostname already, and
otherwise treats 'nextword' as the remote command to execute on the
already-specified remote host, but the same combination of arguments
to GUI PuTTY will _always_ treat 'nextword' as a hostname, overriding
a hostname (if any) in the saved session. That makes some sense to me
because of the different shapes of the overall command lines.
On the other hand, there are two behaviour changes I know of as a
result of this commit: a third argument to GUI PuTTY (after a hostname
and port) now provokes an error message instead of being silently
ignored, and in Plink, if you combine a -P option (specifying a port
number) with the historical comma-separated protocol selection prefix
on the hostname argument (which I'd completely forgotten even existed
until this piece of work), then the -P will now override the selected
protocol's default port number, whereas previously the default port
would win. For example, 'plink -P 12345 telnet,hostname' will now
connect via Telnet to port 12345 instead of to port 23.
There may be scope for removing or rethinking some of the command-
line syntax quirks in the wake of this change. If we do decide to do
anything like that, then hopefully having it all in one place will
make it easier to remove or change things consistently across the
tools.
2017-12-07 19:59:43 +00:00
|
|
|
int do_cmdline(int argc, char **argv, int do_everything, Conf *conf)
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
char *val;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Macros to make argument handling easier. Note that because
|
|
|
|
* they need to call `continue', they cannot be contained in
|
|
|
|
* the usual do {...} while (0) wrapper to make them
|
|
|
|
* syntactically single statements; hence it is not legal to
|
|
|
|
* use one of these macros as an unbraced statement between
|
|
|
|
* `if' and `else'.
|
|
|
|
*/
|
|
|
|
#define EXPECTS_ARG { \
|
|
|
|
if (--argc <= 0) { \
|
|
|
|
err = 1; \
|
|
|
|
fprintf(stderr, "%s: %s expects an argument\n", appname, p); \
|
|
|
|
continue; \
|
|
|
|
} else \
|
|
|
|
val = *++argv; \
|
|
|
|
}
|
|
|
|
#define SECOND_PASS_ONLY { if (!do_everything) continue; }
|
|
|
|
|
|
|
|
while (--argc > 0) {
|
|
|
|
const char *p = *++argv;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Shameless cheating. Debian requires all X terminal
|
|
|
|
* emulators to support `-T title'; but
|
|
|
|
* cmdline_process_param will eat -T (it means no-pty) and
|
|
|
|
* complain that pterm doesn't support it. So, in pterm
|
|
|
|
* only, we convert -T into -title.
|
|
|
|
*/
|
|
|
|
if ((cmdline_tooltype & TOOLTYPE_NONNETWORK) &&
|
|
|
|
!strcmp(p, "-T"))
|
|
|
|
p = "-title";
|
|
|
|
|
|
|
|
ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL),
|
|
|
|
do_everything ? 1 : -1, conf);
|
|
|
|
|
|
|
|
if (ret == -2) {
|
|
|
|
cmdline_error("option \"%s\" requires an argument", p);
|
|
|
|
} else if (ret == 2) {
|
|
|
|
--argc, ++argv; /* skip next argument */
|
|
|
|
continue;
|
|
|
|
} else if (ret == 1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(p, "-fn") || !strcmp(p, "-font")) {
|
|
|
|
FontSpec *fs;
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
fs = fontspec_new(val);
|
|
|
|
conf_set_fontspec(conf, CONF_font, fs);
|
|
|
|
fontspec_free(fs);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-fb")) {
|
|
|
|
FontSpec *fs;
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
fs = fontspec_new(val);
|
|
|
|
conf_set_fontspec(conf, CONF_boldfont, fs);
|
|
|
|
fontspec_free(fs);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-fw")) {
|
|
|
|
FontSpec *fs;
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
fs = fontspec_new(val);
|
|
|
|
conf_set_fontspec(conf, CONF_widefont, fs);
|
|
|
|
fontspec_free(fs);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-fwb")) {
|
|
|
|
FontSpec *fs;
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
fs = fontspec_new(val);
|
|
|
|
conf_set_fontspec(conf, CONF_wideboldfont, fs);
|
|
|
|
fontspec_free(fs);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-cs")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_str(conf, CONF_line_codepage, val);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-geometry")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
geometry_string = val;
|
|
|
|
} else if (!strcmp(p, "-sl")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_savelines, atoi(val));
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-fg") || !strcmp(p, "-bg") ||
|
|
|
|
!strcmp(p, "-bfg") || !strcmp(p, "-bbg") ||
|
|
|
|
!strcmp(p, "-cfg") || !strcmp(p, "-cbg")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
|
|
|
|
{
|
|
|
|
#if GTK_CHECK_VERSION(3,0,0)
|
|
|
|
GdkRGBA rgba;
|
|
|
|
int success = gdk_rgba_parse(&rgba, val);
|
|
|
|
#else
|
|
|
|
GdkColor col;
|
|
|
|
int success = gdk_color_parse(val, &col);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
err = 1;
|
|
|
|
fprintf(stderr, "%s: unable to parse colour \"%s\"\n",
|
|
|
|
appname, val);
|
|
|
|
} else {
|
|
|
|
#if GTK_CHECK_VERSION(3,0,0)
|
|
|
|
int r = rgba.red * 255;
|
|
|
|
int g = rgba.green * 255;
|
|
|
|
int b = rgba.blue * 255;
|
|
|
|
#else
|
|
|
|
int r = col.red / 256;
|
|
|
|
int g = col.green / 256;
|
|
|
|
int b = col.blue / 256;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int index;
|
|
|
|
index = (!strcmp(p, "-fg") ? 0 :
|
|
|
|
!strcmp(p, "-bg") ? 2 :
|
|
|
|
!strcmp(p, "-bfg") ? 1 :
|
|
|
|
!strcmp(p, "-bbg") ? 3 :
|
|
|
|
!strcmp(p, "-cfg") ? 4 :
|
|
|
|
!strcmp(p, "-cbg") ? 5 : -1);
|
|
|
|
assert(index != -1);
|
|
|
|
|
|
|
|
conf_set_int_int(conf, CONF_colours, index*3+0, r);
|
|
|
|
conf_set_int_int(conf, CONF_colours, index*3+1, g);
|
|
|
|
conf_set_int_int(conf, CONF_colours, index*3+2, b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (use_pty_argv && !strcmp(p, "-e")) {
|
|
|
|
/* This option swallows all further arguments. */
|
|
|
|
if (!do_everything)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (--argc > 0) {
|
|
|
|
int i;
|
|
|
|
pty_argv = snewn(argc+1, char *);
|
|
|
|
++argv;
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
pty_argv[i] = argv[i];
|
|
|
|
pty_argv[argc] = NULL;
|
|
|
|
break; /* finished command-line processing */
|
|
|
|
} else
|
|
|
|
err = 1, fprintf(stderr, "%s: -e expects an argument\n",
|
|
|
|
appname);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-title")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_str(conf, CONF_wintitle, val);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-log")) {
|
|
|
|
Filename *fn;
|
|
|
|
EXPECTS_ARG;
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
fn = filename_from_str(val);
|
|
|
|
conf_set_filename(conf, CONF_logfilename, fn);
|
|
|
|
conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
|
|
|
|
filename_free(fn);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_stamp_utmp, 0);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-ut")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_stamp_utmp, 1);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-ls-") || !strcmp(p, "+ls")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_login_shell, 0);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-ls")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_login_shell, 1);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-nethack")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_nethack_keypad, 1);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-sb-") || !strcmp(p, "+sb")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_scrollbar, 0);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-sb")) {
|
|
|
|
SECOND_PASS_ONLY;
|
|
|
|
conf_set_int(conf, CONF_scrollbar, 1);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-name")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
app_name = val;
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-xrm")) {
|
|
|
|
EXPECTS_ARG;
|
|
|
|
provide_xrm_string(val);
|
|
|
|
|
|
|
|
} else if(!strcmp(p, "-help") || !strcmp(p, "--help")) {
|
|
|
|
help(stdout);
|
|
|
|
exit(0);
|
|
|
|
|
|
|
|
} else if(!strcmp(p, "-version") || !strcmp(p, "--version")) {
|
|
|
|
version(stdout);
|
|
|
|
exit(0);
|
|
|
|
|
|
|
|
} else if (!strcmp(p, "-pgpfp")) {
|
|
|
|
pgp_fingerprints();
|
|
|
|
exit(1);
|
|
|
|
|
Centralise PuTTY and Plink's non-option argument handling.
This is another piece of long-overdue refactoring similar to the
recent commit e3796cb77. But where that one dealt with normalisation
of stuff already stored _in_ a Conf by whatever means (including, in
particular, handling a user typing 'username@host.name' into the
Hostname box of the GUI session dialog box), this one deals with
handling argv entries and putting them into the Conf.
This isn't exactly a pure no-functional-change-at-all refactoring. On
the other hand, it isn't a full-on cleanup that completely
rationalises all the user-visible behaviour as well as the code
structure. It's somewhere in between: I've preserved all the behaviour
quirks that I could imagine a reason for having intended, but taken
the opportunity to _not_ faithfully replicate anything I thought was
clearly just a bug.
So, for example, the following inconsistency is carefully preserved:
the command 'plink -load session nextword' treats 'nextword' as a host
name if the loaded session hasn't provided a hostname already, and
otherwise treats 'nextword' as the remote command to execute on the
already-specified remote host, but the same combination of arguments
to GUI PuTTY will _always_ treat 'nextword' as a hostname, overriding
a hostname (if any) in the saved session. That makes some sense to me
because of the different shapes of the overall command lines.
On the other hand, there are two behaviour changes I know of as a
result of this commit: a third argument to GUI PuTTY (after a hostname
and port) now provokes an error message instead of being silently
ignored, and in Plink, if you combine a -P option (specifying a port
number) with the historical comma-separated protocol selection prefix
on the hostname argument (which I'd completely forgotten even existed
until this piece of work), then the -P will now override the selected
protocol's default port number, whereas previously the default port
would win. For example, 'plink -P 12345 telnet,hostname' will now
connect via Telnet to port 12345 instead of to port 23.
There may be scope for removing or rethinking some of the command-
line syntax quirks in the wake of this change. If we do decide to do
anything like that, then hopefully having it all in one place will
make it easier to remove or change things consistently across the
tools.
2017-12-07 19:59:43 +00:00
|
|
|
} else if (p[0] != '-') {
|
|
|
|
/* Non-option arguments not handled by cmdline.c are errors. */
|
|
|
|
if (do_everything) {
|
|
|
|
err = 1;
|
|
|
|
fprintf(stderr, "%s: unexpected non-option argument '%s'\n",
|
|
|
|
appname, p);
|
|
|
|
}
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
err = 1;
|
|
|
|
fprintf(stderr, "%s: unrecognized option '%s'\n", appname, p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
Remove the 'Frontend' type and replace it with a vtable.
After the recent Seat and LogContext revamps, _nearly_ all the
remaining uses of the type 'Frontend' were in terminal.c, which needs
all sorts of interactions with the GUI window the terminal lives in,
from the obvious (actually drawing text on the window, reading and
writing the clipboard) to the obscure (minimising, maximising and
moving the window in response to particular escape sequences).
All of those functions are now provided by an abstraction called
TermWin. The few remaining uses of Frontend after _that_ are internal
to a particular platform directory, so as to spread the implementation
of that particular kind of Frontend between multiple source files; so
I've renamed all of those so that they take a more specifically named
type that refers to the particular implementation rather than the
general abstraction.
So now the name 'Frontend' no longer exists in the code base at all,
and everywhere one used to be used, it's completely clear whether it
was operating in one of Frontend's three abstract roles (and if so,
which), or whether it was specific to a particular implementation.
Another type that's disappeared is 'Context', which used to be a
typedef defined to something different on each platform, describing
whatever short-lived resources were necessary to draw on the terminal
window: the front end would provide a ready-made one when calling
term_paint, and the terminal could request one with get_ctx/free_ctx
if it wanted to do proactive window updates. Now that drawing context
lives inside the TermWin itself, because there was never any need to
have two of those contexts live at the same time.
(Another minor API change is that the window-title functions - both
reading and writing - have had a missing 'const' added to their char *
parameters / return values.)
I don't expect this change to enable any particularly interesting new
functionality (in particular, I have no plans that need more than one
implementation of TermWin in the same application). But it completes
the tidying-up that began with the Seat and LogContext rework.
2018-10-25 17:44:04 +00:00
|
|
|
GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend)
|
2016-03-23 22:03:46 +00:00
|
|
|
{
|
|
|
|
return gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
|
}
|
|
|
|
|
2018-10-29 19:50:29 +00:00
|
|
|
const int buildinfo_gtk_relevant = true;
|
2017-02-22 22:10:05 +00:00
|
|
|
|
Make the configuration dialog non-modal.
Now every call to do_config_box is replaced with a call to
create_config_box, which returns immediately having constructed the
new GTK window object, and is passed a callback function which it will
arrange to be called when the dialog terminates (whether by OK or by
Cancel). That callback is now what triggers the construction of a
session window after 'Open' is pressed in the initial config box, or
the actual mid-session reconfiguration action after 'Apply' is pressed
in a Change Settings box.
We were already prepared to ignore the re-selection of 'Change
Settings' from the context menu of a window that already had a Change
Settings box open (and not accidentally create a second config box for
the same window); but now we do slightly better, by finding the
existing config box and un-minimising and raising it, in case the user
had forgotten it was there.
That's a useful featurelet, but not the main purpose of this change.
The mani point, of course, is that now the multi-window GtkApplication
based front ends now don't do anything confusing to the nesting of
gtk_main() when config boxes are involved. Whether you're changing the
settings of one (or more than one) of your already-running sessions,
preparing to start up a new PuTTY connection, or both at once, we stay
in the same top-level instance of gtk_main() and all sessions' top-
level callbacks continue to run sensibly.
2017-11-26 11:58:02 +00:00
|
|
|
struct post_initial_config_box_ctx {
|
|
|
|
Conf *conf;
|
|
|
|
const char *geometry_string;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void post_initial_config_box(void *vctx, int result)
|
|
|
|
{
|
|
|
|
struct post_initial_config_box_ctx ctx =
|
|
|
|
*(struct post_initial_config_box_ctx *)vctx;
|
|
|
|
sfree(vctx);
|
|
|
|
|
2017-11-26 14:37:38 +00:00
|
|
|
if (result > 0) {
|
Make the configuration dialog non-modal.
Now every call to do_config_box is replaced with a call to
create_config_box, which returns immediately having constructed the
new GTK window object, and is passed a callback function which it will
arrange to be called when the dialog terminates (whether by OK or by
Cancel). That callback is now what triggers the construction of a
session window after 'Open' is pressed in the initial config box, or
the actual mid-session reconfiguration action after 'Apply' is pressed
in a Change Settings box.
We were already prepared to ignore the re-selection of 'Change
Settings' from the context menu of a window that already had a Change
Settings box open (and not accidentally create a second config box for
the same window); but now we do slightly better, by finding the
existing config box and un-minimising and raising it, in case the user
had forgotten it was there.
That's a useful featurelet, but not the main purpose of this change.
The mani point, of course, is that now the multi-window GtkApplication
based front ends now don't do anything confusing to the nesting of
gtk_main() when config boxes are involved. Whether you're changing the
settings of one (or more than one) of your already-running sessions,
preparing to start up a new PuTTY connection, or both at once, we stay
in the same top-level instance of gtk_main() and all sessions' top-
level callbacks continue to run sensibly.
2017-11-26 11:58:02 +00:00
|
|
|
new_session_window(ctx.conf, ctx.geometry_string);
|
2017-11-26 14:37:38 +00:00
|
|
|
} else if (result == 0) {
|
Make the configuration dialog non-modal.
Now every call to do_config_box is replaced with a call to
create_config_box, which returns immediately having constructed the
new GTK window object, and is passed a callback function which it will
arrange to be called when the dialog terminates (whether by OK or by
Cancel). That callback is now what triggers the construction of a
session window after 'Open' is pressed in the initial config box, or
the actual mid-session reconfiguration action after 'Apply' is pressed
in a Change Settings box.
We were already prepared to ignore the re-selection of 'Change
Settings' from the context menu of a window that already had a Change
Settings box open (and not accidentally create a second config box for
the same window); but now we do slightly better, by finding the
existing config box and un-minimising and raising it, in case the user
had forgotten it was there.
That's a useful featurelet, but not the main purpose of this change.
The mani point, of course, is that now the multi-window GtkApplication
based front ends now don't do anything confusing to the nesting of
gtk_main() when config boxes are involved. Whether you're changing the
settings of one (or more than one) of your already-running sessions,
preparing to start up a new PuTTY connection, or both at once, we stay
in the same top-level instance of gtk_main() and all sessions' top-
level callbacks continue to run sensibly.
2017-11-26 11:58:02 +00:00
|
|
|
/* In this main(), which only runs one session in total, a
|
|
|
|
* negative result from the initial config box means we simply
|
|
|
|
* terminate. */
|
|
|
|
conf_free(ctx.conf);
|
|
|
|
gtk_main_quit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void session_window_closed(void)
|
|
|
|
{
|
|
|
|
gtk_main_quit();
|
|
|
|
}
|
|
|
|
|
2016-03-23 21:58:40 +00:00
|
|
|
int main(int argc, char **argv)
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
{
|
|
|
|
Conf *conf;
|
|
|
|
int need_config_box;
|
|
|
|
|
|
|
|
setlocale(LC_CTYPE, "");
|
|
|
|
|
2016-03-23 21:58:40 +00:00
|
|
|
{
|
|
|
|
/* Call the function in ux{putty,pterm}.c to do app-type
|
|
|
|
* specific setup */
|
|
|
|
extern void setup(int);
|
2018-10-29 19:50:29 +00:00
|
|
|
setup(true); /* true means we are a one-session process */
|
2016-03-23 21:58:40 +00:00
|
|
|
}
|
|
|
|
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
progname = argv[0];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy the original argv before letting gtk_init fiddle with
|
|
|
|
* it. It will be required later.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int i, oldargc;
|
|
|
|
gtkargvstart = snewn(argc-1, char *);
|
|
|
|
for (i = 1; i < argc; i++)
|
|
|
|
gtkargvstart[i-1] = dupstr(argv[i]);
|
|
|
|
oldargc = argc;
|
|
|
|
gtk_init(&argc, &argv);
|
|
|
|
ngtkargs = oldargc - argc;
|
|
|
|
}
|
|
|
|
|
|
|
|
conf = conf_new();
|
|
|
|
|
|
|
|
gtkcomm_setup();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Block SIGPIPE: if we attempt Duplicate Session or similar and
|
|
|
|
* it falls over in some way, we certainly don't want SIGPIPE
|
|
|
|
* terminating the main pterm/PuTTY. However, we'll have to
|
|
|
|
* unblock it again when pterm forks.
|
|
|
|
*/
|
|
|
|
block_signal(SIGPIPE, 1);
|
|
|
|
|
|
|
|
if (argc > 1 && !strncmp(argv[1], "---", 3)) {
|
2016-03-27 13:10:06 +00:00
|
|
|
extern const int dup_check_launchable;
|
|
|
|
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
read_dupsession_data(conf, argv[1]);
|
|
|
|
/* Splatter this argument so it doesn't clutter a ps listing */
|
|
|
|
smemclr(argv[1], strlen(argv[1]));
|
|
|
|
|
2016-03-27 13:10:06 +00:00
|
|
|
assert(!dup_check_launchable || conf_launchable(conf));
|
2018-10-29 19:50:29 +00:00
|
|
|
need_config_box = false;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
} else {
|
Centralise PuTTY and Plink's non-option argument handling.
This is another piece of long-overdue refactoring similar to the
recent commit e3796cb77. But where that one dealt with normalisation
of stuff already stored _in_ a Conf by whatever means (including, in
particular, handling a user typing 'username@host.name' into the
Hostname box of the GUI session dialog box), this one deals with
handling argv entries and putting them into the Conf.
This isn't exactly a pure no-functional-change-at-all refactoring. On
the other hand, it isn't a full-on cleanup that completely
rationalises all the user-visible behaviour as well as the code
structure. It's somewhere in between: I've preserved all the behaviour
quirks that I could imagine a reason for having intended, but taken
the opportunity to _not_ faithfully replicate anything I thought was
clearly just a bug.
So, for example, the following inconsistency is carefully preserved:
the command 'plink -load session nextword' treats 'nextword' as a host
name if the loaded session hasn't provided a hostname already, and
otherwise treats 'nextword' as the remote command to execute on the
already-specified remote host, but the same combination of arguments
to GUI PuTTY will _always_ treat 'nextword' as a hostname, overriding
a hostname (if any) in the saved session. That makes some sense to me
because of the different shapes of the overall command lines.
On the other hand, there are two behaviour changes I know of as a
result of this commit: a third argument to GUI PuTTY (after a hostname
and port) now provokes an error message instead of being silently
ignored, and in Plink, if you combine a -P option (specifying a port
number) with the historical comma-separated protocol selection prefix
on the hostname argument (which I'd completely forgotten even existed
until this piece of work), then the -P will now override the selected
protocol's default port number, whereas previously the default port
would win. For example, 'plink -P 12345 telnet,hostname' will now
connect via Telnet to port 12345 instead of to port 23.
There may be scope for removing or rethinking some of the command-
line syntax quirks in the wake of this change. If we do decide to do
anything like that, then hopefully having it all in one place will
make it easier to remove or change things consistently across the
tools.
2017-12-07 19:59:43 +00:00
|
|
|
if (do_cmdline(argc, argv, 0, conf))
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
exit(1); /* pre-defaults pass to get -class */
|
|
|
|
do_defaults(NULL, conf);
|
Centralise PuTTY and Plink's non-option argument handling.
This is another piece of long-overdue refactoring similar to the
recent commit e3796cb77. But where that one dealt with normalisation
of stuff already stored _in_ a Conf by whatever means (including, in
particular, handling a user typing 'username@host.name' into the
Hostname box of the GUI session dialog box), this one deals with
handling argv entries and putting them into the Conf.
This isn't exactly a pure no-functional-change-at-all refactoring. On
the other hand, it isn't a full-on cleanup that completely
rationalises all the user-visible behaviour as well as the code
structure. It's somewhere in between: I've preserved all the behaviour
quirks that I could imagine a reason for having intended, but taken
the opportunity to _not_ faithfully replicate anything I thought was
clearly just a bug.
So, for example, the following inconsistency is carefully preserved:
the command 'plink -load session nextword' treats 'nextword' as a host
name if the loaded session hasn't provided a hostname already, and
otherwise treats 'nextword' as the remote command to execute on the
already-specified remote host, but the same combination of arguments
to GUI PuTTY will _always_ treat 'nextword' as a hostname, overriding
a hostname (if any) in the saved session. That makes some sense to me
because of the different shapes of the overall command lines.
On the other hand, there are two behaviour changes I know of as a
result of this commit: a third argument to GUI PuTTY (after a hostname
and port) now provokes an error message instead of being silently
ignored, and in Plink, if you combine a -P option (specifying a port
number) with the historical comma-separated protocol selection prefix
on the hostname argument (which I'd completely forgotten even existed
until this piece of work), then the -P will now override the selected
protocol's default port number, whereas previously the default port
would win. For example, 'plink -P 12345 telnet,hostname' will now
connect via Telnet to port 12345 instead of to port 23.
There may be scope for removing or rethinking some of the command-
line syntax quirks in the wake of this change. If we do decide to do
anything like that, then hopefully having it all in one place will
make it easier to remove or change things consistently across the
tools.
2017-12-07 19:59:43 +00:00
|
|
|
if (do_cmdline(argc, argv, 1, conf))
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
exit(1); /* post-defaults, do everything */
|
|
|
|
|
|
|
|
cmdline_run_saved(conf);
|
|
|
|
|
2017-12-08 19:34:35 +00:00
|
|
|
if (cmdline_tooltype & TOOLTYPE_HOST_ARG)
|
|
|
|
need_config_box = !cmdline_host_ok(conf);
|
|
|
|
else
|
2018-10-29 19:50:29 +00:00
|
|
|
need_config_box = false;
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
}
|
|
|
|
|
Make the configuration dialog non-modal.
Now every call to do_config_box is replaced with a call to
create_config_box, which returns immediately having constructed the
new GTK window object, and is passed a callback function which it will
arrange to be called when the dialog terminates (whether by OK or by
Cancel). That callback is now what triggers the construction of a
session window after 'Open' is pressed in the initial config box, or
the actual mid-session reconfiguration action after 'Apply' is pressed
in a Change Settings box.
We were already prepared to ignore the re-selection of 'Change
Settings' from the context menu of a window that already had a Change
Settings box open (and not accidentally create a second config box for
the same window); but now we do slightly better, by finding the
existing config box and un-minimising and raising it, in case the user
had forgotten it was there.
That's a useful featurelet, but not the main purpose of this change.
The mani point, of course, is that now the multi-window GtkApplication
based front ends now don't do anything confusing to the nesting of
gtk_main() when config boxes are involved. Whether you're changing the
settings of one (or more than one) of your already-running sessions,
preparing to start up a new PuTTY connection, or both at once, we stay
in the same top-level instance of gtk_main() and all sessions' top-
level callbacks continue to run sensibly.
2017-11-26 11:58:02 +00:00
|
|
|
if (need_config_box) {
|
|
|
|
/*
|
|
|
|
* Put up the initial config box, which will pass the provided
|
|
|
|
* parameters (with conf updated) to new_session_window() when
|
|
|
|
* (if) the user selects Open. Or it might close without
|
|
|
|
* creating a session window, if the user selects Cancel. Or
|
|
|
|
* it might just create the session window immediately if this
|
|
|
|
* is a pterm-style app which doesn't have an initial config
|
|
|
|
* box at all.
|
|
|
|
*/
|
|
|
|
struct post_initial_config_box_ctx *ctx =
|
|
|
|
snew(struct post_initial_config_box_ctx);
|
|
|
|
ctx->conf = conf;
|
|
|
|
ctx->geometry_string = geometry_string;
|
|
|
|
initial_config_box(conf, post_initial_config_box, ctx);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* No initial config needed; just create the session window
|
|
|
|
* now.
|
|
|
|
*/
|
|
|
|
new_session_window(conf, geometry_string);
|
|
|
|
}
|
Divide the whole of gtkwin.c into three parts.
This lays further groundwork for the OS X GTK3 port, which is going to
have to deal with multiple sessions sharing the same process. gtkwin.c
was a bit too monolithic for this, since it included some
process-global runtime state (timers, toplevel callbacks), some
process startup stuff (gtk_init, gtk_main, argv processing) and some
per-session-window stuff.
The per-session stuff remains in gtkwin.c, with the top-level function
now being new_session_window() taking a Conf. The new gtkmain.c
contains the outer skeleton of pt_main(), handling argv processing and
one-off startup stuff like setlocale; and the new gtkcomm.c contains
the pieces of PuTTY infrastructure like timers and uxsel that are
shared between multiple sessions rather than reinstantiated per
session, which have been rewritten to use global variables rather than
fields in 'inst' (since it's now clear to me that they'll have to
apply to all the insts in existence at once).
There are still some lurking assumptions of one-session-per-process,
e.g. the use of gtk_main_quit when a session finishes, and the fact
that the config box insists on running as a separate invocation of
gtk_main so that one session's preliminary config box can't coexist
with another session already active. But this should make it possible
to at least write an OS X app good enough to start testing with, even
if it doesn't get everything quite right yet.
This change is almost entirely rearranging existing code, so it
shouldn't be seriously destabilising. But two noticeable actual
changes have happened, both pleasantly simplifying:
Firstly, the global-variables rewrite of gtkcomm.c has allowed the
post_main edifice to become a great deal simpler. Most of its
complexity was about remembering what 'inst' it had to call back to,
and in fact the right answer is that it shouldn't be calling back to
one at all. So now the post_main() called by gtkdlg.c has become the
same function as the old inst_post_main() that actually did the work,
instead of the two having to be connected by a piece of ugly plumbing.
Secondly, a piece of code that's vanished completely in this
refactoring is the temporary blocking of SIGCHLD around most of the
session setup code. This turns out to have been introduced in 2002,
_before_ I switched to using the intra-process signal pipe strategy
for SIGCHLD handling in 2003. So I now expect that we should be robust
in any case against receiving SIGCHLD at an inconvenient moment, and
hence there's no need to block it.
2016-03-22 21:24:30 +00:00
|
|
|
|
|
|
|
gtk_main();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|