📄 window.c
字号:
{ va_list ap; char *stuff, morestuff[100]; va_start(ap, fmt); stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Fatal Error", appname); MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); sfree(stuff); if (cfg.close_on_exit == FORCE_ON) PostQuitMessage(1); else { close_session(); }}/* * Report an error at the command-line parsing stage. */void cmdline_error(char *fmt, ...){ va_list ap; char *stuff, morestuff[100]; va_start(ap, fmt); stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Command Line Error", appname); MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); sfree(stuff); exit(1);}/* * Actually do the job requested by a WM_NETEVENT */static void enact_pending_netevent(void){ static int reentering = 0; extern int select_result(WPARAM, LPARAM); int ret; if (reentering) return; /* don't unpend the pending */ pending_netevent = FALSE; reentering = 1; ret = select_result(pend_netevent_wParam, pend_netevent_lParam); reentering = 0; if (ret == 0 && !session_closed) { /* Abnormal exits will already have set session_closed and taken * appropriate action. */ if (cfg.close_on_exit == FORCE_ON || cfg.close_on_exit == AUTO) PostQuitMessage(0); else { close_session(); session_closed = TRUE; MessageBox(hwnd, "Connection closed by remote host", appname, MB_OK | MB_ICONINFORMATION); } }}/* * Copy the colour palette from the configuration data into defpal. * This is non-trivial because the colour indices are different. */static void cfgtopalette(void){ 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 }; for (i = 0; i < 24; 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]; } /* Override with system colours if appropriate */ if (cfg.system_colour) systopalette();}/* * Override bit of defpal with colours from the system. * (NB that this takes a copy the system colours at the time this is called, * so subsequent colour scheme changes don't take effect. To fix that we'd * probably want to be using GetSysColorBrush() and the like.) */static void systopalette(void){ 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 */ }; for (i = 0; i < (sizeof(or)/sizeof(or[0])); i++) { COLORREF colour = GetSysColor(or[i].nIndex); defpal[or[i].norm].rgbtRed = defpal[or[i].bold].rgbtRed = GetRValue(colour); defpal[or[i].norm].rgbtGreen = defpal[or[i].bold].rgbtGreen = GetGValue(colour); defpal[or[i].norm].rgbtBlue = defpal[or[i].bold].rgbtBlue = GetBValue(colour); }}/* * Set up the colour palette. */static void init_palette(void){ int i; HDC hdc = GetDC(hwnd); if (hdc) { if (cfg.try_palette && GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) { /* * This is a genuine case where we must use smalloc * because the snew macros can't cope. */ logpal = smalloc(sizeof(*logpal) - sizeof(logpal->palPalEntry) + NCOLOURS * sizeof(PALETTEENTRY)); logpal->palVersion = 0x300; logpal->palNumEntries = NCOLOURS; for (i = 0; i < NCOLOURS; i++) { logpal->palPalEntry[i].peRed = defpal[i].rgbtRed; logpal->palPalEntry[i].peGreen = defpal[i].rgbtGreen; logpal->palPalEntry[i].peBlue = defpal[i].rgbtBlue; logpal->palPalEntry[i].peFlags = PC_NOCOLLAPSE; } pal = CreatePalette(logpal); if (pal) { SelectPalette(hdc, pal, FALSE); RealizePalette(hdc); SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE); } } ReleaseDC(hwnd, hdc); } if (pal) for (i = 0; i < NCOLOURS; i++) colours[i] = PALETTERGB(defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue); else for (i = 0; i < NCOLOURS; i++) colours[i] = RGB(defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue);}/* * This is a wrapper to ExtTextOut() to force Windows to display * the precise glyphs we give it. Otherwise it would do its own * bidi and Arabic shaping, and we would end up uncertain which * characters it had put where. */static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc, unsigned short *lpString, UINT cbCount, CONST INT *lpDx, int opaque){ GCP_RESULTSW gcpr; char *buffer = snewn(cbCount*2+2, char); char *classbuffer = snewn(cbCount, char); memset(&gcpr, 0, sizeof(gcpr)); memset(buffer, 0, cbCount*2+2); memset(classbuffer, GCPCLASS_NEUTRAL, cbCount); gcpr.lStructSize = sizeof(gcpr); gcpr.lpGlyphs = (void *)buffer; gcpr.lpClass = classbuffer; gcpr.nGlyphs = cbCount; GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr, FLI_MASK | GCP_CLASSIN | GCP_DIACRITIC); ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), lprc, buffer, cbCount, lpDx);}/* * Initialise all the fonts we will need initially. There may be as many as * three or as few as one. The other (poentially) twentyone fonts are done * if/when they are needed. * * We also: * * - check the font width and height, correcting our guesses if * necessary. * * - verify that the bold font is the same width as the ordinary * one, and engage shadow bolding if not. * * - verify that the underlined font is the same width as the * ordinary one (manual underlining by means of line drawing can * be done in a pinch). */static void init_fonts(int pick_width, int pick_height){ TEXTMETRIC tm; CPINFO cpinfo; int fontsize[3]; int i; HDC hdc; int fw_dontcare, fw_bold; for (i = 0; i < FONT_MAXNO; i++) fonts[i] = NULL; bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT; und_mode = UND_FONT; if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { fw_dontcare = FW_DONTCARE; fw_bold = FW_BOLD; } hdc = GetDC(hwnd); if (pick_height) font_height = pick_height; else { font_height = cfg.font.height; if (font_height > 0) { font_height = -MulDiv(font_height, GetDeviceCaps(hdc, LOGPIXELSY), 72); } } font_width = pick_width;#define f(i,c,w,u) \ fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ c, OUT_DEFAULT_PRECIS, \ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \ FIXED_PITCH | FF_DONTCARE, cfg.font.name) 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); if (pick_width == 0 || pick_height == 0) { font_height = tm.tmHeight; font_width = tm.tmAveCharWidth; } font_dualwidth = (tm.tmAveCharWidth != tm.tmMaxCharWidth);#ifdef RDB_DEBUG_PATCH debug(23, "Primary font H=%d, AW=%d, MW=%d", tm.tmHeight, tm.tmAveCharWidth, tm.tmMaxCharWidth);#endif { CHARSETINFO info; DWORD cset = tm.tmCharSet; memset(&info, 0xFF, sizeof(info)); /* !!! Yes the next line is right */ if (cset == OEM_CHARSET) ucsdata.font_codepage = GetOEMCP(); else if (TranslateCharsetInfo ((DWORD *) cset, &info, TCI_SRCCHARSET)) ucsdata.font_codepage = info.ciACP; else ucsdata.font_codepage = -1; GetCPInfo(ucsdata.font_codepage, &cpinfo); ucsdata.dbcs_screenfont = (cpinfo.MaxCharSize > 1); } f(FONT_UNDERLINE, cfg.font.charset, fw_dontcare, TRUE); /* * Some fonts, e.g. 9-pt Courier, draw their underlines * outside their character cell. We successfully prevent * screen corruption by clipping the text output, but then * we lose the underline completely. Here we try to work * out whether this is such a font, and if it is, we set a * flag that causes underlines to be drawn by hand. * * Having tried other more sophisticated approaches (such * as examining the TEXTMETRIC structure or requesting the * height of a string), I think we'll do this the brute * force way: we create a small bitmap, draw an underlined * space on it, and test to see whether any pixels are * foreground-coloured. (Since we expect the underline to * go all the way across the character cell, we only search * down a single column of the bitmap, half way across.) */ { HDC und_dc; HBITMAP und_bm, und_oldbm; int i, gotit; COLORREF c; und_dc = CreateCompatibleDC(hdc); und_bm = CreateCompatibleBitmap(hdc, font_width, font_height); und_oldbm = SelectObject(und_dc, und_bm); SelectObject(und_dc, fonts[FONT_UNDERLINE]); SetTextAlign(und_dc, TA_TOP | TA_LEFT | TA_NOUPDATECP); SetTextColor(und_dc, RGB(255, 255, 255)); SetBkColor(und_dc, RGB(0, 0, 0)); SetBkMode(und_dc, OPAQUE); ExtTextOut(und_dc, 0, 0, ETO_OPAQUE, NULL, " ", 1, NULL); gotit = FALSE; for (i = 0; i < font_height; i++) { c = GetPixel(und_dc, font_width / 2, i); if (c != RGB(0, 0, 0)) gotit = TRUE; } SelectObject(und_dc, und_oldbm); DeleteObject(und_bm); DeleteDC(und_dc); if (!gotit) { und_mode = UND_LINE; DeleteObject(fonts[FONT_UNDERLINE]); fonts[FONT_UNDERLINE] = 0; } } if (bold_mode == BOLD_FONT) { f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE); }#undef f descent = tm.tmAscent + 1; if (descent >= font_height) descent = font_height - 1; for (i = 0; i < 3; i++) { if (fonts[i]) { if (SelectObject(hdc, fonts[i]) && GetTextMetrics(hdc, &tm)) fontsize[i] = tm.tmAveCharWidth + 256 * tm.tmHeight; else fontsize[i] = -i; } else fontsize[i] = -i; } ReleaseDC(hwnd, hdc); if (fontsize[FONT_UNDERLINE] != fontsize[FONT_NORMAL]) { und_mode = UND_LINE; DeleteObject(fonts[FONT_UNDERLINE]); fonts[FONT_UNDERLINE] = 0; } if (bold_mode == BOLD_FONT && fontsize[FONT_BOLD] != fontsize[FONT_NORMAL]) { bold_mode = BOLD_SHADOW; DeleteObject(fonts[FONT_BOLD]); fonts[FONT_BOLD] = 0; } fontflag[0] = fontflag[1] = fontflag[2] = 1; init_ucs(&cfg, &ucsdata);}static void another_font(int fontno){ int basefont; int fw_dontcare, fw_bold; int c, u, w, x; char *s; if (fontno < 0 || fontno >= FONT_MAXNO || fontflag[fontno]) return; basefont = (fontno & ~(FONT_BOLDUND)); if (basefont != fontno && !fontflag[basefont]) another_font(basefont); if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { fw_dontcare = FW_DONTCARE; fw_bold = FW_BOLD; } c = cfg.font.charset; w = fw_dontcare; u = FALSE; s = cfg.font.name; x = font_width; if (fontno & FONT_WIDE) x *= 2; if (fontno & FONT_NARROW) x = (x+1)/2; if (fontno & FONT_OEM) c = OEM_CHARSET; if (fontno & FONT_BOLD) w = fw_bold; if (fontno & FONT_UNDERLINE) u = TRUE; fonts[fontno] = CreateFont(font_height * (1 + !!(fontno & FONT_HIGH)), x, 0, 0, w, FALSE, u, FALSE, c, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE, s); fontflag[fontno] = 1;}static void deinit_fonts(void){ int i; for (i = 0; i < FONT_MAXNO; i++) { if (fonts[i]) DeleteObject(fonts[i]); fonts[i] = 0; fontflag[i] = 0; }}void request_resize(void *frontend, int w, int h){ int width, height; /* If the window is maximized supress resizing attempts */ if (IsZoomed(hwnd)) { if (cfg.resize_action == RESIZE_TERM) return; } if (cfg.resize_action == RESIZE_DISABLED) return; if (h == term->rows && w == term->cols) return; /* Sanity checks ... */ { static int first_time = 1; static RECT ss; switch (first_time) { case 1: /* Get the size of the screen */ if (get_fullscreen_rect(&ss)) /* first_time = 0 */ ; else { first_time = 2; break; } case 0: /* Make sure the values are sane */ width = (ss.right - ss.left - extra_width) / 4; height = (ss.bottom - ss.top - extra_height) / 6; if (w > width || h > height) return; if (w < 15) w = 15; if (h < 1) h = 1; } } term_size(term, h, w, cfg.savelines); if (cfg.resize_action != RESIZE_FONT && !IsZoomed(hwnd)) { width = extra_width + font_width * w; height = extra_height + font_height * h;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -