/* * Restore Cursor and Attributes */ void CursorRestore(XtermWidget xw) { TScreen *screen = TScreenOf(xw); SavedCursor *sc = &screen->sc[screen->whichBuf]; /* Restore the character sets, unless we never did a save-cursor op. * In that case, we'll reset the character sets. */ if (sc->saved) { memmove(screen->gsets, sc->gsets, sizeof(screen->gsets)); screen->curgl = sc->curgl; screen->curgr = sc->curgr; } else { resetCharsets(screen); } UIntClr(xw->flags, DECSC_FLAGS); UIntSet(xw->flags, sc->flags & DECSC_FLAGS); CursorSet(screen, ((xw->flags & ORIGIN) ? sc->row - screen->top_marg : sc->row), sc->col, xw->flags); #if OPT_ISO_COLORS xw->sgr_foreground = sc->sgr_foreground; SGR_Foreground(xw, xw->flags & FG_COLOR ? sc->cur_foreground : -1); SGR_Background(xw, xw->flags & BG_COLOR ? sc->cur_background : -1); #endif update_autowrap(); }
static void AlternateScroll(Widget w, long amount) { XtermWidget xw; TScreen *screen; if ((xw = getXtermWidget(w)) != 0 && (screen = TScreenOf(xw)) != 0 && screen->alternateScroll && screen->whichBuf) { ANSI reply; amount /= FontHeight(screen); memset(&reply, 0, sizeof(reply)); reply.a_type = ((xw->keyboard.flags & MODE_DECCKM) ? ANSI_SS3 : ANSI_CSI); if (amount > 0) { reply.a_final = 'B'; } else { amount = -amount; reply.a_final = 'A'; } while (amount-- > 0) { unparseseq(xw, &reply); } } else { ScrollTextUpDownBy(w, (XtPointer) 0, (XtPointer) amount); } }
void initLineData(XtermWidget xw) { TScreen *screen = TScreenOf(xw); initLineExtra(screen); TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra)); TRACE(("...sizeof(LineData) %lu\n", (unsigned long) sizeof(LineData))); #if OPT_ISO_COLORS TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor))); #endif TRACE(("...sizeof(RowData) %lu\n", (unsigned long) sizeof(RowData))); TRACE(("...offset(lineSize) %lu\n", (unsigned long) offsetof(LineData, lineSize))); TRACE(("...offset(bufHead) %lu\n", (unsigned long) offsetof(LineData, bufHead))); #if OPT_WIDE_CHARS TRACE(("...offset(combSize) %lu\n", (unsigned long) offsetof(LineData, combSize))); #endif TRACE(("...offset(attribs) %lu\n", (unsigned long) offsetof(LineData, attribs))); #if OPT_ISO_COLORS TRACE(("...offset(color) %lu\n", (unsigned long) offsetof(LineData, color))); #endif TRACE(("...offset(charData) %lu\n", (unsigned long) offsetof(LineData, charData))); TRACE(("...offset(combData) %lu\n", (unsigned long) offsetof(LineData, combData))); }
/*ARGSUSED*/ static void ScrollTextUpDownBy( Widget scrollbarWidget, XtPointer client_data GCC_UNUSED, XtPointer call_data) { XtermWidget xw = getXtermWidget(scrollbarWidget); if (xw != 0) { long pixels = (long) call_data; TScreen *screen = TScreenOf(xw); int rowOnScreen, newTopLine; rowOnScreen = (int) (pixels / FontHeight(screen)); if (rowOnScreen == 0) { if (pixels < 0) rowOnScreen = -1; else if (pixels > 0) rowOnScreen = 1; } newTopLine = ROW2INX(screen, rowOnScreen); WindowScroll(xw, newTopLine, True); } }
/* * Free any GC associated with the given id. */ GC freeCgs(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId) { CgsCache *me; int j; if ((me = myCache(xw, cgsWin, cgsId)) != 0) { for (j = 0; j < DEPTH; ++j) { if (LIST(j).gc != 0) { TRACE(("freeCgs(%s, %s) gc %p(%d)\n", traceVTwin(xw, cgsWin), traceCgsEnum(cgsId), (void *) LIST(j).gc, j)); clrCgsFonts(xw, cgsWin, LIST(j).font); #if OPT_BOX_CHARS if (cgsId == gcDots) { XmuReleaseStippledPixmap(XtScreen((Widget) xw), LIST(j).tile); } #endif XFreeGC(TScreenOf(xw)->display, LIST(j).gc); memset(&LIST(j), 0, sizeof(LIST(j))); } LINK(0); } } return 0; }
void ResizeScrollBar(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (screen->scrollWidget != 0) { int height = screen->fullVwin.height + screen->border * 2; int width = screen->scrollWidget->core.width; int ypos = -ScrollBarBorder(xw); #ifdef SCROLLBAR_RIGHT int xpos = ((xw->misc.useRight) ? (screen->fullVwin.fullwidth - screen->scrollWidget->core.width - BorderWidth(screen->scrollWidget)) : -ScrollBarBorder(xw)); #else int xpos = -ScrollBarBorder(xw); #endif TRACE(("ResizeScrollBar at %d,%d %dx%d\n", ypos, xpos, height, width)); XtConfigureWidget( screen->scrollWidget, (Position) xpos, (Position) ypos, (Dimension) width, (Dimension) height, BorderWidth(screen->scrollWidget)); ScrollBarDrawThumb(screen->scrollWidget); } }
int xterm_Double_index(XtermWidget xw, unsigned chrset, unsigned flags) { int n; int result = -1; TScreen *screen = TScreenOf(xw); XTermFonts *data = screen->double_fonts; flags &= BOLD; TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", chrset, flags)); for (n = 0; n < screen->fonts_used; n++) { if (data[n].chrset == chrset && data[n].flags == flags) { if (n != 0) { XTermFonts save; TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used)); save = data[n]; while (n > 0) { data[n] = data[n - 1]; n--; } data[n] = save; } result = n; break; } } return result; }
/* * 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; } }
/* * moves the cursor left n, no wrap around */ void CursorBack(XtermWidget xw, int n) { #define WRAP_MASK (REVERSEWRAP | WRAPAROUND) TScreen *screen = TScreenOf(xw); int offset, in_row, length, rev; int left = ScrnLeftMargin(xw); int before = screen->cur_col; if ((rev = (xw->flags & WRAP_MASK) == WRAP_MASK) != 0 && screen->do_wrap) { n--; } /* if the cursor is already before the left-margin, we have to let it go */ if (before < left) left = 0; if ((screen->cur_col -= n) < left) { if (rev) { in_row = ScrnRightMargin(xw) - left + 1; offset = (in_row * screen->cur_row) + screen->cur_col - left; if (offset < 0) { length = in_row * MaxRows(screen); offset += ((-offset) / length + 1) * length; } set_cur_row(screen, (offset / in_row)); set_cur_col(screen, (offset % in_row) + left); do_xevents(); } else { set_cur_col(screen, left); } } ResetWrap(screen); }
/* * Reset all lines on the screen to single-width/single-height. */ void xterm_ResetDouble(XtermWidget xw) { #if OPT_DEC_CHRSET TScreen *screen = TScreenOf(xw); Boolean changed = False; LineData *ld; unsigned code; int row; for (row = 0; row < screen->max_row; ++row) { if ((ld = getLineData(screen, ROW2INX(screen, row))) != 0) { code = GetLineDblCS(ld); if (code != CSET_SWL) { SetLineDblCS(ld, CSET_SWL); changed = True; } } } if (changed) { xtermRepaint(xw); } #else (void) xw; #endif }
/* * Tab to the next stop, returning true if the cursor moved */ Bool TabToNextStop(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int saved_column = screen->cur_col; int next = TabNext(xw, xw->tabs, screen->cur_col); int max = LineMaxCol(screen, getLineData(screen, screen->cur_row)); if (IsLeftRightMode(xw)) max = TScreenOf(xw)->rgt_marg; if (next > max) next = max; set_cur_col(screen, next); return (screen->cur_col > saved_column); }
Graphic * get_new_graphic(XtermWidget xw, int charrow, int charcol, unsigned type) { TScreen const *screen = TScreenOf(xw); int bufferid = screen->whichBuf; int terminal_id = screen->terminal_id; Graphic *graphic; unsigned ii; FOR_EACH_SLOT(ii) { if ((graphic = getInactiveSlot(screen, ii))) { TRACE(("using fresh graphic index=%u id=%u\n", ii, next_graphic_id)); break; } } /* if none are free, recycle the graphic scrolled back the farthest */ if (!graphic) { int min_charrow = 0; Graphic *min_graphic = NULL; FOR_EACH_SLOT(ii) { if (!(graphic = getActiveSlot(ii))) continue; if (!min_graphic || graphic->charrow < min_charrow) { min_charrow = graphic->charrow; min_graphic = graphic; } } TRACE(("recycling old graphic index=%u id=%u\n", ii, next_graphic_id)); graphic = min_graphic; }
static void closePrinter(XtermWidget xw GCC_UNUSED) { if (xtermHasPrinter(xw) != 0) { TScreen *screen = TScreenOf(xw); #ifdef VMS char pcommand[256]; (void) sprintf(pcommand, "%s %s;", SPS.printer_command, VMS_TEMP_PRINT_FILE); #endif if (SPS.fp != 0) { DEBUG_MSG("closePrinter\n"); pclose(SPS.fp); TRACE(("closed printer, waiting...\n")); #ifdef VMS /* This is a quick hack, really should use spawn and check status or system services and go straight to the queue */ (void) system(pcommand); #else /* VMS */ while (nonblocking_wait() > 0) { ; } #endif /* VMS */ SPS.fp = 0; SPS.isOpen = False; TRACE(("closed printer\n")); DEBUG_MSG("...closePrinter (done)\n"); }
/* * Move the cursor to the first column of the n-th previous line. */ void CursorPrevLine(XtermWidget xw, int count) { TScreen *screen = TScreenOf(xw); CursorUp(screen, count < 1 ? 1 : count); CarriageReturn(xw); do_xevents(); }
void WindowScroll(XtermWidget xw, int top, Bool always GCC_UNUSED) { TScreen *screen = TScreenOf(xw); #if OPT_SCROLL_LOCK if (screen->allowScrollLock && (screen->scroll_lock && !always)) { if (screen->scroll_dirty) { screen->scroll_dirty = False; ScrnRefresh(xw, 0, 0, MaxRows(screen), MaxCols(screen), False); } } else #endif { int i; if (top < -screen->savedlines) { top = -screen->savedlines; } else if (top > 0) { top = 0; } if ((i = screen->topline - top) != 0) { int lines; int scrolltop, scrollheight, refreshtop; if (screen->cursor_state) HideCursor(); lines = i > 0 ? i : -i; if (lines > MaxRows(screen)) lines = MaxRows(screen); scrollheight = screen->max_row - lines + 1; if (i > 0) refreshtop = scrolltop = 0; else { scrolltop = lines; refreshtop = scrollheight; } scrolling_copy_area(xw, scrolltop, scrollheight, -i); screen->topline = top; ScrollSelection(screen, i, True); xtermClear2(xw, OriginX(screen), OriginY(screen) + refreshtop * FontHeight(screen), (unsigned) Width(screen), (unsigned) (lines * FontHeight(screen))); ScrnRefresh(xw, refreshtop, 0, lines, MaxCols(screen), False); #if OPT_BLINK_CURS || OPT_BLINK_TEXT RestartBlinking(screen); #endif } } ScrollBarDrawThumb(screen->scrollWidget); }
/* * After writing text to the screen, resolve mismatch between the current * location and any attributes that would have been set by preceding locations. */ void Resolve_XMC(XtermWidget xw) { TScreen *screen = TScreenOf(xw); LineData *ld; Bool changed = False; Char start; Char my_attrs = CharOf(screen->xmc_attributes & XMC_FLAGS); int row = screen->cur_row; int col = screen->cur_col; /* Find the preceding cell. */ ld = getLineData(screen, row); if (ld->charData[col] != XMC_GLITCH) { if (col != 0) { col--; } else if (!screen->xmc_inline && row != 0) { ld = getLineData(screen, --row); col = LineMaxCol(screen, ld); } } start = (ld->attribs[col] & my_attrs); /* Now propagate the starting state until we reach a cell which holds * a glitch. */ for (;;) { if (col < LineMaxCol(screen, ld)) { col++; } else if (!screen->xmc_inline && row < screen->max_row) { col = 0; ld = getLineData(screen, ++row); } else break; if (ld->charData[col] == XMC_GLITCH) break; if ((ld->attribs[col] & my_attrs) != start) { ld->attribs[col] = CharOf(start | (ld->attribs[col] & ~my_attrs)); changed = True; } } TRACE(("XMC %s (%s:%d/%d) from %d,%d to %d,%d\n", changed ? "Ripple" : "Nochange", BtoS(xw->flags & my_attrs), my_attrs, start, screen->cur_row, screen->cur_col, row, col)); if (changed) { ScrnUpdate(xw, screen->cur_row, 0, row + 1 - screen->cur_row, MaxCols(screen), True); } }
CellData * newCellData(XtermWidget xw, Cardinal count) { CellData *result; TScreen *screen = TScreenOf(xw); initLineExtra(screen); result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); return result; }
/* * Tab to the previous stop, returning true if the cursor moved */ Bool TabToPrevStop(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int saved_column = screen->cur_col; set_cur_col(screen, TabPrev(xw->tabs, screen->cur_col)); return (screen->cur_col < saved_column); }
/* * Force a glitch on cursor movement when we're in standout mode and not at the * end of a line. */ void Jump_XMC(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (!screen->move_sgr_ok && screen->cur_col <= LineMaxCol(screen, getLineData(screen, screen->cur_row))) { Mark_XMC(xw, -1); } }
void ScrollBarOn(XtermWidget xw, Bool init) { TScreen *screen = TScreenOf(xw); if (screen->fullVwin.sb_info.width || IsIcon(screen)) return; TRACE(("ScrollBarOn(init %s)\n", BtoS(init))); if (init) { /* then create it only */ if (screen->scrollWidget == 0) { /* make it a dummy size and resize later */ screen->scrollWidget = CreateScrollBar(xw, -ScrollBarBorder(xw), -ScrollBarBorder(xw), 5); if (screen->scrollWidget == NULL) { Bell(xw, XkbBI_MinorError, 0); } } } else if (!screen->scrollWidget || !XtIsRealized((Widget) xw)) { Bell(xw, XkbBI_MinorError, 0); Bell(xw, XkbBI_MinorError, 0); } else { ResizeScrollBar(xw); xtermAddInput(screen->scrollWidget); XtRealizeWidget(screen->scrollWidget); TRACE_TRANS("scrollbar", screen->scrollWidget); screen->fullVwin.sb_info.rv_cached = False; screen->fullVwin.sb_info.width = (screen->scrollWidget->core.width + BorderWidth(screen->scrollWidget)); TRACE(("setting scrollbar width %d = %d + %d\n", screen->fullVwin.sb_info.width, screen->scrollWidget->core.width, BorderWidth(screen->scrollWidget))); ScrollBarDrawThumb(screen->scrollWidget); DoResizeScreen(xw); #ifdef SCROLLBAR_RIGHT updateRightScrollbar(xw); #endif XtMapWidget(screen->scrollWidget); update_scrollbar(); if (screen->visbuf) { xtermClear(xw); Redraw(); } } }
/* * Adjust the scrollbar position if we're asked to turn on scrollbars for the * first time (or after resizing) after the xterm is already running. That * makes the window grow after we've initially configured the scrollbar's * position. (There must be a better way). */ void updateRightScrollbar(XtermWidget xw) { TScreen *screen = TScreenOf(xw); if (xw->misc.useRight && screen->fullVwin.fullwidth < xw->core.width) XtVaSetValues(screen->scrollWidget, XtNx, screen->fullVwin.fullwidth - BorderWidth(screen->scrollWidget), (XtPointer) 0); }
int CursorRow(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int result = screen->cur_row; if (xw->flags & ORIGIN) { result -= screen->top_marg; if (result < 0) result = 0; } return result; }
/* * Return col/row values which can be passed to CursorSet() preserving the * current col/row, e.g., accounting for DECOM. */ int CursorCol(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int result = screen->cur_col; if (xw->flags & ORIGIN) { result -= ScrnLeftMargin(xw); if (result < 0) result = 0; } return result; }
static void repaint_line(XtermWidget xw, unsigned newChrSet) { TScreen *screen = TScreenOf(xw); LineData *ld; int curcol = screen->cur_col; int currow = screen->cur_row; int width = MaxCols(screen); unsigned len = (unsigned) width; assert(width > 0); /* * Ignore repetition. */ if (!IsLeftRightMode(xw) && (ld = getLineData(screen, currow)) != 0) { unsigned oldChrSet = GetLineDblCS(ld); if (oldChrSet != newChrSet) { TRACE(("repaint_line(%2d,%2d) (%s -> %s)\n", currow, screen->cur_col, visibleDblChrset(oldChrSet), visibleDblChrset(newChrSet))); HideCursor(); /* If switching from single-width, keep the cursor in the visible part * of the line. */ if (CSET_DOUBLE(newChrSet)) { width /= 2; if (curcol > width) curcol = width; } /* * ScrnRefresh won't paint blanks for us if we're switching between a * single-size and double-size font. So we paint our own. */ ClearCurBackground(xw, currow, 0, 1, len, (unsigned) LineFontWidth(screen, ld)); SetLineDblCS(ld, newChrSet); set_cur_col(screen, 0); ScrnUpdate(xw, currow, 0, 1, (int) len, True); set_cur_col(screen, curcol); } } }
/* * When resizing the window, if we're showing the alternate screen, we still * have to adjust the saved cursor from the normal screen to account for * shifting of the saved-line region in/out of the viewable window. */ void AdjustSavedCursor(XtermWidget xw, int adjust) { TScreen *screen = TScreenOf(xw); if (screen->whichBuf) { SavedCursor *sc = &screen->sc[0]; if (adjust > 0) { TRACE(("AdjustSavedCursor %d -> %d\n", sc->row, sc->row - adjust)); sc->row += adjust; } } }
static long AmountToScroll(Widget w, String *params, Cardinal nparams) { long result = 0; XtermWidget xw; if ((xw = getXtermWidget(w)) != 0) { TScreen *screen = TScreenOf(xw); if (nparams <= 2 || screen->send_mouse_pos == MOUSE_OFF) { result = params_to_pixels(screen, params, nparams); } } return result; }
/* * Returns the appropriate cache pointer. */ static CgsCache * myCache(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId) { CgsCache *result = 0; if ((int) cgsId >= 0 && cgsId < gcMAX) { #ifdef NO_ACTIVE_ICON (void) xw; (void) cgsWin; #else if (cgsWin == &(TScreenOf(xw)->iconVwin)) result = allocCache(&(TScreenOf(xw)->icon_cgs_cache)); else #endif result = allocCache(&(TScreenOf(xw)->main_cgs_cache)); result += cgsId; if (result->data == 0) { result->data = result->list; } } return result; }
/* * returns the column of the next tabstop * (or MAX_TABS - 1 if there are no more). * A tabstop at col is ignored. */ static int TabNext(XtermWidget xw, Tabs tabs, int col) { TScreen *screen = TScreenOf(xw); if (screen->curses && screen->do_wrap && (xw->flags & WRAPAROUND)) { xtermIndex(xw, 1); set_cur_col(screen, 0); col = 0; screen->do_wrap = False; } for (++col; col < MAX_TABS; ++col) if (TST_TAB(tabs, col)) return (col); return (MAX_TABS - 1); }
/* * Tab to the previous stop, returning true if the cursor moved */ Bool TabToPrevStop(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int saved_column = screen->cur_col; int next_column = TabPrev(xw->tabs, screen->cur_col); if (xw->flags & ORIGIN) { int left = ScrnLeftMargin(xw); if (next_column < left) next_column = left; } set_cur_col(screen, next_column); return (screen->cur_col < saved_column); }
void ScrollBarReverseVideo(Widget scrollWidget) { XtermWidget xw = getXtermWidget(scrollWidget); if (xw != 0) { SbInfo *sb = &(TScreenOf(xw)->fullVwin.sb_info); Arg args[4]; Cardinal nargs = XtNumber(args); /* * Remember the scrollbar's original colors. */ if (sb->rv_cached == False) { XtSetArg(args[0], XtNbackground, &(sb->bg)); XtSetArg(args[1], XtNforeground, &(sb->fg)); XtSetArg(args[2], XtNborderColor, &(sb->bdr)); XtSetArg(args[3], XtNborderPixmap, &(sb->bdpix)); XtGetValues(scrollWidget, args, nargs); sb->rv_cached = True; sb->rv_active = 0; } sb->rv_active = !(sb->rv_active); if (sb->rv_active) { XtSetArg(args[0], XtNbackground, sb->fg); XtSetArg(args[1], XtNforeground, sb->bg); } else { XtSetArg(args[0], XtNbackground, sb->bg); XtSetArg(args[1], XtNforeground, sb->fg); } nargs = 2; /* don't set border_pixmap */ if (sb->bdpix == XtUnspecifiedPixmap) { /* if not pixmap then pixel */ if (sb->rv_active) { /* keep border visible */ XtSetArg(args[2], XtNborderColor, args[1].value); } else { XtSetArg(args[2], XtNborderColor, sb->bdr); } nargs = 3; } XtSetValues(scrollWidget, args, nargs); } }