📄 window.c
字号:
InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> Reposition terminal"));
#endif
}
if (IsZoomed(hwnd)) {
/* We're fullscreen, this means we must not change the size of
* the window so it's the font size or the terminal itself.
*/
extra_width = wr.right - wr.left - cr.right + cr.left;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top;
if (cfg.resize_action != RESIZE_TERM) {
if ( font_width != win_width/term->cols ||
font_height != win_height/term->rows) {
deinit_fonts();
init_fonts(win_width/term->cols, win_height/term->rows);
offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*term->rows)/2;
InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH
debug((25, "reset_window() -> Z font resize to (%d, %d)",
font_width, font_height));
#endif
}
} else {
if ( font_width != win_width/term->cols ||
font_height != win_height/term->rows) {
/* Our only choice at this point is to change the
* size of the terminal; Oh well.
*/
term_size(term, win_height/font_height, win_width/font_width,
cfg.savelines);
offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*term->rows)/2;
InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> Zoomed term_size"));
#endif
}
}
return;
}
/* Hmm, a force re-init means we should ignore the current window
* so we resize to the default font size.
*/
if (reinit>0) {
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> Forced re-init"));
#endif
offset_width = offset_height = cfg.window_border;
extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;
if (win_width != font_width*term->cols + offset_width*2 ||
win_height != font_height*term->rows + offset_height*2) {
/* If this is too large windows will resize it to the maximum
* allowed window size, we will then be back in here and resize
* the font or terminal to fit.
*/
SetWindowPos(hwnd, NULL, 0, 0,
font_width*term->cols + extra_width,
font_height*term->rows + extra_height,
SWP_NOMOVE | SWP_NOZORDER);
}
InvalidateRect(hwnd, NULL, TRUE);
return;
}
/* Okay the user doesn't want us to change the font so we try the
* window. But that may be too big for the screen which forces us
* to change the terminal.
*/
if ((cfg.resize_action == RESIZE_TERM && reinit<=0) ||
(cfg.resize_action == RESIZE_EITHER && reinit<0) ||
reinit>0) {
offset_width = offset_height = cfg.window_border;
extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;
if (win_width != font_width*term->cols + offset_width*2 ||
win_height != font_height*term->rows + offset_height*2) {
static RECT ss;
int width, height;
get_fullscreen_rect(&ss);
width = (ss.right - ss.left - extra_width) / font_width;
height = (ss.bottom - ss.top - extra_height) / font_height;
/* Grrr too big */
if ( term->rows > height || term->cols > width ) {
if (cfg.resize_action == RESIZE_EITHER) {
/* Make the font the biggest we can */
if (term->cols > width)
font_width = (ss.right - ss.left - extra_width)
/ term->cols;
if (term->rows > height)
font_height = (ss.bottom - ss.top - extra_height)
/ term->rows;
deinit_fonts();
init_fonts(font_width, font_height);
width = (ss.right - ss.left - extra_width) / font_width;
height = (ss.bottom - ss.top - extra_height) / font_height;
} else {
if ( height > term->rows ) height = term->rows;
if ( width > term->cols ) width = term->cols;
term_size(term, height, width, cfg.savelines);
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> term resize to (%d,%d)",
height, width));
#endif
}
}
SetWindowPos(hwnd, NULL, 0, 0,
font_width*term->cols + extra_width,
font_height*term->rows + extra_height,
SWP_NOMOVE | SWP_NOZORDER);
InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> window resize to (%d,%d)",
font_width*term->cols + extra_width,
font_height*term->rows + extra_height));
#endif
}
return;
}
/* We're allowed to or must change the font but do we want to ? */
if (font_width != (win_width-cfg.window_border*2)/term->cols ||
font_height != (win_height-cfg.window_border*2)/term->rows) {
deinit_fonts();
init_fonts((win_width-cfg.window_border*2)/term->cols,
(win_height-cfg.window_border*2)/term->rows);
offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*term->rows)/2;
extra_width = wr.right - wr.left - cr.right + cr.left +offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top+offset_height*2;
InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH
debug((25, "reset_window() -> font resize to (%d,%d)",
font_width, font_height));
#endif
}
}
static void set_input_locale(HKL kl)
{
char lbuf[20];
GetLocaleInfo(LOWORD(kl), LOCALE_IDEFAULTANSICODEPAGE,
lbuf, sizeof(lbuf));
kbd_codepage = atoi(lbuf);
}
static void click(Mouse_Button b, int x, int y, int shift, int ctrl, int alt)
{
int thistime = GetMessageTime();
if (send_raw_mouse && !(cfg.mouse_override && shift)) {
lastbtn = MBT_NOTHING;
term_mouse(term, b, translate_button(b), MA_CLICK,
x, y, shift, ctrl, alt);
return;
}
if (lastbtn == b && thistime - lasttime < dbltime) {
lastact = (lastact == MA_CLICK ? MA_2CLK :
lastact == MA_2CLK ? MA_3CLK :
lastact == MA_3CLK ? MA_CLICK : MA_NOTHING);
} else {
lastbtn = b;
lastact = MA_CLICK;
}
if (lastact != MA_NOTHING)
term_mouse(term, b, translate_button(b), lastact,
x, y, shift, ctrl, alt);
lasttime = thistime;
}
/*
* Translate a raw mouse button designation (LEFT, MIDDLE, RIGHT)
* into a cooked one (SELECT, EXTEND, PASTE).
*/
static Mouse_Button translate_button(Mouse_Button button)
{
if (button == MBT_LEFT)
return MBT_SELECT;
if (button == MBT_MIDDLE)
return cfg.mouse_is_xterm == 1 ? MBT_PASTE : MBT_EXTEND;
if (button == MBT_RIGHT)
return cfg.mouse_is_xterm == 1 ? MBT_EXTEND : MBT_PASTE;
return 0; /* shouldn't happen */
}
static void show_mouseptr(int show)
{
static int cursor_visible = 1;
if (!cfg.hide_mouseptr) /* override if this feature disabled */
show = 1;
if (cursor_visible && !show)
ShowCursor(FALSE);
else if (!cursor_visible && show)
ShowCursor(TRUE);
cursor_visible = show;
}
static int is_alt_pressed(void)
{
BYTE keystate[256];
int r = GetKeyboardState(keystate);
if (!r)
return FALSE;
if (keystate[VK_MENU] & 0x80)
return TRUE;
if (keystate[VK_RMENU] & 0x80)
return TRUE;
return FALSE;
}
static int is_shift_pressed(void)
{
BYTE keystate[256];
int r = GetKeyboardState(keystate);
if (!r)
return FALSE;
if (keystate[VK_SHIFT] & 0x80)
return TRUE;
return FALSE;
}
static int resizing;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
static int ignore_clip = FALSE;
static int need_backend_resize = FALSE;
static int fullscr_on_max = FALSE;
static UINT last_mousemove = 0;
switch (message) {
case WM_TIMER:
if (pending_netevent)
enact_pending_netevent();
if (GetCapture() != hwnd ||
(send_raw_mouse && !(cfg.mouse_override && is_shift_pressed())))
term_out(term);
noise_regular();
HideCaret(hwnd);
term_update(term);
ShowCaret(hwnd);
if (cfg.ping_interval > 0) {
time_t now;
time(&now);
if (now - last_movement > cfg.ping_interval) {
back->special(backhandle, TS_PING);
last_movement = now;
}
}
net_pending_errors();
return 0;
case WM_CREATE:
break;
case WM_CLOSE:
{
char *str;
show_mouseptr(1);
str = dupprintf("%s Exit Confirmation", appname);
if (!cfg.warn_on_close || session_closed ||
MessageBox(hwnd,
"Are you sure you want to close this session?",
str, MB_ICONWARNING | MB_OKCANCEL) == IDOK)
DestroyWindow(hwnd);
sfree(str);
}
return 0;
case WM_DESTROY:
show_mouseptr(1);
PostQuitMessage(0);
return 0;
case WM_COMMAND:
case WM_SYSCOMMAND:
switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
case IDM_SHOWLOG:
showeventlog(hwnd);
break;
case IDM_NEWSESS:
case IDM_DUPSESS:
case IDM_SAVEDSESS:
{
char b[2048];
char c[30], *cl;
int freecl = FALSE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE filemap = NULL;
if (wParam == IDM_DUPSESS) {
/*
* Allocate a file-mapping memory chunk for the
* config structure.
*/
SECURITY_ATTRIBUTES sa;
Config *p;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
filemap = CreateFileMapping((HANDLE) 0xFFFFFFFF,
&sa,
PAGE_READWRITE,
0, sizeof(Config), NULL);
if (filemap) {
p = (Config *) MapViewOfFile(filemap,
FILE_MAP_WRITE,
0, 0, sizeof(Config));
if (p) {
*p = cfg; /* structure copy */
UnmapViewOfFile(p);
}
}
sprintf(c, "putty &%p", filemap);
cl = c;
} else if (wParam == IDM_SAVEDSESS) {
if ((lParam - IDM_SAVED_MIN) / 16 < sesslist.nsessions) {
char *session =
sesslist.sessions[(lParam - IDM_SAVED_MIN) / 16];
cl = snewn(16 + strlen(session), char);
/* 8, but play safe */
if (!cl)
cl = NULL;
/* not a very important failure mode */
else {
sprintf(cl, "putty @%s", session);
freecl = TRUE;
}
} else
break;
} else
cl = NULL;
GetModuleFileName(NULL, b, sizeof(b) - 1);
si.cb = sizeof(si);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = 0;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
CreateProcess(b, cl, NULL, NULL, TRUE,
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
if (filemap)
CloseHandle(filemap);
if (freecl)
sfree(cl);
}
break;
case IDM_RECONF:
{
Config prev_cfg;
int init_lvl = 1;
GetWindowText(hwnd, cfg.wintitle, sizeof(cfg.wintitle));
prev_cfg = cfg;
if (!do_reconfig(hwnd))
break;
{
/* Disable full-screen if resizing forbidden */
HMENU m = GetSystemMenu (hwnd, FALSE);
EnableMenuItem(m, IDM_FULLSCREEN, MF_BYCOMMAND |
(cfg.resize_action == RESIZE_DISABLED)
? MF_GRAYED : MF_ENABLED);
/* Gracefully unzoom if necessary */
if (IsZoomed(hwnd) &&
(cfg.resize_action == RESIZE_DISABLED)) {
ShowWindow(hwnd, SW_RESTORE);
}
}
/* Pass new config data to the logging module */
log_reconfig(logctx, &cfg);
sfree(logpal);
/*
* Flush the line discipline's edit buffer in the
* case where local editing has just been disabled.
*/
ldisc_send(ldisc, NULL, 0, 0);
if (pal)
DeleteObject(pal);
logpal = NULL;
pal = NULL;
cfgtopalette();
init_palette();
/* Pass new config data to the terminal */
term_reconfig(term, &cfg);
/* Pass new config data to the back end */
back->reconfig(backhandle, &cfg);
/* Screen size changed ? */
if (cfg.height != prev_cfg.height ||
cfg.width != prev_cfg.width ||
cfg.savelines != prev_cfg.savelines ||
cfg.resize_action == RESIZE_FONT ||
(cfg.resize_action == RESIZE_EITHER && IsZoomed(hwnd)) ||
cfg.resize_action == RESIZE_DISABLED)
term_size(term, cfg.height, cfg.width, cfg.savelines);
/* Enable or disable the scroll bar, etc */
{
LONG nflg, flag = GetWindowLong(hwnd, GWL_STYLE);
LONG nexflag, exflag =
GetWindowLong(hwnd, GWL_EXSTYLE);
nexflag = exflag;
if (cfg.alwaysontop != prev_cfg.alwaysontop) {
if (cfg.alwaysontop) {
nexflag |= WS_EX_TOPMOST;
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE);
} else {
nexflag &= ~(WS_EX_TOPMOST);
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE);
}
}
if (cfg.sunken_edge)
nexflag |= WS_EX_CLIENTEDGE;
else
nexflag &= ~(WS_EX_CLIENTEDGE);
nflg = flag;
if (is_full_screen() ?
cfg.scrollbar_in_fullscreen : cfg.scrollbar)
nflg |= WS_VSCROLL;
else
nflg &= ~WS_VSCROLL;
if (cfg.resize_action == RESIZE_DISABLED ||
is_full_screen())
nflg &= ~WS_THICKFRAME;
else
nflg |= WS_THICKFRAME;
if (cfg.resize_action == RESIZE_DISABLED)
nflg &= ~WS_MAXIMIZEBOX;
else
nflg |= WS_MAXIMIZEBOX;
if (nflg != flag || nexflag != exflag) {
if (nflg != flag)
SetWindowLong(hwnd, GWL_STYLE, nflg);
if (nexflag != exflag)
SetWindowLong(hwnd, GWL_EXSTYLE, nexflag);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -