2021-10-11 18:37:13 -03:00

667 lines
20 KiB
C

#ifndef lint
static char sccsid[] = "@(#)inputset.c 1.1 94/10/31 Copyr 1985-9 Sun Micro";
#endif
/*
* Copyright (c) 1985, 1986, 1987, 1988, 1989 by Sun Microsystems, Inc.
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both that copyright
* notice and this permission notice are retained, and that the name
* of Sun Microsystems, Inc., not be used in advertising or publicity
* pertaining to this software without specific, written prior permission.
* Sun Microsystems, Inc., makes no representations about the suitability
* of this software or the interface defined in this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/*
flush_event_queue
selective_flush_of_event_queue
sample_input
initiate_request
get_last_requested_input
enable_events
disable_events
await_event
_cgi_int_rev_dev_conv
_cgi_err_is_dev_assoc
_cgi_err_is_trig_assoc
_cgi_err_check_94
*/
#include "cgipriv.h"
#include <signal.h>
struct locatstr *_cgi_locator[_CGI_LOCATORS];
struct keybstr *_cgi_keybord[_CGI_KEYBORDS];
struct strokstr *_cgi_stroker[_CGI_STROKES];
struct valstr *_cgi_valuatr[_CGI_VALUATRS];
struct choicestr *_cgi_button[_CGI_CHOICES];
struct pickstr *_cgi_pick[_CGI_PICKS];
struct evqueue _cgi_event_queue[MAXEVENTS]; /* event queue */
int _cgi_num_events;/* event queue pointer */
Cqtype _cgi_que_status; /* event queue status */
Ceqflow _cgi_que_over_status; /* event queue status */
int _cgi_trigger[MAXTRIG][MAXASSOC + 1]; /* association list */
int _cgi_event_occurred; /* event flag */
int _cgi_alarm_occurred; /* alarm flag */
extern char *strcpy();
/****************************************************************************/
/* */
/* FUNCTION: flush_event_queue */
/* */
/* Discards all events in the event queue */
/****************************************************************************/
Cerror flush_event_queue()
{
int i, err;
err = _cgi_check_state_5();
if (!err)
{
_cgi_ioint_handle();
for (i = 0; i < _cgi_num_events; i++)
{
/* clean-up malloc'ed space */
_cgi_free_queue_element(&_cgi_event_queue[i]);
}
_cgi_que_status = EMPTY;
_cgi_num_events = 0;
_cgi_que_over_status = NO_OFLO;
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: selective_flush_of_event_queue */
/* */
/* Discards all events in the event queue corresponding to */
/* the specified device */
/****************************************************************************/
Cerror selective_flush_of_event_queue(devclass, devnum)
Cdevoff devclass; /* device type */
Cint devnum; /* device number */
{
int err, i, j, num, tnum;
err = _cgi_err_check_481(devclass, devnum);
if (err == 4)
err = _cgi_check_state_5();
if (!err)
{
_cgi_ioint_handle();
num = _cgi_int_dev_conv(devclass, devnum); /* get code number */
tnum = _cgi_num_events;
for (i = 0; i < _cgi_num_events; i++)
{ /* discard events */
if (_cgi_event_queue[i].n == num)
{
_cgi_free_queue_element(&_cgi_event_queue[i]);
for (j = i; j < tnum; j++)
{
_cgi_event_queue[j] = _cgi_event_queue[j + 1];
}
tnum--;
}
}
_cgi_num_events = tnum;
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: sample_input */
/* */
/* Reports current value of the specified input device. */
/****************************************************************************/
Cerror sample_input(devclass, devnum, valid, sample)
Cdevoff devclass;
Cint devnum; /* device type, device number */
Clogical *valid; /* device status */
Cinrep *sample; /* device value */
{
int err;
err = _cgi_err_check_481(devclass, devnum);
/* standard input device error checking */
if (!err)
{
_cgi_ioint_handle();
*valid = L_TRUE;
switch (devclass)
{ /* get current measure of device depending on
* dev. type */
case IC_STRING:
sample->string = _cgi_keybord[devnum - 1]->initstring;
break;
case IC_CHOICE:
sample->choice = _cgi_button[devnum - 1]->curval;
break;
case IC_LOCATOR:
sample->xypt->x = _cgi_locator[devnum - 1]->x;
sample->xypt->y = _cgi_locator[devnum - 1]->y;
break;
case IC_VALUATOR:
sample->val = _cgi_valuatr[devnum - 1]->curval;
break;
case IC_STROKE:
sample->points = _cgi_stroker[devnum - 1]->sarray;
break;
}
}
else
*valid = L_FALSE; /* device SNAFUed */
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: initiate_request */
/* */
/* Sets up a device to process a on-shot request (input). */
/****************************************************************************/
Cerror initiate_request(devclass, devnum)
Cdevoff devclass;
Cint devnum; /* device type, device number */
{
int err;
err = _cgi_err_check_481(devclass, devnum);
/* standard input device error checking */ if (!err)
err =
_cgi_err_is_dev_assoc(devclass, devnum);
if (!err)
{
switch
(devclass)
{
case IC_STRING:
_cgi_keybord[devnum - 1]->subkey.enable = REQUEST_EVENT;
break;
case IC_STROKE:
_cgi_stroker[devnum - 1]->substroke.enable = REQUEST_EVENT;
/* allow STROKE to pickup events */
_cgi_temp_assoc_stroke(devnum);
break;
case IC_LOCATOR:
_cgi_locator[devnum - 1]->subloc.enable = REQUEST_EVENT;
break;
case IC_PICK:
_cgi_pick[devnum - 1]->subpick.enable = REQUEST_EVENT;
break;
case IC_VALUATOR:
_cgi_valuatr[devnum - 1]->subval.enable = REQUEST_EVENT;
break;
case IC_CHOICE:
_cgi_button[devnum - 1]->subchoice.enable = REQUEST_EVENT;
break;
}
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: get_last_requested_input */
/* */
/* Reports the value of the request register. */
/****************************************************************************/
Cerror get_last_requested_input(devclass, devnum, valid, sample)
/* WARNING: Revision A of the SunCGI Reference Manual is wrong here. */
Cdevoff devclass; /* device type */
Cint devnum; /* device number */
Clogical *valid; /* device status */
Cinrep *sample; /* device value */
{
int err;
/* Return error if device not initialized (err 81) */
err = _cgi_err_check_481(devclass, devnum);
if (!err && (valid == (Clogical *) NULL
|| sample == (Cinrep *) NULL))
err = EBADDATA;
if (!err)
{
_cgi_ioint_handle();
*valid = L_TRUE;
switch (devclass)
{
case IC_STRING:
if (sample->string == (char *) NULL)
err = EBADDATA;
else
(void) strcpy(sample->string,
_cgi_keybord[devnum - 1]->rinitstring);
break;
case IC_CHOICE:
sample->choice = _cgi_button[devnum - 1]->rcurval;
break;
case IC_LOCATOR:
sample->xypt->x = _cgi_locator[devnum - 1]->rx;
sample->xypt->y = _cgi_locator[devnum - 1]->ry;
break;
case IC_VALUATOR:
sample->val = _cgi_valuatr[devnum - 1]->rcurval;
break;
case IC_STROKE:
/* WCL 860911 should copy points, not return internal data area */
sample->points = _cgi_stroker[devnum - 1]->rsarray;
break;
}
}
else
*valid = L_FALSE; /* device SNAFUed */
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: enable_events */
/* */
/* Allows device to put events on the input queue. */
/****************************************************************************/
Cerror enable_events(devclass, devnum)
Cdevoff devclass;
Cint devnum; /* device type, device number */
{
int err;
err = _cgi_err_check_94(devclass, devnum);
if (!err)
{
switch (devclass)
{
case IC_STRING:
_cgi_keybord[devnum - 1]->subkey.enable = QUEUE_EVENT;
break;
case IC_STROKE:
_cgi_stroker[devnum - 1]->substroke.enable = QUEUE_EVENT;
break;
case IC_LOCATOR:
_cgi_locator[devnum - 1]->subloc.enable = QUEUE_EVENT;
break;
case IC_PICK:
_cgi_pick[devnum - 1]->subpick.enable = QUEUE_EVENT;
break;
case IC_VALUATOR:
_cgi_valuatr[devnum - 1]->subval.enable = QUEUE_EVENT;
break;
case IC_CHOICE:
_cgi_button[devnum - 1]->subchoice.enable = QUEUE_EVENT;
break;
}
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: disable_events */
/* */
/* Prevents device to put events on the input queue. */
/****************************************************************************/
Cerror disable_events(devclass, devnum)
Cdevoff devclass;
Cint devnum; /* device type, device number */
{
int err;
err = _cgi_err_check_481(devclass, devnum);
/* standard input device error checking */
if (!err)
{
switch (devclass)
{
case IC_STRING:
_cgi_keybord[devnum - 1]->subkey.enable = NO_EVENTS;
break;
case IC_STROKE:
_cgi_stroker[devnum - 1]->substroke.enable = NO_EVENTS;
break;
case IC_LOCATOR:
_cgi_locator[devnum - 1]->subloc.enable = NO_EVENTS;
break;
case IC_PICK:
_cgi_pick[devnum - 1]->subpick.enable = NO_EVENTS;
break;
case IC_VALUATOR:
_cgi_valuatr[devnum - 1]->subval.enable = NO_EVENTS;
break;
case IC_CHOICE:
_cgi_button[devnum - 1]->subchoice.enable = NO_EVENTS;
break;
}
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: await_event */
/* */
/* Reports next event and returns information about the */
/* generating device. */
/****************************************************************************/
Cerror await_event(timeout, valid, devclass, devnum,
measure, message_link, replost, time_stamp, qstat, overflow)
Cint timeout; /* amount of time to wait for input */
Cawresult *valid; /* status */
Cdevoff *devclass; /* device type */
Cint *devnum; /* device number */
Cinrep *measure; /* device value */
Cmesstype *message_link; /* type of message */
Cint *replost; /* reports lost */
Cint *time_stamp; /* time_stamp */
Cqtype *qstat; /* queue status */
Ceqflow *overflow; /* event queue */
{
int err;
int i, nm;
int cnt;
/* static Cinrep imeas;
static Ccoorlist pts;
static Ccoor list[MAXPTS], pt;
static char keys[MAXCHAR]; */
if (valid == (Cawresult *) NULL
|| devclass == (Cdevoff *) NULL
|| devnum == (Cint *) NULL
|| measure == (Cinrep *) NULL
|| message_link == (Cmesstype *) NULL
|| replost == (Cint *) NULL
|| time_stamp == (Cint *) NULL
|| qstat == (Cqtype *) NULL
|| overflow == (Ceqflow *) NULL)
{
err = EBADDATA;
}
else
{
*qstat = _cgi_que_status;
*overflow = _cgi_que_over_status;
*replost = 0;
*time_stamp = 0;
*valid = WRONG_STATE;
err = _cgi_err_check_4();
}
if (!err)
{
/* Set an itimer for the user-specified timeout */
if (timeout >= 0) {
(void) _cgi_set_timeout((unsigned) timeout);
*valid = TIMED_OUT;
}
do
{
if (! (_cgi_event_occurred || _cgi_alarm_occurred))
(void) _cgi_timeout(timeout);
if (_cgi_event_occurred)
(void) _cgi_ioint_handle();/* process pending events */
*qstat = _cgi_que_status;
*overflow = _cgi_que_over_status;
if (_cgi_num_events)
{
/* dequeue event at the head of the queue */
nm = _cgi_event_queue[0].n;
_cgi_int_rev_dev_conv(nm, devclass, devnum);
/* copy to a safe place before freeing */
switch (*devclass)
{
case IC_STROKE:
if (!measure->points)
return (_cgi_errhand(EBADDATA));
cnt = _cgi_event_queue[0].contents->points->n;
if (cnt > measure->points->n)
cnt = measure->points->n;
for (i = 0; i < cnt; i++)
{
measure->points->ptlist[i] =
_cgi_event_queue[0].contents->points->ptlist[i];
}
break;
case IC_LOCATOR:
if (!measure->xypt)
return (_cgi_errhand(EBADDATA));
*measure->xypt = *_cgi_event_queue[0].contents->xypt;
break;
case IC_STRING:
if (!measure->string)
return (_cgi_errhand(EBADDATA));
(void) strcpy(measure->string,
_cgi_event_queue[0].contents->string);
break;
case IC_CHOICE:
measure->choice = _cgi_event_queue[0].contents->choice;
break;
case IC_PICK:
if (!measure->pick)
return (_cgi_errhand(EBADDATA));
measure->pick->segid =
_cgi_event_queue[0].contents->pick->segid;
measure->pick->pickid =
_cgi_event_queue[0].contents->pick->pickid;
break;
case IC_VALUATOR:
measure->val = _cgi_event_queue[0].contents->val;
break;
default:
break;
}
_cgi_free_queue_element(&_cgi_event_queue[0]);
*valid = VALID_DATA; /* set returned args. */
*message_link = SINGLE_EVENT;
for (i = 1; i < _cgi_num_events; i++)
{
_cgi_event_queue[i - 1] = _cgi_event_queue[i];
if (_cgi_event_queue[i].n == nm)
*message_link = SIMULTANEOUS_EVENT_FOLLOWS;
}
_cgi_num_events--;
if (!_cgi_num_events)
_cgi_que_status = EMPTY;
if (_cgi_que_status == FULL)
_cgi_que_status = ALMOST_FULL;
break; /* break out of timeout loop */
}
} while (!_cgi_alarm_occurred);
*qstat = _cgi_que_status;
*overflow = _cgi_que_over_status;
if (_cgi_que_over_status == OFLO)
err = 97;
}
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_int_rev_dev_conv */
/* */
/* Converts a device name into a device type and number. */
/****************************************************************************/
_cgi_int_rev_dev_conv(nm, devclass, devnum)
int nm;
Cdevoff *devclass;
Cint *devnum;
{
if (nm <= OFF2)
{
*devclass = IC_STRING;
*devnum = nm - OFF1;
}
else
{
if (nm < OFF3)
{
*devclass = IC_STROKE;
*devnum = nm - OFF2;
}
else
{
if (nm < OFF4)
{
*devclass = IC_LOCATOR;
*devnum = nm - OFF3;
}
else
{
if (nm < OFF5)
{
*devclass = IC_VALUATOR;
*devnum = nm - OFF4;
}
else if (nm < OFF6)
{
*devclass = IC_CHOICE;
*devnum = nm - OFF5;
}
else
{
*devclass = IC_PICK;
*devnum = nm - OFF6;
}
}
}
}
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_err_is_dev_assoc */
/* */
/* */
/****************************************************************************/
int _cgi_err_is_dev_assoc(devclass, devnum)
Cdevoff devclass;
Cint devnum; /* device type, device number */
{
int err, i, terr;
err = 85;
for (i = 1; i < MAXTRIG + 1; i++)
{
terr = _cgi_err_is_trig_assoc(devclass, devnum, i);
if (terr)
{ /* trigger is associated */
err = 0;
break;
}
}
return (err);
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_err_is_trig_assoc */
/* */
/* */
/****************************************************************************/
int _cgi_err_is_trig_assoc(devclass, devnum, trigger)
Cdevoff devclass;
Cint devnum; /* device type, device number */
int trigger;
{
int err, temp, tpt, i;
err = 0;
temp = _cgi_int_dev_conv(devclass, devnum);
tpt = _cgi_trigger[trigger - 1][0];
if (tpt != 0)
{
tpt++;
for (i = 0; i < tpt; i++)
if (_cgi_trigger[trigger - 1][i] == temp)
err = 83;
}
return (err);
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_err_check_94 */
/* */
/* */
/****************************************************************************/
int _cgi_err_check_94(devclass, devnum)
Cdevoff devclass;
Cint devnum; /* device type, device number */
{
int err = 0;
err = _cgi_err_check_481(devclass, devnum);
if (!err)
{
switch (devclass)
{
case IC_STRING:
if (_cgi_keybord[devnum - 1]->subkey.enable != NO_EVENTS)
err = 94;
break;
case IC_STROKE:
if (_cgi_stroker[devnum - 1]->substroke.enable != NO_EVENTS)
err = 94;
break;
case IC_LOCATOR:
if (_cgi_locator[devnum - 1]->subloc.enable != NO_EVENTS)
err = 94;
break;
case IC_PICK:
if (_cgi_pick[devnum - 1]->subpick.enable != NO_EVENTS)
err = 94;
break;
case IC_VALUATOR:
if (_cgi_valuatr[devnum - 1]->subval.enable != NO_EVENTS)
err = 94;
break;
case IC_CHOICE:
if (_cgi_button[devnum - 1]->subchoice.enable != NO_EVENTS)
err = 94;
break;
}
}
return (err);
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_free_queue_element */
/* */
/* frees an event queue element */
/* */
/****************************************************************************/
_cgi_free_queue_element(elem)
struct evqueue *elem; /* event queue element */
{
Cdevoff devclass; /* device type */
Cint devnum; /* device number */
_cgi_int_rev_dev_conv(elem->n, &devclass, &devnum);
switch (devclass)
{
case IC_STROKE:
free((char *) elem->contents->points->ptlist);
free((char *) elem->contents->points);
break;
case IC_LOCATOR:
free((char *) elem->contents->xypt);
break;
case IC_STRING:
free((char *) elem->contents->string);
break;
default:
break;
}
free((char *) elem->contents);
}