1 /*
2  * screen.c
3  *
4  * All rights reserved. Copyright (C) 1996 by NARITA Tomio.
5  * $Id: screen.c,v 1.4 2004/01/05 07:36:02 nrt Exp $
6  */
7 /*
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 #include <stdlib.h>
24 
25 #include <import.h>
26 #include <position.h>
27 #include <fetch.h>
28 #include <console.h>
29 #include <begin.h>
30 #include <screen.h>
31 
32 #define ScreenSetBoth( f, seg, blk, off, phy )				\
33 {									\
34   PositionSet( (f)->screen.top, (seg), (blk), (off), (phy) );		\
35   PositionSet( (f)->screen.bot, (seg), (blk), (off), (phy) );		\
36 }
37 
38 #define ScreenDecTop( f )						\
39   PositionDec( (f), (f)->screen.top.seg, (f)->screen.top.blk, (f)->screen.top.off, (f)->screen.top.phy )
40 
41 #define ScreenDecBot( f )						\
42   PositionDec( (f), (f)->screen.bot.seg, (f)->screen.bot.blk, (f)->screen.bot.off, (f)->screen.bot.phy )
43 
44 #define ScreenIncTop( f )						\
45   PositionInc( (f), (f)->screen.top.seg, (f)->screen.top.blk, (f)->screen.top.off, (f)->screen.top.phy )
46 
47 #define ScreenIncBot( f )						\
48   PositionInc( (f), (f)->screen.bot.seg, (f)->screen.bot.blk, (f)->screen.bot.off, (f)->screen.bot.phy )
49 
50 /*
51  * $B2hLL$N0LCV$N@)8f(B
52  * $BA0$N%Z!<%8(B, $B<!$N%Z!<%8(B, $BO@M}9T$N2?9TL\(B, $BJ*M}9T$N2?9TL\(B, $B$H$$$C$?CM$G(B
53  * $B%Z!<%8$r%a%b%j$X%m!<%I$9$k(B.
54  */
55 
ScreenPrev(file_t * f,int physical)56 public unsigned int ScreenPrev( file_t *f, int physical )
57 {
58   int i;
59 
60   for( i = 0 ; i < physical ; i++ ){
61     ScreenDecTop( f );
62     f->screen.lines++;
63     if( f->screen.lines > f->height ){
64       ScreenDecBot( f );
65       f->screen.lines--;
66     }
67   }
68 
69   if( i < physical )
70     f->top = TRUE;
71   else
72     f->top = FALSE;
73 
74   if( f->screen.lines < f->height )
75     f->bottom = TRUE;
76   else
77     f->bottom = FALSE;
78 
79   f->find.pos = f->screen.top;
80 
81   return i;
82 }
83 
ScreenNext(file_t * f,int physical)84 public unsigned int ScreenNext( file_t *f, int physical )
85 {
86   int i;
87 
88   for( i = 0 ; i < physical ; i++ ){
89     ScreenIncBot( f );
90     f->screen.lines++;
91     if( f->screen.lines > f->height ){
92       ScreenIncTop( f );
93       f->screen.lines--;
94     }
95   }
96 
97   if( i < physical ){
98     f->top = FALSE;
99     f->bottom = TRUE;
100   } else {
101     f->top = FALSE;
102     f->bottom = FALSE;
103   }
104 
105   f->find.pos = f->screen.top;
106 
107   return i;
108 }
109 
ScreenBot(file_t * f)110 public boolean_t ScreenBot( file_t *f )
111 {
112   int i;
113   unsigned int seg;
114   int blk, off, phy;
115 
116   if( FALSE == f->done ){
117     ConsoleEnableInterrupt();
118     FileStretch( f, LV_PAGE_SIZE * SLOT_SIZE * FRAME_SIZE - 1 );
119     ConsoleDisableInterrupt();
120   }
121 
122   if( FALSE == FetchLine( f, f->lastSegment - 1, 0 ) ){
123     /*
124      * null file
125      */
126     f->top = FALSE;
127     f->bottom = TRUE;
128     f->screen.lines = 0;
129     ScreenSetBoth( f, 0, 0, 0, 0 );
130     f->find.pos = f->screen.top;
131     return FALSE;
132   }
133 
134   seg = f->lastSegment - 1;
135   blk = Block( seg );
136   off = f->page[ blk ].lines - 1;
137   phy = f->page[ blk ].line[ off ].heads - 1;
138 
139   ScreenSetBoth( f, seg, blk, off, phy );
140 
141   for( i = 0 ; i < ( f->height - 1 ) ; i++ )
142     ScreenDecTop( f );
143 
144   f->top = FALSE;
145   f->bottom = TRUE;
146   f->screen.lines = i + 1;
147   f->find.pos = f->screen.top;
148 
149   if( TRUE == kb_interrupted )
150     return FALSE;
151 
152   return TRUE;
153 }
154 
ScreenTop(file_t * f,unsigned int logical)155 public boolean_t ScreenTop( file_t *f, unsigned int logical )
156 {
157   int i;
158   unsigned int seg;
159   int blk, off, phy;
160   boolean_t res;
161 
162   if( logical > 0 )
163     logical--;
164 
165   ConsoleEnableInterrupt();
166   res = FetchLine( f, Segment( logical ), Offset( logical ) );
167   ConsoleDisableInterrupt();
168 
169   if( FALSE == res ){
170     return ScreenBot( f );
171   }
172 
173   seg = Segment( logical );
174   blk = Block( seg );
175   off = Offset( logical );
176   phy = 0;
177 
178   ScreenSetBoth( f, seg, blk, off, phy );
179 
180   for( i = 0 ; i < ( f->height - 1 ) ; i++ )
181     ScreenIncBot( f );
182 
183   if( 0 == logical )
184     f->top = TRUE;
185   else
186     f->top = FALSE;
187 
188   if( i < f->height - 1 )
189     f->bottom = TRUE;
190   else
191     f->bottom = FALSE;
192 
193   f->screen.lines = i + 1;
194   f->find.pos = f->screen.top;
195 
196   if( TRUE == kb_interrupted )
197     return FALSE;
198 
199   return TRUE;
200 }
201 
ScreenTopPhysical(file_t * f,position_t * pos)202 public boolean_t ScreenTopPhysical( file_t *f, position_t *pos )
203 {
204   int i;
205 
206   if( FALSE == FetchLine( f, pos->seg, pos->off ) )
207     return ScreenBot( f );
208 
209   f->screen.top.seg = f->screen.bot.seg = pos->seg;
210   f->screen.top.blk = f->screen.bot.blk = pos->blk;
211   f->screen.top.off = f->screen.bot.off = pos->off;
212   f->screen.top.phy = f->screen.bot.phy = pos->phy;
213 
214   for( i = 0 ; i < ( f->height - 1 ) ; i++ )
215     ScreenIncBot( f );
216 
217   if( f->screen.top.seg == 0 && f->screen.top.off == 0 && f->screen.top.phy == 0 )
218     f->top = TRUE;
219   else
220     f->top = FALSE;
221 
222   if( i < f->height - 1 )
223     f->bottom = TRUE;
224   else
225     f->bottom = FALSE;
226 
227   f->screen.lines = i + 1;
228   f->find.pos = f->screen.top;
229 
230   return TRUE;
231 }
232 
233 /*
234  * $B2hLL%5%$%:$r<hF@$7$F(B file_t $B9=B$BN$X3JG<$9$k(B.
235  * $B$=$N2hLL$N%j%5%$%:$KJ*M}9T4IM}$r@09g$5$;$k$?$a$K=>Mh$N@hF,9T$r(B
236  * $BO@M}9T$G;XDj$7(B, $B%U%!%$%k$r%a%b%j$X:F%m!<%I$9$k(B.
237  *
238  * $B"((B $B%Z!<%8!&%-%c%C%7%e$r=i4|2=$7$F$+$i8F$V$3$H(B.
239  */
240 
ScreenRefresh(file_t * f)241 public void ScreenRefresh( file_t *f )
242 {
243   unsigned int logical;
244 
245   ConsoleGetWindowSize();
246 
247   if( HEIGHT > LV_PAGE_SIZE * ( BLOCK_SIZE - 1 ) )
248     HEIGHT = LV_PAGE_SIZE * ( BLOCK_SIZE - 1 );
249 
250   f->width = WIDTH;
251   f->height = HEIGHT - 1;
252 
253   logical = 1 + f->screen.top.seg * LV_PAGE_SIZE + f->screen.top.off;
254   ScreenTop( f, logical );
255 }
256