/* TN5250
* Copyright (C) 1997 Michael Madore
*
* This file is part of TN5250.
*
* TN5250 is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* TN5250 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
*
*/
#include "tn5250-private.h"
/****f* lib5250/tn5250_field_new
* NAME
* tn5250_field_new
* SYNOPSIS
* ret = tn5250_field_new (w);
* INPUTS
* int w -
* DESCRIPTION
* DOCUMENT ME!!!
*****/
Tn5250Field *
tn5250_field_new (int w)
{
Tn5250Field *This = tn5250_new (Tn5250Field, 1);
if (This == NULL)
{
return NULL;
}
memset (This, 0, sizeof (Tn5250Field));
This->id = -1;
This->w = w;
return This;
}
/****f* lib5250/tn5250_field_copy
* NAME
* tn5250_field_copy
* SYNOPSIS
* ret = tn5250_field_copy (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* DOCUMENT ME!!!
*****/
Tn5250Field *
tn5250_field_copy (Tn5250Field * This)
{
Tn5250Field *fld = tn5250_new (Tn5250Field, 1);
if (fld == NULL)
{
return NULL;
}
memcpy (fld, This, sizeof (Tn5250Field));
fld->next = NULL;
fld->prev = NULL;
fld->script_slot = NULL;
return fld;
}
/****f* lib5250/tn5250_field_destroy
* NAME
* tn5250_field_destroy
* SYNOPSIS
* tn5250_field_destroy (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* DOCUMENT ME!!!
*****/
void
tn5250_field_destroy (Tn5250Field * This)
{
free (This);
}
#ifndef NDEBUG
/****f* lib5250/tn5250_field_dump
* NAME
* tn5250_field_dump
* SYNOPSIS
* tn5250_field_dump (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* DOCUMENT ME!!!
*****/
void
tn5250_field_dump (Tn5250Field * This)
{
Tn5250Uint16 ffw = This->FFW;
TN5250_LOG (("tn5250_field_dump: ffw flags = "));
if ((ffw & TN5250_FIELD_BYPASS) != 0)
{
TN5250_LOG (("bypass "));
}
if ((ffw & TN5250_FIELD_DUP_ENABLE) != 0)
{
TN5250_LOG (("dup-enable "));
}
if ((ffw & TN5250_FIELD_MODIFIED) != 0)
{
TN5250_LOG (("mdt "));
}
if ((ffw & TN5250_FIELD_AUTO_ENTER) != 0)
{
TN5250_LOG (("auto-enter"));
}
if ((ffw & TN5250_FIELD_FER) != 0)
{
TN5250_LOG (("fer "));
}
if ((ffw & TN5250_FIELD_MONOCASE) != 0)
{
TN5250_LOG (("monocase "));
}
if ((ffw & TN5250_FIELD_MANDATORY) != 0)
{
TN5250_LOG (("mandatory "));
}
TN5250_LOG (("\ntn5250_field_dump: fcw flags = "));
if (This->resequence != 0)
{
TN5250_LOG (("Entry field resequencing: %d ", This->resequence));
}
if (This->magstripe)
{
TN5250_LOG (("Magnetic stripe reader entry field "));
}
if (This->lightpen)
{
TN5250_LOG (("Selector light pen or cursor select field "));
}
if (This->magandlight)
{
TN5250_LOG (("Magnetic stripe reader and selector light pen entry field "));
}
if (This->lightandattn)
{
TN5250_LOG (("Selector light pen and selectable attention entry field "));
}
if (This->ideographiconly)
{
TN5250_LOG (("Ideographic-only entry field "));
}
if (This->ideographicdatatype)
{
TN5250_LOG (("Ideographic data type entry field "));
}
if (This->ideographiceither)
{
TN5250_LOG (("Ideographic-either entry field "));
}
if (This->ideographicopen)
{
TN5250_LOG (("Ideographic-open entry field "));
}
if (This->transparency != 0)
{
TN5250_LOG (("Transparency entry field: %d ", This->transparency));
}
if (This->forwardedge)
{
TN5250_LOG (("Forward edge trigger entry field "));
}
if (This->continuous)
{
TN5250_LOG (("continuous "));
}
if (tn5250_field_is_continued_first (This))
{
TN5250_LOG (("(first) "));
}
if (tn5250_field_is_continued_middle (This))
{
TN5250_LOG (("(middle) "));
}
if (tn5250_field_is_continued_last (This))
{
TN5250_LOG (("(last) "));
}
if (This->wordwrap)
{
TN5250_LOG (("wordwrap "));
}
if (This->nextfieldprogressionid != 0)
{
TN5250_LOG (("cursor progression: %d ", This->nextfieldprogressionid));
}
if ((int) This->highlightentryattr != 0)
{
TN5250_LOG (("Highlighted entry field: %x ", This->highlightentryattr));
}
if ((int) This->pointeraid != 0)
{
TN5250_LOG (("Pointer device selection entry field: %x ", This->pointeraid));
}
if (This->selfcheckmod11)
{
TN5250_LOG (("Self-check modulus 11 entry field "));
}
if (This->selfcheckmod10)
{
TN5250_LOG (("Self-check modulus 10 entry field "));
}
TN5250_LOG (("\ntn5250_field_dump: type = %s\n",
tn5250_field_description (This)));
TN5250_LOG (("tn5250_field_dump: adjust = %s\ntn5250_field_dump: data = ",
tn5250_field_adjust_description (This)));
TN5250_LOG (("\n"));
}
#endif
/****f* lib5250/tn5250_field_hit_test
* NAME
* tn5250_field_hit_test
* SYNOPSIS
* ret = tn5250_field_hit_test (This, y, x);
* INPUTS
* Tn5250Field * This -
* int y -
* int x -
* DESCRIPTION
* Determine if the screen position at row ``y'', column ``x'' is contained
* within this field. (A hit-test, in other words.)
*****/
int
tn5250_field_hit_test (Tn5250Field * This, int y, int x)
{
int pos = (y * This->w) + x;
return (pos >= tn5250_field_start_pos (This)
&& pos <= tn5250_field_end_pos (This));
}
/****f* lib5250/tn5250_field_start_pos
* NAME
* tn5250_field_start_pos
* SYNOPSIS
* ret = tn5250_field_start_pos (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Figure out the starting address of this field.
*****/
int
tn5250_field_start_pos (Tn5250Field * This)
{
return This->start_row * This->w + This->start_col;
}
/****f* lib5250/tn5250_field_end_pos
* NAME
* tn5250_field_end_pos
* SYNOPSIS
* ret = tn5250_field_end_pos (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Figure out the ending address of this field.
*****/
int
tn5250_field_end_pos (Tn5250Field * This)
{
return tn5250_field_start_pos (This) + tn5250_field_length (This) - 1;
}
/****f* lib5250/tn5250_field_end_row
* NAME
* tn5250_field_end_row
* SYNOPSIS
* ret = tn5250_field_end_row (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Figure out the ending row of this field.
*****/
int
tn5250_field_end_row (Tn5250Field * This)
{
return tn5250_field_end_pos (This) / This->w;
}
/****f* lib5250/tn5250_field_end_col
* NAME
* tn5250_field_end_col
* SYNOPSIS
* ret = tn5250_field_end_col (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Figure out the ending column of this field.
*****/
int
tn5250_field_end_col (Tn5250Field * This)
{
return tn5250_field_end_pos (This) % This->w;
}
/****f* lib5250/tn5250_field_description
* NAME
* tn5250_field_description
* SYNOPSIS
* ret = tn5250_field_description (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Get a description of this field.
*****/
const char *
tn5250_field_description (Tn5250Field * This)
{
switch (This->FFW & TN5250_FIELD_FIELD_MASK)
{
case TN5250_FIELD_ALPHA_SHIFT:
return "Alpha Shift";
case TN5250_FIELD_DUP_ENABLE:
return "Dup Enabled";
case TN5250_FIELD_ALPHA_ONLY:
return "Alpha Only";
case TN5250_FIELD_NUM_SHIFT:
return "Numeric Shift";
case TN5250_FIELD_NUM_ONLY:
return "Numeric Only";
case TN5250_FIELD_KATA_SHIFT:
return "Katakana";
case TN5250_FIELD_DIGIT_ONLY:
return "Digits Only";
case TN5250_FIELD_MAG_READER:
return "Mag Reader I/O Field";
case TN5250_FIELD_SIGNED_NUM:
return "Signed Numeric";
default:
return "(?)";
}
}
/****f* lib5250/tn5250_field_adjust_description
* NAME
* tn5250_field_adjust_description
* SYNOPSIS
* ret = tn5250_field_adjust_description (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Get a description of the mandatory fill mode for this field.
*****/
const char *
tn5250_field_adjust_description (Tn5250Field * This)
{
switch (This->FFW & TN5250_FIELD_MAND_FILL_MASK)
{
case TN5250_FIELD_NO_ADJUST:
return "No Adjust";
case TN5250_FIELD_MF_RESERVED_1:
return "Reserved 1";
case TN5250_FIELD_MF_RESERVED_2:
return "Reserved 2";
case TN5250_FIELD_MF_RESERVED_3:
return "Reserved 3";
case TN5250_FIELD_MF_RESERVED_4:
return "Reserved 4";
case TN5250_FIELD_RIGHT_ZERO:
return "Right Adjust, Zero Fill";
case TN5250_FIELD_RIGHT_BLANK:
return "Right Adjust, Blank Fill";
case TN5250_FIELD_MANDATORY_FILL:
return "Mandatory Fill";
default:
return "";
}
}
/****f* lib5250/tn5250_field_count_left
* NAME
* tn5250_field_count_left
* SYNOPSIS
* ret = tn5250_field_count_left (This, y, x);
* INPUTS
* Tn5250Field * This -
* int y -
* int x -
* DESCRIPTION
* Return the number of characters in the this field which
* are to the left of the specified cursor position. Used
* as an index to insert data when the user types.
*****/
int
tn5250_field_count_left (Tn5250Field * This, int y, int x)
{
int pos;
pos = (y * This->w + x);
pos -= tn5250_field_start_pos (This);
TN5250_ASSERT (tn5250_field_hit_test (This, y, x));
TN5250_ASSERT (pos >= 0);
TN5250_ASSERT (pos < tn5250_field_length (This));
return pos;
}
/****f* lib5250/tn5250_field_count_right
* NAME
* tn5250_field_count_right
* SYNOPSIS
* ret = tn5250_field_count_right (This, y, x);
* INPUTS
* Tn5250Field * This -
* int y -
* int x -
* DESCRIPTION
* This returns the number of characters in the specified field
* which are to the right of the specified cursor position.
*****/
int
tn5250_field_count_right (Tn5250Field * This, int y, int x)
{
TN5250_ASSERT (tn5250_field_hit_test (This, y, x));
return tn5250_field_end_pos (This) - (y * This->w + x);
}
/****f* lib5250/tn5250_field_valid_char
* NAME
* tn5250_field_valid_char
* SYNOPSIS
* ret = tn5250_field_valid_char (field, ch);
* INPUTS
* Tn5250Field * field -
* int ch -
* int * src -
* DESCRIPTION
* Determine if the supplied character is a valid data character
* for this field, and return system reference code for errors (SRC)
*****/
int
tn5250_field_valid_char (Tn5250Field * field, int ch, int *src)
{
TN5250_LOG (("HandleKey: fieldtype = %d; char = '%c'.\n",
tn5250_field_type (field), ch));
*src = TN5250_KBDSRC_NONE;
switch (tn5250_field_type (field))
{
case TN5250_FIELD_ALPHA_SHIFT:
return 1;
case TN5250_FIELD_ALPHA_ONLY:
if (!(isalpha (ch) || ch == ',' || ch == '.' || ch == '-' || ch == ' '))
{
*src = TN5250_KBDSRC_ALPHAONLY;
return 0;
}
return 1;
case TN5250_FIELD_NUM_SHIFT:
return 1;
case TN5250_FIELD_NUM_ONLY:
if (!(isdigit (ch) || ch == ',' || ch == '.' || ch == '-' || ch == ' '))
{
*src = TN5250_KBDSRC_NUMONLY;
return 0;
}
return 1;
case TN5250_FIELD_KATA_SHIFT:
TN5250_LOG (("KATAKANA not implemented.\n"));
return 1;
case TN5250_FIELD_DIGIT_ONLY:
if (!isdigit (ch))
{
*src = TN5250_KBDSRC_ONLY09;
return 0;
}
return 1;
case TN5250_FIELD_MAG_READER:
TN5250_LOG (("MAG_READER not implemented.\n"));
return 1;
case TN5250_FIELD_SIGNED_NUM:
if (!isdigit (ch))
{
*src = TN5250_KBDSRC_ONLY09;
return 0;
}
return 1;
}
return 0;
}
/****f* lib5250/tn5250_field_set_mdt
* NAME
* tn5250_field_set_mdt
* SYNOPSIS
* tn5250_field_set_mdt (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Set the MDT flag for this field and for the table which owns it.
*****/
void
tn5250_field_set_mdt (Tn5250Field * This)
{
TN5250_ASSERT (This->table != NULL);
/* Taken from tn5250j
* get the first field of a continued edit field if it is continued
*/
if ((This->continuous) && !tn5250_field_is_continued_first (This))
{
Tn5250Field *iter;
for (iter = This->prev;
(iter->continuous && !tn5250_field_is_continued_first (iter));
iter = iter->prev)
{
TN5250_ASSERT (iter->continuous);
}
tn5250_field_set_mdt (iter);
tn5250_dbuffer_set_mdt (iter->table);
}
else
{
This->FFW |= TN5250_FIELD_MODIFIED;
tn5250_dbuffer_set_mdt (This->table);
}
return;
}
/****f* lib5250/tn5250_field_list_destroy
* NAME
* tn5250_field_list_destroy
* SYNOPSIS
* ret = tn5250_field_list_destroy (list);
* INPUTS
* Tn5250Field * list -
* DESCRIPTION
* Destroy all fields in a field list.
*****/
Tn5250Field *
tn5250_field_list_destroy (Tn5250Field * list)
{
Tn5250Field *iter, *next;
if ((iter = list) != NULL)
{
/*@-usereleased@ */
do
{
next = iter->next;
tn5250_field_destroy (iter);
iter = next;
}
while (iter != list);
/*@=usereleased@ */
}
return NULL;
}
/****f* lib5250/tn5250_field_list_add
* NAME
* tn5250_field_list_add
* SYNOPSIS
* ret = tn5250_field_list_add (list, node);
* INPUTS
* Tn5250Field * list -
* Tn5250Field * node -
* DESCRIPTION
* Add a field to the end of a list of fields.
*****/
Tn5250Field *
tn5250_field_list_add (Tn5250Field * list, Tn5250Field * node)
{
node->prev = node->next = NULL;
if (list == NULL)
{
node->next = node->prev = node;
return node;
}
node->next = list;
node->prev = list->prev;
node->prev->next = node;
node->next->prev = node;
return list;
}
/****f* lib5250/tn5250_field_list_remove
* NAME
* tn5250_field_list_remove
* SYNOPSIS
* ret = tn5250_field_list_remove (list, node);
* INPUTS
* Tn5250Field * list -
* Tn5250Field * node -
* DESCRIPTION
* Remove a field from a list of fields.
*****/
Tn5250Field *
tn5250_field_list_remove (Tn5250Field * list, Tn5250Field * node)
{
if (list == NULL)
{
return NULL;
}
if (list->next == list && list == node)
{
node->next = node->prev = NULL;
return NULL;
}
if (list == node)
{
list = list->next;
}
node->next->prev = node->prev;
node->prev->next = node->next;
node->prev = node->next = NULL;
return list;
}
/****f* lib5250/tn5250_field_list_find_by_id
* NAME
* tn5250_field_list_find_by_id
* SYNOPSIS
* ret = tn5250_field_list_find_by_id (list, id);
* INPUTS
* Tn5250Field * list -
* int id -
* DESCRIPTION
* Find a field by its numeric id.
*****/
Tn5250Field *
tn5250_field_list_find_by_id (Tn5250Field * list, int id)
{
Tn5250Field *iter;
if ((iter = list) != NULL)
{
do
{
if (iter->id == id)
return iter;
iter = iter->next;
}
while (iter != list);
}
return NULL;
}
/****f* lib5250/tn5250_field_list_copy
* NAME
* tn5250_field_list_copy
* SYNOPSIS
* ret = tn5250_field_list_copy (This);
* INPUTS
* Tn5250Field * This -
* DESCRIPTION
* Copy all fields in a list to another list.
*****/
Tn5250Field *
tn5250_field_list_copy (Tn5250Field * This)
{
Tn5250Field *new_list = NULL, *iter, *new_field;
if ((iter = This) != NULL)
{
do
{
new_field = tn5250_field_copy (iter);
if (new_field != NULL)
{
new_list = tn5250_field_list_add (new_list, new_field);
}
iter = iter->next;
}
while (iter != This);
}
return new_list;
}
syntax highlighted by Code2HTML, v. 0.9.1