Skip to content

Commit

Permalink
workaround a bug in cursor positioning
Browse files Browse the repository at this point in the history
this testprogram is supposed to create a rotating wheel animation:

  #include <ncurses.h>
  #include <unistd.h>

  int main() {
    int i, x, y;
    initscr(); cbreak(); noecho();
    printw("press a key to start - you should see a 'rotating wheel' animation");
    getch();
    getmaxyx(stdscr, y, x);
    for (i = 0; i < 16; i++) {
      move(0, x-1);
      addch("\\-/|"[i%4]);
      refresh();
      sleep(1);
    }
    clear(); refresh(); endwin();
    return 0;
  }

however it actually produced output like "\-/|\-/|\-/|".
this is due to an optimization that does not move the terminal cursor if the
target position is the same as the supposedly current position.
supposedly, because the code that writes a single character does not increment
the internal cursor position, even though the terminal's cursor is advanced
by one through the write.
it is possible that the author of the code in question trusted in the domvcur()
function to do the bookkeeping for him, and wasn't aware of the optimization,
or vice versa the author of the optimization unaware of the usage of the
function for syncing the cursor position.
  • Loading branch information
rofl0r committed Aug 10, 2016
1 parent bf1e504 commit 4b9444c
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions libcurses/refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,9 @@ makech(int wy)
#endif
#else
if (WCOL(*nsp) > 0) {
/* FIXME: putting a character advances the cursor, but the internal
housekeeping is not updated, this prevents from using the now commented
out optimization in domvcur(). */
__cputwchar((int) nsp->ch);
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH,
Expand Down Expand Up @@ -1318,8 +1321,18 @@ domvcur(oy, ox, ny, nx)
oy, ox, ny, nx );
#endif /* DEBUG */
__unsetattr(1);
/* FIXME: we have to turn off this optimization, because the internal cursor
position is not updated in makech() when putting a character.
eventually this optimization was not here when the other code was written,
so the author assumed that calling domvcur() would take care of that.
this causes breakage in a loop like:
for(i...) { move(0, 0); addch("\\-/|"[i%4]); refresh(); sleep(1); }
which is supposed to create a rotating wheel animation, but actually wrote
"\-/|\-/|\-/|\-/|\-/|" etc to the screen since the move() call turned NOP. */
#if 0
if ( oy == ny && ox == nx )
return;
#endif
__mvcur(oy, ox, ny, nx, 1);
}

Expand Down

0 comments on commit 4b9444c

Please sign in to comment.