886 lines
25 KiB
C
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);
|
|
}
|