bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Corrections for 20030920


From: Philippe Blain
Subject: Corrections for 20030920
Date: Fri, 26 Sep 2003 21:37:05 +0200

>From Philippe Blain, Bordeaux, France.
My computer: P133 - 8,4 Go - 32 Mo Red Hat Linux 7.0

Corrections for ncurses-5.3-20030920+

1-----------------------------------------------------------------------
File : ncurses/tty/tty_update.c

Forgot to change line 1092 as said in NEWS-20030920:
    ....................
    if (ceol_standout_glitch && clr_eol) {
    firstChar = 0;
==> while ((firstChar < screen_columns) && !attrchanged) {
        if (AttrOf(newLine[firstChar]) != AttrOf(oldLine[firstChar]))
        attrchanged = TRUE;
        firstChar++;
    }
    }
    ....................

2-----------------------------------------------------------------------
File : ncurses/tinfo/lib_napms.c

Function nanosleep() can be interrupted by a signal. See nanosleep(2).
Propose modifs :

NCURSES_EXPORT (int) napms (int ms)
{
    T ((T_CALLED ("napms(%d)"), ms));

#if HAVE_NANOSLEEP
    {
==>     struct timespec request, remaining;
==>     int err;
==>     request.tv_sec = ms / 1000;
==>     request.tv_nsec = (ms % 1000) * 1000000;
==>     while ((err = nanosleep (&request, &remaining)) == -1
==>             && errno == EINTR)
==>         request = remaining;
==>     return (err);
    }
#else

==> return (_nc_timed_wait (0, ms, (int *) 0 EVENTLIST_2nd (0)));
#endif
}

NOTE :
* Recursion problems between napms() and _nc_timed_wait() if don't have
  nanosleep().

3-----------------------------------------------------------------------
File : ncurses/tty/lib_twait.c

Due to the structure of timeval, _nc_gettime() need some corrections
to give a good value :

static long _nc_gettime (bool first)
{
    long res;

#if HAVE_GETTIMEOFDAY
# define PRECISE_GETTIME 1
    static struct timeval t0;
    struct timeval t1;
    gettimeofday (&t1, (struct timezone *) 0);
    if (first) {
        t0 = t1; /* Useless to compute, result will be 0 */
    }
==> /* Time correction */
==> if (t0.tv_usec > t1.tv_usec) {
==>     t1.tv_usec += 1000000;
==>     t1.tv_sec--;
==> }
    res = (t1.tv_sec - t0.tv_sec) * 1000 + (t1.tv_usec - t0.tv_usec) / 1000;
#else
    ...................
    return res;
}

NOTE :
* Having t0 hidden (static) and counting on the boolean 'first' is a
   bad design :
    starttime = _nc_gettime (TRUE);      always return 0 as t0=t1.

If would be better to implement a small flexible timer library which
could be used instead of gettimeofday() in lib_mvcur.c, lib_twait.c
Pb : the system must have 'gettimeofday' for a precise time.
Under example of such dynamic code :

##############################   lib_timer.c
#################################

#define MICROSEC_PER_SEC   1000000
#define GETTIME(v)         gettimeofday (&v, (struct timezone *) 0)

typedef struct _nc_timer {
    struct timeval start;
    struct timeval end;
    bool active;
} NCURSES_TIMER;

NCURSES_TIMER *_nc_timer_new (void)
{
    NCURSES_TIMER *timer;

    if (timer = typeCalloc (NCURSES_TIMER, 1)) {
        if (GETTIME (timer->start) == 0) /* Mark start time */
            timer->active = TRUE;
    }
    return (timer);
}

NCURSES_EXPORT(void) _nc_timer_destroy (NCURSES_TIMER * timer)
{
    FreeIfNeeded (timer);
}

/* (Re)Marks a start time. */
NCURSES_EXPORT(int) _nc_timer_start (NCURSES_TIMER * timer)
{
    if (timer) {
        if (GETTIME (timer->start) == 0) {
            timer->active = TRUE;
             returnCode (OK);
        }
    }
    returnCode (ERR);
}

/* Marks an end time. */
NCURSES_EXPORT(int) _nc_timer_stop (NCURSES_TIMER * timer)
{
    if (timer) {
        if (GETTIME (timer->end) == 0)
            timer->active = FALSE;
             returnCode (OK);
        }
    }
    returnCode (ERR);
}

/*
    If timer has been started but not stopped, obtains the time since the
    timer was started. If timer has been stopped, obtains the elapsed
    time between the time it was started and the time it was stopped.

    The return value is the number of SECONDS elapsed, and the microseconds
    argument allows you to get the number of microseconds.
*/
long _nc_timer_elapsed (NCURSES_TIMER * timer, long * microseconds)
{
    struct timeval elapsed;
    long total;

    if (!timer) return (0);

    if (timer->active) /* Stops the timer */
        GETTIME (timer->end);

    /* Time correction */
    if (timer->start.tv_usec > timer->end.tv_usec) {
        timer->end.tv_usec += MICROSEC_PER_SEC;
        timer->end.tv_sec--;
    }
    elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
    elapsed.tv_usec = timer->end.tv_usec - timer->start.tv_usec;

    total = elapsed.tv_sec + (elapsed.tv_usec / MICROSEC_PER_SEC);
    if (total < 0) {
        total = 0;
        if (microseconds) *microseconds = 0;
    }
    else if (microseconds) *microseconds = elapsed.tv_usec;
    return (total);
}

/*
    Adds a number of microseconds to a struct timeval.
    Microseconds can also be negative to decrease the value.
*/
NCURSES_EXPORT(int) _nc_timeval_add (struct timeval * t, long microseconds)
{
    if (t->tv_usec < 0 || t->tv_usec >= MICROSEC_PER_SEC)
        returnCode (ERR);

    t->tv_sec += microseconds / MICROSEC_PER_SEC;
    t->tv_usec += microseconds % MICROSEC_PER_SEC;
    if (microseconds >= 0) {
        if (t->tv_usec >= MICROSEC_PER_SEC) {
            t->tv_usec -= MICROSEC_PER_SEC;
            t->tv_sec++;
        }
    }
    else {
        if (t->tv_usec < 0) {
            t->tv_usec += MICROSEC_PER_SEC;
            t->tv_sec--;
        }
    }
    returnCode (OK);
}

void _nc_usleep (unsigned long microseconds)
{
# ifdef HAVE_NANOSLEEP
    struct timespec request, remaining;
    request.tv_sec = microseconds / MICROSEC_PER_SEC;
    request.tv_nsec = 1000 * (microseconds % MICROSEC_PER_SEC);
    while (nanosleep (&request, &remaining) == -1 && errno == EINTR)
        request = remaining;
# else /* !HAVE_NANOSLEEP */
    /* select() with NULLs is a fairly portable way */
    struct timeval tv;
    tv.tv_sec = microseconds / MICROSEC_PER_SEC;
    tv.tv_usec = microseconds % MICROSEC_PER_SEC;
    select (0, NULL, NULL, NULL, &tv);
# endif    /* !HAVE_NANOSLEEP */
}

/* End of lib_timer.c */
############################################################################
####

------------------------------------------------------------------------
- Philippe






reply via email to

[Prev in Thread] Current Thread [Next in Thread]