mirror of https://github.com/XEphem/XEphem.git
189 lines
4.5 KiB
C
189 lines
4.5 KiB
C
/* this file implements two handy fifo interfaces to sky view.
|
|
* 1. Inbound: A marker may be placed on the Sky View by writing a text string
|
|
* to the fifo named fifos/xephem_in_fifo. The format is "RA:X Dec:Y",
|
|
* where X and Y are in radians at epoch 2000.0. This fifo is opened and
|
|
* closed each time the Sky View window is opened and closed.
|
|
* 2. Outbound: If a process has the fifo fifos/xephem_loc_fifo open for reading
|
|
* then sky view popup menu will offer a button to send the cursor postion to
|
|
* this fifo. The format is the same as a line in .edb format. This fifo is
|
|
* attempted opened each time the popup is activated, and remains open until
|
|
* writing to it fails.
|
|
* Both fifos must be in the ShareDir directory.
|
|
* We also implement a common query and command interface to this facility and
|
|
* INDI.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#include <Xm/Xm.h>
|
|
|
|
#include "xephem.h"
|
|
|
|
static int sfifo_outready(void);
|
|
static void sfifo_sendout (Obj *op);
|
|
static void ififo_cb (XtPointer client, int *fdp, XtInputId *idp);
|
|
|
|
/* fifo names, with respect to ShareDir */
|
|
static char iname[] = "fifos/xephem_in_fifo"; /* inbound name */
|
|
static char oname[] = "fifos/xephem_loc_fifo"; /* outbound name */
|
|
|
|
/* inbound fifo fd and XtAddInput id */
|
|
static int ififo_fd = -1;
|
|
static XtInputId ififo_id;
|
|
|
|
/* outbound fifo fd */
|
|
static int ofifo_fd = -1;
|
|
|
|
/* return whether either our fifos or INDI is currently accepting commands */
|
|
int
|
|
telIsOn()
|
|
{
|
|
return (sc_isGotoOn() || !sfifo_outready());
|
|
}
|
|
|
|
/* send object to our fifos and INDI, ok if either not open */
|
|
void
|
|
telGoto (Obj *op)
|
|
{
|
|
/* check horizons */
|
|
if (op->s_alt < 0) {
|
|
xe_msg (1, "%s is below the horizon", op->o_name);
|
|
return;
|
|
} else if (!sv_hznOpOk(op)) {
|
|
xe_msg (1, "%s is below Sky View user horizon map", op->o_name);
|
|
return;
|
|
}
|
|
|
|
/* ok */
|
|
sfifo_sendout (op);
|
|
(void) sc_goto (op);
|
|
}
|
|
|
|
/* return 0 if the outbound fifo is ready, else -1.
|
|
* if successful, leave open. harmless if already open.
|
|
*/
|
|
static int
|
|
sfifo_outready()
|
|
{
|
|
char fn[1024];
|
|
|
|
/* success if already open */
|
|
if (ofifo_fd >= 0)
|
|
return(0);
|
|
|
|
/* open for write, non-blocking. only succeeds if a reader is active */
|
|
sprintf (fn, "%s/%s", getPrivateDir(), oname);
|
|
ofifo_fd = open (fn, O_WRONLY|O_NONBLOCK);
|
|
if (ofifo_fd < 0) {
|
|
sprintf (fn, "%s/%s", getShareDir(), oname);
|
|
ofifo_fd = open (fn, O_WRONLY|O_NONBLOCK);
|
|
if (ofifo_fd < 0)
|
|
return (-1);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
/* send op to ofifo, must be open already. close if trouble. */
|
|
static void
|
|
sfifo_sendout (Obj *op)
|
|
{
|
|
char buf[256];
|
|
|
|
/* must already be open */
|
|
if (ofifo_fd < 0)
|
|
return;
|
|
|
|
/* format and write */
|
|
db_write_line (op, buf);
|
|
strcat (buf, "\n");
|
|
if (write (ofifo_fd, buf, strlen(buf)) < 0) {
|
|
close (ofifo_fd);
|
|
ofifo_fd = -1;
|
|
}
|
|
}
|
|
|
|
/* connect to the inbound fifo. arrange for a marker to be drawn on skyview if
|
|
* a legal string is ever received. harmless to call if already open.
|
|
*/
|
|
void
|
|
sfifo_openin()
|
|
{
|
|
char fn[1024];
|
|
|
|
/* do nothing if already open */
|
|
if (ififo_fd >= 0)
|
|
return;
|
|
|
|
/* open r/w so we never block on the open but do block on reads */
|
|
sprintf (fn, "%s/%s", getPrivateDir(), iname);
|
|
ififo_fd = open (fn, O_RDWR);
|
|
if (ififo_fd < 0) {
|
|
sprintf (fn, "%s/%s", getShareDir(), iname);
|
|
ififo_fd = open (fn, O_RDWR);
|
|
if (ififo_fd < 0)
|
|
return;
|
|
}
|
|
|
|
/* connect a callback to monitor */
|
|
ififo_id = XtAppAddInput(xe_app, ififo_fd, (XtPointer)XtInputReadMask,
|
|
ififo_cb, NULL);
|
|
}
|
|
|
|
/* close the inbound fifo, if open */
|
|
void
|
|
sfifo_closein()
|
|
{
|
|
if (ififo_fd >= 0) {
|
|
close (ififo_id);
|
|
ififo_fd = -1;
|
|
XtRemoveInput (ififo_id);
|
|
}
|
|
}
|
|
|
|
/* called when reading from ififo will not block */
|
|
static void
|
|
ififo_cb (XtPointer client, int *fdp, XtInputId *idp)
|
|
{
|
|
char buf[64];
|
|
double ra, dec;
|
|
double alt, az;
|
|
int nr;
|
|
|
|
/* read */
|
|
nr = read (ififo_fd, buf, sizeof(buf));
|
|
if (nr <= 0) {
|
|
sfifo_closein();
|
|
return;
|
|
}
|
|
buf[nr] = '\0';
|
|
|
|
/* parse and mark */
|
|
if (sscanf (buf, "RA:%lf Dec:%lf", &ra, &dec) == 2) {
|
|
Now *np = mm_get_now();
|
|
Obj o;
|
|
|
|
memset (&o, 0, sizeof(o));
|
|
o.o_type = FIXED;
|
|
o.f_RA = ra;
|
|
o.f_dec = dec;
|
|
o.f_epoch = J2000;
|
|
obj_cir (np, &o);
|
|
sv_scopeMark (&o);
|
|
} else if (sscanf (buf, "Alt:%lf Az:%lf", &alt, &az) == 2) {
|
|
Now *np = mm_get_now();
|
|
Obj o;
|
|
|
|
sv_other (alt, az, 1, &dec, &ra);
|
|
memset (&o, 0, sizeof(o));
|
|
o.o_type = FIXED;
|
|
o.f_RA = ra;
|
|
o.f_dec = dec;
|
|
o.f_epoch = epoch == EOD ? mjd : epoch;
|
|
obj_cir (np, &o);
|
|
sv_scopeMark (&o);
|
|
}
|
|
}
|
|
|