Esempio n. 1
0
static int find_top_to_recenter (SLscroll_Window_Type *win)
{
   unsigned int nrows;
   unsigned int hidden_mask;
   SLscroll_Type *prev, *last_prev, *cline;

   nrows = win->nrows;
   cline = win->current_line;
   hidden_mask = win->hidden_mask;

   nrows = nrows / 2;

   last_prev = prev = cline;

   while (nrows && (prev != NULL))
     {
	nrows--;
	last_prev = prev;
	do
	  {
	     prev = prev->prev;
	  }
	while (hidden_mask
	       && (prev != NULL)
	       && (prev->flags & hidden_mask));
     }

   if (prev == NULL) prev = last_prev;

   win->top_window_line = prev;
   find_window_bottom (win);

   return 0;
}
Esempio n. 2
0
int SLscroll_pageup (SLscroll_Window_Type *win)
{
   SLscroll_Type *l, *top;
   unsigned int nrows, hidden_mask;
   unsigned int n;

   if (win == NULL)
     return -1;

   (void) SLscroll_find_top (win);

   nrows = win->nrows;

   if ((NULL != (top = win->top_window_line))
       && (nrows > 2))
     {
	n = 0;
	hidden_mask = win->hidden_mask;
	l = win->current_line;
	while ((l != NULL) && (l != top))
	  {
	     l = l->prev;
	     if ((hidden_mask == 0)
		 || ((l != NULL) && (0 == (l->flags & hidden_mask))))
	       n++;
	  }

	if (l != NULL)
	  {
	     unsigned int save_line_num;
	     int ret = 0;

	     win->current_line = l;
	     win->line_num -= n;

	     /* Compute a new top/bottom header */
	     save_line_num = win->line_num;

	     if ((0 == SLscroll_prev_n (win, nrows - 1))
		 && (n == 0))
	       ret = -1;

	     win->top_window_line = win->current_line;
	     win->current_line = l;
	     win->line_num = save_line_num;

	     find_window_bottom (win);
	     return ret;
	  }
     }

   if (nrows < 2) nrows++;
   if (0 == SLscroll_prev_n (win, nrows - 1))
     return -1;
   return 0;
}
Esempio n. 3
0
int SLscroll_pagedown (SLscroll_Window_Type *win)
{
   SLscroll_Type *l, *bot;
   unsigned int nrows, hidden_mask;
   unsigned int n;

   if (win == NULL)
     return -1;

   (void) SLscroll_find_top (win);

   nrows = win->nrows;

   if ((NULL != (bot = win->bot_window_line))
       && (nrows > 2))
     {
	n = 0;
	hidden_mask = win->hidden_mask;
	l = win->current_line;
	while ((l != NULL) && (l != bot))
	  {
	     l = l->next;
	     if ((hidden_mask == 0)
		 || ((l != NULL) && (0 == (l->flags & hidden_mask))))
	       n++;
	  }

	if (l != NULL)
	  {
	     win->current_line = l;
	     win->top_window_line = l;
	     win->line_num += n;

	     find_window_bottom (win);

	     if (n || (bot != win->bot_window_line))
	       return 0;

	     return -1;
	  }
     }

   if (nrows < 2) nrows++;
   if (0 == SLscroll_next_n (win, nrows - 1))
     return -1;
   return 0;
}
Esempio n. 4
0
int SLscroll_find_top (SLscroll_Window_Type *win)
{
   unsigned int i;
   SLscroll_Type *cline, *prev, *next;
   SLscroll_Type *top_window_line;
   unsigned int nrows;
   unsigned int hidden_mask;
   int scroll_mode;
   unsigned int border;

   cline = win->current_line;
   nrows = win->nrows;
   scroll_mode = win->cannot_scroll;
   border = win->border;
   if (scroll_mode == 2)
     border = 0;

   if ((cline == NULL) || (nrows <= 1))
     {
	win->top_window_line = cline;
	find_window_bottom (win);
	return 0;
     }

   hidden_mask = win->hidden_mask;

   /* Note: top_window_line might be a bogus pointer.  This means that I cannot
    * access it unless it really corresponds to a pointer in the buffer.
    */
   top_window_line = win->top_window_line;

   if (top_window_line == NULL)
     return find_top_to_recenter (win);

   /* Chances are that the current line is visible in the window.  This means
    * that the top window line should be above it.
    */
   prev = cline;

   i = 0;

   while ((i < nrows) && (prev != NULL))
     {
	if (prev == top_window_line)
	  {
	     SLscroll_Type *twl = top_window_line;
	     int dir = 0;

	     if (i < border) dir = -1; else if (i + border >= nrows) dir = 1;

	     if (dir) while (border)
	       {
		  if (dir < 0) twl = twl->prev;
		  else twl = twl->next;

		  if (twl == NULL)
		    {
		       twl = top_window_line;
		       break;
		    }
		  if ((hidden_mask == 0)
		      || (0 == (twl->flags & hidden_mask)))
		    border--;
	       }

	     win->top_window_line = twl;
	     find_window_bottom (win);
	     return 0;
	  }

	do
	  {
	     prev = prev->prev;
	  }
	while (hidden_mask
	       && (prev != NULL)
	       && (prev->flags & hidden_mask));
	i++;
     }

   /* Now check the borders of the window.  Perhaps the current line lies
    * outsider the border by a line.  Only do this if terminal can scroll.
    */

   if (scroll_mode == 1)
     return find_top_to_recenter (win);
   else if (scroll_mode == -1)
     scroll_mode = 0;

   next = cline->next;
   while (hidden_mask
	  && (next != NULL)
	  && (next->flags & hidden_mask))
     next = next->next;

   if ((next != NULL)
       && (next == top_window_line))
     {
	/* The current line is one line above the window.  This means user
	 * has moved up past the top of the window.  If scroll_mode is set
	 * to scroll by pages, we need to do a page up.
	 */

	win->top_window_line = cline;
	find_window_bottom (win);

	if (scroll_mode) return SLscroll_pageup (win);

	return 0;
     }

   prev = cline->prev;

   while (hidden_mask
	  && (prev != NULL)
	  && (prev->flags & hidden_mask))
     prev = prev->prev;

   if ((prev == NULL)
       || (prev != win->bot_window_line))
     return find_top_to_recenter (win);

   /* It looks like cline is below window by one line.  See what line should
    * be at top to scroll it into view.  Only do this unless we are scrolling
    * by pages.
    */
   if (scroll_mode)
     {
	win->top_window_line = cline;
	find_window_bottom (win);
	return 0;
     }

   i = 2;
   while ((i < nrows) && (prev != NULL))
     {
	do
	  {
	     prev = prev->prev;
	  }
	while (hidden_mask
	       && (prev != NULL)
	       && (prev->flags & hidden_mask));
	i++;
     }

   if (prev != NULL)
     {
	win->top_window_line = prev;
	find_window_bottom (win);
	return 0;
     }

   return find_top_to_recenter (win);
}