104b94745Smrg/* $XTermId: tabs.c,v 1.47 2019/11/13 23:19:01 tom Exp $ */ 2d522f475Smrg 3d522f475Smrg/* 4f2e35a3aSmrg * Copyright 2000-2018,2019 by Thomas E. Dickey 5d522f475Smrg * 6d522f475Smrg * All Rights Reserved 7d522f475Smrg * 8d522f475Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9d522f475Smrg * copy of this software and associated documentation files (the 10d522f475Smrg * "Software"), to deal in the Software without restriction, including 11d522f475Smrg * without limitation the rights to use, copy, modify, merge, publish, 12d522f475Smrg * distribute, sublicense, and/or sell copies of the Software, and to 13d522f475Smrg * permit persons to whom the Software is furnished to do so, subject to 14d522f475Smrg * the following conditions: 15d522f475Smrg * 16d522f475Smrg * The above copyright notice and this permission notice shall be included 17d522f475Smrg * in all copies or substantial portions of the Software. 18d522f475Smrg * 19d522f475Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20d522f475Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21d522f475Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22d522f475Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23d522f475Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24d522f475Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25d522f475Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26d522f475Smrg * 27d522f475Smrg * Except as contained in this notice, the name(s) of the above copyright 28d522f475Smrg * holders shall not be used in advertising or otherwise to promote the 29d522f475Smrg * sale, use or other dealings in this Software without prior written 30d522f475Smrg * authorization. 31d522f475Smrg * 320bd37d32Smrg * 33d522f475Smrg * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 34d522f475Smrg * 35d522f475Smrg * All Rights Reserved 36d522f475Smrg * 37d522f475Smrg * Permission to use, copy, modify, and distribute this software and its 38d522f475Smrg * documentation for any purpose and without fee is hereby granted, 39d522f475Smrg * provided that the above copyright notice appear in all copies and that 40d522f475Smrg * both that copyright notice and this permission notice appear in 41d522f475Smrg * supporting documentation, and that the name of Digital Equipment 42d522f475Smrg * Corporation not be used in advertising or publicity pertaining to 43d522f475Smrg * distribution of the software without specific, written prior permission. 44d522f475Smrg * 45d522f475Smrg * 46d522f475Smrg * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 47d522f475Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 48d522f475Smrg * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 49d522f475Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 50d522f475Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 51d522f475Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 52d522f475Smrg * SOFTWARE. 53d522f475Smrg */ 54d522f475Smrg 55d522f475Smrg/* tabs.c */ 56d522f475Smrg 57d522f475Smrg#include <xterm.h> 58d522f475Smrg#include <data.h> 59d522f475Smrg 60d522f475Smrg#define TAB_INDEX(n) ((n) >> TAB_BITS_SHIFT) 61f2e35a3aSmrg#define TAB_MASK(n) (1U << ((n) & (TAB_BITS_WIDTH-1))) 62d522f475Smrg 6320d2c4d2Smrg#define SET_TAB(tabs,n) UIntSet(tabs[TAB_INDEX(n)], TAB_MASK(n)) 6420d2c4d2Smrg#define CLR_TAB(tabs,n) UIntClr(tabs[TAB_INDEX(n)], TAB_MASK(n)) 6520d2c4d2Smrg#define TST_TAB(tabs,n) (tabs[TAB_INDEX(n)] & (unsigned) TAB_MASK(n)) 66d522f475Smrg 67d522f475Smrg/* 68d522f475Smrg * places tabstops at only every 8 columns 69d522f475Smrg */ 70d522f475Smrgvoid 71d522f475SmrgTabReset(Tabs tabs) 72d522f475Smrg{ 73d522f475Smrg int i; 74d522f475Smrg 75d522f475Smrg TabZonk(tabs); 76d522f475Smrg 77d522f475Smrg for (i = 0; i < MAX_TABS; i += 8) 78d522f475Smrg TabSet(tabs, i); 79d522f475Smrg} 80d522f475Smrg 81d522f475Smrg/* 82d522f475Smrg * places a tabstop at col 83d522f475Smrg */ 84d522f475Smrgvoid 85d522f475SmrgTabSet(Tabs tabs, int col) 86d522f475Smrg{ 87f2e35a3aSmrg if (OkTAB(col)) { 88d522f475Smrg SET_TAB(tabs, col); 89d522f475Smrg } 90d522f475Smrg} 91d522f475Smrg 92d522f475Smrg/* 93d522f475Smrg * clears a tabstop at col 94d522f475Smrg */ 95d522f475Smrgvoid 96d522f475SmrgTabClear(Tabs tabs, int col) 97d522f475Smrg{ 98f2e35a3aSmrg if (OkTAB(col)) { 99d522f475Smrg CLR_TAB(tabs, col); 100d522f475Smrg } 101d522f475Smrg} 102d522f475Smrg 103d522f475Smrg/* 104d522f475Smrg * returns the column of the next tabstop 105d522f475Smrg * (or MAX_TABS - 1 if there are no more). 106d522f475Smrg * A tabstop at col is ignored. 107d522f475Smrg */ 108d522f475Smrgstatic int 109d522f475SmrgTabNext(XtermWidget xw, Tabs tabs, int col) 110d522f475Smrg{ 11120d2c4d2Smrg TScreen *screen = TScreenOf(xw); 112d522f475Smrg 113d522f475Smrg if (screen->curses && screen->do_wrap && (xw->flags & WRAPAROUND)) { 114d522f475Smrg xtermIndex(xw, 1); 115d522f475Smrg set_cur_col(screen, 0); 1162eaa94a1Schristos col = 0; 1170bd37d32Smrg ResetWrap(screen); 118d522f475Smrg } 119d522f475Smrg for (++col; col < MAX_TABS; ++col) 120d522f475Smrg if (TST_TAB(tabs, col)) 121d522f475Smrg return (col); 122d522f475Smrg 123d522f475Smrg return (MAX_TABS - 1); 124d522f475Smrg} 125d522f475Smrg 126d522f475Smrg/* 127d522f475Smrg * returns the column of the previous tabstop 128d522f475Smrg * (or 0 if there are no more). 129d522f475Smrg * A tabstop at col is ignored. 130d522f475Smrg */ 131d522f475Smrgstatic int 132d522f475SmrgTabPrev(Tabs tabs, int col) 133d522f475Smrg{ 134d522f475Smrg for (--col; col >= 0; --col) 1352eaa94a1Schristos if ((col < MAX_TABS) && TST_TAB(tabs, col)) 136d522f475Smrg return (col); 137d522f475Smrg 138d522f475Smrg return (0); 139d522f475Smrg} 140d522f475Smrg 141d522f475Smrg/* 142d522f475Smrg * Tab to the next stop, returning true if the cursor moved 143d522f475Smrg */ 144d522f475SmrgBool 145d522f475SmrgTabToNextStop(XtermWidget xw) 146d522f475Smrg{ 14720d2c4d2Smrg TScreen *screen = TScreenOf(xw); 148d522f475Smrg int saved_column = screen->cur_col; 149d522f475Smrg int next = TabNext(xw, xw->tabs, screen->cur_col); 150956cc18dSsnj int max = LineMaxCol(screen, getLineData(screen, screen->cur_row)); 151d522f475Smrg 1520bd37d32Smrg if (IsLeftRightMode(xw)) 1530bd37d32Smrg max = TScreenOf(xw)->rgt_marg; 154d522f475Smrg if (next > max) 155d522f475Smrg next = max; 156d522f475Smrg set_cur_col(screen, next); 157d522f475Smrg 158d522f475Smrg return (screen->cur_col > saved_column); 159d522f475Smrg} 160d522f475Smrg 161d522f475Smrg/* 162d522f475Smrg * Tab to the previous stop, returning true if the cursor moved 163d522f475Smrg */ 164d522f475SmrgBool 165d522f475SmrgTabToPrevStop(XtermWidget xw) 166d522f475Smrg{ 16720d2c4d2Smrg TScreen *screen = TScreenOf(xw); 168d522f475Smrg int saved_column = screen->cur_col; 1690bd37d32Smrg int next_column = TabPrev(xw->tabs, screen->cur_col); 1700bd37d32Smrg 1710bd37d32Smrg if (xw->flags & ORIGIN) { 1720bd37d32Smrg int left = ScrnLeftMargin(xw); 1730bd37d32Smrg if (next_column < left) 1740bd37d32Smrg next_column = left; 1750bd37d32Smrg } 176d522f475Smrg 1770bd37d32Smrg set_cur_col(screen, next_column); 178d522f475Smrg 179d522f475Smrg return (screen->cur_col < saved_column); 180d522f475Smrg} 181d522f475Smrg 182d522f475Smrg/* 183d522f475Smrg * clears all tabs 184d522f475Smrg */ 185d522f475Smrgvoid 186d522f475SmrgTabZonk(Tabs tabs) 187d522f475Smrg{ 188d522f475Smrg memset(tabs, 0, sizeof(*tabs) * TAB_ARRAY_SIZE); 189d522f475Smrg} 190f2e35a3aSmrg 191f2e35a3aSmrg/* 192f2e35a3aSmrg * Check if a tab is set for the given column 193f2e35a3aSmrg */ 194f2e35a3aSmrgBool 195f2e35a3aSmrgTabIsSet(Tabs tabs, int col) 196f2e35a3aSmrg{ 197f2e35a3aSmrg return TST_TAB(tabs, col) ? True : False; 198f2e35a3aSmrg} 199