/* * Interchange colors in the cache, e.g., for reverse-video. */ void redoCgs(XtermWidget xw, Pixel fg, Pixel bg, CgsEnum cgsId) { int n; VTwin *cgsWin = WhichVWin(TScreenOf(xw)); CgsCache *me = myCache(xw, cgsWin, cgsId); if (me != 0) { CgsCacheData *save_data = me->data; for (n = 0; n < DEPTH; ++n) { if (LIST(n).gc != 0 && HaveFont(LIST(n).font)) { LINK(n); if (LIST(n).fg == fg && LIST(n).bg == bg) { setCgsFore(xw, cgsWin, cgsId, bg); setCgsBack(xw, cgsWin, cgsId, fg); } else if (LIST(n).fg == bg && LIST(n).bg == fg) { setCgsFore(xw, cgsWin, cgsId, fg); setCgsBack(xw, cgsWin, cgsId, bg); } else { continue; } (void) chgCache(xw, cgsId, me, False); } } me->data = save_data; } }
/* Resize the text window for a terminal screen, modifying the * appropriate WM_SIZE_HINTS and taking advantage of bit gravity. */ void DoResizeScreen(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int border = 2 * screen->border; int min_wide = border + screen->fullVwin.sb_info.width; int min_high = border; XtGeometryResult geomreqresult; Dimension reqWidth, reqHeight, repWidth, repHeight; #ifndef NO_ACTIVE_ICON VTwin *saveWin = WhichVWin(screen); /* all units here want to be in the normal font units */ WhichVWin(screen) = &screen->fullVwin; #endif /* NO_ACTIVE_ICON */ /* * I'm going to try to explain, as I understand it, why we * have to do XGetWMNormalHints and XSetWMNormalHints here, * although I can't guarantee that I've got it right. * * In a correctly written toolkit program, the Shell widget * parses the user supplied geometry argument. However, * because of the way xterm does things, the VT100 widget does * the parsing of the geometry option, not the Shell widget. * The result of this is that the Shell widget doesn't set the * correct window manager hints, and doesn't know that the * user has specified a geometry. * * The XtVaSetValues call below tells the Shell widget to * change its hints. However, since it's confused about the * hints to begin with, it doesn't get them all right when it * does the SetValues -- it undoes some of what the VT100 * widget did when it originally set the hints. * * To fix this, we do the following: * * 1. Get the sizehints directly from the window, going around * the (confused) shell widget. * 2. Call XtVaSetValues to let the shell widget know which * hints have changed. Note that this may not even be * necessary, since we're going to right ahead after that * and set the hints ourselves, but it's good to put it * here anyway, so that when we finally do fix the code so * that the Shell does the right thing with hints, we * already have the XtVaSetValues in place. * 3. We set the sizehints directly, this fixing up whatever * damage was done by the Shell widget during the * XtVaSetValues. * * Gross, huh? * * The correct fix is to redo VTRealize, VTInitialize and * VTSetValues so that font processing happens early enough to * give back responsibility for the size hints to the Shell. * * Someday, we hope to have time to do this. Someday, we hope * to have time to completely rewrite xterm. */ TRACE(("DoResizeScreen\n")); #if 1 /* ndef nothack */ /* * NOTE: the hints and the XtVaSetValues() must match. */ TRACE(("%s@%d -- ", __FILE__, __LINE__)); TRACE_WM_HINTS(xw); getXtermSizeHints(xw); xtermSizeHints(xw, ScrollbarWidth(screen)); /* These are obsolete, but old clients may use them */ xw->hints.width = MaxCols(screen) * FontWidth(screen) + xw->hints.min_width; xw->hints.height = MaxRows(screen) * FontHeight(screen) + xw->hints.min_height; #if OPT_MAXIMIZE /* assure single-increment resize for fullscreen */ if (xw->work.ewmh[0].mode) { xw->hints.width_inc = 1; xw->hints.height_inc = 1; } #endif /* OPT_MAXIMIZE */ #endif XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); reqWidth = (Dimension) (MaxCols(screen) * FontWidth(screen) + min_wide); reqHeight = (Dimension) (MaxRows(screen) * FontHeight(screen) + min_high); #if OPT_MAXIMIZE /* compensate for fullscreen mode */ if (xw->work.ewmh[0].mode) { Screen *xscreen = DefaultScreenOfDisplay(xw->screen.display); reqWidth = (Dimension) WidthOfScreen(xscreen); reqHeight = (Dimension) HeightOfScreen(xscreen); ScreenResize(xw, reqWidth, reqHeight, &xw->flags); } #endif /* OPT_MAXIMIZE */ TRACE(("...requesting screensize chars %dx%d, pixels %dx%d\n", MaxRows(screen), MaxCols(screen), reqHeight, reqWidth)); geomreqresult = REQ_RESIZE((Widget) xw, reqWidth, reqHeight, &repWidth, &repHeight); if (geomreqresult == XtGeometryAlmost) { TRACE(("...almost, retry screensize %dx%d\n", repHeight, repWidth)); geomreqresult = REQ_RESIZE((Widget) xw, repWidth, repHeight, NULL, NULL); } if (geomreqresult != XtGeometryYes) { /* The resize wasn't successful, so we might need to adjust our idea of how large the screen is. */ TRACE(("...still no (%d) - resize the core-class\n", geomreqresult)); xw->core.widget_class->core_class.resize((Widget) xw); } #if 1 /* ndef nothack */ /* * XtMakeResizeRequest() has the undesirable side-effect of clearing * the window manager's hints, even on a failed request. This would * presumably be fixed if the shell did its own work. */ if (xw->hints.flags && repHeight && repWidth) { xw->hints.height = repHeight; xw->hints.width = repWidth; TRACE_HINTS(&xw->hints); XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); } #endif XSync(screen->display, False); /* synchronize */ if (xtermAppPending()) xevents(); #ifndef NO_ACTIVE_ICON WhichVWin(screen) = saveWin; #endif /* NO_ACTIVE_ICON */ }
/* * Lookup/cache a GC for the double-size character display. We save up to * NUM_CHRSET values. */ GC xterm_DoubleGC(XtermWidget xw, unsigned chrset, unsigned attr_flags, unsigned draw_flags, GC old_gc, int *inxp) { TScreen *screen = TScreenOf(xw); VTwin *cgsWin = WhichVWin(screen); char *name; GC result = 0; if ((name = xtermSpecialFont(screen, attr_flags, draw_flags, chrset)) != 0) { CgsEnum cgsId = WhichCgsId(attr_flags); Boolean found = False; XTermFonts *data = 0; int n; if ((n = xterm_Double_index(xw, chrset, attr_flags)) >= 0) { data = &(screen->double_fonts[n]); if (data->fn != 0) { if (!strcmp(data->fn, name) && data->fs != 0) { found = True; free(name); } else { discard_font(xw, n); } } } if (!found) { XTermFonts temp; TRACE(("xterm_DoubleGC %s %d: %s\n", (attr_flags & BOLD) ? "BOLD" : "NORM", n, name)); memset(&temp, 0, sizeof(temp)); temp.fn = name; temp.chrset = chrset; temp.flags = (attr_flags & BOLD); if (!xtermOpenFont(xw, name, &temp, fwAlways, False)) { /* Retry with * in resolutions */ char *nname = xtermSpecialFont(screen, attr_flags, draw_flags | NORESOLUTION, chrset); if (nname != 0) { found = (Boolean) xtermOpenFont(xw, nname, &temp, fwAlways, False); free(nname); } } else { found = True; } free(name); if (found) { n = 0; data = pushback_font(xw, &temp); } TRACE(("-> %s\n", found ? "OK" : "FAIL")); } if (found) { setCgsCSet(xw, cgsWin, cgsId, chrset); setCgsFont(xw, cgsWin, cgsId, data); setCgsFore(xw, cgsWin, cgsId, getCgsFore(xw, cgsWin, old_gc)); setCgsBack(xw, cgsWin, cgsId, getCgsBack(xw, cgsWin, old_gc)); result = getCgsGC(xw, cgsWin, cgsId); *inxp = n; } else if (attr_flags & BOLD) { UIntClr(attr_flags, BOLD); result = xterm_DoubleGC(xw, chrset, attr_flags, draw_flags, old_gc, inxp); } } return result; }