Category : C Source Code
Archive   : WIND.ZIP
Filename : W_FIELDS.C

 
Output of file : W_FIELDS.C contained in archive : WIND.ZIP

/* w_fields.c -- part of Windows package; contains showField, getField,
* clearToEnd, fieldStart, fieldEnd, fieldLeft, fieldRight,
* toggleInsert, delChar, addChar, backspace, fatCursor, thinCursor
*/

#include
#include
#include "windows.h"

/* using these #defines for character tests instead of those supplied in
* ctype.h, in order to allow one library to be used for Borland
* and Microsoft compilers. If you are compiling the source code
* for the package yourself and will only be working with one
* compiler, you can replace these defines with ctype.h, but you
* won't really notice any improvement in efficiency, since the
* speed constraint here is the user's keystroke rate, which will
* be many times slower than either method can handle
*/

#define isalpha(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
#define isdigit(c) ((c) >= '0' && (c) <= '9')

/****************************************************************************/
/* Display prompt and field at appropriate location within window. */
/****************************************************************************/

void showField(f, w)
Field *f;
Window *w;
{
int i;

w->cursor = f->promptLoc;
w->attribute = f->promptAtt;
w_puts(f->prompt, w);
w->cursor = f->dataLoc;
w->attribute = f->dataAtt;
for (i = 0; i < f->size; i++)
w_putc(i < f->length ? f->str[i] : ' ', w);
}

/****************************************************************************/
/* Get a string from an input field -- a much more sophisticated */
/* replacement for gets(). By setting appropriate members of Field */
/* structure whose pointer is passed to the function, caller can */
/* specify masks for characters to be accepted, location of field, */
/* location and contents of prompt, if any, attribute for prompt */
/* and field display, etc. */
/****************************************************************************/

int getField(f, w)
Field *f;
Window *w;
{
int i, ch;

if (f->size < 1 || f->length > f->size) /* safety measures */
return 0;
for (i = f->size; i >= f->length; i--)
f->str[i] = '\0'; /* another safety measure */
w->cursor = f->dataLoc;
f->position = 0;
w->attribute = f->dataAtt;
w_putcrs(w);
for (;;)
switch (ch = getch()) {
case '\0':
switch (ch = getch()) {
case UP:
case DOWN:
case PGUP:
case FUNC_KEYS:
case PGDOWN: return ch;
case ALT_B: beepFlag ^= ON; break;
case CTRL_END: clearToEnd(f, w); break;
case HOME: fieldStart(f, w); break;
case END: fieldEnd(f, w); break;
case LEFT: fieldLeft(f, w); break;
case RIGHT: fieldRight(f, w); break;
case INS: toggleInsert(); break;
case DEL: delChar(f, w); break;
}
break;
case '\t':
case '\r':
case ESC:
case CTRL_W: return ch;
case '\b': backspace(f, w); break;
default: addChar(ch, f, w);
}
}

/****************************************************************************/
/* Clear from current position to end of field. */
/****************************************************************************/

void clearToEnd(f, w)
Field *f;
Window *w;
{
int i;
for (i = f->position;
i < f->size;
i++) {
f->str[i] = '\0';
w_putc(' ', w);
}
w->cursor.col = f->position + f->dataLoc.col;
w_putcrs(w);
f->length = f->position;
}

/****************************************************************************/
/* Move to beginning of field */
/****************************************************************************/

void fieldStart(f, w)
Field *f;
Window *w;
{
f->position = 0;
w->cursor = f->dataLoc;
w_putcrs(w);
}

/****************************************************************************/
/* Move to end of input field. */
/****************************************************************************/

void fieldEnd(f, w)
Field *f;
Window *w;
{
if ((f->position = f->length) == f->size)
f->position--;
w->cursor.col = f->position + f->dataLoc.col;
w_putcrs(w);
}

/****************************************************************************/
/* If possible, move left one position in input field. */
/****************************************************************************/

void fieldLeft(f, w)
Field *f;
Window *w;
{
if (f->position) {
f->position--;
w->cursor.col--;
w_putcrs(w);
}
}

/****************************************************************************/
/* If possible, move right one position in input field */
/****************************************************************************/

void fieldRight(f, w)
Field *f;
Window *w;
{
if (f->position < f->length) {
f->position++;
w->cursor.col++;
w_putcrs(w);
}
}

/****************************************************************************/
/* Change insert flag to opposite condition, setting shape of cursor */
/* to thin if insert is off, fat if on. */
/****************************************************************************/

void toggleInsert()
{
if (insertFlag ^= ON)
fatCursor();
else
thinCursor();
}

/****************************************************************************/
/* Delete character at current field position, moving any characters */
/* on the right over to fill in. */
/****************************************************************************/

void delChar(f, w)
Field *f;
Window *w;
{
if (f->position < f->length) {
f->length--;
strcpy(f->str + f->position, f->str + f->position + 1);
w_puts(f->str + f->position, w);
w_putc(' ', w);
w->cursor.col = f->position + f->dataLoc.col;
}
}

/****************************************************************************/
/* If possible, move current position left one character, deleting */
/* character originally to the left of the current position, and */
/* moving any characters on the right over to fill in. */
/****************************************************************************/

void backspace(f, w)
Field *f;
Window *w;
{
if (f->position) {
f->length--;
f->position--;
w->cursor.col--;
w_putcrs(w);
strcpy(f->str + f->position, f->str + f->position + 1);
w_puts(f->str + f->position, w);
w_putc(' ', w);
w->cursor.col = f->position + f->dataLoc.col;
}
}

/****************************************************************************/
/* If character pressed by user matches mask specified for this field */
/* add the character to the current position. Behaves appropriately */
/* according to current setting of insertFlag. */
/****************************************************************************/

void addChar(ch, f, w)
int ch;
Field *f;
Window *w;
{
int i;

if (f->alpha && isalpha(ch) || f->num && isdigit(ch)
|| strchr(f->specials, ch)) {
if (f->position == f->length) {
w_putc(ch, w);
f->str[f->length++] = ch;
if (f->length < f->size)
f->position++;
else
w->cursor.col--;
} else if (f->position == f->size - 1) {
w_putc(ch, w);
w->cursor.col--;
f->str[f->position] = ch;
if (beepFlag)
beep();
} else if (insertFlag) {
if ((i = f->length) == f->size)
i--;
else
f->length++;
while (i > f->position) {
f->str[i] = f->str[i-1];
i--;
}
f->str[i] = ch;
w_puts(f->str + i, w);
f->position++;
w->cursor.col = f->position + f->dataLoc.col;
} else {
w_putc(ch, w);
f->str[f->position++] = ch;
}
w_putcrs(w);
}
}

/****************************************************************************/
/* Enlarge cursor. */
/****************************************************************************/

void fatCursor()
{
union REGS r;
char mode;

r.h.ah = 15; /* get mode */
int86(16, &r, &r);
mode = r.h.al;
r.h.ah = 3; /* get current cursor setting */
int86(16, &r, &r);
r.h.ch = r.h.ch & 0x70; /* starting line 0 */
r.h.cl = r.h.cl & 0x70 | (mode == 7) ? 12 : 7; /* ending line */
r.h.ah = 1; /* set cursor type */
int86(16, &r, &r);
}

/****************************************************************************/
/* Set cursor to defaults used by BIOS. */
/****************************************************************************/

void thinCursor()
{
union REGS r;
char mode;

r.h.ah = 15; /* get mode */
int86(16, &r, &r);
mode = r.h.al;
r.h.ah = 3; /* get current cursor setting */
int86(16, &r, &r);
r.h.ch = r.h.ch & 0x70 | (mode == 7) ? 11 : 6; /* starting line */
r.h.cl = r.h.cl & 0x70 | (mode == 7) ? 12 : 7; /* ending line */
r.h.ah = 1; /* set cursor type */
int86(16, &r, &r);
}