mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 01:18:00 +00:00
8d186c3c93
Sometimes, within a switch statement, you want to declare local variables specific to the handler for one particular case. Until now I've mostly been writing this in the form switch (discriminant) { case SIMPLE: do stuff; break; case COMPLICATED: { declare variables; do stuff; } break; } which is ugly because the two pieces of essentially similar code appear at different indent levels, and also inconvenient because you have less horizontal space available to write the complicated case handler in - particuarly undesirable because _complicated_ case handlers are the ones most likely to need all the space they can get! After encountering a rather nicer idiom in the LLVM source code, and after a bit of hackery this morning figuring out how to persuade Emacs's auto-indent to do what I wanted with it, I've decided to move to an idiom in which the open brace comes right after the case statement, and the code within it is indented the same as it would have been without the brace. Then the whole case handler (including the break) lives inside those braces, and you get something that looks more like this: switch (discriminant) { case SIMPLE: do stuff; break; case COMPLICATED: { declare variables; do stuff; break; } } This commit is a big-bang change that reformats all the complicated case handlers I could find into the new layout. This is particularly nice in the Pageant main function, in which almost _every_ case handler had a bundle of variables and was long and complicated. (In fact that's what motivated me to get round to this.) Some of the innermost parts of the terminal escape-sequence handling are also breathing a bit easier now the horizontal pressure on them is relieved. (Also, in a few cases, I was able to remove the extra braces completely, because the only variable local to the case handler was a loop variable which our new C99 policy allows me to move into the initialiser clause of its for statement.) Viewed with whitespace ignored, this is not too disruptive a change. Downstream patches that conflict with it may need to be reapplied using --ignore-whitespace or similar.
193 lines
4.3 KiB
C
193 lines
4.3 KiB
C
/*
|
|
* sizetip.c - resize tips for PuTTY(tel) terminal window.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <tchar.h>
|
|
|
|
#include "putty.h"
|
|
|
|
static ATOM tip_class = 0;
|
|
|
|
static HFONT tip_font;
|
|
static COLORREF tip_bg;
|
|
static COLORREF tip_text;
|
|
|
|
static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
|
|
switch (nMsg) {
|
|
case WM_ERASEBKGND:
|
|
return true;
|
|
|
|
case WM_PAINT: {
|
|
HBRUSH hbr;
|
|
HGDIOBJ holdbr;
|
|
RECT cr;
|
|
int wtlen;
|
|
LPTSTR wt;
|
|
HDC hdc;
|
|
|
|
PAINTSTRUCT ps;
|
|
hdc = BeginPaint(hWnd, &ps);
|
|
|
|
SelectObject(hdc, tip_font);
|
|
SelectObject(hdc, GetStockObject(BLACK_PEN));
|
|
|
|
hbr = CreateSolidBrush(tip_bg);
|
|
holdbr = SelectObject(hdc, hbr);
|
|
|
|
GetClientRect(hWnd, &cr);
|
|
Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
|
|
|
|
wtlen = GetWindowTextLength(hWnd);
|
|
wt = (LPTSTR) snewn(wtlen + 1, TCHAR);
|
|
GetWindowText(hWnd, wt, wtlen + 1);
|
|
|
|
SetTextColor(hdc, tip_text);
|
|
SetBkColor(hdc, tip_bg);
|
|
|
|
TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
|
|
|
|
sfree(wt);
|
|
|
|
SelectObject(hdc, holdbr);
|
|
DeleteObject(hbr);
|
|
|
|
EndPaint(hWnd, &ps);
|
|
return 0;
|
|
}
|
|
|
|
case WM_NCHITTEST:
|
|
return HTTRANSPARENT;
|
|
|
|
case WM_DESTROY:
|
|
DeleteObject(tip_font);
|
|
tip_font = NULL;
|
|
break;
|
|
|
|
case WM_SETTEXT: {
|
|
LPCTSTR str = (LPCTSTR) lParam;
|
|
SIZE sz;
|
|
HDC hdc = CreateCompatibleDC(NULL);
|
|
|
|
SelectObject(hdc, tip_font);
|
|
GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
|
|
|
|
SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
|
|
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
|
InvalidateRect(hWnd, NULL, false);
|
|
|
|
DeleteDC(hdc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return DefWindowProc(hWnd, nMsg, wParam, lParam);
|
|
}
|
|
|
|
static HWND tip_wnd = NULL;
|
|
static bool tip_enabled = false;
|
|
|
|
void UpdateSizeTip(HWND src, int cx, int cy)
|
|
{
|
|
TCHAR str[32];
|
|
|
|
if (!tip_enabled)
|
|
return;
|
|
|
|
if (!tip_wnd) {
|
|
NONCLIENTMETRICS nci;
|
|
|
|
/* First make sure the window class is registered */
|
|
|
|
if (!tip_class) {
|
|
WNDCLASS wc;
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = SizeTipWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hinst;
|
|
wc.hIcon = NULL;
|
|
wc.hCursor = NULL;
|
|
wc.hbrBackground = NULL;
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = "SizeTipClass";
|
|
|
|
tip_class = RegisterClass(&wc);
|
|
}
|
|
#if 0
|
|
/* Default values based on Windows Standard color scheme */
|
|
|
|
tip_font = GetStockObject(SYSTEM_FONT);
|
|
tip_bg = RGB(255, 255, 225);
|
|
tip_text = RGB(0, 0, 0);
|
|
#endif
|
|
|
|
/* Prepare other GDI objects and drawing info */
|
|
|
|
tip_bg = GetSysColor(COLOR_INFOBK);
|
|
tip_text = GetSysColor(COLOR_INFOTEXT);
|
|
|
|
memset(&nci, 0, sizeof(NONCLIENTMETRICS));
|
|
nci.cbSize = sizeof(NONCLIENTMETRICS);
|
|
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
|
|
sizeof(NONCLIENTMETRICS), &nci, 0);
|
|
tip_font = CreateFontIndirect(&nci.lfStatusFont);
|
|
}
|
|
|
|
/* Generate the tip text */
|
|
|
|
sprintf(str, "%dx%d", cx, cy);
|
|
|
|
if (!tip_wnd) {
|
|
HDC hdc;
|
|
SIZE sz;
|
|
RECT wr;
|
|
int ix, iy;
|
|
|
|
/* calculate the tip's size */
|
|
|
|
hdc = CreateCompatibleDC(NULL);
|
|
GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
|
|
DeleteDC(hdc);
|
|
|
|
GetWindowRect(src, &wr);
|
|
|
|
ix = wr.left;
|
|
if (ix < 16)
|
|
ix = 16;
|
|
|
|
iy = wr.top - sz.cy;
|
|
if (iy < 16)
|
|
iy = 16;
|
|
|
|
/* Create the tip window */
|
|
|
|
tip_wnd =
|
|
CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
|
MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
|
|
iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);
|
|
|
|
ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
|
|
|
|
} else {
|
|
|
|
/* Tip already exists, just set the text */
|
|
|
|
SetWindowText(tip_wnd, str);
|
|
}
|
|
}
|
|
|
|
void EnableSizeTip(bool bEnable)
|
|
{
|
|
if (tip_wnd && !bEnable) {
|
|
DestroyWindow(tip_wnd);
|
|
tip_wnd = NULL;
|
|
}
|
|
|
|
tip_enabled = bEnable;
|
|
}
|