mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-18 11:38:05 -05:00
Implement `Restart Session', in both Unix and Windows PuTTY. Largely
because Owen questioned whether it was really easy enough to be labelled `fun' in the bug database :-) [originally from svn r4453]
This commit is contained in:
parent
f16d8aff82
commit
0047bbe70f
142
unix/pterm.c
142
unix/pterm.c
@ -44,7 +44,8 @@ struct gui_data {
|
|||||||
GtkWidget *window, *area, *sbar;
|
GtkWidget *window, *area, *sbar;
|
||||||
GtkBox *hbox;
|
GtkBox *hbox;
|
||||||
GtkAdjustment *sbar_adjust;
|
GtkAdjustment *sbar_adjust;
|
||||||
GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2;
|
GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2,
|
||||||
|
*restartitem;
|
||||||
GtkWidget *sessionsmenu;
|
GtkWidget *sessionsmenu;
|
||||||
GdkPixmap *pixmap;
|
GdkPixmap *pixmap;
|
||||||
GdkFont *fonts[4]; /* normal, bold, wide, widebold */
|
GdkFont *fonts[4]; /* normal, bold, wide, widebold */
|
||||||
@ -94,6 +95,8 @@ static int send_raw_mouse;
|
|||||||
|
|
||||||
static char *app_name = "pterm";
|
static char *app_name = "pterm";
|
||||||
|
|
||||||
|
static void start_backend(struct gui_data *inst);
|
||||||
|
|
||||||
char *x_get_default(const char *key)
|
char *x_get_default(const char *key)
|
||||||
{
|
{
|
||||||
return XGetDefault(GDK_DISPLAY(), app_name, key);
|
return XGetDefault(GDK_DISPLAY(), app_name, key);
|
||||||
@ -981,7 +984,8 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|||||||
* should never matter.
|
* should never matter.
|
||||||
*/
|
*/
|
||||||
output[end] = '\0'; /* NUL-terminate */
|
output[end] = '\0'; /* NUL-terminate */
|
||||||
ldisc_send(inst->ldisc, output+start, -2, 1);
|
if (inst->ldisc)
|
||||||
|
ldisc_send(inst->ldisc, output+start, -2, 1);
|
||||||
} else if (!inst->direct_to_font) {
|
} else if (!inst->direct_to_font) {
|
||||||
if (!use_ucsoutput) {
|
if (!use_ucsoutput) {
|
||||||
/*
|
/*
|
||||||
@ -996,21 +1000,24 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|||||||
* far as I can tell, and it's poorly documented
|
* far as I can tell, and it's poorly documented
|
||||||
* even in 2.0, so it'll have to wait.
|
* even in 2.0, so it'll have to wait.
|
||||||
*/
|
*/
|
||||||
lpage_send(inst->ldisc, CS_ISO8859_1, output+start,
|
if (inst->ldisc)
|
||||||
end-start, 1);
|
lpage_send(inst->ldisc, CS_ISO8859_1, output+start,
|
||||||
|
end-start, 1);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We generated our own Unicode key data from the
|
* We generated our own Unicode key data from the
|
||||||
* keysym, so use that instead.
|
* keysym, so use that instead.
|
||||||
*/
|
*/
|
||||||
luni_send(inst->ldisc, ucsoutput+start, end-start, 1);
|
if (inst->ldisc)
|
||||||
|
luni_send(inst->ldisc, ucsoutput+start, end-start, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* In direct-to-font mode, we just send the string
|
* In direct-to-font mode, we just send the string
|
||||||
* exactly as we received it.
|
* exactly as we received it.
|
||||||
*/
|
*/
|
||||||
ldisc_send(inst->ldisc, output+start, end-start, 1);
|
if (inst->ldisc)
|
||||||
|
ldisc_send(inst->ldisc, output+start, end-start, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_mouseptr(inst, 0);
|
show_mouseptr(inst, 0);
|
||||||
@ -1134,6 +1141,17 @@ gint timer_func(gpointer data)
|
|||||||
if (inst->cfg.close_on_exit == FORCE_ON ||
|
if (inst->cfg.close_on_exit == FORCE_ON ||
|
||||||
(inst->cfg.close_on_exit == AUTO && exitcode == 0))
|
(inst->cfg.close_on_exit == AUTO && exitcode == 0))
|
||||||
exit(0); /* just go. */
|
exit(0); /* just go. */
|
||||||
|
if (inst->ldisc) {
|
||||||
|
ldisc_free(inst->ldisc);
|
||||||
|
inst->ldisc = NULL;
|
||||||
|
}
|
||||||
|
if (inst->back) {
|
||||||
|
inst->back->free(inst->backhandle);
|
||||||
|
inst->backhandle = NULL;
|
||||||
|
inst->back = NULL;
|
||||||
|
update_specials_menu(inst);
|
||||||
|
}
|
||||||
|
gtk_widget_show(inst->restartitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_update(inst->term);
|
term_update(inst->term);
|
||||||
@ -2732,7 +2750,8 @@ void reset_terminal_menuitem(GtkMenuItem *item, gpointer data)
|
|||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)data;
|
struct gui_data *inst = (struct gui_data *)data;
|
||||||
term_pwron(inst->term);
|
term_pwron(inst->term);
|
||||||
ldisc_send(inst->ldisc, NULL, 0, 0);
|
if (inst->ldisc)
|
||||||
|
ldisc_send(inst->ldisc, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_all_menuitem(GtkMenuItem *item, gpointer data)
|
void copy_all_menuitem(GtkMenuItem *item, gpointer data)
|
||||||
@ -2747,7 +2766,8 @@ void special_menuitem(GtkMenuItem *item, gpointer data)
|
|||||||
int code = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),
|
int code = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),
|
||||||
"user-data"));
|
"user-data"));
|
||||||
|
|
||||||
inst->back->special(inst->backhandle, code);
|
if (inst->back)
|
||||||
|
inst->back->special(inst->backhandle, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void about_menuitem(GtkMenuItem *item, gpointer data)
|
void about_menuitem(GtkMenuItem *item, gpointer data)
|
||||||
@ -2788,11 +2808,13 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
|||||||
* Flush the line discipline's edit buffer in the case
|
* Flush the line discipline's edit buffer in the case
|
||||||
* where local editing has just been disabled.
|
* where local editing has just been disabled.
|
||||||
*/
|
*/
|
||||||
ldisc_send(inst->ldisc, NULL, 0, 0);
|
if (inst->ldisc)
|
||||||
|
ldisc_send(inst->ldisc, NULL, 0, 0);
|
||||||
/* Pass new config data to the terminal */
|
/* Pass new config data to the terminal */
|
||||||
term_reconfig(inst->term, &cfg2);
|
term_reconfig(inst->term, &cfg2);
|
||||||
/* Pass new config data to the back end */
|
/* Pass new config data to the back end */
|
||||||
inst->back->reconfig(inst->backhandle, &cfg2);
|
if (inst->back)
|
||||||
|
inst->back->reconfig(inst->backhandle, &cfg2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just setting inst->cfg is sufficient to cause colour
|
* Just setting inst->cfg is sufficient to cause colour
|
||||||
@ -3083,6 +3105,17 @@ void new_session_menuitem(GtkMenuItem *item, gpointer data)
|
|||||||
fork_and_exec_self(inst, -1, NULL);
|
fork_and_exec_self(inst, -1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restart_session_menuitem(GtkMenuItem *item, gpointer data)
|
||||||
|
{
|
||||||
|
struct gui_data *inst = (struct gui_data *)data;
|
||||||
|
|
||||||
|
if (!inst->back) {
|
||||||
|
logevent(inst, "----- Session restarted -----");
|
||||||
|
start_backend(inst);
|
||||||
|
inst->exited = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void saved_session_menuitem(GtkMenuItem *item, gpointer data)
|
void saved_session_menuitem(GtkMenuItem *item, gpointer data)
|
||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)data;
|
struct gui_data *inst = (struct gui_data *)data;
|
||||||
@ -3104,7 +3137,11 @@ void update_specials_menu(void *frontend)
|
|||||||
|
|
||||||
const struct telnet_special *specials;
|
const struct telnet_special *specials;
|
||||||
|
|
||||||
specials = inst->back->get_specials(inst->backhandle);
|
if (inst->back)
|
||||||
|
specials = inst->back->get_specials(inst->backhandle);
|
||||||
|
else
|
||||||
|
specials = NULL;
|
||||||
|
|
||||||
gtk_container_foreach(GTK_CONTAINER(inst->specialsmenu),
|
gtk_container_foreach(GTK_CONTAINER(inst->specialsmenu),
|
||||||
(GtkCallback)gtk_widget_destroy, NULL);
|
(GtkCallback)gtk_widget_destroy, NULL);
|
||||||
if (specials) {
|
if (specials) {
|
||||||
@ -3130,9 +3167,51 @@ void update_specials_menu(void *frontend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pt_main(int argc, char **argv)
|
static void start_backend(struct gui_data *inst)
|
||||||
{
|
{
|
||||||
extern Backend *select_backend(Config *cfg);
|
extern Backend *select_backend(Config *cfg);
|
||||||
|
char *realhost;
|
||||||
|
const char *error;
|
||||||
|
|
||||||
|
inst->back = select_backend(&inst->cfg);
|
||||||
|
|
||||||
|
error = inst->back->init((void *)inst, &inst->backhandle,
|
||||||
|
&inst->cfg, inst->cfg.host, inst->cfg.port,
|
||||||
|
&realhost, inst->cfg.tcp_nodelay,
|
||||||
|
inst->cfg.tcp_keepalives);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
char *msg = dupprintf("Unable to open connection to %s:\n%s",
|
||||||
|
inst->cfg.host, error);
|
||||||
|
inst->exited = TRUE;
|
||||||
|
fatal_message_box(inst->window, msg);
|
||||||
|
sfree(msg);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->cfg.wintitle[0]) {
|
||||||
|
set_title(inst, inst->cfg.wintitle);
|
||||||
|
set_icon(inst, inst->cfg.wintitle);
|
||||||
|
} else {
|
||||||
|
char *title = make_default_wintitle(realhost);
|
||||||
|
set_title(inst, title);
|
||||||
|
set_icon(inst, title);
|
||||||
|
sfree(title);
|
||||||
|
}
|
||||||
|
inst->back->provide_logctx(inst->backhandle, inst->logctx);
|
||||||
|
update_specials_menu(inst);
|
||||||
|
|
||||||
|
term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
|
||||||
|
|
||||||
|
inst->ldisc =
|
||||||
|
ldisc_create(&inst->cfg, inst->term, inst->back, inst->backhandle,
|
||||||
|
inst);
|
||||||
|
|
||||||
|
gtk_widget_hide(inst->restartitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pt_main(int argc, char **argv)
|
||||||
|
{
|
||||||
extern int cfgbox(Config *cfg);
|
extern int cfgbox(Config *cfg);
|
||||||
struct gui_data *inst;
|
struct gui_data *inst;
|
||||||
|
|
||||||
@ -3298,6 +3377,9 @@ int pt_main(int argc, char **argv)
|
|||||||
} while (0)
|
} while (0)
|
||||||
if (new_session)
|
if (new_session)
|
||||||
MKMENUITEM("New Session", new_session_menuitem);
|
MKMENUITEM("New Session", new_session_menuitem);
|
||||||
|
MKMENUITEM("Restart Session", restart_session_menuitem);
|
||||||
|
inst->restartitem = menuitem;
|
||||||
|
gtk_widget_hide(inst->restartitem);
|
||||||
MKMENUITEM("Duplicate Session", dup_session_menuitem);
|
MKMENUITEM("Duplicate Session", dup_session_menuitem);
|
||||||
if (saved_sessions) {
|
if (saved_sessions) {
|
||||||
struct sesslist sesslist;
|
struct sesslist sesslist;
|
||||||
@ -3363,42 +3445,8 @@ int pt_main(int argc, char **argv)
|
|||||||
|
|
||||||
term_size(inst->term, inst->cfg.height, inst->cfg.width, inst->cfg.savelines);
|
term_size(inst->term, inst->cfg.height, inst->cfg.width, inst->cfg.savelines);
|
||||||
|
|
||||||
inst->back = select_backend(&inst->cfg);
|
start_backend(inst);
|
||||||
{
|
|
||||||
char *realhost;
|
|
||||||
const char *error;
|
|
||||||
|
|
||||||
error = inst->back->init((void *)inst, &inst->backhandle,
|
|
||||||
&inst->cfg, inst->cfg.host, inst->cfg.port,
|
|
||||||
&realhost, inst->cfg.tcp_nodelay,
|
|
||||||
inst->cfg.tcp_keepalives);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
char *msg = dupprintf("Unable to open connection to %s:\n%s",
|
|
||||||
inst->cfg.host, error);
|
|
||||||
inst->exited = TRUE;
|
|
||||||
fatal_message_box(inst->window, msg);
|
|
||||||
sfree(msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inst->cfg.wintitle[0]) {
|
|
||||||
set_title(inst, inst->cfg.wintitle);
|
|
||||||
set_icon(inst, inst->cfg.wintitle);
|
|
||||||
} else {
|
|
||||||
char *title = make_default_wintitle(realhost);
|
|
||||||
set_title(inst, title);
|
|
||||||
set_icon(inst, title);
|
|
||||||
sfree(title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inst->back->provide_logctx(inst->backhandle, inst->logctx);
|
|
||||||
update_specials_menu(inst);
|
|
||||||
|
|
||||||
term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
|
|
||||||
|
|
||||||
inst->ldisc =
|
|
||||||
ldisc_create(&inst->cfg, inst->term, inst->back, inst->backhandle, inst);
|
|
||||||
ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
|
ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
|
||||||
|
|
||||||
/* now we're reday to deal with the child exit handler being
|
/* now we're reday to deal with the child exit handler being
|
||||||
|
278
window.c
278
window.c
@ -25,9 +25,10 @@
|
|||||||
#define IDM_SHOWLOG 0x0010
|
#define IDM_SHOWLOG 0x0010
|
||||||
#define IDM_NEWSESS 0x0020
|
#define IDM_NEWSESS 0x0020
|
||||||
#define IDM_DUPSESS 0x0030
|
#define IDM_DUPSESS 0x0030
|
||||||
#define IDM_RECONF 0x0040
|
#define IDM_RESTART 0x0040
|
||||||
#define IDM_CLRSB 0x0050
|
#define IDM_RECONF 0x0050
|
||||||
#define IDM_RESET 0x0060
|
#define IDM_CLRSB 0x0060
|
||||||
|
#define IDM_RESET 0x0070
|
||||||
#define IDM_HELP 0x0140
|
#define IDM_HELP 0x0140
|
||||||
#define IDM_ABOUT 0x0150
|
#define IDM_ABOUT 0x0150
|
||||||
#define IDM_SAVEDSESS 0x0160
|
#define IDM_SAVEDSESS 0x0160
|
||||||
@ -182,6 +183,110 @@ void ldisc_update(void *frontend, int echo, int edit)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void start_backend(void)
|
||||||
|
{
|
||||||
|
const char *error;
|
||||||
|
char msg[1024], *title;
|
||||||
|
char *realhost;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select protocol. This is farmed out into a table in a
|
||||||
|
* separate file to enable an ssh-free variant.
|
||||||
|
*/
|
||||||
|
back = NULL;
|
||||||
|
for (i = 0; backends[i].backend != NULL; i++)
|
||||||
|
if (backends[i].protocol == cfg.protocol) {
|
||||||
|
back = backends[i].backend;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (back == NULL) {
|
||||||
|
char *str = dupprintf("%s Internal Error", appname);
|
||||||
|
MessageBox(NULL, "Unsupported protocol number found",
|
||||||
|
str, MB_OK | MB_ICONEXCLAMATION);
|
||||||
|
sfree(str);
|
||||||
|
cleanup_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = back->init(NULL, &backhandle, &cfg,
|
||||||
|
cfg.host, cfg.port, &realhost, cfg.tcp_nodelay,
|
||||||
|
cfg.tcp_keepalives);
|
||||||
|
back->provide_logctx(backhandle, logctx);
|
||||||
|
if (error) {
|
||||||
|
char *str = dupprintf("%s Error", appname);
|
||||||
|
sprintf(msg, "Unable to open connection to\n"
|
||||||
|
"%.800s\n" "%s", cfg.host, error);
|
||||||
|
MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK);
|
||||||
|
sfree(str);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
window_name = icon_name = NULL;
|
||||||
|
if (*cfg.wintitle) {
|
||||||
|
title = cfg.wintitle;
|
||||||
|
} else {
|
||||||
|
sprintf(msg, "%s - %s", realhost, appname);
|
||||||
|
title = msg;
|
||||||
|
}
|
||||||
|
sfree(realhost);
|
||||||
|
set_title(NULL, title);
|
||||||
|
set_icon(NULL, title);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect the terminal to the backend for resize purposes.
|
||||||
|
*/
|
||||||
|
term_provide_resize_fn(term, back->size, backhandle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up a line discipline.
|
||||||
|
*/
|
||||||
|
ldisc = ldisc_create(&cfg, term, back, backhandle, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy the Restart Session menu item. (This will return
|
||||||
|
* failure if it's already absent, as it will be the very first
|
||||||
|
* time we call this function. We ignore that, because as long
|
||||||
|
* as the menu item ends up not being there, we don't care
|
||||||
|
* whether it was us who removed it or not!)
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lenof(popup_menus); i++) {
|
||||||
|
DeleteMenu(popup_menus[i].menu, IDM_RESTART, MF_BYCOMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
session_closed = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_session(void)
|
||||||
|
{
|
||||||
|
char morestuff[100];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
session_closed = TRUE;
|
||||||
|
sprintf(morestuff, "%.70s (inactive)", appname);
|
||||||
|
set_icon(NULL, morestuff);
|
||||||
|
set_title(NULL, morestuff);
|
||||||
|
|
||||||
|
if (ldisc) {
|
||||||
|
ldisc_free(ldisc);
|
||||||
|
ldisc = NULL;
|
||||||
|
}
|
||||||
|
if (back) {
|
||||||
|
back->free(backhandle);
|
||||||
|
backhandle = NULL;
|
||||||
|
back = NULL;
|
||||||
|
update_specials_menu(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show the Restart Session menu item. Do a precautionary
|
||||||
|
* delete first to ensure we never end up with more than one.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lenof(popup_menus); i++) {
|
||||||
|
DeleteMenu(popup_menus[i].menu, IDM_RESTART, MF_BYCOMMAND);
|
||||||
|
InsertMenu(popup_menus[i].menu, IDM_DUPSESS, MF_BYCOMMAND | MF_ENABLED,
|
||||||
|
IDM_RESTART, "&Restart Session");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||||
{
|
{
|
||||||
WNDCLASS wndclass;
|
WNDCLASS wndclass;
|
||||||
@ -452,27 +557,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Select protocol. This is farmed out into a table in a
|
|
||||||
* separate file to enable an ssh-free variant.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
back = NULL;
|
|
||||||
for (i = 0; backends[i].backend != NULL; i++)
|
|
||||||
if (backends[i].protocol == cfg.protocol) {
|
|
||||||
back = backends[i].backend;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (back == NULL) {
|
|
||||||
char *str = dupprintf("%s Internal Error", appname);
|
|
||||||
MessageBox(NULL, "Unsupported protocol number found",
|
|
||||||
str, MB_OK | MB_ICONEXCLAMATION);
|
|
||||||
sfree(str);
|
|
||||||
cleanup_exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for invalid Port number (i.e. zero) */
|
/* Check for invalid Port number (i.e. zero) */
|
||||||
if (cfg.port == 0) {
|
if (cfg.port == 0) {
|
||||||
char *str = dupprintf("%s Internal Error", appname);
|
char *str = dupprintf("%s Internal Error", appname);
|
||||||
@ -602,49 +686,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
SetScrollInfo(hwnd, SB_VERT, &si, FALSE);
|
SetScrollInfo(hwnd, SB_VERT, &si, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
start_backend();
|
||||||
* Start up the telnet connection.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
const char *error;
|
|
||||||
char msg[1024], *title;
|
|
||||||
char *realhost;
|
|
||||||
|
|
||||||
error = back->init(NULL, &backhandle, &cfg,
|
|
||||||
cfg.host, cfg.port, &realhost, cfg.tcp_nodelay,
|
|
||||||
cfg.tcp_keepalives);
|
|
||||||
back->provide_logctx(backhandle, logctx);
|
|
||||||
if (error) {
|
|
||||||
char *str = dupprintf("%s Error", appname);
|
|
||||||
sprintf(msg, "Unable to open connection to\n"
|
|
||||||
"%.800s\n" "%s", cfg.host, error);
|
|
||||||
MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK);
|
|
||||||
sfree(str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
window_name = icon_name = NULL;
|
|
||||||
if (*cfg.wintitle) {
|
|
||||||
title = cfg.wintitle;
|
|
||||||
} else {
|
|
||||||
sprintf(msg, "%s - %s", realhost, appname);
|
|
||||||
title = msg;
|
|
||||||
}
|
|
||||||
sfree(realhost);
|
|
||||||
set_title(NULL, title);
|
|
||||||
set_icon(NULL, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Connect the terminal to the backend for resize purposes.
|
|
||||||
*/
|
|
||||||
term_provide_resize_fn(term, back->size, backhandle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up a line discipline.
|
|
||||||
*/
|
|
||||||
ldisc = ldisc_create(&cfg, term, back, backhandle, NULL);
|
|
||||||
|
|
||||||
session_closed = FALSE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the mouse handler.
|
* Prepare the mouse handler.
|
||||||
@ -865,13 +907,17 @@ char *do_select(SOCKET skt, int startup)
|
|||||||
*/
|
*/
|
||||||
void update_specials_menu(void *frontend)
|
void update_specials_menu(void *frontend)
|
||||||
{
|
{
|
||||||
HMENU m = GetSystemMenu(hwnd, FALSE);
|
HMENU p;
|
||||||
int menu_already_exists = (specials != NULL);
|
int menu_already_exists = (specials != NULL);
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
specials = back->get_specials(backhandle);
|
if (back)
|
||||||
|
specials = back->get_specials(backhandle);
|
||||||
|
else
|
||||||
|
specials = NULL;
|
||||||
|
|
||||||
if (specials) {
|
if (specials) {
|
||||||
HMENU p = CreateMenu();
|
p = CreateMenu();
|
||||||
for (i = 0; specials[i].name; i++) {
|
for (i = 0; specials[i].name; i++) {
|
||||||
assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
|
assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
|
||||||
if (*specials[i].name)
|
if (*specials[i].name)
|
||||||
@ -880,15 +926,22 @@ void update_specials_menu(void *frontend)
|
|||||||
else
|
else
|
||||||
AppendMenu(p, MF_SEPARATOR, 0, 0);
|
AppendMenu(p, MF_SEPARATOR, 0, 0);
|
||||||
}
|
}
|
||||||
for (j = 0; j < lenof(popup_menus); j++) {
|
} else
|
||||||
if (menu_already_exists)
|
p = NULL;
|
||||||
DeleteMenu(popup_menus[j].menu,
|
|
||||||
popup_menus[j].specials_submenu_pos,
|
for (j = 0; j < lenof(popup_menus); j++) {
|
||||||
MF_BYPOSITION);
|
if (menu_already_exists) {
|
||||||
else
|
DeleteMenu(popup_menus[j].menu,
|
||||||
InsertMenu(popup_menus[j].menu,
|
popup_menus[j].specials_submenu_pos,
|
||||||
popup_menus[j].specials_submenu_pos,
|
MF_BYPOSITION);
|
||||||
MF_BYPOSITION | MF_SEPARATOR, 0, 0);
|
DeleteMenu(popup_menus[j].menu,
|
||||||
|
popup_menus[j].specials_submenu_pos,
|
||||||
|
MF_BYPOSITION);
|
||||||
|
}
|
||||||
|
if (specials) {
|
||||||
|
InsertMenu(popup_menus[j].menu,
|
||||||
|
popup_menus[j].specials_submenu_pos,
|
||||||
|
MF_BYPOSITION | MF_SEPARATOR, 0, 0);
|
||||||
InsertMenu(popup_menus[j].menu,
|
InsertMenu(popup_menus[j].menu,
|
||||||
popup_menus[j].specials_submenu_pos,
|
popup_menus[j].specials_submenu_pos,
|
||||||
MF_BYPOSITION | MF_POPUP | MF_ENABLED,
|
MF_BYPOSITION | MF_POPUP | MF_ENABLED,
|
||||||
@ -925,10 +978,7 @@ void connection_fatal(void *frontend, char *fmt, ...)
|
|||||||
if (cfg.close_on_exit == FORCE_ON)
|
if (cfg.close_on_exit == FORCE_ON)
|
||||||
PostQuitMessage(1);
|
PostQuitMessage(1);
|
||||||
else {
|
else {
|
||||||
session_closed = TRUE;
|
close_session();
|
||||||
sprintf(morestuff, "%.70s (inactive)", appname);
|
|
||||||
set_icon(NULL, morestuff);
|
|
||||||
set_title(NULL, morestuff);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,11 +1023,8 @@ static void enact_pending_netevent(void)
|
|||||||
if (cfg.close_on_exit == FORCE_ON ||
|
if (cfg.close_on_exit == FORCE_ON ||
|
||||||
cfg.close_on_exit == AUTO) PostQuitMessage(0);
|
cfg.close_on_exit == AUTO) PostQuitMessage(0);
|
||||||
else {
|
else {
|
||||||
char morestuff[100];
|
close_session();
|
||||||
session_closed = TRUE;
|
session_closed = TRUE;
|
||||||
sprintf(morestuff, "%.70s (inactive)", appname);
|
|
||||||
set_icon(NULL, morestuff);
|
|
||||||
set_title(NULL, morestuff);
|
|
||||||
MessageBox(hwnd, "Connection closed by remote host",
|
MessageBox(hwnd, "Connection closed by remote host",
|
||||||
appname, MB_OK | MB_ICONINFORMATION);
|
appname, MB_OK | MB_ICONINFORMATION);
|
||||||
}
|
}
|
||||||
@ -1738,7 +1785,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
if (now - last_movement > cfg.ping_interval) {
|
if (now - last_movement > cfg.ping_interval) {
|
||||||
back->special(backhandle, TS_PING);
|
if (back)
|
||||||
|
back->special(backhandle, TS_PING);
|
||||||
last_movement = now;
|
last_movement = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1840,6 +1888,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
if (freecl)
|
if (freecl)
|
||||||
sfree(cl);
|
sfree(cl);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case IDM_RESTART:
|
||||||
|
if (!back) {
|
||||||
|
logevent(NULL, "----- Session restarted -----");
|
||||||
|
start_backend();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IDM_RECONF:
|
case IDM_RECONF:
|
||||||
{
|
{
|
||||||
@ -1873,7 +1928,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
* Flush the line discipline's edit buffer in the
|
* Flush the line discipline's edit buffer in the
|
||||||
* case where local editing has just been disabled.
|
* case where local editing has just been disabled.
|
||||||
*/
|
*/
|
||||||
ldisc_send(ldisc, NULL, 0, 0);
|
if (ldisc)
|
||||||
|
ldisc_send(ldisc, NULL, 0, 0);
|
||||||
if (pal)
|
if (pal)
|
||||||
DeleteObject(pal);
|
DeleteObject(pal);
|
||||||
logpal = NULL;
|
logpal = NULL;
|
||||||
@ -1885,7 +1941,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
term_reconfig(term, &cfg);
|
term_reconfig(term, &cfg);
|
||||||
|
|
||||||
/* Pass new config data to the back end */
|
/* Pass new config data to the back end */
|
||||||
back->reconfig(backhandle, &cfg);
|
if (back)
|
||||||
|
back->reconfig(backhandle, &cfg);
|
||||||
|
|
||||||
/* Screen size changed ? */
|
/* Screen size changed ? */
|
||||||
if (cfg.height != prev_cfg.height ||
|
if (cfg.height != prev_cfg.height ||
|
||||||
@ -1993,7 +2050,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
break;
|
break;
|
||||||
case IDM_RESET:
|
case IDM_RESET:
|
||||||
term_pwron(term);
|
term_pwron(term);
|
||||||
ldisc_send(ldisc, NULL, 0, 0);
|
if (ldisc)
|
||||||
|
ldisc_send(ldisc, NULL, 0, 0);
|
||||||
break;
|
break;
|
||||||
case IDM_ABOUT:
|
case IDM_ABOUT:
|
||||||
showabout(hwnd);
|
showabout(hwnd);
|
||||||
@ -2041,7 +2099,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
if (!specials || !specials[j].name)
|
if (!specials || !specials[j].name)
|
||||||
break;
|
break;
|
||||||
if (j == i) {
|
if (j == i) {
|
||||||
back->special(backhandle, specials[i].code);
|
if (back)
|
||||||
|
back->special(backhandle, specials[i].code);
|
||||||
net_pending_errors();
|
net_pending_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2613,7 +2672,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
* we're sent.
|
* we're sent.
|
||||||
*/
|
*/
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
ldisc_send(ldisc, buf, len, 1);
|
if (ldisc)
|
||||||
|
ldisc_send(ldisc, buf, len, 1);
|
||||||
show_mouseptr(0);
|
show_mouseptr(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2661,7 +2721,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
*/
|
*/
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
for (i = 0; i < n; i += 2) {
|
for (i = 0; i < n; i += 2) {
|
||||||
luni_send(ldisc, (unsigned short *)(buff+i), 1, 1);
|
if (ldisc)
|
||||||
|
luni_send(ldisc, (unsigned short *)(buff+i), 1, 1);
|
||||||
}
|
}
|
||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
@ -2676,11 +2737,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
buf[1] = wParam;
|
buf[1] = wParam;
|
||||||
buf[0] = wParam >> 8;
|
buf[0] = wParam >> 8;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
lpage_send(ldisc, kbd_codepage, buf, 2, 1);
|
if (ldisc)
|
||||||
|
lpage_send(ldisc, kbd_codepage, buf, 2, 1);
|
||||||
} else {
|
} else {
|
||||||
char c = (unsigned char) wParam;
|
char c = (unsigned char) wParam;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
lpage_send(ldisc, kbd_codepage, &c, 1, 1);
|
if (ldisc)
|
||||||
|
lpage_send(ldisc, kbd_codepage, &c, 1, 1);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
@ -2694,7 +2757,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
|||||||
{
|
{
|
||||||
char c = (unsigned char)wParam;
|
char c = (unsigned char)wParam;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
lpage_send(ldisc, CP_ACP, &c, 1, 1);
|
if (ldisc)
|
||||||
|
lpage_send(ldisc, CP_ACP, &c, 1, 1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case WM_SETCURSOR:
|
case WM_SETCURSOR:
|
||||||
@ -3990,7 +4054,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
}
|
}
|
||||||
keybuf = nc;
|
keybuf = nc;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
luni_send(ldisc, &keybuf, 1, 1);
|
if (ldisc)
|
||||||
|
luni_send(ldisc, &keybuf, 1, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4001,7 +4066,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
if (in_utf(term) || ucsdata.dbcs_screenfont) {
|
if (in_utf(term) || ucsdata.dbcs_screenfont) {
|
||||||
keybuf = alt_sum;
|
keybuf = alt_sum;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
luni_send(ldisc, &keybuf, 1, 1);
|
if (ldisc)
|
||||||
|
luni_send(ldisc, &keybuf, 1, 1);
|
||||||
} else {
|
} else {
|
||||||
ch = (char) alt_sum;
|
ch = (char) alt_sum;
|
||||||
/*
|
/*
|
||||||
@ -4014,12 +4080,14 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
* everything we're sent.
|
* everything we're sent.
|
||||||
*/
|
*/
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
ldisc_send(ldisc, &ch, 1, 1);
|
if (ldisc)
|
||||||
|
ldisc_send(ldisc, &ch, 1, 1);
|
||||||
}
|
}
|
||||||
alt_sum = 0;
|
alt_sum = 0;
|
||||||
} else {
|
} else {
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
lpage_send(ldisc, kbd_codepage, &ch, 1, 1);
|
if (ldisc)
|
||||||
|
lpage_send(ldisc, kbd_codepage, &ch, 1, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(capsOn && ch < 0x80) {
|
if(capsOn && ch < 0x80) {
|
||||||
@ -4027,14 +4095,16 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
|||||||
cbuf[0] = 27;
|
cbuf[0] = 27;
|
||||||
cbuf[1] = xlat_uskbd2cyrllic(ch);
|
cbuf[1] = xlat_uskbd2cyrllic(ch);
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
luni_send(ldisc, cbuf+!left_alt, 1+!!left_alt, 1);
|
if (ldisc)
|
||||||
|
luni_send(ldisc, cbuf+!left_alt, 1+!!left_alt, 1);
|
||||||
} else {
|
} else {
|
||||||
char cbuf[2];
|
char cbuf[2];
|
||||||
cbuf[0] = '\033';
|
cbuf[0] = '\033';
|
||||||
cbuf[1] = ch;
|
cbuf[1] = ch;
|
||||||
term_seen_key_event(term);
|
term_seen_key_event(term);
|
||||||
lpage_send(ldisc, kbd_codepage,
|
if (ldisc)
|
||||||
cbuf+!left_alt, 1+!!left_alt, 1);
|
lpage_send(ldisc, kbd_codepage,
|
||||||
|
cbuf+!left_alt, 1+!!left_alt, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
show_mouseptr(0);
|
show_mouseptr(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user