#include <sys/types.h>
#include "utility.h"
#define first(f) (f->field [Pmin(f, P(f))])
#define last(f) (f->field [Pmax(f, P(f))])
#define sfirst(f) (f->field [Smin(f, P(f))])
#define slast(f) (f->field [Smax(f, P(f))])
#define Active(f) (Opt(f, O_ACTIVE) && Opt(f, O_VISIBLE))
static FIELD *
next(FIELD *f)
{
FORM *t = f->form;
FIELD **p = t->field + f->index;
FIELD **pmin = t->field + Pmin(t, P(t));
FIELD **pmax = t->field + Pmax(t, P(t));
do
p = p == pmax ? pmin : p+1;
while ((!Active(*p)) && (*p != f));
return (*p);
}
static FIELD *
prev(FIELD *f)
{
FORM *t = f->form;
FIELD **p = t->field + f->index;
FIELD **pmin = t->field + Pmin(t, P(t));
FIELD **pmax = t->field + Pmax(t, P(t));
do
p = p == pmin ? pmax : p-1;
while ((!Active(*p)) && (*p != f));
return (*p);
}
static FIELD *
snext(FIELD *f)
{
FIELD *x = f;
do
f = f->snext;
while ((!Active(f)) && (f != x));
return (f);
}
static FIELD *
sprev(FIELD *f)
{
FIELD *x = f;
do
f = f->sprev;
while ((!Active(f)) && (f != x));
return (f);
}
static FIELD *
left(FIELD *f)
{
int row = f->frow;
do
f = sprev(f);
while (f->frow != row);
return (f);
}
static FIELD *
right(FIELD *f)
{
int row = f->frow;
do
f = snext(f);
while (f->frow != row);
return (f);
}
static FIELD *
up(FIELD *f)
{
int row = f->frow;
int col = f->fcol;
do
f = sprev(f);
while (f->frow == row && f->fcol != col);
if (f->frow != row) {
row = f->frow;
while (f->frow == row && f->fcol > col)
f = sprev(f);
if (f->frow != row)
f = snext(f);
}
return (f);
}
static FIELD *
down(FIELD *f)
{
int row = f->frow;
int col = f->fcol;
do
f = snext(f);
while (f->frow == row && f->fcol != col);
if (f->frow != row) {
row = f->frow;
while (f->frow == row && f->fcol < col)
f = snext(f);
if (f ->frow != row)
f = sprev(f);
}
return (f);
}
int
_next_field(FORM *f)
{
return (_set_current_field(f, next(C(f))));
}
int
_prev_field(FORM *f)
{
return (_set_current_field(f, prev(C(f))));
}
int
_first_field(FORM *f)
{
return (_set_current_field(f, next(last(f))));
}
int
_last_field(FORM *f)
{
return (_set_current_field(f, prev(first(f))));
}
int
_snext_field(FORM *f)
{
return (_set_current_field(f, snext(C(f))));
}
int
_sprev_field(FORM *f)
{
return (_set_current_field(f, sprev(C(f))));
}
int
_sfirst_field(FORM *f)
{
return (_set_current_field(f, snext(slast(f))));
}
int
_slast_field(FORM *f)
{
return (_set_current_field(f, sprev(sfirst(f))));
}
int
_left_field(FORM *f)
{
return (_set_current_field(f, left(C(f))));
}
int
_right_field(FORM *f)
{
return (_set_current_field(f, right(C(f))));
}
int
_up_field(FORM *f)
{
return (_set_current_field(f, up(C(f))));
}
int
_down_field(FORM *f)
{
return (_set_current_field(f, down(C(f))));
}
FIELD *
_first_active(FORM *f)
{
return (next(last(f)));
}