📄 main.c
字号:
*//* EXTPROTO */voidrxvt_change_font(rxvt_t *r, int init, const char *fontname){ const char *msg = "can't load font \"%s\""; int fh, fw, recheckfonts; int pf; int idx = 0; /* index into r->h->rs[Rs_font] */ XFontStruct *xfont;#ifdef MULTICHAR_SET int i; char *c, *enc; char tmpbuf[64];#endif#define IDX2FNUM(i) ((i) == 0 ? FONT0_IDX : ((i) <= FONT0_IDX ? ((i)-1) : (i)))#define FNUM2IDX(f) ((f) == FONT0_IDX ? 0 : ((f) < FONT0_IDX ? ((f)+1) : (f))) if (!init) { pf = r->h->fnum; switch (fontname[0]) { case '\0': r->h->fnum = FONT0_IDX; fontname = NULL; break; /* special (internal) prefix for font commands */ case FONT_CMD: idx = atoi(fontname + 1); switch (fontname[1]) { case '+': /* corresponds to FONT_UP */ rxvt_font_up_down(r, (idx ? idx : 1), 1); break; case '-': /* corresponds to FONT_DN */ rxvt_font_up_down(r, (idx ? idx : 1), -1); break; default: if (fontname[1] != '\0' && !isdigit(fontname[1])) return; if (idx < 0 || idx >= MAX_NFONTS) return; r->h->fnum = IDX2FNUM(idx); break; } fontname = NULL; break; default: if (fontname == NULL) return; else /* search for existing fontname */ for (idx = 0; idx < MAX_NFONTS; idx++) if (r->h->rs[Rs_font + idx] == NULL) continue; if (!STRCMP(r->h->rs[Rs_font + idx], fontname)) { r->h->fnum = IDX2FNUM(idx); fontname = NULL; break; } break; } /* re-position around the normal font */ idx = FNUM2IDX(r->h->fnum); if (pf == r->h->fnum) return; /* no change */ if (fontname != NULL) { char *name; xfont = XLoadQueryFont(r->Xdisplay, fontname); if (!xfont) return; name = rxvt_malloc(STRLEN(fontname + 1) * sizeof(char)); if (name == NULL) { XFreeFont(r->Xdisplay, xfont); return; } STRCPY(name, fontname); if (r->h->newfont[idx] != NULL) free(r->h->newfont[idx]); r->h->newfont[idx] = name; r->h->rs[Rs_font + idx] = r->h->newfont[idx]; } } if (r->TermWin.font) XFreeFont(r->Xdisplay, r->TermWin.font);/* load font or substitute */ xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_font + idx]); if (!xfont) { rxvt_print_error(msg, r->h->rs[Rs_font + idx]); r->h->rs[Rs_font + idx] = "fixed"; xfont = XLoadQueryFont(r->Xdisplay, "fixed"); if (!xfont) { rxvt_print_error(msg, "fixed"); goto Abort; } } r->TermWin.font = xfont;#ifndef NO_BOLDFONT/* fail silently */ if (init && r->h->rs[Rs_boldFont] != NULL) r->TermWin.boldFont_loaded = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_boldFont]);#endif/* alter existing GC */ if (!init) XSetFont(r->Xdisplay, r->TermWin.gc, r->TermWin.font->fid);/* set the sizes */ fw = rxvt_get_fontwidest(r->TermWin.font); fh = r->TermWin.font->ascent + r->TermWin.font->descent + r->TermWin.lineSpace; if (fw == r->TermWin.font->min_bounds.width) r->TermWin.propfont &= ~PROPFONT_NORMAL;/* Mono-spaced font */ else r->TermWin.propfont |= PROPFONT_NORMAL; /* Proportional font */ recheckfonts = !(fw == r->TermWin.fwidth && fh == r->TermWin.fheight); r->TermWin.fwidth = fw; r->TermWin.fheight = fh;/* check that size of boldFont is okay */#ifndef NO_BOLDFONT if (recheckfonts) { r->TermWin.boldFont = NULL; if (r->TermWin.boldFont_loaded != NULL) { fw = rxvt_get_fontwidest(r->TermWin.boldFont_loaded); fh = r->TermWin.boldFont_loaded->ascent + r->TermWin.boldFont_loaded->descent; if (fw <= r->TermWin.fwidth && fh <= r->TermWin.fheight) r->TermWin.boldFont = r->TermWin.boldFont_loaded; if (fw == r->TermWin.fwidth /* && fh == r->TermWin.fheight */ ) r->TermWin.propfont &= ~PROPFONT_BOLD; else r->TermWin.propfont |= PROPFONT_BOLD; } }#endif /* NO_BOLDFONT */#ifdef MULTICHAR_SET if (r->TermWin.mfont) XFreeFont(r->Xdisplay, r->TermWin.mfont); xfont = NULL;/* load font or substitute */ if (r->h->rs[Rs_mfont + idx] == NULL || (xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_mfont + idx])) == NULL) { /* TODO: this is now mainly handled in rxvt_set_defaultfont() */ i = 0; c = enc = ""; switch (r->encoding_method) { case GB: c = "-*-r-*-%.2d-*-gb2312.1980-0"; enc = "GB"; break; case BIG5: c = "-*-r-*-%.2d-*-big5-0"; enc = "BIG5"; break; case EUCJ: case SJIS: c = "-*-%.2d-*-jisx0208*-*"; enc = "EUCJ/SJIS"; break; case EUCKR: c = "-*-%.2d-*-ksc5601*-*"; enc = "KR"; break; default: i = fh; /* jump past next two sections */ break; } for (; i < fh / 2; i++) { sprintf(tmpbuf, c, fh - i); xfont = XLoadQueryFont(r->Xdisplay, tmpbuf); if (xfont) { r->h->rs[Rs_mfont + idx] = rxvt_malloc(STRLEN(tmpbuf) + 1); STRCPY(r->h->rs[Rs_mfont + idx], tmpbuf); break; } } if (xfont == NULL && i != fh) rxvt_print_error("no similar multichar font: encoding %s; size %d", enc, fh); } r->TermWin.mfont = xfont; if (recheckfonts) if (r->TermWin.mfont != NULL) { fw = rxvt_get_fontwidest(r->TermWin.mfont); fh = r->TermWin.mfont->ascent + r->TermWin.mfont->descent; if (fw > (r->TermWin.fwidth * 2) || fh > r->TermWin.fheight) r->TermWin.mfont = NULL; if (fw == (r->TermWin.fwidth * 2) /* && fh==r->TermWin.fheight */ ) r->TermWin.propfont &= ~PROPFONT_MULTI; else r->TermWin.propfont |= PROPFONT_MULTI; }#endif /* MULTICHAR_SET */ /* Fontset setting is only valid when xlocale initialized. Since * rxvt_init_xlocale() is called after here, so we don't set fontset when * initialization, but let it set by rxvt_init_xlocale() */ if (init) rxvt_setTermFontSet(r, -1); else rxvt_setTermFontSet(r, idx); rxvt_set_colorfgbg(r); if (!init) { rxvt_resize_all_windows(r, 0, 0, 0); rxvt_scr_touch(r, True); } return; Abort: rxvt_print_error("aborting"); /* fatal problem */ exit(EXIT_FAILURE);}/* INTPROTO */voidrxvt_font_up_down(rxvt_t *r, int n, int direction){ const char *p; int initial, j; for (j = 0; j < n; j++) { initial = r->h->fnum; for (;;) { r->h->fnum += direction; if (r->h->fnum == MAX_NFONTS || r->h->fnum == -1) { r->h->fnum = initial; return; } p = r->h->rs[Rs_font + FNUM2IDX(r->h->fnum)]; if (p != NULL && STRLEN(p) > 1) break; } }}#undef IDX2FNUM#undef FNUM2IDX#ifdef STRICT_FONT_CHECKING/* INTPROTO */intrxvt_get_fontwidest(XFontStruct *f){ int i, cw, fw = 0; if (f->min_bounds.width == f->max_bounds.width) return f->min_bounds.width; if (f->per_char == NULL) return f->max_bounds.width; for (i = f->max_char_or_byte2 - f->min_char_or_byte2; --i >= 0;) { cw = f->per_char[i].width; MAX_IT(fw, cw); } return fw;}#endif/*----------------------------------------------------------------------*//*----------------------------------------------------------------------*//* xterm sequences - title, iconName, color (exptl) *//* EXTPROTO */voidrxvt_set_title(rxvt_t *r, const char *str){#ifndef SMART_WINDOW_TITLE XStoreName(r->Xdisplay, r->TermWin.parent[0], str);#else char *name; if (XFetchName(r->Xdisplay, r->TermWin.parent[0], &name) == 0) name = NULL; if (name == NULL || STRCMP(name, str)) XStoreName(r->Xdisplay, r->TermWin.parent[0], str); if (name) XFree(name);#endif}/* EXTPROTO */voidrxvt_set_iconName(rxvt_t *r, const char *str){#ifndef SMART_WINDOW_TITLE XSetIconName(r->Xdisplay, r->TermWin.parent[0], str);#else char *name; if (XGetIconName(r->Xdisplay, r->TermWin.parent[0], &name)) name = NULL; if (name == NULL || STRCMP(name, str)) XSetIconName(r->Xdisplay, r->TermWin.parent[0], str); if (name) XFree(name);#endif}#ifdef XTERM_COLOR_CHANGE/* EXTPROTO */voidrxvt_set_window_color(rxvt_t *r, int idx, const char *color){ XColor xcol; int i; if (color == NULL || *color == '\0') return;/* handle color aliases */ if (isdigit(*color)) { i = atoi(color); if (i >= 8 && i <= 15) { /* bright colors */ i -= 8;# ifndef NO_BRIGHTCOLOR r->PixColors[idx] = r->PixColors[minBrightCOLOR + i]; SET_PIXCOLOR(r->h, idx); goto Done;# endif } if (i >= 0 && i <= 7) { /* normal colors */ r->PixColors[idx] = r->PixColors[minCOLOR + i]; SET_PIXCOLOR(r->h, idx); goto Done; } } if (!rxvt_rXParseAllocColor(r, &xcol, color)) return;/* XStoreColor (r->Xdisplay, XCMAP, XColor*); *//* * FIXME: should free colors here, but no idea how to do it so instead, * so just keep gobbling up the colormap */# if 0 for (i = Color_Black; i <= Color_White; i++) if (r->PixColors[idx] == r->PixColors[i]) break; if (i > Color_White) { /* fprintf (stderr, "XFreeColors: r->PixColors [%d] = %lu\n", idx, r->PixColors [idx]); */ XFreeColors(r->Xdisplay, XCMAP, (r->PixColors + idx), 1, DisplayPlanes(r->Xdisplay, Xscreen)); }# endif r->PixColors[idx] = xcol.pixel; SET_PIXCOLOR(r->h, idx);/* XSetWindowAttributes attr; *//* Cursor cursor; */ Done: if (idx == Color_bg && !(r->Options & Opt_transparent)) XSetWindowBackground(r->Xdisplay, r->TermWin.vt, r->PixColors[Color_bg]);/* handle Color_BD, scrollbar background, etc. */ rxvt_set_colorfgbg(r); rxvt_recolour_cursor(r);/* the only reasonable way to enforce a clean update */ rxvt_scr_touch(r, False);}#else# define rxvt_set_window_color(r, idx,color) ((void)0)#endif /* XTERM_COLOR_CHANGE *//* EXTPROTO */voidrxvt_recolour_cursor(rxvt_t *r){ XColor xcol[2]; xcol[0].pixel = r->PixColors[Color_pointer]; xcol[1].pixel = r->PixColors[Color_bg]; XQueryColors(r->Xdisplay, XCMAP, xcol, 2); XRecolorCursor(r->Xdisplay, r->TermWin_cursor, &(xcol[0]), &(xcol[1]));}/*----------------------------------------------------------------------*//* * find if fg/bg matches any of the normal (low-intensity) colors *//* INTPROTO */voidrxvt_set_colorfgbg(rxvt_t *r){ unsigned int i; const char *xpmb = "\0"; char fstr[sizeof("default") + 1], bstr[sizeof("default") + 1]; r->h->env_colorfgbg = rxvt_malloc(sizeof("COLORFGBG=default;default;bg") + 1); STRCPY(fstr, "default"); STRCPY(bstr, "default"); for (i = Color_Black; i <= Color_White; i++) if (r->PixColors[Color_fg] == r->PixColors[i]) { sprintf(fstr, "%d", (i - Color_Black)); break; } for (i = Color_Black; i <= Color_White; i++) if (r->PixColors[Color_bg] == r->PixColors[i]) { sprintf(bstr, "%d", (i - Color_Black));#ifdef XPM_BACKGROUND xpmb = "default;";#endif break; } sprintf(r->h->env_colorfgbg, "COLORFGBG=%s;%s%s", fstr, xpmb, bstr); putenv(r->h->env_colorfgbg);#ifndef NO_BRIGHTCOLOR r->h->colorfgbg = DEFAULT_RSTYLE; for (i = minCOLOR; i <= maxCOLOR; i++) { if (r->PixColors[Color_fg] == r->PixColors[i]# ifndef NO_BOLD_UNDERLINE_REVERSE && r->PixColors[Color_fg] == r->PixColors[Color_BD]# endif /* ! NO_BOLD_UNDERLINE_REVERSE */ /* if we wanted boldFont to have precedence */# if 0 /* ifndef NO_BOLDFONT */ && r->TermWin.boldFont == NULL# endif /* NO_BOLDFONT */ ) r->h->colorfgbg = SET_FGCOLOR(r->h->colorfgbg, i); if (r->PixColors[Color_bg] == r->PixColors[i]) r->h->colorfgbg = SET_BGCOLOR(r->h->colorfgbg, i); }#endif}/*----------------------------------------------------------------------*//* * Colour determination for low colour displays, routine from * Hans de Goede <hans@highrise.nl> *//* EXTPROTO */intrxvt_rXParseAllocColor(rxvt_t *r, XColor *screen_in_out, const char *colour){ int res = 0; if (!XParseColor(r->Xdisplay, XCMAP, colour, screen_in_out)) rxvt_print_error("can't determine colour: %s", colour); else res = rxvt_rXAllocColor(r, screen_in_out, colour); return res;}/* EXTPROTO */intrxvt_rXAllocColor(rxvt_t *r, XColor *screen_in_out, const char *colour){ int res; if ((res = XAllocColor(r->Xdisplay, XCMAP, screen_in_out))) return res; /* try again with closest match */ if (XDEPTH >= 4 && XDEPTH <= 8) { int i, numcol; int best_pixel = 0; unsigned long best_diff, diff; XColor *colors;#define rSQR(x) ((x)*(x)) best_diff = 0; numcol = 0x01 << XDEPTH; if ((colors = rxvt_malloc(numcol * sizeof(XColor)))) { for (i = 0; i < numcol; i++) colors[i].pixel = i; XQueryColors(r->Xdisplay, XCMAP, colors, numcol); for (i = 0; i < numcol; i++) { diff = rSQR(screen_in_out->red - colors[i].red) + rSQR(screen_in_out->green - colors[i].green) + rSQR(screen_in_out->blue - colors[i].blue); if (i == 0 || diff < best_diff) { best_pixel = colors[i].pixel; best_diff = diff; } } *screen_in_out = colors[best_pixel]; free(colors); res = XAllocColor(r->Xdisplay, XCMAP, screen_in_out); } } if (res == 0) rxvt_print_error("can't allocate colour: %s", colour); return res;}/* -------------------------------------------------------------------- * * - WINDOW RESIZING - * * -------------------------------------------------------------------- *//* EXTPROTO */voidrxvt_resize_all_windows(rxvt_t *r, unsigned int width, unsigned int height, int ignoreparent){ int fix_screen;#ifdef SMART_RESIZE int old_width = r->szHint.width, old_height = r->szHint.height;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -