1 /* PDCurses */
2 
3 #include <curspriv.h>
4 
5 /*man-start**************************************************************
6 
7 touch
8 -----
9 
10 ### Synopsis
11 
12     int touchwin(WINDOW *win);
13     int touchline(WINDOW *win, int start, int count);
14     int untouchwin(WINDOW *win);
15     int wtouchln(WINDOW *win, int y, int n, int changed);
16     bool is_linetouched(WINDOW *win, int line);
17     bool is_wintouched(WINDOW *win);
18 
19     int touchoverlap(const WINDOW *win1, WINDOW *win2);
20 
21 ### Description
22 
23    touchwin() and touchline() throw away all information about which
24    parts of the window have been touched, pretending that the entire
25    window has been drawn on. This is sometimes necessary when using
26    overlapping windows, since a change to one window will affect the
27    other window, but the records of which lines have been changed in the
28    other window will not reflect the change.
29 
30    untouchwin() marks all lines in the window as unchanged since the
31    last call to wrefresh().
32 
33    wtouchln() makes n lines in the window, starting at line y, look as
34    if they have (changed == 1) or have not (changed == 0) been changed
35    since the last call to wrefresh().
36 
37    is_linetouched() returns TRUE if the specified line in the specified
38    window has been changed since the last call to wrefresh().
39 
40    is_wintouched() returns TRUE if the specified window has been changed
41    since the last call to wrefresh().
42 
43    touchoverlap(win1, win2) marks the portion of win2 which overlaps
44    with win1 as modified.
45 
46 ### Return Value
47 
48    All functions return OK on success and ERR on error except
49    is_wintouched() and is_linetouched().
50 
51 ### Portability
52                              X/Open  ncurses  NetBSD
53     touchwin                    Y       Y       Y
54     touchline                   Y       Y       Y
55     untouchwin                  Y       Y       Y
56     wtouchln                    Y       Y       Y
57     is_linetouched              Y       Y       Y
58     is_wintouched               Y       Y       Y
59     touchoverlap                -       -       Y
60 
61 **man-end****************************************************************/
62 
touchwin(WINDOW * win)63 int touchwin(WINDOW *win)
64 {
65     int i;
66 
67     PDC_LOG(("touchwin() - called: Win=%x\n", win));
68 
69     if (!win)
70         return ERR;
71 
72     for (i = 0; i < win->_maxy; i++)
73     {
74         win->_firstch[i] = 0;
75         win->_lastch[i] = win->_maxx - 1;
76     }
77 
78     return OK;
79 }
80 
touchline(WINDOW * win,int start,int count)81 int touchline(WINDOW *win, int start, int count)
82 {
83     int i;
84 
85     PDC_LOG(("touchline() - called: win=%p start %d count %d\n",
86              win, start, count));
87 
88     if (!win || start > win->_maxy || start + count > win->_maxy)
89         return ERR;
90 
91     for (i = start; i < start + count; i++)
92     {
93         win->_firstch[i] = 0;
94         win->_lastch[i] = win->_maxx - 1;
95     }
96 
97     return OK;
98 }
99 
untouchwin(WINDOW * win)100 int untouchwin(WINDOW *win)
101 {
102     int i;
103 
104     PDC_LOG(("untouchwin() - called: win=%p", win));
105 
106     if (!win)
107         return ERR;
108 
109     for (i = 0; i < win->_maxy; i++)
110     {
111         win->_firstch[i] = _NO_CHANGE;
112         win->_lastch[i] = _NO_CHANGE;
113     }
114 
115     return OK;
116 }
117 
wtouchln(WINDOW * win,int y,int n,int changed)118 int wtouchln(WINDOW *win, int y, int n, int changed)
119 {
120     int i;
121 
122     PDC_LOG(("wtouchln() - called: win=%p y=%d n=%d changed=%d\n",
123              win, y, n, changed));
124 
125     if (!win || y > win->_maxy || y + n > win->_maxy)
126         return ERR;
127 
128     for (i = y; i < y + n; i++)
129     {
130         if (changed)
131         {
132             win->_firstch[i] = 0;
133             win->_lastch[i] = win->_maxx - 1;
134         }
135         else
136         {
137             win->_firstch[i] = _NO_CHANGE;
138             win->_lastch[i] = _NO_CHANGE;
139         }
140     }
141 
142     return OK;
143 }
144 
is_linetouched(WINDOW * win,int line)145 bool is_linetouched(WINDOW *win, int line)
146 {
147     PDC_LOG(("is_linetouched() - called: win=%p line=%d\n", win, line));
148 
149     if (!win || line > win->_maxy || line < 0)
150         return FALSE;
151 
152     return (win->_firstch[line] != _NO_CHANGE) ? TRUE : FALSE;
153 }
154 
is_wintouched(WINDOW * win)155 bool is_wintouched(WINDOW *win)
156 {
157     int i;
158 
159     PDC_LOG(("is_wintouched() - called: win=%p\n", win));
160 
161     if (win)
162         for (i = 0; i < win->_maxy; i++)
163             if (win->_firstch[i] != _NO_CHANGE)
164                 return TRUE;
165 
166     return FALSE;
167 }
168 
touchoverlap(const WINDOW * win1,WINDOW * win2)169 int touchoverlap(const WINDOW *win1, WINDOW *win2)
170 {
171     int y, endy, endx, starty, startx;
172 
173     PDC_LOG(("touchoverlap() - called: win1=%p win2=%p\n", win1, win2));
174 
175     if (!win1 || !win2)
176         return ERR;
177 
178     starty = max(win1->_begy, win2->_begy);
179     startx = max(win1->_begx, win2->_begx);
180     endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begy);
181     endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx);
182 
183     if (starty >= endy || startx >= endx)
184         return OK;
185 
186     starty -= win2->_begy;
187     startx -= win2->_begx;
188     endy -= win2->_begy;
189     endx -= win2->_begx;
190     endx -= 1;
191 
192     for (y = starty; y < endy; y++)
193     {
194         win2->_firstch[y] = startx;
195         win2->_lastch[y] = endx;
196     }
197 
198     return OK;
199 }
200