static struct unicode_data ucsdata;
static int session_closed;
+static int reconfiguring = FALSE;
static const struct telnet_special *specials;
static int n_specials;
int guess_width, guess_height;
hinst = inst;
+ hwnd = NULL;
flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
sk_init();
i++; /* skip next argument */
} else if (ret == 1) {
continue; /* nothing further needs doing */
- } else if (!strcmp(p, "-cleanup")) {
+ } else if (!strcmp(p, "-cleanup") ||
+ !strcmp(p, "-cleanup-during-uninstall")) {
/*
* `putty -cleanup'. Remove all registry
* entries associated with PuTTY, and also find
* and delete the random seed file.
*/
char *s1, *s2;
- s1 = dupprintf("This procedure will remove ALL Registry\n"
- "entries associated with %s, and will\n"
- "also remove the random seed file.\n"
- "\n"
- "THIS PROCESS WILL DESTROY YOUR SAVED\n"
- "SESSIONS. Are you really sure you want\n"
- "to continue?", appname);
- s2 = dupprintf("%s Warning", appname);
- if (MessageBox(NULL, s1, s2,
- MB_YESNO | MB_ICONWARNING) == IDYES) {
+ /* Are we being invoked from an uninstaller? */
+ if (!strcmp(p, "-cleanup-during-uninstall")) {
+ s1 = dupprintf("Remove saved sessions and random seed file?\n"
+ "\n"
+ "If you hit Yes, ALL Registry entries associated\n"
+ "with %s will be removed, as well as the\n"
+ "random seed file. THIS PROCESS WILL\n"
+ "DESTROY YOUR SAVED SESSIONS.\n"
+ "(This only affects the currently logged-in user.)\n"
+ "\n"
+ "If you hit No, uninstallation will proceed, but\n"
+ "saved sessions etc will be left on the machine.",
+ appname);
+ s2 = dupprintf("%s Uninstallation", appname);
+ } else {
+ s1 = dupprintf("This procedure will remove ALL Registry entries\n"
+ "associated with %s, and will also remove\n"
+ "the random seed file. (This only affects the\n"
+ "currently logged-in user.)\n"
+ "\n"
+ "THIS PROCESS WILL DESTROY YOUR SAVED SESSIONS.\n"
+ "Are you really sure you want to continue?",
+ appname);
+ s2 = dupprintf("%s Warning", appname);
+ }
+ if (message_box(s1, s2,
+ MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2,
+ HELPCTXID(option_cleanup)) == IDYES) {
cleanup_all();
}
sfree(s1);
sfree(s2);
exit(0);
+ } else if (!strcmp(p, "-pgpfp")) {
+ pgp_fingerprints();
+ exit(1);
} else if (*p != '-') {
char *q = p;
if (got_host) {
RegisterClass(&wndclass);
}
- hwnd = NULL;
-
memset(&ucsdata, 0, sizeof(ucsdata));
cfgtopalette();
f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE);
- lfont.lfHeight = font_height;
- lfont.lfWidth = font_width;
- lfont.lfEscapement = 0;
- lfont.lfOrientation = 0;
- lfont.lfWeight = fw_dontcare;
- lfont.lfItalic = FALSE;
- lfont.lfUnderline = FALSE;
- lfont.lfStrikeOut = FALSE;
- lfont.lfCharSet = cfg.font.charset;
- lfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
- lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lfont.lfQuality = DEFAULT_QUALITY;
- lfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
- strncpy(lfont.lfFaceName, cfg.font.name, LF_FACESIZE);
-
SelectObject(hdc, fonts[FONT_NORMAL]);
GetTextMetrics(hdc, &tm);
+ GetObject(fonts[FONT_NORMAL], sizeof(LOGFONT), &lfont);
+
if (pick_width == 0 || pick_height == 0) {
font_height = tm.tmHeight;
font_width = tm.tmAveCharWidth;
if (!cfg.warn_on_close || session_closed ||
MessageBox(hwnd,
"Are you sure you want to close this session?",
- str, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2)
+ str, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1)
== IDOK)
DestroyWindow(hwnd);
sfree(str);
char b[2048];
char c[30], *cl;
int freecl = FALSE;
+ BOOL inherit_handles;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE filemap = NULL;
UnmapViewOfFile(p);
}
}
+ inherit_handles = TRUE;
sprintf(c, "putty &%p", filemap);
cl = c;
} else if (wParam == IDM_SAVEDSESS) {
char *session = sesslist.sessions[sessno];
/* XXX spaces? quotes? "-load"? */
cl = dupprintf("putty @%s", session);
+ inherit_handles = FALSE;
freecl = TRUE;
} else
break;
- } else
+ } else /* IDM_NEWSESS */ {
cl = NULL;
+ inherit_handles = FALSE;
+ }
GetModuleFileName(NULL, b, sizeof(b) - 1);
si.cb = sizeof(si);
si.dwFlags = 0;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
- CreateProcess(b, cl, NULL, NULL, TRUE,
+ CreateProcess(b, cl, NULL, NULL, inherit_handles,
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
if (filemap)
{
Config prev_cfg;
int init_lvl = 1;
+ int reconfig_result;
+
+ if (reconfiguring)
+ break;
+ else
+ reconfiguring = TRUE;
GetWindowText(hwnd, cfg.wintitle, sizeof(cfg.wintitle));
prev_cfg = cfg;
- if (!do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0))
+ reconfig_result =
+ do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0);
+ reconfiguring = FALSE;
+ if (!reconfig_result)
break;
{
RealizePalette(hdc);
}
+ /*
+ * We have to be careful about term_paint(). It will
+ * set a bunch of character cells to INVALID and then
+ * call do_paint(), which will redraw those cells and
+ * _then mark them as done_. This may not be accurate:
+ * when painting in WM_PAINT context we are restricted
+ * to the rectangle which has just been exposed - so if
+ * that only covers _part_ of a character cell and the
+ * rest of it was already visible, that remainder will
+ * not be redrawn at all. Accordingly, we must not
+ * paint any character cell in a WM_PAINT context which
+ * already has a pending update due to terminal output.
+ * The simplest solution to this - and many, many
+ * thanks to Hung-Te Lin for working all this out - is
+ * not to do any actual painting at _all_ if there's a
+ * pending terminal update: just mark the relevant
+ * character cells as INVALID and wait for the
+ * scheduled full update to sort it out.
+ *
+ * I have a suspicion this isn't the _right_ solution.
+ * An alternative approach would be to have terminal.c
+ * separately track what _should_ be on the terminal
+ * screen and what _is_ on the terminal screen, and
+ * have two completely different types of redraw (one
+ * for full updates, which syncs the former with the
+ * terminal itself, and one for WM_PAINT which syncs
+ * the latter with the former); yet another possibility
+ * would be to have the Windows front end do what the
+ * GTK one already does, and maintain a bitmap of the
+ * current terminal appearance so that WM_PAINT becomes
+ * completely trivial. However, this should do for now.
+ */
term_paint(term, hdc,
(p.rcPaint.left-offset_width)/font_width,
(p.rcPaint.top-offset_height)/font_height,
(p.rcPaint.right-offset_width-1)/font_width,
(p.rcPaint.bottom-offset_height-1)/font_height,
- TRUE);
+ !term->window_update_pending);
if (p.fErase ||
p.rcPaint.left < offset_width ||
unsigned char buf[20];
int len;
- if (wParam == VK_PROCESSKEY) {
- MSG m;
- m.hwnd = hwnd;
- m.message = WM_KEYDOWN;
- m.wParam = wParam;
- m.lParam = lParam & 0xdfff;
- TranslateMessage(&m);
+ if (wParam == VK_PROCESSKEY) { /* IME PROCESS key */
+ if (message == WM_KEYDOWN) {
+ MSG m;
+ m.hwnd = hwnd;
+ m.message = WM_KEYDOWN;
+ m.wParam = wParam;
+ m.lParam = lParam & 0xdfff;
+ TranslateMessage(&m);
+ } else break; /* pass to Windows for default processing */
} else {
len = TranslateKey(message, wParam, lParam, buf);
if (len == -1)
set_input_locale((HKL)lParam);
sys_cursor_update();
break;
- case WM_IME_NOTIFY:
- if(wParam == IMN_SETOPENSTATUS) {
+ case WM_IME_STARTCOMPOSITION:
+ {
HIMC hImc = ImmGetContext(hwnd);
ImmSetCompositionFont(hImc, &lfont);
ImmReleaseContext(hwnd, hImc);
- return 0;
}
break;
case WM_IME_COMPOSITION:
}
}
+ /*
+ * Any messages we don't process completely above are passed through to
+ * DefWindowProc() for default processing.
+ */
return DefWindowProc(hwnd, message, wParam, lParam);
}