} und_mode;
static int descent;
-#define NCOLOURS 24
-static COLORREF colours[NCOLOURS];
+#define NCFGCOLOURS 22
+#define NEXTCOLOURS 240
+#define NALLCOLOURS (NCFGCOLOURS + NEXTCOLOURS)
+static COLORREF colours[NALLCOLOURS];
static HPALETTE pal;
static LPLOGPALETTE logpal;
-static RGBTRIPLE defpal[NCOLOURS];
-
-static HWND hwnd;
+static RGBTRIPLE defpal[NALLCOLOURS];
static HBITMAP caretbm;
static int send_raw_mouse = 0;
static int wheel_accumulator = 0;
+static int busy_status = BUSY_NOT;
+
static char *window_name, *icon_name;
static int compose_state = 0;
if (p && p >= r) r = p+1;
q = strrchr(b, ':');
if (q && q >= r) r = q+1;
- strcpy(r, "putty.hlp");
+ strcpy(r, PUTTY_HELP_FILE);
if ( (fp = fopen(b, "r")) != NULL) {
help_path = dupstr(b);
fclose(fp);
} else
help_path = NULL;
- strcpy(r, "putty.cnt");
+ strcpy(r, PUTTY_HELP_CONTENTS);
if ( (fp = fopen(b, "r")) != NULL) {
help_has_contents = TRUE;
fclose(fp);
}
/*
- * Trim a colon suffix off the hostname if it's there.
+ * Trim a colon suffix off the hostname if it's there. In
+ * order to protect IPv6 address literals against this
+ * treatment, we do not do this if there's _more_ than one
+ * colon.
*/
- cfg.host[strcspn(cfg.host, ":")] = '\0';
+ {
+ char *c = strchr(cfg.host, ':');
+
+ if (c) {
+ char *d = strchr(c+1, ':');
+ if (!d)
+ *c = '\0';
+ }
+ }
/*
* Remove any remaining whitespace from the hostname.
memset(&ucsdata, 0, sizeof(ucsdata));
- term = term_init(&cfg, &ucsdata, NULL);
- logctx = log_init(NULL, &cfg);
- term_provide_logctx(term, logctx);
-
cfgtopalette();
/*
font_height = 20;
extra_width = 25;
extra_height = 28;
- term_size(term, cfg.height, cfg.width, cfg.savelines);
- guess_width = extra_width + font_width * term->cols;
- guess_height = extra_height + font_height * term->rows;
+ guess_width = extra_width + font_width * cfg.width;
+ guess_height = extra_height + font_height * cfg.height;
{
RECT r;
get_fullscreen_rect(&r);
}
/*
+ * Initialise the terminal. (We have to do this _after_
+ * creating the window, since the terminal is the first thing
+ * which will call schedule_timer(), which will in turn call
+ * timer_change_notify() which will expect hwnd to exist.)
+ */
+ term = term_init(&cfg, &ucsdata, NULL);
+ logctx = log_init(NULL, &cfg);
+ term_provide_logctx(term, logctx);
+ term_size(term, cfg.height, cfg.width, cfg.savelines);
+
+ /*
* Initialise the fonts, simultaneously correcting the guesses
* for font_{width,height}.
*/
logpal = NULL;
init_palette();
- term->has_focus = (GetForegroundWindow() == hwnd);
+ term_set_focus(term, GetForegroundWindow() == hwnd);
UpdateWindow(hwnd);
if (GetMessage(&msg, NULL, 0, 0) == 1) {
continue;
/* The messages seem unreliable; especially if we're being tricky */
- term->has_focus = (GetForegroundWindow() == hwnd);
+ term_set_focus(term, GetForegroundWindow() == hwnd);
net_pending_errors();
}
}
+static void update_mouse_pointer(void)
+{
+ LPTSTR curstype;
+ int force_visible = FALSE;
+ static int forced_visible = FALSE;
+ switch (busy_status) {
+ case BUSY_NOT:
+ if (send_raw_mouse)
+ curstype = IDC_ARROW;
+ else
+ curstype = IDC_IBEAM;
+ break;
+ case BUSY_WAITING:
+ curstype = IDC_APPSTARTING; /* this may be an abuse */
+ force_visible = TRUE;
+ break;
+ case BUSY_CPU:
+ curstype = IDC_WAIT;
+ force_visible = TRUE;
+ break;
+ default:
+ assert(0);
+ }
+ {
+ HCURSOR cursor = LoadCursor(NULL, curstype);
+ SetClassLong(hwnd, GCL_HCURSOR, (LONG)cursor);
+ SetCursor(cursor); /* force redraw of cursor at current posn */
+ }
+ if (force_visible != forced_visible) {
+ /* We want some cursor shapes to be visible always.
+ * Along with show_mouseptr(), this manages the ShowCursor()
+ * counter such that if we switch back to a non-force_visible
+ * cursor, the previous visibility state is restored. */
+ ShowCursor(force_visible);
+ forced_visible = force_visible;
+ }
+}
+
+void set_busy_status(void *frontend, int status)
+{
+ busy_status = status;
+ update_mouse_pointer();
+}
+
/*
* set or clear the "raw mouse message" mode
*/
{
activate = activate && !cfg.no_mouse_rep;
send_raw_mouse = activate;
- SetCursor(LoadCursor(NULL, activate ? IDC_ARROW : IDC_IBEAM));
+ update_mouse_pointer();
}
/*
{
int i;
static const int ww[] = {
- 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21,
- 0, 1, 2, 3, 4, 4, 5, 5
+ 256, 257, 258, 259, 260, 261,
+ 0, 8, 1, 9, 2, 10, 3, 11,
+ 4, 12, 5, 13, 6, 14, 7, 15
};
- for (i = 0; i < 24; i++) {
+ for (i = 0; i < 22; i++) {
int w = ww[i];
- defpal[i].rgbtRed = cfg.colours[w][0];
- defpal[i].rgbtGreen = cfg.colours[w][1];
- defpal[i].rgbtBlue = cfg.colours[w][2];
+ defpal[w].rgbtRed = cfg.colours[i][0];
+ defpal[w].rgbtGreen = cfg.colours[i][1];
+ defpal[w].rgbtBlue = cfg.colours[i][2];
+ }
+ for (i = 0; i < NEXTCOLOURS; i++) {
+ if (i < 216) {
+ int r = i / 36, g = (i / 6) % 6, b = i % 6;
+ defpal[i+16].rgbtRed = r * 0x33;
+ defpal[i+16].rgbtGreen = g * 0x33;
+ defpal[i+16].rgbtBlue = b * 0x33;
+ } else {
+ int shade = i - 216;
+ shade = (shade + 1) * 0xFF / (NEXTCOLOURS - 216 + 1);
+ defpal[i+16].rgbtRed = defpal[i+16].rgbtGreen =
+ defpal[i+16].rgbtBlue = shade;
+ }
}
/* Override with system colours if appropriate */
int i;
static const struct { int nIndex; int norm; int bold; } or[] =
{
- { COLOR_WINDOWTEXT, 16, 17 }, /* Default Foreground */
- { COLOR_WINDOW, 18, 19 }, /* Default Background */
- { COLOR_HIGHLIGHTTEXT, 20, 21 }, /* Cursor Text */
- { COLOR_HIGHLIGHT, 22, 23 }, /* Cursor Colour */
+ { COLOR_WINDOWTEXT, 256, 257 }, /* Default Foreground */
+ { COLOR_WINDOW, 258, 259 }, /* Default Background */
+ { COLOR_HIGHLIGHTTEXT, 260, 260 }, /* Cursor Text */
+ { COLOR_HIGHLIGHT, 261, 261 }, /* Cursor Colour */
};
for (i = 0; i < (sizeof(or)/sizeof(or[0])); i++) {
*/
logpal = smalloc(sizeof(*logpal)
- sizeof(logpal->palPalEntry)
- + NCOLOURS * sizeof(PALETTEENTRY));
+ + NALLCOLOURS * sizeof(PALETTEENTRY));
logpal->palVersion = 0x300;
- logpal->palNumEntries = NCOLOURS;
- for (i = 0; i < NCOLOURS; i++) {
+ logpal->palNumEntries = NALLCOLOURS;
+ for (i = 0; i < NALLCOLOURS; i++) {
logpal->palPalEntry[i].peRed = defpal[i].rgbtRed;
logpal->palPalEntry[i].peGreen = defpal[i].rgbtGreen;
logpal->palPalEntry[i].peBlue = defpal[i].rgbtBlue;
ReleaseDC(hwnd, hdc);
}
if (pal)
- for (i = 0; i < NCOLOURS; i++)
+ for (i = 0; i < NALLCOLOURS; i++)
colours[i] = PALETTERGB(defpal[i].rgbtRed,
defpal[i].rgbtGreen,
defpal[i].rgbtBlue);
else
- for (i = 0; i < NCOLOURS; i++)
+ for (i = 0; i < NALLCOLOURS; i++)
colours[i] = RGB(defpal[i].rgbtRed,
defpal[i].rgbtGreen, defpal[i].rgbtBlue);
}
static void show_mouseptr(int show)
{
+ /* NB that the counter in ShowCursor() is also frobbed by
+ * update_mouse_pointer() */
static int cursor_visible = 1;
if (!cfg.hide_mouseptr) /* override if this feature disabled */
show = 1;
if (!cfg.warn_on_close || session_closed ||
MessageBox(hwnd,
"Are you sure you want to close this session?",
- str, MB_ICONWARNING | MB_OKCANCEL) == IDOK)
+ str, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1)
+ == IDOK)
DestroyWindow(hwnd);
sfree(str);
}
GetWindowText(hwnd, cfg.wintitle, sizeof(cfg.wintitle));
prev_cfg = cfg;
- if (!do_reconfig(hwnd))
+ if (!do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0))
break;
{
HBRUSH fillcolour, oldbrush;
HPEN edge, oldpen;
fillcolour = CreateSolidBrush (
- colours[(ATTR_DEFBG>>ATTR_BGSHIFT)*2]);
+ colours[ATTR_DEFBG>>ATTR_BGSHIFT]);
oldbrush = SelectObject(hdc, fillcolour);
edge = CreatePen(PS_SOLID, 0,
- colours[(ATTR_DEFBG>>ATTR_BGSHIFT)*2]);
+ colours[ATTR_DEFBG>>ATTR_BGSHIFT]);
oldpen = SelectObject(hdc, edge);
/*
Rectangle(hdc, p.rcPaint.left, p.rcPaint.top,
p.rcPaint.right, p.rcPaint.bottom);
- // SelectClipRgn(hdc, NULL);
+ /* SelectClipRgn(hdc, NULL); */
SelectObject(hdc, oldbrush);
DeleteObject(fillcolour);
net_pending_errors();
return 0;
case WM_SETFOCUS:
- term->has_focus = TRUE;
+ term_set_focus(term, TRUE);
CreateCaret(hwnd, caretbm, font_width, font_height);
ShowCaret(hwnd);
flash_window(0); /* stop */
break;
case WM_KILLFOCUS:
show_mouseptr(1);
- term->has_focus = FALSE;
+ term_set_focus(term, FALSE);
DestroyCaret();
caret_x = caret_y = -1; /* ensure caret is replaced next time */
term_update(term);
lpage_send(ldisc, CP_ACP, &c, 1, 1);
}
return 0;
- case WM_SETCURSOR:
- if (send_raw_mouse && LOWORD(lParam) == HTCLIENT) {
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- return TRUE;
- }
- break;
case WM_SYSCOLORCHANGE:
if (cfg.system_colour) {
/* Refresh palette from system colours. */
y += offset_height;
if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || term->big_cursor)) {
- attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0);
- attr ^= ATTR_CUR_XOR;
+ attr &= ~(ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS);
+ if (bold_mode == BOLD_COLOURS)
+ attr &= ~ATTR_BOLD;
+
+ /* cursor fg and bg */
+ attr |= (260 << ATTR_FGSHIFT) | (261 << ATTR_BGSHIFT);
}
nfont = 0;
nfont |= FONT_OEM;
nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
- nfg = 2 * (nfg & 0xF) + (nfg & 0x10 ? 1 : 0);
nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
- nbg = 2 * (nbg & 0xF) + (nbg & 0x10 ? 1 : 0);
if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD))
nfont |= FONT_BOLD;
if (und_mode == UND_FONT && (attr & ATTR_UNDER))
nfg = nbg;
nbg = t;
}
- if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD))
- nfg |= 1;
- if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK))
- nbg |= 1;
+ if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD)) {
+ if (nfg < 16) nfg |= 8;
+ else if (nfg >= 256) nfg |= 1;
+ }
+ if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK)) {
+ if (nbg < 16) nbg |= 8;
+ else if (nbg >= 256) nbg |= 1;
+ }
fg = colours[nfg];
bg = colours[nbg];
SelectObject(hdc, fonts[nfont]);
pts[2].x = pts[3].x = x + char_width - 1;
pts[0].y = pts[3].y = pts[4].y = y;
pts[1].y = pts[2].y = y + font_height - 1;
- oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[23]));
+ oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[261]));
Polyline(hdc, pts, 5);
oldpen = SelectObject(hdc, oldpen);
DeleteObject(oldpen);
if (attr & TATTR_ACTCURS) {
HPEN oldpen;
oldpen =
- SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[23]));
+ SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[261]));
MoveToEx(hdc, startx, starty, NULL);
LineTo(hdc, startx + dx * length, starty + dy * length);
oldpen = SelectObject(hdc, oldpen);
} else {
for (i = 0; i < length; i++) {
if (i % 2 == 0) {
- SetPixel(hdc, startx, starty, colours[23]);
+ SetPixel(hdc, startx, starty, colours[261]);
}
startx += dx;
starty += dy;
logpal->palPalEntry[n].peBlue = b;
logpal->palPalEntry[n].peFlags = PC_NOCOLLAPSE;
colours[n] = PALETTERGB(r, g, b);
- SetPaletteEntries(pal, 0, NCOLOURS, logpal->palPalEntry);
+ SetPaletteEntries(pal, 0, NALLCOLOURS, logpal->palPalEntry);
} else
colours[n] = RGB(r, g, b);
}
void palette_set(void *frontend, int n, int r, int g, int b)
{
- static const int first[21] = {
- 0, 2, 4, 6, 8, 10, 12, 14,
- 1, 3, 5, 7, 9, 11, 13, 15,
- 16, 17, 18, 20, 22
- };
- real_palette_set(first[n], r, g, b);
- if (first[n] >= 18)
- real_palette_set(first[n] + 1, r, g, b);
+ if (n >= 16)
+ n += 256 - 16;
+ if (n > NALLCOLOURS)
+ return;
+ real_palette_set(n, r, g, b);
if (pal) {
HDC hdc = get_ctx(frontend);
UnrealizeObject(pal);
{
int i;
- for (i = 0; i < NCOLOURS; i++) {
+ /* And this */
+ for (i = 0; i < NALLCOLOURS; i++) {
if (pal) {
logpal->palPalEntry[i].peRed = defpal[i].rgbtRed;
logpal->palPalEntry[i].peGreen = defpal[i].rgbtGreen;
if (pal) {
HDC hdc;
- SetPaletteEntries(pal, 0, NCOLOURS, logpal->palPalEntry);
+ SetPaletteEntries(pal, 0, NALLCOLOURS, logpal->palPalEntry);
hdc = get_ctx(frontend);
RealizePalette(hdc);
free_ctx(hdc);