📄 window.c
字号:
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, FONT_QUALITY(cfg.font_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;
SetWindowPos(hwnd, NULL, 0, 0, width, height,
SWP_NOACTIVATE | SWP_NOCOPYBITS |
SWP_NOMOVE | SWP_NOZORDER);
} else
reset_window(0);
InvalidateRect(hwnd, NULL, TRUE);
}
static void reset_window(int reinit) {
/*
* This function decides how to resize or redraw when the
* user changes something.
*
* This function doesn't like to change the terminal size but if the
* font size is locked that may be it's only soluion.
*/
int win_width, win_height;
RECT cr, wr;
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window()"));
#endif
/* Current window sizes ... */
GetWindowRect(hwnd, &wr);
GetClientRect(hwnd, &cr);
win_width = cr.right - cr.left;
win_height = cr.bottom - cr.top;
if (cfg.resize_action == RESIZE_DISABLED) reinit = 2;
/* Are we being forced to reload the fonts ? */
if (reinit>1) {
#ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -- Forced deinit"));
#endif
deinit_fonts();
init_fonts(0,0);
}
/* Oh, looks like we're minimised */
if (win_width == 0 || win_height == 0)
return;
/* Is the window out of position ? */
if ( !reinit &&
(offset_width != (win_width-font_width*term->cols)/2 ||
offset_height != (win_height-font_height*term->rows)/2) ){
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() -> 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 * term->cols != win_width ||
font_height * term->rows != win_height) {
/* 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -