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

886 lines
25 KiB
C

/*
* Copyright (c) 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.
*/
#ifndef lint
static char sccsid[] = "@(#)inprims.c 1.1 94/10/31 Copyr 1986 Sun Micro";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include "coretypes.h"
#include "corevars.h"
#include <sys/time.h>
#define NULL 0
extern char backspace_character;
static struct timeval systime, newtime;
static struct timezone zone;
pickstr *_core_check_pick();
keybstr *_core_check_keyboard();
strokstr *_core_check_stroke();
locatstr *_core_check_locator();
valstr *_core_check_valuator();
butnstr *_core_check_button();
get_mouse_state(devclass, devnum, x, y, buttons)
int devclass, devnum;
float *x, *y;
int *buttons;
{
static char funcname[] = "get_mouse_state";
pickstr *pickptr;
locatstr *locatptr;
strokstr *strokptr;
valstr *valptr;
butnstr *butnptr;
ddargtype ddstruct;
int (*dev) ();
dev = 0;
switch (devclass) {
case PICK:
if ((pickptr = _core_check_pick(funcname, devnum, TRUE)) == 0)
return (1);
if (pickptr->subpick.echosurfp != NULL) {
dev = pickptr->subpick.devdrive;
ddstruct.instance = pickptr->subpick.instance;
}
break;
case KEYBOARD:
_core_errhand(funcname, 105);
return (1);
break;
case STROKE:
if ((strokptr = _core_check_stroke(funcname, devnum, TRUE)) == 0)
return (1);
if (strokptr->substroke.echosurfp != NULL) {
dev = strokptr->substroke.devdrive;
ddstruct.instance = strokptr->substroke.instance;
}
break;
case LOCATOR:
if ((locatptr = _core_check_locator(funcname, devnum, TRUE)) == 0)
return (1);
if (locatptr->subloc.echosurfp != NULL) {
dev = locatptr->subloc.devdrive;
ddstruct.instance = locatptr->subloc.instance;
}
break;
case VALUATOR:
if ((valptr = _core_check_valuator(funcname, devnum, TRUE)) == 0)
return (1);
if (valptr->subval.echosurfp != NULL) {
dev = valptr->subval.devdrive;
ddstruct.instance = valptr->subval.instance;
}
break;
case BUTTON:
if ((butnptr = _core_check_button(funcname, devnum, TRUE)) == 0)
return (1);
if (butnptr->subbut.echosurfp != NULL) {
dev = butnptr->subbut.devdrive;
ddstruct.instance = butnptr->subbut.instance;
}
break;
default:
_core_errhand(funcname, 105);
return (1);
break;
}
if (dev == 0) {
*x = 0.0;
*y = 0.0;
*buttons = 0;
return (0);
}
ddstruct.opcode = XYREAD; /* get x,y in ndcspace */
(*dev) (&ddstruct);
*x = (float) ddstruct.int1 / MAX_NDC_COORD;
*y = (float) ddstruct.int2 / MAX_NDC_COORD;
*buttons = ddstruct.int3; /* bit 0 = R button, 1 M, 2 L. 1=down, 0 up. */
return (0);
}
await_any_button(tim, butnum)
int tim;
int *butnum;
{
static char funcname[] = "await_any_button";
int i, someinit;
ddargtype ddstruct;
long elapsed_time;
butnstr *butnptr;
locatstr *locatptr;
pickstr *pickptr;
strokstr *strokptr;
valstr *valptr;
(void) gettimeofday(&systime, &zone);
*butnum = 0;
ddstruct.opcode = BUTREAD;
ddstruct.logical = FALSE;
someinit = FALSE;
do {
for (i = 0; i < BUTTONS; i++) {
butnptr = &_core_button[i];
if (!(butnptr->subbut.enable & 1))
continue;
someinit = TRUE;
ddstruct.int1 = 4 >> i;
if (butnptr->subbut.echosurfp != NULL) {
ddstruct.instance = butnptr->subbut.instance;
(*butnptr->subbut.devdrive) (&ddstruct);
if (ddstruct.logical) {
*butnum = i + 1;
break;
}
} else {
for (locatptr = &_core_locator[0];
locatptr < &_core_locator[LOCATORS] &&
ddstruct.logical == FALSE; locatptr++)
if ((locatptr->subloc.enable & 1) &&
(locatptr->subloc.echosurfp != NULL)) {
ddstruct.instance = locatptr->subloc.instance;
(*locatptr->subloc.devdrive) (&ddstruct);
}
if (ddstruct.logical) {
*butnum = i + 1;
break;
}
for (pickptr = &_core_pick[0]; pickptr < &_core_pick[PICKS] &&
ddstruct.logical == FALSE; pickptr++)
if ((pickptr->subpick.enable & 1) && (pickptr->subpick.echosurfp != NULL)) {
ddstruct.instance = pickptr->subpick.instance;
(*pickptr->subpick.devdrive) (&ddstruct);
}
if (ddstruct.logical) {
*butnum = i + 1;
break;
}
for (strokptr = &_core_stroker[0];
strokptr < &_core_stroker[STROKES] &&
ddstruct.logical == FALSE; strokptr++)
if ((strokptr->substroke.enable & 1) &&
(strokptr->substroke.echosurfp != NULL)) {
ddstruct.instance = strokptr->substroke.instance;
(*strokptr->substroke.devdrive) (&ddstruct);
}
if (ddstruct.logical) {
*butnum = i + 1;
break;
}
for (valptr = &_core_valuatr[0];
valptr < &_core_valuatr[VALUATRS] &&
ddstruct.logical == FALSE; valptr++)
if ((valptr->subval.enable & 1) &&
(valptr->subval.echosurfp != NULL)) {
ddstruct.instance = valptr->subval.instance;
(*valptr->subval.devdrive) (&ddstruct);
}
if (ddstruct.logical) {
*butnum = i + 1;
break;
}
}
}
if (ddstruct.logical)
break;
if (!someinit) {
_core_errhand(funcname, 113);
return (1);
}
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
return (0);
}
#define PICKBUTTON 0
await_pick(tim, picknum, segnam, pickid)
int tim;
int picknum, *segnam, *pickid;
{
/* await mouse button 1 then return segment and pickid pointed to. */
static char funcname[] = "await_pick";
int newpickid; /* pickid candidate */
int x, y; /* mouse pointer position */
int offset, seg; /* index into segment list */
int oldhilite;
int i, j, k;
int try_for_hit;
short n, sdopcode, *dummy;
short highest_detectability;
long elapsed_time;
ipt_type p[200], p1; /* extent boundary pts NDC */
ipt_type aw[2]; /* aperture window LL UR */
ipt_type cur_point; /* current point ... used for polylines */
ddargtype ddstruct;
pickstr *pickptr, *_core_check_pick();
segstruc *hit_segment;
if ((pickptr = _core_check_pick(funcname, picknum, TRUE)) == 0)
return (1);
if (pickptr->subpick.echosurfp == NULL) {
*segnam = 0;
*pickid = 0;
return (0);
}
if (!(_core_button[PICKBUTTON].subbut.enable & 1)) {
ddstruct.opcode = INITBUT;
ddstruct.int1 = 4 >> PICKBUTTON;
(*pickptr->subpick.devdrive) (&ddstruct);
}
/*
* get x,y in NDC from pick device
*/
(void) gettimeofday(&systime, &zone);
ddstruct.instance = pickptr->subpick.instance;
do { /* until timeout, check pickbutton */
ddstruct.opcode = BUTREAD; /* has pickbutton been hit? */
ddstruct.int1 = 4 >> PICKBUTTON;
(*pickptr->subpick.devdrive) (&ddstruct);
if (ddstruct.logical)
break;
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
if (!(_core_button[PICKBUTTON].subbut.enable & 1)) {
ddstruct.opcode = TERMBUT;
ddstruct.int1 = 4 >> PICKBUTTON;
(*pickptr->subpick.devdrive) (&ddstruct);
}
*segnam = 0;
*pickid = 0;
if (!ddstruct.logical)
return (0);
ddstruct.opcode = XYREAD; /* pickbutton hit,get x,y in ndcsp */
(*pickptr->subpick.devdrive) (&ddstruct);
x = ddstruct.int1;
y = ddstruct.int2;
/* setup aperture window */
aw[0].x = x - pickptr->aperture;
if (aw[0].x < 0)
aw[0].x = 0;
aw[0].y = y - pickptr->aperture;
if (aw[0].y < 0)
aw[0].y = 0;
aw[1].x = x + pickptr->aperture;
if (aw[1].x > MAX_NDC_COORD)
aw[1].x = MAX_NDC_COORD;
aw[1].y = y + pickptr->aperture;
if (aw[1].y > MAX_NDC_COORD)
aw[1].y = MAX_NDC_COORD;
/*
* Find those detectable segments and pickids closest to the mouse ptr
*/
_core_critflag++;
highest_detectability = 0;
for (seg = 0; seg < SEGNUM && _core_segment[seg].type != EMPTY; seg++) {
/* for all segs */
if (_core_segment[seg].type >= RETAIN &&
_core_segment[seg].segats.detectbl && /* if detectable */
_core_segment[seg].segats.visbilty) { /* and visible */
j = FALSE;
for (i = 0; i < _core_segment[seg].vsurfnum; i++)
if (_core_segment[seg].vsurfptr[i] == pickptr->subpick.echosurfp) {
j = TRUE;
break;
}
if (!j)
continue;
/* if no xform ... take seg bounding square as is */
if (_core_segment[seg].idenflag) {
p[0].x = _core_segment[seg].bndbox_min.x;
p[0].y = _core_segment[seg].bndbox_min.y;
p[1].x = _core_segment[seg].bndbox_min.x;
p[1].y = _core_segment[seg].bndbox_max.y;
p[2].x = _core_segment[seg].bndbox_max.x;
p[2].y = _core_segment[seg].bndbox_max.y;
p[3].x = _core_segment[seg].bndbox_max.x;
p[3].y = _core_segment[seg].bndbox_min.y;
}
/* else calculate bounding square from transformed box */
else {
int minx = MAX_NDC_COORD;
int miny = MAX_NDC_COORD;
int maxx = -MAX_NDC_COORD;
int maxy = -MAX_NDC_COORD;
p[0].x = _core_segment[seg].bndbox_min.x;
p[0].y = _core_segment[seg].bndbox_min.y;
p[0].z = _core_segment[seg].bndbox_min.z;
p[1].x = _core_segment[seg].bndbox_min.x;
p[1].y = _core_segment[seg].bndbox_min.y;
p[1].z = _core_segment[seg].bndbox_max.z;
p[2].x = _core_segment[seg].bndbox_min.x;
p[2].y = _core_segment[seg].bndbox_max.y;
p[2].z = _core_segment[seg].bndbox_min.z;
p[3].x = _core_segment[seg].bndbox_min.x;
p[3].y = _core_segment[seg].bndbox_max.y;
p[3].z = _core_segment[seg].bndbox_max.z;
p[4].x = _core_segment[seg].bndbox_max.x;
p[4].y = _core_segment[seg].bndbox_min.y;
p[4].z = _core_segment[seg].bndbox_min.z;
p[5].x = _core_segment[seg].bndbox_max.x;
p[5].y = _core_segment[seg].bndbox_min.y;
p[5].z = _core_segment[seg].bndbox_max.z;
p[6].x = _core_segment[seg].bndbox_max.x;
p[6].y = _core_segment[seg].bndbox_max.y;
p[6].z = _core_segment[seg].bndbox_min.z;
p[7].x = _core_segment[seg].bndbox_max.x;
p[7].y = _core_segment[seg].bndbox_max.y;
p[7].z = _core_segment[seg].bndbox_max.z;
for (i = 0; i < 8; i++) {
_core_imxfrm3(&_core_segment[seg], &p[i], &p1);
if (p1.x < minx)
minx = p1.x;
if (p1.x > maxx)
maxx = p1.x;
if (p1.y < miny)
miny = p1.y;
if (p1.y > maxy)
maxy = p1.y;
}
p[0].x = minx;
p[0].y = miny;
p[1].x = minx;
p[1].y = maxy;
p[2].x = maxx;
p[2].y = maxy;
p[3].x = maxx;
p[3].y = miny;
}
if (_core_test_for_hit(x, y, aw, 4, p)) {
offset = _core_segment[seg].pdfptr;
(void)_core_pdfseek(offset, 0, &dummy);
while (TRUE) {
(void)_core_pdfread(SHORT, &sdopcode);
if (sdopcode == PDFENDSEGMENT)
break;
try_for_hit = FALSE;
switch (sdopcode) {
case PDFMOVE:
(void)_core_pdfread(FLOAT * 3, (short *) &cur_point);
break;
case PDFLINE:
(void)_core_pdfread(FLOAT * 3, (short *) &p[1]);
p[0] = cur_point;
cur_point = p[1];
n = 2;
try_for_hit = TRUE;
break;
case PDFTEXT:
(void)_core_pdfread(SHORT, &n);
(void)_core_pdfskip((n+1)>>1);
break;
case PDFMARKER:
(void)_core_pdfskip(FLOAT);
break;
case PDFBITMAP:
(void)_core_pdfread(FLOAT, (short *) &i); /* width */
(void)_core_pdfread(FLOAT, (short *) &j); /* height */
(void)_core_pdfread(FLOAT, (short *) &k); /* depth */
if (k == 1)
j = ((i + 15) >> 4) * j * SHORT;
else if (k == 8)
j = i * j;
else
j = i * j * 3;
(void)_core_pdfskip(j);
break;
case PDFPOL2:
(void)_core_pdfread(SHORT, &n);
(void)_core_pdfskip(FLOAT * n * 4);
break;
case PDFPOL3:
(void)_core_pdfread(SHORT, &n);
(void)_core_pdfskip(FLOAT * n * 8);
break;
case PDFLCOLOR:
(void)_core_pdfskip(FLOAT);
break;
case PDFFCOLOR:
(void)_core_pdfskip(FLOAT);
break;
case PDFTCOLOR:
(void)_core_pdfskip(FLOAT);
break;
case PDFLINESTYLE:
(void)_core_pdfskip(FLOAT);
break;
case PDFPISTYLE:
(void)_core_pdfskip(FLOAT);
break;
case PDFPESTYLE:
(void)_core_pdfskip(FLOAT);
break;
case PDFLINEWIDTH:
(void)_core_pdfskip(FLOAT);
break;
case PDFFONT:
(void)_core_pdfskip(FLOAT);
break;
case PDFPEN:
(void)_core_pdfskip(FLOAT);
break;
case PDFSPACE:
(void)_core_pdfskip(FLOAT * 3);
break;
case PDFPATH:
(void)_core_pdfskip(FLOAT * 3);
break;
case PDFUP:
(void)_core_pdfskip(FLOAT * 3);
break;
case PDFCHARJUST:
(void)_core_pdfskip(FLOAT);
break;
case PDFCHARQUALITY:
(void)_core_pdfskip(FLOAT);
break;
case PDFVWPORT:
(void)_core_pdfskip(FLOAT * 6);
break;
case PDFROP:
(void)_core_pdfskip(FLOAT);
break;
case PDFPICKID:
(void)_core_pdfread(FLOAT, (short *) &newpickid);
/* get pick extents */
(void)_core_pdfread(SHORT, &n);
for (i = 0; i < n; i++)
/* read extent bounds */
(void)_core_pdfread(FLOAT * 3, (short *) &p[i]);
if (n)
try_for_hit = TRUE;
break;
default:
break;
}
if (try_for_hit) {
if (!_core_segment[seg].idenflag)
for (i = 0; i < n; i++) {
/* apply image transform */
_core_imxfrm3(&_core_segment[seg], &p[i], &p1);
p[i] = p1;
}
if (_core_test_for_hit(x, y, aw, n, p)) {
if ((&_core_segment[seg])->segats.detectbl >=
highest_detectability) {
highest_detectability = (&_core_segment[seg])->segats.detectbl;
hit_segment = &_core_segment[seg];
*segnam = hit_segment->segname;
*pickid = newpickid;
}
}
}
}
}
}
}
if (--_core_critflag == 0 && _core_updatewin && _core_sighandle)
(*_core_sighandle) ();
if (*segnam != 0) {
if (pickptr->subpick.echo == 1) { /* echo by blinking segment */
oldhilite = hit_segment->segats.highlght;
set_segment_highlighting(*segnam, TRUE);
set_segment_highlighting(*segnam, oldhilite);
}
}
return (0);
}
_core_test_for_hit(x, y, aw, n, p)
int x, y, n;
ipt_type aw[2], p[200];
{
int i, j, testval, under, count;
for (i = 0; i < n; i++) { /* check for any point inside window */
if ((p[i].x >= aw[0].x) && (p[i].x <= aw[1].x) &&
(p[i].y >= aw[0].y) && (p[i].y <= aw[1].y)) {
return 1;
}
}
for (i = 0; i < n; i++) { /* for each point in bounding polygon */
j = i + 1;
if (j == n)
j = 0;
if ((p[i].x >= aw[0].x) && (p[i].x <= aw[1].x) &&
(p[i].y >= aw[0].y) && (p[i].y <= aw[1].y)) {
return 1;
}
if ((p[i].x < aw[0].x) ^ (p[j].x < aw[0].x) &&
(testval = p[i].y + (p[j].y - p[i].y) * (aw[0].x - p[i].x) /
(p[j].x - p[i].x)) >= aw[0].y && testval <= aw[1].y) {
return 1;
}
if ((p[i].x < aw[1].x) ^ (p[j].x < aw[1].x) &&
(testval = p[i].y + (p[j].y - p[i].y) * (aw[1].x - p[i].x) /
(p[j].x - p[i].x)) >= aw[0].y && testval <= aw[1].y) {
return 1;
}
if ((p[i].y < aw[0].y) ^ (p[j].y < aw[0].y) &&
(testval = p[i].x + (p[j].x - p[i].x) * (aw[0].y - p[i].y) /
(p[j].y - p[i].y)) >= aw[0].x && testval <= aw[1].x) {
return 1;
}
if ((p[i].y < aw[1].y) ^ (p[j].y < aw[1].y) &&
(testval = p[i].x + (p[j].x - p[i].x) * (aw[1].y - p[i].y) /
(p[j].y - p[i].y)) >= aw[0].x && testval <= aw[1].x) {
return 1;
}
}
under = FALSE; /* last try ... see if center point in
* polygon */
count = 0;
for (i = 0; i < n; i++) { /* test for hit */
j = i + 1;
if (j == n)
j = 0;
if (p[j].x > p[i].x)
under = x <= p[j].x && x >= p[i].x &&
y <= (p[i].y + (p[j].y - p[i].y) *
(x - p[i].x) / (p[j].x - p[i].x));
else if (p[j].x < p[i].x)
under = x <= p[i].x && x >= p[j].x &&
y <= (p[i].y + (p[j].y - p[i].y) *
(p[i].x - x) / (p[i].x - p[j].x));
else
under = FALSE;
if (under)
count++;
}
if (count & 1) {
return 1;
}
return 0; /* not hit */
}
await_keyboard(tim, keynum, string, length)
int tim, keynum;
char *string;
int *length;
{
static char funcname[] = "await_keyboard";
int count, lastcount, ipos;
char ch;
viewsurf *surfp;
ddargtype ddstruct;
long elapsed_time;
keybstr *keybptr, *_core_check_keyboard();
if ((keybptr = _core_check_keyboard(funcname, keynum, TRUE)) == 0)
return (1);
keynum--;
(void) gettimeofday(&systime, &zone);
*string = '\0';
count = 0;
lastcount = 0;
if (keybptr->subkey.echo > 0)
surfp = keybptr->subkey.echosurfp;
else
surfp = 0;
if (surfp) {
_core_critflag++;
ddstruct.instance = surfp->vsurf.instance;
ddstruct.opcode = SETTCOL; /* set xor on */
ddstruct.int1 = 255;
ddstruct.int2 = XORROP;
ddstruct.int3 = FALSE;
(*surfp->vsurf.dd) (&ddstruct);
}
ipos = keybptr->initpos;
_core_devecho(KEYBOARD, keynum, 0, 0, keybptr->initstring, 0.0);
ddstruct.opcode = KEYREAD;
do { /* read any chars */
ddstruct.int1 = 1; /* one at a time */
ddstruct.ptr1 = string + count; /* accumul in string */
(*keybptr->subkey.devdrive) (&ddstruct);
count += ddstruct.int1;
ch = *(string + (count - 1));
if (count && ch == backspace_character) { /* back space to erase char */
count--;
lastcount--;
*(string + count) = '\0';
if (lastcount < count)
_core_devecho(KEYBOARD, keynum, 0, 0, string + lastcount,
(float) (ipos + lastcount));
count = lastcount;
}
if (count && (ch == '\r' || ch == '\n' /* CR or LF to quit */
|| count >= keybptr->bufsize)) {
*(string + (count - 1)) = '\n';
*(string + count) = '\0';
if (lastcount < count)
_core_devecho(KEYBOARD, keynum, 0, 0, string + lastcount,
(float) (ipos + lastcount));
break;
}
*(string + count) = '\0'; /* write new chars */
if (lastcount < count)
_core_devecho(KEYBOARD, keynum, 0, 0, string + lastcount,
(float) (ipos + lastcount));
lastcount = count;
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
/* erase prompt */
_core_devecho(KEYBOARD, keynum, 0, 0, keybptr->initstring, 0.0);
/* erase string */
_core_devecho(KEYBOARD, keynum, 0, 0, string, (float) ipos);
if (surfp) {
ddstruct.instance = surfp->vsurf.instance;
ddstruct.opcode = SETTCOL; /* restore xor to original */
ddstruct.int1 = _core_current.textindx;
ddstruct.int2 = (_core_xorflag) ? XORROP : _core_current.rasterop;
ddstruct.int3 = FALSE;
(*surfp->vsurf.dd) (&ddstruct);
if (--_core_critflag == 0 && _core_updatewin && _core_sighandle)
(*_core_sighandle) ();
}
*length = count;
return (0);
}
#define STKBUTTON 2
await_stroke_2(tim, strokenum, arrsize, xarray, yarray, numxy)
int tim, strokenum, arrsize, *numxy;
float xarray[], yarray[];
{
static char funcname[] = "await_stroke_2";
int oldx, oldy, cx, cy;
ddargtype ddstruct;
long elapsed_time;
register strokstr *strokptr;
strokstr *_core_check_stroke();
if ((strokptr = _core_check_stroke(funcname, strokenum, TRUE)) == 0)
return (1);
*numxy = 0;
if (strokptr->substroke.echosurfp == NULL)
return (0);
if (!(_core_button[STKBUTTON].subbut.enable & 1)) {
ddstruct.opcode = INITBUT;
ddstruct.int1 = 4 >> STKBUTTON;
(*strokptr->substroke.devdrive) (&ddstruct);
}
(void) gettimeofday(&systime, &zone);
ddstruct.opcode = XYREAD; /* get x,y in ndcspace */
ddstruct.instance = strokptr->substroke.instance;
(*strokptr->substroke.devdrive) (&ddstruct);
oldx = ddstruct.int1;
oldy = ddstruct.int2;
do { /* await button, and echo */
ddstruct.opcode = XYREAD; /* if pickbutton hit,get x,y in ndcsp */
(*strokptr->substroke.devdrive) (&ddstruct);
cx = ddstruct.int1;
cy = ddstruct.int2;
ddstruct.opcode = BUTREAD;
ddstruct.int1 = 4 >> STKBUTTON;
(*strokptr->substroke.devdrive) (&ddstruct);
if (ddstruct.logical)
break;
if (abs(oldx - cx) >= strokptr->distance
|| abs(oldy - cy) >= strokptr->distance) {
if (*numxy < arrsize) {
xarray[*numxy] = (float) cx / MAX_NDC_COORD;
yarray[*numxy] = (float) cy / MAX_NDC_COORD;
(*numxy)++;
oldx = cx;
oldy = cy;
} else
break;
}
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
if (!(_core_button[STKBUTTON].subbut.enable & 1)) {
ddstruct.opcode = TERMBUT;
ddstruct.int1 = 4 >> STKBUTTON;
(*strokptr->substroke.devdrive) (&ddstruct);
}
return (0);
}
await_any_button_get_locator_2(tim, locnum, butnum, x, y)
int tim, locnum, *butnum;
float *x, *y;
{
static char funcname[] = "await_any_button_get_locator_2";
int i;
int oldx, oldy, cx, cy;
ddargtype ddstruct;
long elapsed_time;
register locatstr *locatptr;
locatstr *_core_check_locator();
butnstr *butnptr;
if ((locatptr = _core_check_locator(funcname, locnum, TRUE)) == 0)
return (1);
locnum--;
i = FALSE;
for (butnptr = &_core_button[0]; butnptr < &_core_button[BUTTONS]; butnptr++)
if (butnptr->subbut.enable & 1) {
i = TRUE;
break;
}
if (!i) {
_core_errhand(funcname, 113);
return (1);
}
if (locatptr->subloc.echosurfp == NULL) {
*butnum = 0;
*x = 0;
*y = 0;
return (0);
}
(void) gettimeofday(&systime, &zone);
*butnum = 0;
if (locatptr->subloc.echo > 1)
_core_critflag++;
ddstruct.opcode = XYREAD; /* get x,y in ndcspace */
ddstruct.instance = locatptr->subloc.instance;
(*locatptr->subloc.devdrive) (&ddstruct);
oldx = ddstruct.int1;
oldy = ddstruct.int2;
_core_devecho(LOCATOR, locnum, oldx, oldy, " ", 0.);
do { /* await button, and echo */
ddstruct.opcode = BUTREAD;
for (i = 0; i < BUTTONS; i++) {
ddstruct.int1 = 4 >> i;
(*locatptr->subloc.devdrive) (&ddstruct);
if (ddstruct.logical) {
*butnum = i + 1;
}
}
ddstruct.opcode = XYREAD; /* get x,y in ndcspace */
(*locatptr->subloc.devdrive) (&ddstruct);
cx = ddstruct.int1;
cy = ddstruct.int2;
if (oldx != cx || oldy != cy) {
_core_devecho(LOCATOR, locnum, oldx, oldy, " ", 0.);
_core_devecho(LOCATOR, locnum, cx, cy, " ", 0.);
}
oldx = cx;
oldy = cy;
if (*butnum)
break;
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
_core_devecho(LOCATOR, locnum, oldx, oldy, " ", 0.);
if (locatptr->subloc.echo > 1)
if (--_core_critflag == 0 && _core_updatewin && _core_sighandle)
(*_core_sighandle) ();
*x = (float) cx / MAX_NDC_COORD;
*y = (float) cy / MAX_NDC_COORD;
return (0);
}
await_any_button_get_valuator(tim, valnum, butnum, val)
int tim, valnum, *butnum;
float *val;
{
static char funcname[] = "await_any_button_get_valuator";
int i;
float mm, bb;
ddargtype ddstruct;
long elapsed_time;
register valstr *valptr;
valstr *_core_check_valuator();
butnstr *butnptr;
if ((valptr = _core_check_valuator(funcname, valnum, TRUE)) == 0)
return (1);
valnum--;
i = FALSE;
for (butnptr = &_core_button[0]; butnptr < &_core_button[BUTTONS]; butnptr++)
if (butnptr->subbut.enable & 1) {
i = TRUE;
break;
}
if (!i) {
_core_errhand(funcname, 113);
return (1);
}
if (valptr->subval.echosurfp == NULL) {
*butnum = 0;
*val = 0.0;
return (0);
}
(void) gettimeofday(&systime, &zone);
*butnum = 0;
*val = valptr->vlinit;
mm = (valptr->vlmax - valptr->vlmin) / (float) _core_ndcspace[0];
bb = valptr->vlmin;
if (valptr->subval.echo > 0)
_core_critflag++;
ddstruct.instance = valptr->subval.instance;
do { /* await button, and echo */
for (i = 0; i < BUTTONS; i++) {
ddstruct.opcode = BUTREAD;
ddstruct.int1 = 4 >> i;
(*valptr->subval.devdrive) (&ddstruct);
if (ddstruct.logical)
*butnum = i + 1;
}
if (*butnum) {
ddstruct.opcode = XYREAD;
(*valptr->subval.devdrive) (&ddstruct);
*val = mm * (float) ddstruct.int1 + bb;
_core_devecho(VALUATOR, valnum, 0, 0, " ", *val);
break;
}
(void) gettimeofday(&newtime, &zone);
elapsed_time = (newtime.tv_sec - systime.tv_sec) * 1000000 +
(newtime.tv_usec - systime.tv_usec);
} while (elapsed_time < tim);
_core_devecho(VALUATOR, valnum, 0, 0, " ", *val);
if (valptr->subval.echo > 0)
if (--_core_critflag == 0 && _core_updatewin && _core_sighandle)
(*_core_sighandle) ();
return (0);
}