Esempio n. 1
0
/*
 * Ask user for a window definition.
 */
static bool
getwindow(WINDOW *parent, PAIR * ul, PAIR * lr)
{
    int min_col = (parent == stdscr) ? COL_MIN : 0;
    int max_col = (parent == stdscr) ? COL_MAX : getmaxx(parent);
    int min_line = (parent == stdscr) ? LINE_MIN : 0;
    int max_line = (parent == stdscr) ? LINE_MAX : getmaxy(parent);
    PAIR *tmp;
    bool result = FALSE;

    head_line("Use arrows to move cursor, anything else to mark corner 1");
    if ((tmp = selectcell(parent, min_line, min_col, max_line, max_col)) != 0) {
	*ul = *tmp;
	mvwaddch(parent, ul->y, ul->x, '*');

	head_line("Use arrows to move cursor, anything else to mark corner 2");
	if ((tmp = selectcell(parent, ul->y, ul->x, max_line, max_col)) != 0) {
	    *lr = *tmp;
	    mvwaddch(parent, lr->y, lr->x, '*');
	    wmove(parent, lr->y, lr->x);
	    wsyncdown(parent);
	    wrefresh(parent);
	    result = (lr->y != ul->y && lr->x != ul->x);
	}
    }
    head_line("done");
    return result;
}
Esempio n. 2
0
void wsyncdown(WINDOW *win)
/* mark changed every cell in win that is changed in any of its ancestors */
/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...)           */
{
  if (win && win->_parent)
    {
      WINDOW *pp = win->_parent;
      int y;

      /* This recursion guarantees, that the changes are propagated down-
	 wards from the root to our direct parent. */
      wsyncdown(pp);

      /* and now we only have to propagate the changes from our direct
	 parent, if there are any. */
      assert((win->_pary <= pp->_maxy) &&
	     ((win->_pary + win->_maxy) <= pp->_maxy));

      for (y = 0; y <= win->_maxy; y++)
	{
	  if (pp->_line[win->_pary + y].firstchar >= 0) /* parent changed */
	    {
	      /* left and right character in child coordinates */
	      int left  = pp->_line[win->_pary + y].firstchar - win->_parx;
	      int right = pp->_line[win->_pary + y].lastchar  - win->_parx;
	      /* The change maybe outside the childs range */
	      if (left<0)
		left = 0;
	      if (right > win->_maxx)
		right = win->_maxx;
	      if (win->_line[y].firstchar == _NOCHANGE)
		{
		  win->_line[y].firstchar = left;
		  win->_line[y].lastchar  = right;
		}
	      else
		{
		  if (left < win->_line[y].firstchar)
		    win->_line[y].firstchar = left;
		  if (win->_line[y].lastchar < right)
		    win->_line[y].lastchar = right;
		}
	    }
	}
    }
}
Esempio n. 3
0
static void
fill_window(WINDOW *win, chtype ch)
{
    int y, x;
    int y0, x0;
    int y1, x1;

    getyx(win, y0, x0);
    getmaxyx(win, y1, x1);
    for (y = 0; y < y1; ++y) {
	for (x = 0; x < x1; ++x) {
	    mvwaddch(win, y, x, ch);
	}
    }
    wsyncdown(win);
    wmove(win, y0, x0);
    wrefresh(win);
}
Esempio n. 4
0
static void
fill_with_pattern(WINDOW *win)
{
    int y, x;
    int y0, x0;
    int y1, x1;
    int ch = 'a';

    getyx(win, y0, x0);
    getmaxyx(win, y1, x1);
    for (y = 0; y < y1; ++y) {
	for (x = 0; x < x1; ++x) {
	    MvWAddCh(win, y, x, (chtype) ch);
	    if (++ch > 'z')
		ch = 'a';
	}
    }
    wsyncdown(win);
    wmove(win, y0, x0);
    wrefresh(win);
}
Esempio n. 5
0
wsyncdown(WINDOW *win)
/* mark changed every cell in win that is changed in any of its ancestors */
/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...)           */
{
    T((T_CALLED("wsyncdown(%p)"), win));

    if (win && win->_parent) {
	WINDOW *pp = win->_parent;
	int y;

	/* This recursion guarantees, that the changes are propagated down-
	   wards from the root to our direct parent. */
	wsyncdown(pp);

	/* and now we only have to propagate the changes from our direct
	   parent, if there are any. */
	assert((win->_pary <= pp->_maxy) &&
	       ((win->_pary + win->_maxy) <= pp->_maxy));

	for (y = 0; y <= win->_maxy; y++) {
	    if (pp->_line[win->_pary + y].firstchar >= 0) {	/* parent changed */
		struct ldat *line = &(win->_line[y]);
		/* left and right character in child coordinates */
		int left = pp->_line[win->_pary + y].firstchar - win->_parx;
		int right = pp->_line[win->_pary + y].lastchar - win->_parx;
		/* The change maybe outside the childs range */
		if (left < 0)
		    left = 0;
		if (right > win->_maxx)
		    right = win->_maxx;
		CHANGED_RANGE(line, left, right);
	    }
	}
    }
    returnVoid;
}
Esempio n. 6
0
/*
 * Draw a box inside the given window.
 */
static void
box_inside(WINDOW *win)
{
    int y0, x0;
    int y1, x1;

    getyx(win, y0, x0);
    getmaxyx(win, y1, x1);

    mvwhline(win, 0, 0, ACS_HLINE, x1);
    mvwhline(win, y1 - 1, 0, ACS_HLINE, x1);

    mvwvline(win, 0, 0, ACS_VLINE, y1);
    mvwvline(win, 0, x1 - 1, ACS_VLINE, y1);

    mvwaddch(win, 0, 0, ACS_ULCORNER);
    mvwaddch(win, y1 - 1, 0, ACS_LLCORNER);
    mvwaddch(win, 0, x1 - 1, ACS_URCORNER);
    mvwaddch(win, y1 - 1, x1 - 1, ACS_LRCORNER);

    wsyncdown(win);
    wmove(win, y0, x0);
    wrefresh(win);
}
Esempio n. 7
0
int wnoutrefresh(WINDOW *win)
{
short	i, j;
short	begx;
short	begy;
short	m, n;
bool	wide;

	T((T_CALLED("wnoutrefresh(%p)"), win));
#ifdef TRACE
	if (_nc_tracing & TRACE_UPDATE)
	    _tracedump("...win", win);
#endif /* TRACE */

	/*
	 * This function will break badly if we try to refresh a pad.
	 */
	if ((win == 0)
	 || (win->_flags & _ISPAD))
		returnCode(ERR);

	/* put them here so "win == 0" won't break our code */
	begx = win->_begx;
	begy = win->_begy;

	/*
	 * If 'newscr' has a different background than the window that we're
	 * trying to refresh, we'll have to copy the whole thing.
	 */
	if (win->_bkgd != newscr->_bkgd) {
		touchwin(win);
		newscr->_bkgd = win->_bkgd;
	}
	newscr->_attrs = win->_attrs;

	/* merge in change information from all subwindows of this window */
	wsyncdown(win);

	/*
	 * For pure efficiency, we'd want to transfer scrolling information
	 * from the window to newscr whenever the window is wide enough that
	 * its update will dominate the cost of the update for the horizontal
	 * band of newscr that it occupies.  Unfortunately, this threshold
	 * tends to be complex to estimate, and in any case scrolling the
	 * whole band and rewriting the parts outside win's image would look
	 * really ugly.  So.  What we do is consider the window "wide" if it
	 * either (a) occupies the whole width of newscr, or (b) occupies
	 * all but at most one column on either vertical edge of the screen
	 * (this caters to fussy people who put boxes around full-screen
	 * windows).  Note that changing this formula will not break any code,
	 * merely change the costs of various update cases.
	 */
	wide = (begx <= 1 && win->_maxx >= (newscr->_maxx - 1));

	win->_flags &= ~_HASMOVED;

	/*
	 * Microtweaking alert!  This double loop is one of the genuine
	 * hot spots in the code.  Even gcc doesn't seem to do enough
	 * common-subexpression chunking to make it really tense,
	 * so we'll force the issue.
	 */
	for (i = 0, m = begy + win->_yoffset;
	     i <= win->_maxy && m <= newscr->_maxy;
	     i++, m++) {
		register struct ldat	*nline = &newscr->_line[m];
		register struct ldat	*oline = &win->_line[i];

		if (oline->firstchar != _NOCHANGE) {
			int last = oline->lastchar;

			/* limit(j) */
			if (last > win->_maxx)
				last = win->_maxx;
			/* limit(n) */
			if (last > newscr->_maxx - begx)
				last = newscr->_maxx - begx;

			for (j = oline->firstchar, n = j + begx; j <= last; j++, n++) {
				if (oline->text[j] != nline->text[n]) {
					nline->text[n] = oline->text[j];

					if (nline->firstchar == _NOCHANGE)
						nline->firstchar = nline->lastchar = n;
					else if (n < nline->firstchar)
						nline->firstchar = n;
					else if (n > nline->lastchar)
						nline->lastchar = n;
				}
			}

		}

#if USE_SCROLL_HINTS
		if (wide) {
		    int	oind = oline->oldindex;

		    nline->oldindex = (oind == _NEWINDEX) ? _NEWINDEX : begy + oind + win->_yoffset;
		}
#endif /* USE_SCROLL_HINTS */

		oline->firstchar = oline->lastchar = _NOCHANGE;
		if_USE_SCROLL_HINTS(oline->oldindex = i);
	}

	if (win->_clear) {
		win->_clear = FALSE;
		newscr->_clear = TRUE;
	}

	if (! win->_leaveok) {
		newscr->_cury = win->_cury + win->_begy + win->_yoffset;
		newscr->_curx = win->_curx + win->_begx;
	}
	newscr->_leaveok = win->_leaveok;
	
#ifdef TRACE
	if (_nc_tracing & TRACE_UPDATE)
	    _tracedump("newscr", newscr);
#endif /* TRACE */
	returnCode(OK);
}
Esempio n. 8
0
void c_ecurses_wsyncdown (EIF_POINTER w)
{
    wsyncdown ((WINDOW *)w)  ;
};
Esempio n. 9
0
wnoutrefresh(WINDOW *win)
{
    int limit_x;
    int src_row, src_col;
    int begx;
    int begy;
    int dst_row, dst_col;
#if USE_SCROLL_HINTS
    bool wide;
#endif
#if NCURSES_SP_FUNCS
    SCREEN *SP_PARM = _nc_screen_of(win);
#endif

    T((T_CALLED("wnoutrefresh(%p)"), (void *) win));
#ifdef TRACE
    if (USE_TRACEF(TRACE_UPDATE)) {
	_tracedump("...win", win);
	_nc_unlock_global(tracef);
    }
#endif /* TRACE */

    /*
     * This function will break badly if we try to refresh a pad.
     */
    if ((win == 0)
	|| (win->_flags & _ISPAD))
	returnCode(ERR);

    /* put them here so "win == 0" won't break our code */
    begx = win->_begx;
    begy = win->_begy;

    NewScreen(SP_PARM)->_nc_bkgd = win->_nc_bkgd;
    WINDOW_ATTRS(NewScreen(SP_PARM)) = WINDOW_ATTRS(win);

    /* merge in change information from all subwindows of this window */
    wsyncdown(win);

#if USE_SCROLL_HINTS
    /*
     * For pure efficiency, we'd want to transfer scrolling information
     * from the window to newscr whenever the window is wide enough that
     * its update will dominate the cost of the update for the horizontal
     * band of newscr that it occupies.  Unfortunately, this threshold
     * tends to be complex to estimate, and in any case scrolling the
     * whole band and rewriting the parts outside win's image would look
     * really ugly.  So.  What we do is consider the window "wide" if it
     * either (a) occupies the whole width of newscr, or (b) occupies
     * all but at most one column on either vertical edge of the screen
     * (this caters to fussy people who put boxes around full-screen
     * windows).  Note that changing this formula will not break any code,
     * merely change the costs of various update cases.
     */
    wide = (begx <= 1 && win->_maxx >= (NewScreen(SP_PARM)->_maxx - 1));
#endif

    win->_flags &= ~_HASMOVED;

    /*
     * Microtweaking alert!  This double loop is one of the genuine
     * hot spots in the code.  Even gcc doesn't seem to do enough
     * common-subexpression chunking to make it really tense,
     * so we'll force the issue.
     */

    /* limit(dst_col) */
    limit_x = win->_maxx;
    /* limit(src_col) */
    if (limit_x > NewScreen(SP_PARM)->_maxx - begx)
	limit_x = NewScreen(SP_PARM)->_maxx - begx;

    for (src_row = 0, dst_row = begy + win->_yoffset;
	 src_row <= win->_maxy && dst_row <= NewScreen(SP_PARM)->_maxy;
	 src_row++, dst_row++) {
	struct ldat *nline = &(NewScreen(SP_PARM)->_line[dst_row]);
	struct ldat *oline = &win->_line[src_row];

	if (oline->firstchar != _NOCHANGE) {
	    int last_src = oline->lastchar;

	    if (last_src > limit_x)
		last_src = limit_x;

	    src_col = oline->firstchar;
	    dst_col = src_col + begx;

	    if_WIDEC({
		int j;

		/*
		 * Ensure that we will copy complete multi-column characters
		 * on the left-boundary.
		 */
		if (isWidecExt(oline->text[src_col])) {
		    j = 1 + dst_col - WidecExt(oline->text[src_col]);
		    if (j < 0)
			j = 0;
		    if (dst_col > j) {
			src_col -= (dst_col - j);
			dst_col = j;
		    }
		}

		/*
		 * Ensure that we will copy complete multi-column characters
		 * on the right-boundary.
		 */
		j = last_src;
		if (WidecExt(oline->text[j])) {
		    ++j;
		    while (j <= limit_x) {
			if (isWidecBase(oline->text[j])) {
			    break;
			} else {
			    last_src = j;
			}
			++j;
		    }
		}
	    });

	    if_WIDEC({
		static cchar_t blank = BLANK;
		int last_dst = begx + ((last_src < win->_maxx)
				       ? last_src
				       : win->_maxx);
		int fix_left = dst_col;
		int fix_right = last_dst;
		int j;

		/*
		 * Check for boundary cases where we may overwrite part of a
		 * multi-column character.  For those, wipe the remainder of
		 * the character to blanks.
		 */
		j = dst_col;
		if (isWidecExt(nline->text[j])) {
		    /*
		     * On the left, we only care about multi-column characters
		     * that extend into the changed region.
		     */
		    fix_left = 1 + j - WidecExt(nline->text[j]);
		    if (fix_left < 0)
			fix_left = 0;	/* only if cell is corrupt */
		}

		j = last_dst;
		if (WidecExt(nline->text[j]) != 0) {
		    /*
		     * On the right, any multi-column character is a problem,
		     * unless it happens to be contained in the change, and
		     * ending at the right boundary of the change.  The
		     * computation for 'fix_left' accounts for the left-side of
		     * this character.  Find the end of the character.
		     */
		    ++j;
		    while (j <= NewScreen(SP_PARM)->_maxx &&
			   isWidecExt(nline->text[j])) {
			fix_right = j++;
		    }
		}

		/*
		 * The analysis is simpler if we do the clearing afterwards.
		 * Do that now.
		 */
		if (fix_left < dst_col || fix_right > last_dst) {
		    for (j = fix_left; j <= fix_right; ++j) {
			nline->text[j] = blank;
			CHANGED_CELL(nline, j);
		    }
		}
	    });