mirror of https://github.com/XEphem/XEphem.git
1218 lines
32 KiB
C
1218 lines
32 KiB
C
/* code to manage the sun display
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <dirent.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
|
|
#include <Xm/Xm.h>
|
|
#include <Xm/Form.h>
|
|
#include <Xm/Frame.h>
|
|
#include <Xm/Label.h>
|
|
#include <Xm/PushB.h>
|
|
#include <Xm/DrawingA.h>
|
|
#include <Xm/CascadeB.h>
|
|
#include <Xm/ToggleB.h>
|
|
#include <Xm/ScrolledW.h>
|
|
#include <Xm/Separator.h>
|
|
#include <Xm/List.h>
|
|
#include <Xm/Text.h>
|
|
#include <Xm/RowColumn.h>
|
|
|
|
#include "xephem.h"
|
|
|
|
static void sun_create_shell (void);
|
|
static void sun_help_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_close_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_popdown_cb (Widget w, XtPointer client, XtPointer call);
|
|
static void sun_fpd_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_load_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_exp_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_download_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_save_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_load1(void);
|
|
static void sun_print_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_mloop_cb (Widget w, XtPointer client, XtPointer data);
|
|
static void sun_motion_eh (Widget w, XtPointer client, XEvent *ev,
|
|
Boolean *continue_to_dispatch);
|
|
static int readSOHOImage(void);
|
|
static int displayPic (char fn[], unsigned char *pic, int picl);
|
|
static void storePicFN (char fn[], int w);
|
|
static int getTS (int *tp, int *sp);
|
|
static int scanDir (char *dir, char ***files, int nfiles);
|
|
static void sun_refresh(void);
|
|
static int sun_ano (double *fracX, double *fracY, int *xp, int *yp, int w2x,
|
|
int arg);
|
|
static void sun_print(void);
|
|
static void sun_ps_annotate(void);
|
|
static void location (int x, int dx, int y, int dy, double scale, double *rap,
|
|
double *decp);
|
|
static int sun_gather (char ***files);
|
|
static void sun_display (FILE *fp, char *name);
|
|
static double carrington(Now *np);
|
|
|
|
#define SUNPOLERA degrad(286.13000) /* RA of n pole */
|
|
#define SUNPOLEDEC degrad(63.87000) /* dec of n pole */
|
|
|
|
#define NSREAD 2048 /* size of socket read */
|
|
|
|
static Widget sunshell_w; /* main shell */
|
|
static Widget sunda_w; /* main drawing area */
|
|
static Widget ssw_w; /* scrolled window for sun */
|
|
static Widget lpd_w; /* Load pulldown */
|
|
static Widget bytype_w; /* whether to filter by Type */
|
|
static Widget bysize_w; /* whether to filter by Size */
|
|
static Widget ts_w; /* timestamp label */
|
|
static Widget save_w; /* save PB */
|
|
static Widget coords_w; /* coordinates label */
|
|
static Widget crn_w; /* Carrington rotation number label */
|
|
static Pixmap sun_pm; /* staging area */
|
|
static unsigned char *rawpic; /* current raw picture file, if any */
|
|
static long rawpicl; /* length of rawpic */
|
|
static char *picfn; /* malloced name of current picture */
|
|
|
|
/* info about each image format choice */
|
|
typedef struct {
|
|
char *name; /* widget name of this choice */
|
|
char *label; /* widget label of this choice */
|
|
char *file; /* string in file name for this type */
|
|
int dx, dy; /* shift from image center to sun @ 1024 */
|
|
float scale; /* image scale, rads/pixel @ 1024 */
|
|
Widget w; /* controlling TB */
|
|
} SOHOType;
|
|
/* N.B. order must agree with switch in sun_print() */
|
|
static SOHOType stype[] = {
|
|
{"EIT171", "EIT 171", "eit_171", 0, 0, degrad(0.00075)},
|
|
{"EIT195", "EIT 195", "eit_195", 0, 0, degrad(0.00075)},
|
|
{"EIT284", "EIT 284", "eit_284", 0, 0, degrad(0.00075)},
|
|
{"EIT304", "EIT 304", "eit_304", 0, 0, degrad(0.00075)},
|
|
{"HMICon", "HMI Continuum", "hmi_igr", 0, 0, degrad(0.00055)},
|
|
{"HMIMag", "HMI Magnetogram", "hmi_mag", 0, 0, degrad(0.00055)},
|
|
{"LASC2", "LASCO C2", "c2", -16, 20, degrad(0.00365)},
|
|
{"LASC3", "LASCO C3", "c3", -16, 20, degrad(0.00775)},
|
|
};
|
|
|
|
/* info about size of image to get/display */
|
|
typedef struct {
|
|
char *name; /* widget name of this choice */
|
|
char *label; /* widget label of this choice */
|
|
char *file; /* string in file name for this size */
|
|
int scale; /* wrt 256 */
|
|
Widget w; /* controlling TB */
|
|
} SOHOSize;
|
|
static SOHOSize ssize[] = {
|
|
{"512x512", "512x512", "512", 2},
|
|
{"1024x1024", "1024x1024", "1024", 1},
|
|
};
|
|
|
|
static char *sohohost; /* SOHO web site */
|
|
static char suncategory[] = "Sun";
|
|
|
|
/* bring up the sun menu, creating if first time */
|
|
void
|
|
sun_manage (void)
|
|
{
|
|
if (!sunshell_w) {
|
|
sun_create_shell();
|
|
sohohost = getXRes ("SOHOhost", NULL);
|
|
}
|
|
|
|
XtPopup (sunshell_w, XtGrabNone);
|
|
set_something (sunshell_w, XmNiconic, (XtArgVal)False);
|
|
/* rely on expose to do fresh update */
|
|
|
|
/* register we are now up */
|
|
setXRes (sun_viewupres(), "1");
|
|
}
|
|
|
|
/* called to update our scene */
|
|
void
|
|
sun_update (Now *np, int how_much)
|
|
{
|
|
if (!isUp(sunshell_w))
|
|
return;
|
|
|
|
timestamp (np, ts_w);
|
|
f_double (crn_w, "CRN: %.6f", carrington(np));
|
|
if (sun_pm)
|
|
sun_refresh();
|
|
}
|
|
|
|
/* called to put up or remove the watch cursor. */
|
|
void
|
|
sun_cursor (Cursor c)
|
|
{
|
|
Window win;
|
|
|
|
if (sunshell_w && (win = XtWindow(sunshell_w)) != 0) {
|
|
Display *dsp = XtDisplay(sunshell_w);
|
|
if (c)
|
|
XDefineCursor (dsp, win, c);
|
|
else
|
|
XUndefineCursor (dsp, win);
|
|
}
|
|
}
|
|
|
|
/* called when basic resources change */
|
|
void
|
|
sun_newres (void)
|
|
{
|
|
if (!sunshell_w)
|
|
return;
|
|
sun_update (mm_get_now(), 1);
|
|
}
|
|
|
|
/* return the name of the resource containing whether this view is up */
|
|
char *
|
|
sun_viewupres (void)
|
|
{
|
|
return ("SunViewUp");
|
|
}
|
|
|
|
/* create main shell */
|
|
static void
|
|
sun_create_shell (void)
|
|
{
|
|
Widget pd_w, cb_w, mb_w;
|
|
Widget w, f_w;
|
|
Arg args[20];
|
|
char buf[64];
|
|
int i;
|
|
int n;
|
|
|
|
/* create outter shell and form */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNcolormap, xe_cm); n++;
|
|
XtSetArg (args[n], XmNtitle, "xephem Sun"); n++;
|
|
XtSetArg (args[n], XmNiconName, "Sun"); n++;
|
|
XtSetArg (args[n], XmNdeleteResponse, XmUNMAP); n++;
|
|
sunshell_w = XtCreatePopupShell ("Sun", topLevelShellWidgetClass,
|
|
toplevel_w, args, n);
|
|
set_something (sunshell_w, XmNcolormap, (XtArgVal)xe_cm);
|
|
XtAddCallback (sunshell_w, XmNpopdownCallback, sun_popdown_cb, 0);
|
|
setup_icon (sunshell_w);
|
|
sr_reg (sunshell_w, "XEphem*Sun.x", suncategory, 0);
|
|
sr_reg (sunshell_w, "XEphem*Sun.y", suncategory, 0);
|
|
sr_reg (sunshell_w, "XEphem*Sun.height", suncategory, 0);
|
|
sr_reg (sunshell_w, "XEphem*Sun.width", suncategory, 0);
|
|
sr_reg (NULL, sun_viewupres(), suncategory, 0);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNverticalSpacing, 5); n++;
|
|
XtSetArg (args[n], XmNhorizontalSpacing, 5); n++;
|
|
f_w = XmCreateForm (sunshell_w, "SunF", args, n);
|
|
XtAddCallback (f_w, XmNhelpCallback, sun_help_cb, 0);
|
|
XtManageChild(f_w);
|
|
|
|
/* menu bar */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
|
mb_w = XmCreateMenuBar (f_w, "SMB", args, n);
|
|
XtManageChild (mb_w);
|
|
|
|
/* Control */
|
|
|
|
n = 0;
|
|
pd_w = XmCreatePulldownMenu (mb_w, "CPD", args, n);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'D'); n++;
|
|
w = XmCreatePushButton (pd_w, "Download", args, n);
|
|
set_xmstring (w, XmNlabelString, "Download latest");
|
|
wtip (w, "Download latest SOHO image of given Type and Size");
|
|
XtAddCallback (w, XmNactivateCallback, sun_download_cb, 0);
|
|
XtManageChild (w);
|
|
|
|
/* save not sensitive until image has been downloaded */
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'S'); n++;
|
|
XtSetArg (args[n], XmNsensitive, False); n++;
|
|
save_w = XmCreatePushButton (pd_w, "Save", args, n);
|
|
set_xmstring (save_w, XmNlabelString, "Save downloaded image");
|
|
wtip (save_w, "Save newly downloaded image to local disk");
|
|
XtAddCallback (save_w, XmNactivateCallback, sun_save_cb, 0);
|
|
XtManageChild (save_w);
|
|
|
|
n = 0;
|
|
w = XmCreateSeparator (pd_w, "S1", args, n);
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'T'); n++;
|
|
XtSetArg (args[n], XmNindicatorOn, True); n++;
|
|
XtSetArg (args[n], XmNvisibleWhenOff, True); n++;
|
|
bytype_w = XmCreateToggleButton (pd_w, "ByType", args, n);
|
|
set_xmstring (bytype_w, XmNlabelString, "Filter Files by Type");
|
|
wtip (bytype_w, "Whether Files restricts choices to Type");
|
|
sr_reg (bytype_w, NULL, suncategory, 0);
|
|
XtManageChild (bytype_w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'F'); n++;
|
|
XtSetArg (args[n], XmNindicatorOn, True); n++;
|
|
XtSetArg (args[n], XmNvisibleWhenOff, True); n++;
|
|
bysize_w = XmCreateToggleButton (pd_w, "BySize", args, n);
|
|
set_xmstring (bysize_w, XmNlabelString, "Filter Files by Size");
|
|
wtip (bysize_w, "Whether Files restricts choices to Size");
|
|
sr_reg (bysize_w, NULL, suncategory, 0);
|
|
XtManageChild (bysize_w);
|
|
|
|
n = 0;
|
|
w = XmCreateSeparator (pd_w, "S1", args, n);
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'P'); n++;
|
|
w = XmCreatePushButton (pd_w, "Print", args, n);
|
|
XtAddCallback (w, XmNactivateCallback, sun_print_cb, NULL);
|
|
wtip (w, "Print the current SOHO image");
|
|
set_xmstring (w, XmNlabelString, "Print...");
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'U'); n++;
|
|
w = XmCreatePushButton (pd_w, "Ann", args, n);
|
|
XtAddCallback (w, XmNactivateCallback, ano_cb, NULL);
|
|
set_xmstring (w, XmNlabelString, "User annotation...");
|
|
wtip (w, "Draw text and lines on curret SOHO image");
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
n += ml_addacc (args, n);
|
|
XtSetArg (args[n], XmNmnemonic, 'm'); n++;
|
|
w = XmCreatePushButton (pd_w, "Movie", args, n);
|
|
XtAddCallback (w, XmNactivateCallback, sun_mloop_cb, NULL);
|
|
set_xmstring (w, XmNlabelString, "Add to movie...");
|
|
wtip (w, "Add current image to movie loop");
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
w = XmCreateSeparator (pd_w, "S1", args, n);
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'C'); n++;
|
|
w = XmCreatePushButton (pd_w, "Close", args, n);
|
|
wtip (w, "Close this SOHO window");
|
|
XtAddCallback (w, XmNactivateCallback, sun_close_cb, NULL);
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'C'); n++;
|
|
XtSetArg (args[n], XmNsubMenuId, pd_w); n++;
|
|
cb_w = XmCreateCascadeButton (mb_w, "Control", args, n);
|
|
XtManageChild (cb_w);
|
|
|
|
/* Load */
|
|
|
|
n = 0;
|
|
lpd_w = XmCreatePulldownMenu (mb_w, "FPD", args, n);
|
|
XtAddCallback (lpd_w, XmNmapCallback, sun_fpd_cb, NULL);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'L'); n++;
|
|
XtSetArg (args[n], XmNsubMenuId, lpd_w); n++;
|
|
cb_w = XmCreateCascadeButton (mb_w, "Files", args, n);
|
|
wtip (cb_w, "Select a local SOHO file to display");
|
|
XtManageChild (cb_w);
|
|
|
|
/* Type */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNradioBehavior, True); n++;
|
|
XtSetArg (args[n], XmNradioAlwaysOne, True); n++;
|
|
pd_w = XmCreatePulldownMenu (mb_w, "TPD", args, n);
|
|
|
|
for (i = 0; i < XtNumber(stype); i++) {
|
|
SOHOType *tp = &stype[i];
|
|
n = 0;
|
|
XtSetArg (args[n], XmNindicatorOn, True); n++;
|
|
XtSetArg (args[n], XmNvisibleWhenOff, True); n++;
|
|
tp->w = XmCreateToggleButton (pd_w, tp->name, args, n);
|
|
set_xmstring (tp->w, XmNlabelString, tp->label);
|
|
sprintf (buf, "XEphem*Sun*%s.set", tp->name);
|
|
sr_reg (tp->w, buf, suncategory, 0);
|
|
XtManageChild (tp->w);
|
|
}
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'T'); n++;
|
|
XtSetArg (args[n], XmNsubMenuId, pd_w); n++;
|
|
cb_w = XmCreateCascadeButton (mb_w, "Type", args, n);
|
|
wtip (cb_w, "Specify SOHO image type to download");
|
|
XtManageChild (cb_w);
|
|
|
|
/* Size */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNradioBehavior, True); n++;
|
|
XtSetArg (args[n], XmNradioAlwaysOne, True); n++;
|
|
pd_w = XmCreatePulldownMenu (mb_w, "TPD", args, n);
|
|
|
|
for (i = 0; i < XtNumber(ssize); i++) {
|
|
SOHOSize *sp = &ssize[i];
|
|
n = 0;
|
|
XtSetArg (args[n], XmNindicatorOn, True); n++;
|
|
XtSetArg (args[n], XmNvisibleWhenOff, True); n++;
|
|
sp->w = XmCreateToggleButton (pd_w, sp->name, args, n);
|
|
set_xmstring (sp->w, XmNlabelString, sp->label);
|
|
sprintf (buf, "XEphem*Sun*%s.set", sp->name);
|
|
sr_reg (sp->w, buf, suncategory, 0);
|
|
XtManageChild (sp->w);
|
|
}
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'S'); n++;
|
|
XtSetArg (args[n], XmNsubMenuId, pd_w); n++;
|
|
cb_w = XmCreateCascadeButton (mb_w, "Size", args, n);
|
|
wtip (cb_w, "Specify SOHO image size to download");
|
|
XtManageChild (cb_w);
|
|
|
|
/* help */
|
|
|
|
n = 0;
|
|
pd_w = XmCreatePulldownMenu (mb_w, "TPD", args, n);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'H'); n++;
|
|
w = XmCreatePushButton (pd_w, "Help", args, n);
|
|
XtAddCallback (w, XmNactivateCallback, sun_help_cb, 0);
|
|
XtManageChild (w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNmnemonic, 'H'); n++;
|
|
XtSetArg (args[n], XmNsubMenuId, pd_w); n++;
|
|
cb_w = XmCreateCascadeButton (mb_w, "Help", args, n);
|
|
set_something (mb_w, XmNmenuHelpWidget, (XtArgVal)cb_w);
|
|
XtManageChild (cb_w);
|
|
|
|
/* time stamp and CRN at bottom */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
|
|
XtSetArg (args[n], XmNrightPosition, 50); n++;
|
|
XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
|
|
ts_w = XmCreateLabel (f_w, "TS", args, n);
|
|
XtManageChild (ts_w);
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
|
|
XtSetArg (args[n], XmNleftPosition, 50); n++;
|
|
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
|
|
crn_w = XmCreateLabel (f_w, "CRN", args, n);
|
|
XtManageChild (crn_w);
|
|
|
|
/* cursor coords above */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
|
|
XtSetArg (args[n], XmNbottomWidget, ts_w); n++;
|
|
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
|
|
coords_w = XmCreateLabel (f_w, "Coordinates", args, n);
|
|
XtManageChild (coords_w);
|
|
|
|
/* remainder is scrolled window for image */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
|
XtSetArg (args[n], XmNtopWidget, mb_w); n++;
|
|
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
|
|
XtSetArg (args[n], XmNbottomWidget, coords_w); n++;
|
|
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
|
|
XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
|
|
XtSetArg (args[n], XmNshadowThickness, 1); n++;
|
|
ssw_w = XmCreateScrolledWindow (f_w, "SunSW", args, n);
|
|
XtManageChild (ssw_w);
|
|
|
|
/* workarea is a drawing area */
|
|
|
|
n = 0;
|
|
XtSetArg (args[n], XmNwidth, 1024); n++; /* not critical */
|
|
XtSetArg (args[n], XmNheight, 1024); n++; /* not critical */
|
|
XtSetArg (args[n], XmNmarginHeight, 0); n++;
|
|
sunda_w = XmCreateDrawingArea (ssw_w, "SunMap", args, n);
|
|
XtAddEventHandler (sunda_w,PointerMotionMask,False,sun_motion_eh,0);
|
|
XtAddCallback (sunda_w, XmNexposeCallback, sun_exp_cb, NULL);
|
|
XtManageChild (sunda_w);
|
|
|
|
/* SW assumes work is its child but just to be tidy about it .. */
|
|
set_something (ssw_w, XmNworkWindow, (XtArgVal)sunda_w);
|
|
}
|
|
|
|
/* called when the main scrolled area needs refreshing */
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_exp_cb (Widget w, XtPointer client, XtPointer call)
|
|
{
|
|
XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
|
|
XExposeEvent *e = &c->event->xexpose;
|
|
Now *np = mm_get_now();
|
|
|
|
watch_cursor (1);
|
|
|
|
switch (c->reason) {
|
|
case XmCR_EXPOSE: {
|
|
/* turn off gravity so we get expose events for either shrink or
|
|
* expand.
|
|
* also center the scroll bars initially.
|
|
*/
|
|
static int before;
|
|
|
|
if (!before) {
|
|
XSetWindowAttributes swa;
|
|
unsigned long mask = CWBitGravity | CWBackingStore;
|
|
|
|
swa.bit_gravity = ForgetGravity;
|
|
swa.backing_store = NotUseful;
|
|
XChangeWindowAttributes (e->display, e->window, mask, &swa);
|
|
|
|
before = 1;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
printf ("Unexpected mda_w event. type=%d\n", c->reason);
|
|
abort();
|
|
}
|
|
|
|
if (!sun_pm)
|
|
sun_load1(); /* load initial if possible */
|
|
if (sun_pm)
|
|
sun_refresh();
|
|
timestamp (np, ts_w);
|
|
f_double (crn_w, "CRN: %.6f", carrington(np));
|
|
|
|
watch_cursor (0);
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_help_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
static char *msg[] = {
|
|
"This tool opens and displays solar images"
|
|
};
|
|
|
|
hlp_dialog ("Sun", msg, XtNumber(msg));
|
|
}
|
|
|
|
static void
|
|
sun_popdown_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
/* register we are now down */
|
|
setXRes (sun_viewupres(), "0");
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_close_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
/* let popdown do the real work */
|
|
XtPopdown (sunshell_w);
|
|
}
|
|
|
|
static int
|
|
fn_cmp (const void *s1, const void *s2)
|
|
{
|
|
return (strcmp (*(char **)s1, *(char **)s2));
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_print_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
XPSAsk ("Sun View", sun_print);
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_mloop_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
ml_add (sun_pm, ts_w);
|
|
}
|
|
|
|
/* proceed to generate a postscript file.
|
|
* call XPSClose() when finished.
|
|
*/
|
|
static void
|
|
sun_print (void)
|
|
{
|
|
Display *dsp = XtDisplay(sunda_w);
|
|
Window win = XtWindow(sunda_w);
|
|
Window root;
|
|
Pixmap drawpm;
|
|
int rx, ry;
|
|
unsigned int bw, dep;
|
|
unsigned int wid, hei;
|
|
int s, t;
|
|
|
|
/* must be up and showing */
|
|
if (!isUp(sunshell_w) || !sun_pm) {
|
|
xe_msg (1, "Sun image be open to print.");
|
|
XPSClose();
|
|
return;
|
|
}
|
|
|
|
watch_cursor(1);
|
|
|
|
/* get size */
|
|
getTS (&t, &s);
|
|
s = 1024/ssize[s].scale;
|
|
|
|
/* fit view in square across the top and prepare to capture X calls */
|
|
XPSXBegin (sun_pm, 0, 0, s, s, 1*72, 10*72, (int)(6.5*72));
|
|
|
|
/* since our normal expose refresh draws annotation directly into the
|
|
* sunda_w window (which in turn is because we don't want to burn it
|
|
* into the sun_pm which we create only once when the image is read)
|
|
* we have to build another temp pixmap here just to add annotation
|
|
* Also, it would look nice to block out the black background of
|
|
* the MDI images but they use the same color in the dark sunspots.
|
|
*/
|
|
XGetGeometry (dsp, win, &root, &rx, &ry, &wid, &hei, &bw, &dep);
|
|
drawpm = XCreatePixmap (dsp, win, wid, hei, dep);
|
|
XCopyArea (XtD, sun_pm, drawpm, DefaultGC(XtD, DefaultScreen(XtD)),
|
|
0, 0, wid, hei, 0, 0);
|
|
ano_draw (sunda_w, drawpm, sun_ano, 0);
|
|
XPSPixmap (drawpm, s, s, xe_cm, 0, 0);
|
|
XFreePixmap (dsp, drawpm);
|
|
|
|
/* no more X captures */
|
|
XPSXEnd();
|
|
|
|
/* add some extra info */
|
|
sun_ps_annotate ();
|
|
|
|
/* finished */
|
|
XPSClose();
|
|
|
|
watch_cursor(0);
|
|
}
|
|
|
|
static void
|
|
sun_ps_annotate (void)
|
|
{
|
|
Now *np = mm_get_now();
|
|
char dir[128];
|
|
char buf[128];
|
|
int ctr = 306; /* = 8.5*72/2 */
|
|
int lx = ctr-5;
|
|
int y;
|
|
|
|
/* caption */
|
|
y = AROWY(13);
|
|
(void) strcpy (buf, "XEphem Solar View");
|
|
(void) sprintf (dir, "(%s) %d %d cstr", buf, ctr, y);
|
|
XPSDirect (dir);
|
|
|
|
y = AROWY(9);
|
|
fs_date (buf, pref_get(PREF_DATE_FORMAT), mjd_day(mjd));
|
|
(void) sprintf (dir, "(UTC Date:) %d %d rstr (%s) %d %d lstr\n",
|
|
lx, y, buf, lx+10, y);
|
|
XPSDirect (dir);
|
|
|
|
y = AROWY(8);
|
|
fs_time (buf, mjd_hr(mjd));
|
|
(void) sprintf (dir, "(UTC Time:) %d %d rstr (%s) %d %d lstr\n",
|
|
lx, y, buf, lx+10, y);
|
|
XPSDirect (dir);
|
|
|
|
y = AROWY(7);
|
|
sprintf (buf, "%.6f", carrington(np));
|
|
(void) sprintf (dir,"(Carrington number:) %d %d rstr (%s) %d %d lstr\n",
|
|
lx, y, buf, lx+10, y);
|
|
XPSDirect (dir);
|
|
}
|
|
|
|
/* load one file initially for fun */
|
|
static void
|
|
sun_load1 (void)
|
|
{
|
|
char **files;
|
|
int nfiles;
|
|
|
|
nfiles = sun_gather (&files);
|
|
if (nfiles > 0) {
|
|
FILE *fp = fopend (files[0], "auxil", "r");
|
|
sun_display (fp, files[0]);
|
|
fclose (fp);
|
|
XtFree ((char *) files);
|
|
}
|
|
}
|
|
|
|
/* gather and sort all qualified file names.
|
|
* N.B. caller must free *files
|
|
*/
|
|
static int
|
|
sun_gather (char ***files)
|
|
{
|
|
char sdir[1024];
|
|
int nfiles = 0;
|
|
|
|
*files = NULL;
|
|
sprintf (sdir, "%s/auxil", getShareDir());
|
|
nfiles += scanDir (sdir, files, nfiles);
|
|
nfiles += scanDir (getPrivateDir(), files, nfiles);
|
|
qsort (*files, nfiles, sizeof(char *), fn_cmp);
|
|
|
|
return (nfiles);
|
|
}
|
|
|
|
/* display the given picture file stream */
|
|
static void
|
|
sun_display (FILE *fp, char *name)
|
|
{
|
|
unsigned char *pic;
|
|
int picl;
|
|
|
|
fseek (fp, 0L, SEEK_END);
|
|
picl = (int) ftell(fp);
|
|
pic = (unsigned char *) XtMalloc (picl);
|
|
fseek (fp, 0L, SEEK_SET);
|
|
fread (pic, picl, 1, fp);
|
|
if (displayPic (name, pic, picl) < 0)
|
|
XtFree ((char *)pic); /* already told user why */
|
|
}
|
|
|
|
/* called when the Files pulldown is about to come up */
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_fpd_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
WidgetList children;
|
|
Cardinal numChildren;
|
|
char **files;
|
|
int i, nfiles;
|
|
|
|
/* gather and sort all file names */
|
|
nfiles = sun_gather (&files);
|
|
|
|
/* load into pulldown menu */
|
|
get_something (lpd_w, XmNchildren, (XtArgVal)&children);
|
|
get_something (lpd_w, XmNnumChildren, (XtArgVal)&numChildren);
|
|
for (i = 0; i < nfiles; i++) {
|
|
Widget w;
|
|
if (i < numChildren) {
|
|
w = children[i];
|
|
} else {
|
|
w = XmCreatePushButton (lpd_w, "LPDPB", NULL, 0);
|
|
XtAddCallback (w, XmNactivateCallback, sun_load_cb, NULL);
|
|
}
|
|
set_xmstring (w, XmNlabelString, files[i]);
|
|
XtManageChild (w);
|
|
}
|
|
|
|
/* turn off unused buttons */
|
|
for (; i < numChildren; i++)
|
|
XtUnmanageChild (children[i]);
|
|
|
|
/* set to multi-column if lots of files */
|
|
if (nfiles >= 5)
|
|
set_something (w,XmNnumColumns,(XtArgVal)((int)(sqrt(nfiles/5.0))));
|
|
else
|
|
set_something (w, XmNnumColumns, (XtArgVal)1);
|
|
|
|
/* finished with list */
|
|
XtFree ((char *) files);
|
|
}
|
|
|
|
/* called to load a local file when a Load PB is clicked.
|
|
* local file name is our labelString
|
|
*/
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_load_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
char *name;
|
|
FILE *fp;
|
|
int i;
|
|
|
|
get_xmstring (w, XmNlabelString, &name);
|
|
|
|
fp = fopend (name, "auxil", "r");
|
|
if (fp) {
|
|
/* display */
|
|
sun_display (fp, name);
|
|
fclose (fp);
|
|
|
|
/* set type and size in menus to match based on fn */
|
|
for (i = 0; i < XtNumber(stype); i++) {
|
|
if (strstr (name, stype[i].file)) {
|
|
XmToggleButtonSetState (stype[i].w, True, True);
|
|
break;
|
|
}
|
|
}
|
|
for (i = 0; i < XtNumber(ssize); i++) {
|
|
if (strstr (name, ssize[i].file)) {
|
|
XmToggleButtonSetState (ssize[i].w, True, True);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* can not save a file loaded from disk */
|
|
XtSetSensitive (save_w, False);
|
|
}
|
|
|
|
XtFree (name);
|
|
}
|
|
|
|
/* called to download the latest image of the current type and size */
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_download_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
watch_cursor (1);
|
|
|
|
/* read image */
|
|
if (readSOHOImage() < 0) {
|
|
stopd_down();
|
|
watch_cursor (0);
|
|
return;
|
|
}
|
|
|
|
/* ok to save */
|
|
XtSetSensitive (save_w, True);
|
|
|
|
stopd_down();
|
|
watch_cursor (0);
|
|
}
|
|
|
|
/* called to save giffn[], if any, in private dir */
|
|
/* ARGSUSED */
|
|
static void
|
|
sun_save_cb (Widget w, XtPointer client, XtPointer data)
|
|
{
|
|
char fn[1024];
|
|
FILE *fp;
|
|
|
|
/* never allowed again until new download */
|
|
XtSetSensitive (save_w, False);
|
|
|
|
/* sanity check */
|
|
if (!picfn || !rawpic) {
|
|
xe_msg (1, "No image to save");
|
|
return;
|
|
}
|
|
|
|
/* create file */
|
|
sprintf (fn, "%s/%s", getPrivateDir(), picfn);
|
|
fp = fopenh (fn, "w");
|
|
if (!fp) {
|
|
xe_msg (1, "%s:\n%s", fn, syserrstr());
|
|
return;
|
|
}
|
|
|
|
/* write */
|
|
if (fwrite (rawpic, rawpicl, 1, fp) != 1) {
|
|
xe_msg (1, "%s:\n%s", picfn, syserrstr());
|
|
fclose (fp);
|
|
return;
|
|
}
|
|
|
|
/* ok */
|
|
if (confirm())
|
|
xe_msg (1, "%s:\nWritten successfully", picfn);
|
|
fclose (fp);
|
|
}
|
|
|
|
/* called to display coords from cursor roaming */
|
|
static void
|
|
sun_motion_eh (Widget w, XtPointer client, XEvent *ev, Boolean *dispatch)
|
|
{
|
|
Display *dsp = XtDisplay(w);
|
|
Window win = XtWindow(w);
|
|
SOHOType *tp;
|
|
SOHOSize *sp;
|
|
int t, s;
|
|
Window root, child;
|
|
int rx, ry, wx, wy;
|
|
unsigned mask;
|
|
unsigned int bw, dep;
|
|
unsigned int wid, hei;
|
|
double r, d;
|
|
char cbuf[64], rbuf[32], dbuf[32];
|
|
|
|
if (!picfn || !rawpic)
|
|
return;
|
|
|
|
XGetGeometry (dsp, win, &root, &rx, &ry, &wid, &hei, &bw, &dep);
|
|
XQueryPointer (dsp, win, &root, &child, &rx, &ry, &wx, &wy, &mask);
|
|
|
|
getTS (&t, &s);
|
|
tp = &stype[t];
|
|
sp = &ssize[s];
|
|
location (wx-wid/2, tp->dx/sp->scale, wy-hei/2, tp->dy/sp->scale,
|
|
tp->scale*sp->scale, &r, &d);
|
|
|
|
fs_sexa (rbuf, radhr(r), 3, 600);
|
|
fs_sexa (dbuf, raddeg(d), 3, 60);
|
|
sprintf (cbuf, "RA, Dec: %s %s", rbuf, dbuf);
|
|
set_xmstring (coords_w, XmNlabelString, cbuf);
|
|
}
|
|
|
|
/* read picture from sohohost and display.
|
|
* store picture in rawpic[] and its filename in *picfn.
|
|
* return 0 if ok else xe_msg and -1
|
|
*/
|
|
static int
|
|
readSOHOImage (void)
|
|
{
|
|
char fn[1024];
|
|
int t, s;
|
|
char get[1024];
|
|
char buf[1024];
|
|
char filetime[100];
|
|
char filetype[100];
|
|
int isjpeg, jpegl;
|
|
int njpeg;
|
|
unsigned char *jpeg;
|
|
XE_SSL_FD ssl_fd;
|
|
int fd, nr;
|
|
struct tm tm;
|
|
|
|
memset(&ssl_fd, 0, sizeof(ssl_fd));
|
|
memset(&tm, 0, sizeof(struct tm));
|
|
|
|
/* get desired type and size */
|
|
if (getTS (&t, &s) < 0)
|
|
return (-1);
|
|
|
|
/* build latest fn */
|
|
sprintf (filetype, "%s", stype[t].file);
|
|
sprintf (fn, "/data/realtime/%s/%s/latest.jpg", filetype, ssize[s].file);
|
|
|
|
/* build GET command */
|
|
sprintf (get, "GET http://%s%s HTTP/1.0\r\nUser-Agent: xephem/%s\r\n\r\n", sohohost, fn, PATCHLEVEL);
|
|
|
|
/* query server */
|
|
fd = httpsGET (sohohost, get, buf, &ssl_fd);
|
|
if (fd < 0) {
|
|
xe_msg (1, "https get: %s", buf);
|
|
return (-1);
|
|
}
|
|
|
|
/* read header (everything to first blank line), looking for jpeg */
|
|
isjpeg = 0;
|
|
jpegl = 0;
|
|
while (ssl_recvline (&ssl_fd, buf, sizeof(buf)) > 1) {
|
|
xe_msg (0, "Rcv: %s", buf);
|
|
if (strstr (buf, "Content-Type:") && strstr (buf, "image/jpeg"))
|
|
isjpeg = 1;
|
|
if (strstr (buf, "Content-Length:"))
|
|
jpegl = atoi (buf+15);
|
|
if (strstr (buf, "Last-Modified:")) {
|
|
strptime(buf+20, "%d %b %Y %H:%M:%S %Z", &tm);
|
|
strftime(filetime, sizeof(filetime), "%Y%m%d_%H%M%S", &tm);
|
|
xe_msg (0, "Rcv: Filetime: %s", filetime);
|
|
}
|
|
}
|
|
if (!isjpeg) {
|
|
while (ssl_recvline (&ssl_fd, buf, sizeof(buf)) > 0)
|
|
xe_msg (0, "Rcv: %s", buf);
|
|
xe_msg (1, "Error talking to SOHO .. see File->System log\n");
|
|
SSL_free (ssl_fd.ssl);
|
|
close (ssl_fd.fd);
|
|
return (-1);
|
|
}
|
|
if (jpegl == 0) {
|
|
xe_msg (1, "No Content-Length in header");
|
|
SSL_free (ssl_fd.ssl);
|
|
close (ssl_fd.fd);
|
|
return (-1);
|
|
}
|
|
|
|
/* remainder should be a jpeg file, read into jpeg[] */
|
|
pm_up();
|
|
jpeg = NULL;
|
|
for (njpeg = 0; njpeg < jpegl; njpeg += nr) {
|
|
pm_set (100*njpeg/jpegl);
|
|
jpeg = (unsigned char *) XtRealloc ((char*)jpeg, njpeg+NSREAD);
|
|
nr = SSL_read (ssl_fd.ssl, jpeg+njpeg, NSREAD);
|
|
if (nr <= 0) {
|
|
xe_msg (1, "%s: ssl read error code: %d", sohohost, SSL_get_error(ssl_fd.ssl, nr));
|
|
pm_down();
|
|
SSL_free (ssl_fd.ssl);
|
|
close (ssl_fd.fd);
|
|
return (-1);
|
|
}
|
|
if (nr == 0)
|
|
break;
|
|
}
|
|
pm_down();
|
|
SSL_free (ssl_fd.ssl);
|
|
close (ssl_fd.fd);
|
|
|
|
sprintf (fn, "/%s_%s.jpg", filetime, filetype);
|
|
/* display jpeg */
|
|
if (displayPic (fn, jpeg, njpeg) < 0)
|
|
return (-1);
|
|
|
|
/* clean up */
|
|
return (0);
|
|
}
|
|
|
|
/* display the picture file named fn and install as the "current" file.
|
|
* return 0 if ok, else -1 and why xe_msg()
|
|
* N.B. picture must be malloced memory and user should /not/ free, let us manage it
|
|
*/
|
|
static int
|
|
displayPic (char fn[], unsigned char *pic, int picl)
|
|
{
|
|
static XColor xcol[256];
|
|
static int xcolset;
|
|
Pixmap pm;
|
|
char buf[1024];
|
|
int w, h;
|
|
int ok = 0;
|
|
|
|
/* explode into pm */
|
|
if (strstr (fn, ".gif")) {
|
|
ok = 1;
|
|
if (gif2pm (XtD, xe_cm, pic, picl, &w, &h, &pm, buf) < 0) {
|
|
xe_msg (1, "Display GIF: %s:\n%s", fn, buf);
|
|
return (-1);
|
|
}
|
|
}
|
|
if (strstr (fn, ".jpg")) {
|
|
char tmpfn[2048];
|
|
FILE *tmpfp;
|
|
|
|
ok = 1;
|
|
|
|
/* free last batch of colors */
|
|
if (xcolset) {
|
|
freeXColors (XtD, xe_cm, xcol, XtNumber(xcol));
|
|
xcolset = 0;
|
|
}
|
|
|
|
/* convert JPEG to pixmap */
|
|
(void) tempfilename (tmpfn, "suntmp", ".jpg");
|
|
tmpfp = fopen (tmpfn, "wb+");
|
|
if (!tmpfp) {
|
|
xe_msg (1, "Can not create tmp file: %s", tmpfn);
|
|
return (-1);
|
|
}
|
|
fwrite(pic, picl, 1, tmpfp);
|
|
rewind(tmpfp);
|
|
if (jpeg2pm (XtD, xe_cm, tmpfp, &w, &h, &pm, xcol, buf) < 0) {
|
|
xe_msg (1, "Display JPEG: %s:\n%s", fn, buf);
|
|
fclose (tmpfp);
|
|
unlink (tmpfn);
|
|
return (-1);
|
|
}
|
|
xcolset = 1;
|
|
fclose (tmpfp);
|
|
unlink (tmpfn);
|
|
}
|
|
|
|
if (ok == 0) {
|
|
xe_msg (1, "Unknown file type: %s", fn);
|
|
return (-1);
|
|
}
|
|
|
|
/* replace pixmap and center */
|
|
if (sun_pm)
|
|
XFreePixmap (XtD, sun_pm);
|
|
sun_pm = pm;
|
|
set_something (sunda_w, XmNwidth, (XtArgVal)(Dimension)w);
|
|
set_something (sunda_w, XmNheight, (XtArgVal)(Dimension)h);
|
|
centerScrollBars(ssw_w);
|
|
sun_refresh();
|
|
if (rawpic)
|
|
XtFree ((char *)rawpic);
|
|
rawpic = pic;
|
|
rawpicl = picl;
|
|
storePicFN (fn, w);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/* store base of fn[] in picfn[], include width w in name somewhere */
|
|
static void
|
|
storePicFN (char fn[], int w)
|
|
{
|
|
char buf[1024];
|
|
char *sp, *lsp;
|
|
|
|
/* find last slash in fn */
|
|
lsp = NULL;
|
|
for (sp = fn; sp; sp = strchr (sp+1, '/'))
|
|
lsp = sp;
|
|
if (!lsp) {
|
|
printf ("Bug! no / in filename '%s'\n", fn);
|
|
abort();
|
|
}
|
|
|
|
sprintf (buf, "SOHO_%d_%s", w, lsp+1);
|
|
if (picfn)
|
|
XtFree (picfn);
|
|
picfn = XtNewString (buf);
|
|
}
|
|
|
|
/* get indices into user's current type and size settings.
|
|
* either can be NULL if not interested.
|
|
*/
|
|
static int
|
|
getTS (int *tp, int *sp)
|
|
{
|
|
int i;
|
|
|
|
if (tp) {
|
|
for (i = 0; i < XtNumber(stype); i++) {
|
|
if (XmToggleButtonGetState (stype[i].w)) {
|
|
*tp = i;
|
|
break;
|
|
}
|
|
}
|
|
if (i == XtNumber(stype)) {
|
|
xe_msg (1, "No SOHO type");
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
if (sp) {
|
|
for (i = 0; i < XtNumber(ssize); i++) {
|
|
if (XmToggleButtonGetState (ssize[i].w)) {
|
|
*sp = i;
|
|
break;
|
|
}
|
|
}
|
|
if (i == XtNumber(ssize)) {
|
|
xe_msg (1, "No SOHO size");
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int
|
|
scanDir (char *dir, char ***files, int nfiles)
|
|
{
|
|
int bytype = XmToggleButtonGetState (bytype_w);
|
|
int bysize = XmToggleButtonGetState (bysize_w);
|
|
int t, s;
|
|
DIR *dirp;
|
|
struct dirent *dp;
|
|
int n;
|
|
|
|
/* get type and size settings if currently interested */
|
|
if ((bytype || bysize) && getTS (&t, &s) < 0)
|
|
return (0);
|
|
|
|
/* open and scan the directory for matching names */
|
|
dirp = opendir (dir);
|
|
if (!dirp)
|
|
return (0);
|
|
for (n = 0; (dp = readdir (dirp)) != NULL; ) {
|
|
if (strncmp (dp->d_name, "SOHO", 4) == 0 &&
|
|
(!bytype || strstr (dp->d_name, stype[t].file)) &&
|
|
(!bysize || strstr (dp->d_name, ssize[s].file))) {
|
|
*files = (char **) XtRealloc ((char *)(*files),
|
|
(nfiles + n + 1) * sizeof(char *));
|
|
(*files)[nfiles + n++] = XtNewString (dp->d_name);
|
|
}
|
|
}
|
|
|
|
/* finished */
|
|
closedir (dirp);
|
|
return (n);
|
|
}
|
|
|
|
static void
|
|
sun_refresh (void)
|
|
{
|
|
Dimension w, h;
|
|
|
|
get_something (sunda_w, XmNwidth, (XtArgVal)&w);
|
|
get_something (sunda_w, XmNheight, (XtArgVal)&h);
|
|
XCopyArea (XtD, sun_pm, XtWindow(sunda_w),
|
|
DefaultGC(XtD, DefaultScreen(XtD)), 0, 0, w, h, 0, 0);
|
|
|
|
/* draw annotation directly onto window so we don't dirty up the
|
|
* pixmap (which we only load with the image once)
|
|
*/
|
|
ano_draw (sunda_w, XtWindow(sunda_w), sun_ano, 0);
|
|
}
|
|
|
|
/* convert image proportions to/from X windows coords depending on w2x.
|
|
* return whether visible.
|
|
*/
|
|
static int
|
|
sun_ano (double *fracX, double *fracY, int *xp, int *yp, int w2x, int arg)
|
|
{
|
|
Display *dsp = XtDisplay (sunda_w);
|
|
unsigned int nx, ny, bw, d;
|
|
Window root;
|
|
int x, y;
|
|
|
|
XGetGeometry(dsp, sun_pm, &root, &x, &y, &nx, &ny, &bw, &d);
|
|
|
|
if (w2x) {
|
|
*xp = (int)floor(*fracX*nx + 0.5);
|
|
*yp = (int)floor(*fracY*ny + 0.5);
|
|
} else {
|
|
*fracX = (double)*xp/nx;
|
|
*fracY = (double)*yp/ny;
|
|
}
|
|
|
|
return (*xp>=0 && *xp<nx && *yp>=0 && *yp<ny);
|
|
}
|
|
|
|
/* given location in X pixels from center of image, scale in rads/pix,
|
|
* dy is the amount by which the sun is below the center of the image.
|
|
* return ra/dec at current moment.
|
|
*/
|
|
static void
|
|
location (int x, int dx, int y, int dy, double scale, double *rap, double *decp)
|
|
{
|
|
Obj *sop = db_basic (SUN);
|
|
double sd = sin (sop->s_dec);
|
|
double cd = cos (sop->s_dec);
|
|
double xp, yp, p, cp, sp;
|
|
|
|
/* SOHO image is always rotated with N solar axis vertical.
|
|
* find rotation, p, to bring equatoral N up.
|
|
*/
|
|
solve_sphere (sop->s_ra-SUNPOLERA, PI/2-SUNPOLEDEC, sd, cd, NULL, &p);
|
|
|
|
/* rotate screen coords so eq N is up */
|
|
cp = cos(p);
|
|
sp = sin(p);
|
|
y -= dy;
|
|
x -= dx;
|
|
xp = x*cp - y*sp;
|
|
yp = x*sp + y*cp;
|
|
|
|
*decp = sop->s_dec - yp*scale;
|
|
*rap = sop->s_ra - xp*scale/cos(*decp);
|
|
range (rap, 2*PI);
|
|
}
|
|
|
|
/* display carrington coord for current time */
|
|
static double
|
|
carrington(Now *np)
|
|
{
|
|
return ((1./27.2753)*((mjd+MJD0)-2398167.0) + 1.0);
|
|
}
|
|
|
|
|