/* xsiviewinter - XLISP interface to IVIEW dynamic graphics package. */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include "xlisp.h"
#include "xlstat.h"
/* external variables */
extern LVAL s_true, sk_adjust_points_in_rect, sk_unselect_all_points,
k_set_mode_cursor;
/* symbol pointers */
extern LVAL s_selecting, s_brushing, s_user, sk_mark_points_in_rect,
sk_adjust_screen, s_number_of_variables, sk_variable_labels,
s_variable_labels, sk_allocate, sk_showing_labels, s_showing_labels,
s_fixed_aspect, s_mouse_mode, sk_overlay_click, sk_new_menu,
s_invisible, s_normal, s_hilited, s_selected, sk_show, sk_show_window,
sk_adjust_screen_point, s_hardware_address, s_mode_list, s_scale_type,
sk_scale, s_fixed, s_variable, sk_draw, sk_resize, sk_redraw;
/*forward declarations */
LOCAL VOID get_iview_keys _((LVAL object));
LOCAL int OverlayMouse _((LVAL object));
LOCAL VOID set_mode_cursor _((LVAL object));
LOCAL LVAL encode_point_state _((PointState state));
/**************************************************************************/
/** **/
/** IView Creation Functions **/
/** **/
/**************************************************************************/
/* :ISNEW message for GRAPH-PROTO */
LVAL iview_isnew(V)
{
LVAL object, vars, args;
int show;
object = xlgaobject();
vars = xlgafixnum();
if (getfixnum(vars) < 0) xlerror("not a nonnegative integer", vars);
else set_slot_value(object, s_number_of_variables, vars);
show = (xsboolkey(sk_show, TRUE)) ? TRUE : FALSE;
object_isnew(object);
get_iview_keys(object);
initialize_graph(object);
send_message(object, sk_new_menu);
xlsave1(args);
if (show) args = consa(s_true);
else args = consa(NIL);
args = cons(sk_show, args);
apply_send(object, sk_allocate, args);
xlpop();
return(object);
}
VOID initialize_graph P1C(LVAL, object)
{
initialize_graph_window(object);
}
/* :ALLOCATE message for GRAPH-PROTO */
LVAL iview_allocate(V)
{
LVAL object;
IVIEW_WINDOW w;
int show;
object = xlgaobject();
show = xsboolkey(sk_show, TRUE);
w = IViewNew(object);
initialize_iview(w, object);
/* use StShowWindow to show (map) window but NOT send :resize or :redraw */
if (show) StShowWindow(w);
return(object);
}
LOCAL VOID get_iview_keys P1C(LVAL, object)
{
LVAL arg;
if (xlgetkeyarg(sk_variable_labels, &arg))
set_slot_value(object, s_variable_labels, coerce_to_tvec(arg, s_true));
if (xlgetkeyarg(sk_scale, &arg)) {
if (arg != s_fixed && arg != s_variable) arg = NIL;
set_slot_value(object, s_scale_type, arg);
}
}
VOID IViewMarkPointsInRect P5C(IVIEW_WINDOW, w, int, left, int, top, int, width, int, height)
{
LVAL argv[6], Lleft, Ltop, Lwidth, Lheight;
xlstkcheck(4);
xlsave(Lleft);
xlsave(Ltop);
xlsave(Lwidth);
xlsave(Lheight);
argv[0] = IViewWindowGetObject(w);
argv[1] = sk_mark_points_in_rect;
argv[2] = Lleft = cvfixnum((FIXTYPE) left);
argv[3] = Ltop = cvfixnum((FIXTYPE) top);
argv[4] = Lwidth = cvfixnum((FIXTYPE) width);
argv[5] = Lheight = cvfixnum((FIXTYPE) height);
xscallsubrvec(xmsend, 6, argv);
xlpopn(4);
}
LOCAL LVAL encode_point_state P1C(PointState, state)
{
switch (state) {
case pointInvisible: return(s_invisible);
case pointNormal: return(s_normal);
case pointHilited: return(s_hilited);
case pointSelected: return(s_selected);
default: xlfail("unknown point state");
}
/* not reached */
return(NIL);
}
VOID IViewAdjustPointsInRect P6C(IVIEW_WINDOW, w, int, left, int, top, int, width, int, height,
PointState, state)
{
LVAL argv[7], Lleft, Ltop, Lwidth, Lheight;
xlstkcheck(4);
xlsave(Lleft);
xlsave(Ltop);
xlsave(Lwidth);
xlsave(Lheight);
argv[0] = IViewWindowGetObject(w);
argv[1] = sk_adjust_points_in_rect;
argv[2] = Lleft = cvfixnum((FIXTYPE) left);
argv[3] = Ltop = cvfixnum((FIXTYPE) top);
argv[4] = Lwidth = cvfixnum((FIXTYPE) width);
argv[5] = Lheight = cvfixnum((FIXTYPE) height);
argv[6] = encode_point_state(state);
xscallsubrvec(xmsend, 7, argv);
xlpopn(4);
}
VOID IViewAdjustOwnScreenPoint P2C(IVIEW_WINDOW, w, int, point)
{
LVAL object = IViewWindowGetObject(w);
if (objectp(object))
send_message1(object, sk_adjust_screen_point, point);
}
VOID IViewUnselectAllPoints P1C(IVIEW_WINDOW, w)
{
LVAL object = IViewWindowGetObject(w);
if (objectp(object))
send_message(object, sk_unselect_all_points);
}
VOID initialize_iview P2C(IVIEW_WINDOW, w, LVAL, object)
{
int i, vars, len;
LVAL labels;
MouseMode mode;
labels = slot_value(object, s_variable_labels);
if (vectorp(labels)) {
len = getsize(labels);
vars = IViewNumVariables(w);
for (i = 0; i < len && i < vars; i++) {
if (stringp(getelement(labels, i)))
IViewSetVariableLabel(w, i, (char *) getstring(getelement(labels, i)));
}
}
else set_slot_value(object, s_variable_labels, NIL);
if (slot_value(object, s_showing_labels) != NIL)
IViewSetShowingLabels(w, TRUE);
IViewSetFixedAspect(w, (slot_value(object, s_fixed_aspect) != NIL));
if (slot_value(object, s_mouse_mode) == s_brushing) mode = brushing;
else if (slot_value(object, s_mouse_mode) == s_selecting) mode = selecting;
else mode = usermode;
IViewSetMouseMode(w, mode);
}
VOID get_iview_ivars P2C(LVAL, object, int *, vars)
{
LVAL num_variables;
num_variables = slot_value(object, s_number_of_variables);
if (! fixp(num_variables) || getfixnum(num_variables) < 0)
xlerror("number of variables is not a nonnegative integer", num_variables);
*vars = getfixnum(num_variables);
}
/* :SHOW-WINDOW message for GRAPH-PROTO */
LVAL iview_window_show_window(V)
{
LVAL object = xlgaobject();
IVIEW_WINDOW w = (IVIEW_WINDOW) GETWINDOWADDRESS(object);
StGWWinInfo *gwinfo = StGWObWinInfo(object);
if (IVIEW_WINDOW_NULL(w)) send_message(object, sk_allocate);
StGWShowWindow(gwinfo);
return(NIL);
}
/**************************************************************************/
/** **/
/** IView State Accessors and Mutators **/
/** **/
/**************************************************************************/
static LVAL state_access P1C(int, which)
{
StGWWinInfo *gwinfo;
LVAL list, arg, object;
int a, b, c, d, set = FALSE;
object = xlgaobject();
gwinfo = StGWObWinInfo(object);
if (moreargs()) {
set = TRUE;
a = getfixnum(xlgafixnum());
b = getfixnum(xlgafixnum());
if (which == 'R' || which == 'M') {
c = getfixnum(xlgafixnum());
d = getfixnum(xlgafixnum());
}
}
if (set)
switch (which) {
case 'R': StGrSetContentRect(gwinfo, a, b, c, d); break;
case 'O': StGrSetContentOrigin(gwinfo, a, b); break;
case 'V': StGrSetContentVariables(gwinfo, a, b); break;
case 'C': StGrSetClickRange(gwinfo, a, b); break;
case 'M':
StGrSetMargin(gwinfo, a, b, c, d);
if (! xlgetkeyarg(sk_draw, &arg)) arg = s_true;
if (arg != NIL) send_message(object, sk_resize);
if (arg != NIL) send_message(object, sk_redraw);
break;
}
switch (which) {
case 'R': StGrGetContentRect(gwinfo, &a, &b, &c, &d); break;
case 'O': StGrGetContentOrigin(gwinfo, &a, &b); break;
case 'V': StGrGetContentVariables(gwinfo, &a, &b); break;
case 'C': StGrGetClickRange(gwinfo, &a, &b); break;
case 'M': StGrGetMargin(gwinfo, &a, &b, &c, &d); break;
}
if (which == 'R' || which == 'M') list = integer_list_4(a, b, c, d);
else list = integer_list_2(a, b);
return(list);
}
LVAL iview_content_rect(V) { return(state_access('R')); }
LVAL iview_content_origin(V) { return(state_access('O')); }
LVAL iview_content_variables(V) { return(state_access('V')); }
LVAL iview_click_range(V) { return(state_access('C')); }
LVAL iview_mouse_mode(V)
{
IVIEW_WINDOW w;
LVAL modesym, object;
MouseMode mode;
int set = FALSE;
object = xlgaobject();
w = (IVIEW_WINDOW) get_iview_address(object);
if (moreargs()) {
set = TRUE;
modesym = xlgasymbol();
}
else modesym = NIL; /* to keep compiler happy */
xllastarg();
if (set) {
if (modesym == s_selecting) mode = selecting;
else if (modesym == s_brushing) mode = brushing;
else mode = usermode;
set_slot_value(object, s_mouse_mode, modesym);
IViewSetMouseMode(w, mode);
set_mode_cursor(object);
}
switch (IViewMouseMode(w)) {
case selecting: modesym = s_selecting; break;
case brushing: modesym = s_brushing; break;
default: modesym = slot_value(object, s_mouse_mode);
}
return(modesym);
}
LVAL iview_showing_labels(V)
{
IVIEW_WINDOW w;
int set = FALSE, show = FALSE;
LVAL object;
object = xlgaobject();
w = (IVIEW_WINDOW) get_iview_address(object);
if (moreargs()) {
set = TRUE;
show = (xlgetarg() != NIL) ? TRUE : FALSE;
}
xllastarg();
if (set) IViewSetShowingLabels(w, show);
return((IViewShowingLabels(w)) ? s_true : NIL);
}
LVAL iview_margin(V) { return(state_access('M')); }
LVAL iview_fixed_aspect(V)
{
IVIEW_WINDOW w;
LVAL object;
int set = FALSE, fixed = FALSE;
object = xlgaobject();
if (moreargs()) {
set = TRUE;
fixed = (xlgetarg() != NIL) ? TRUE : FALSE;
}
xllastarg();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (! IVIEW_WINDOW_NULL(w)) {
if (set) {
set_slot_value(object, s_fixed_aspect, (fixed) ? s_true : NIL);
IViewSetFixedAspect(w, fixed);
StGWObResize(object);
StGWObRedraw(object);
}
return((IViewFixedAspect(w)) ? s_true : NIL);
}
else {
if (set) set_slot_value(object, s_fixed_aspect, (fixed) ? s_true : NIL);
return(slot_value(object, s_fixed_aspect));
}
}
LVAL iview_dirty(V)
{
StGWWinInfo *gwinfo;
LVAL object;
int set;
object = xlgaobject();
set = moreargs();
gwinfo = StGWObWinInfo(object);
if (set) StGrSetDirty(gwinfo, (xlgetarg() != NIL) ? TRUE : FALSE);
return(StGrDirty(gwinfo) ? s_true : NIL);
}
/**************************************************************************/
/** **/
/** Axis Functions **/
/** **/
/**************************************************************************/
static LVAL iview_axis P1C(int, which)
{
IVIEW_WINDOW w;
int showing, labeled, ticks, set = FALSE, draw;
LVAL object, temp, result;
object = xlgaobject();
w = (IVIEW_WINDOW) get_iview_address(object);
if (moreargs()) {
set = TRUE;
showing = (xlgetarg() != NIL) ? TRUE : FALSE;
labeled = (moreargs() && xlgetarg() != NIL) ? TRUE : FALSE;
ticks = (moreargs()) ? getfixnum(xlgafixnum()) : 4;
}
if (set) {
switch (which) {
case 'X': IViewSetXaxis(w, showing, labeled, ticks); break;
case 'Y': IViewSetYaxis(w, showing, labeled, ticks); break;
}
draw = draw_key_arg(TRUE);
StGWObResize(object);
check_redraw(object, draw, FALSE);
}
switch(which) {
case 'X': IViewGetXaxis(w, &showing, &labeled, &ticks); break;
case 'Y': IViewGetYaxis(w, &showing, &labeled, &ticks); break;
}
xlstkcheck(2);
xlsave(result);
xlsave(temp);
temp = cvfixnum((FIXTYPE) ticks); result = consa(temp);
temp = (labeled) ? s_true : NIL; result = cons(temp, result);
temp = (showing) ? s_true : NIL; result = cons(temp, result);
xlpopn(2);
return(result);
}
LVAL iview_x_axis(V) { return(iview_axis('X')); }
LVAL iview_y_axis(V) { return(iview_axis('Y')); }
/**************************************************************************/
/** **/
/** Brush Functions **/
/** **/
/**************************************************************************/
static LVAL brush P1C(int, which)
{
IVIEW_WINDOW w;
int x, y, width, height, set = FALSE;
LVAL result;
w = (IVIEW_WINDOW) get_iview_address(xlgaobject());
if (which == 'B' && moreargs()) {
set = TRUE;
x = getfixnum(xlgafixnum());
y = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
}
else if (which == 'M') {
x = getfixnum(xlgafixnum());
y = getfixnum(xlgafixnum());
}
xllastarg();
if (set) IViewSetBrush(w, x, y, width, height);
switch (which) {
case 'B': IViewGetBrush(w, &x, &y, &width, &height); break;
case 'E': IViewEraseBrush(w); break;
case 'D': IViewDrawBrush(w); break;
case 'M': IViewMoveBrush(w, x, y); break;
}
if (which == 'B') result = integer_list_4(x, y, width, height);
else result = NIL;
return(result);
}
LVAL iview_brush(V) { return(brush('B')); }
LVAL iview_erase_brush(V) { return(brush('E')); }
LVAL iview_draw_brush(V) { return(brush('D')); }
LVAL iview_move_brush(V) { return(brush('M')); }
LVAL iview_resize_brush(V)
{
IVIEW_WINDOW w;
int x, y, width, height, new_width, new_height, changed;
w = (IVIEW_WINDOW) get_iview_address(xlgaobject());
changed = IViewGetNewBrushSize(w, &new_width, &new_height);
if (changed) {
IViewGetBrush(w, &x, &y, &width, &height);
IViewSetBrush(w, x, y, new_width, new_height);
}
return((changed) ? s_true : NIL);
}
/**************************************************************************/
/** **/
/** Mouse Action Functions **/
/** **/
/**************************************************************************/
static LVAL get_mouse_selector P2C(LVAL, object, MouseEventType, type)
{
LVAL selector, mode, list, entry;
mode = slot_value(object, s_mouse_mode);
list = slot_value(object, s_mode_list);
for (selector = NIL; consp(list); list = cdr(list)) {
entry = car(list);
if (consp(entry) && car(entry) == mode) {
if (type == MouseClick) {
if (llength(entry) >= 4) selector = car(cdr(cdr(cdr(entry))));
}
else {
if (llength(entry) >= 5) selector = car(cdr(cdr(cdr(cdr(entry)))));
}
break;
}
}
return(selector);
}
VOID IViewDoClick P1C(LVAL, object)
{
LVAL selector = get_mouse_selector(object, MouseClick);
if (! OverlayMouse(object) && !null(selector))
send_message_stk(object, selector);
}
VOID IViewDoMotion P1C(LVAL, object)
{
LVAL selector = get_mouse_selector(object, MouseMove);
if (!null(selector))
send_message_stk(object, selector);
}
LOCAL int OverlayMouse P1C(LVAL, object)
{
LVAL argv[6], result;
int i;
argv[0] = object;
argv[1] = sk_overlay_click;
for (i = 0; i < 4 && i < xlargc; i++)
argv[i + 2] = xlargv[i];
result = xscallsubrvec(xmsend, 6, argv);
return(result != NIL);
}
LVAL iview_do_click(V)
{
LVAL object;
object = xlgaobject();
IViewDoClick(object);
return(NIL);
}
LVAL iview_do_motion(V)
{
LVAL object;
object = xlgaobject();
IViewDoMotion(object);
return(NIL);
}
static LVAL iview_std_mouse P1C(MouseEventType, type)
{
IVIEW_WINDOW w;
int x, y;
MouseClickModifier mods;
w = (IVIEW_WINDOW) get_iview_address(xlgaobject());
x = getfixnum(xlgafixnum());
y = getfixnum(xlgafixnum());
if (type == MouseClick) {
mods = (MouseClickModifier) ((xlgetarg() != NIL) ? 1 : 0);
if (xlgetarg() != NIL) mods = (MouseClickModifier) (((int) mods) + 2);
}
else mods = (MouseClickModifier) 0; /* to keep compiler happy */
xllastarg();
IViewStdMouseAction(w, x, y, type, mods);
return(NIL);
}
LVAL iview_std_click(V) { return(iview_std_mouse(MouseClick)); }
LVAL iview_std_motion(V) { return(iview_std_mouse(MouseMove)); }
static LVAL multi_state_set P1C(int, which)
{
IVIEW_WINDOW w;
int result = FALSE;
w = (IVIEW_WINDOW) get_iview_address(xlgaobject());
xllastarg();
switch (which) {
case 'U': IViewStdUnselectAllPoints(w); break;
case 'E': IViewEraseSelection(w); break;
case 'M': IViewMaskSelection(w); break;
case 'u': IViewUnmaskAllPoints(w); break;
case 'S': IViewShowAllPoints(w); break;
case 'A': result = IViewAllPointsShowing(w); break;
case 'a': result = IViewAllPointsUnmasked(w); break;
case 's': result = IViewAnyPointsSelected(w); break;
}
return((result) ? s_true : NIL);
}
LVAL iview_unselect_all_points(V) { return(multi_state_set('U')); }
LVAL iview_erase_selection(V) { return(multi_state_set('E')); }
LVAL iview_mask_selection(V) { return(multi_state_set('M')); }
LVAL iview_unmask_all_points(V) { return(multi_state_set('u')); }
LVAL iview_show_all_points(V) { return(multi_state_set('S')); }
LVAL iview_all_points_showing(V) { return(multi_state_set('A')); }
LVAL iview_all_points_unmasked(V) { return(multi_state_set('a')); }
LVAL iview_any_points_selected(V) { return(multi_state_set('s')); }
/*************************************************************************/
/** **/
/** IView Linking Functions **/
/** **/
/*************************************************************************/
extern LVAL s_linked_plots, sk_links, sk_linked;
int IViewInternalIsLinked P1C(IVIEW_WINDOW, w)
{
return (IViewIsLinked(w));
}
LVAL iview_linked(V)
{
LVAL object, temp;
IVIEW_WINDOW w;
int set = FALSE, linked = FALSE, i, n;
object = xlgaobject();
w = (IVIEW_WINDOW) get_iview_address(object);
if (moreargs()) {
set = TRUE;
linked = (xlgetarg() != NIL) ? TRUE : FALSE;
}
xllastarg();
if (set) {
if (linked) {
setvalue(s_linked_plots, cons(object, getvalue(s_linked_plots)));
IViewCheckLinks(w);
n = IViewNumPoints(w);
for (i = 0; i < n; i++) IViewMatchPointState(w, i);
IViewAdjustScreens(w);
}
else {
temp = xlcallsubr2(xremove, object, getvalue(s_linked_plots));
setvalue(s_linked_plots, temp);
IViewCheckLinks(w);
}
}
else IViewCheckLinks(w);
return(IViewIsLinked(w) ? s_true : NIL);
}
LVAL iview_links(V)
{
LVAL object, links, next;
object = xlgaobject();
links = getvalue(s_linked_plots);
for (next = links; consp(next); next = cdr(next))
if (object == car(next)) return(links);
return(NIL);
}
VOID IViewUnlinkWindow P1C(IVIEW_WINDOW, w)
{
LVAL object = IViewWindowGetObject(w);
if (objectp(object)) send_message_1L(object, sk_linked, NIL);
IViewCheckLinks(w);
}
LVAL iview_unlink_all_windows(V)
{
LVAL links = getvalue(s_linked_plots);
xllastarg();
for (; consp(links); links = cdr(links))
send_message_1L(car(links), sk_linked, NIL);
return(NIL);
}
VOID IViewMatchPointState P2C(IVIEW_WINDOW, w, unsigned, p)
{
IVIEW_WINDOW lw;
LVAL links, object;
for (links = IViewGetLinks(w); consp(links); links = cdr(links)) {
object = car(links);
lw = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (w != lw && IViewPointState(w, p) != IViewPointState(lw, p)) {
IViewSetPointScreenState(lw, p, IViewPointState(lw, p));
IViewDataSetPointState(IViewDataPtr(lw), p, IViewPointState(w, p));
send_message1(object, sk_adjust_screen_point, p);
IViewSetPointScreenState(lw, p, IViewPointState(lw, p));
}
}
}
VOID IViewAdjustScreens P1C(IVIEW_WINDOW, w)
{
LVAL links, object;
object = IViewWindowGetObject(w);
if (objectp(object)) send_message(object, sk_adjust_screen);
if (IViewIsLinked(w)) {
for (links = IViewGetLinks(w); consp(links); links = cdr(links)) {
object = car(links);
if (objectp(object)) send_message(object, sk_adjust_screen);
}
}
}
VOID IViewCheckLinks P1C(IVIEW_WINDOW, w)
{
LVAL links;
links = send_message(IViewWindowGetObject(w), sk_links);
IViewSetLinks(w, links);
}
/*************************************************************************/
/** **/
/** Miscellaneous Functions **/
/** **/
/*************************************************************************/
LOCAL VOID set_mode_cursor P1C(LVAL, object)
{
send_message(object, k_set_mode_cursor);
}
syntax highlighted by Code2HTML, v. 0.9.1