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