magic/windows/windCmdSZ.c

1255 lines
28 KiB
C

/* windCmdSZ.c -
*
* This file contains Magic command routines for those commands
* that are valid in all windows.
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/windows/windCmdSZ.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for sleep() */
#include <string.h>
#include <math.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "textio/textio.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "windows/windows.h"
#include "graphics/glyphs.h"
#include "windows/windInt.h"
#include "utils/undo.h"
#include "utils/utils.h"
#include "utils/signals.h"
#include "textio/txcommands.h"
#include "utils/hash.h"
#include "database/database.h"
#include "dbwind/dbwind.h"
#include "graphics/graphics.h"
/* C99 compat */
#include "commands/commands.h"
/*
* ----------------------------------------------------------------------------
*
* windScrollCmd --
*
* Scroll the view around
*
* Usage:
* scroll dir [amount [units]]
*
* Results:
* None.
*
* Side effects:
* The window underneath the cursor is changed.
* Note: behavior has been changed from original. To have "amount"
* parsed as a fractional scroll amount, "units" *must* be declared
* as "w". Otherwise, no units implies that "amount" is an absolute
* value.
*
*
* ----------------------------------------------------------------------------
*/
void
windScrollCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
Rect r;
int xsize, ysize;
Point p;
int pos, locargc = cmd->tx_argc;
float amount;
bool doFractional = FALSE;
if ( (cmd->tx_argc < 2) || (cmd->tx_argc > 4) )
{
TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]);
return;
}
if (w == NULL)
{
TxError("Point to a window first.\n");
return;
}
if ((w->w_flags & WIND_SCROLLABLE) == 0) {
TxError("Sorry, can't scroll this window.\n");
return;
};
pos = GeoNameToPos(cmd->tx_argv[1], FALSE, TRUE);
if (pos < 0 || pos == GEO_CENTER)
return;
if (cmd->tx_argc == 2) /* default = half-screen pan */
{
r = w->w_screenArea;
amount = 0.5;
doFractional = TRUE;
}
else if (cmd->tx_argc == 4)
{
char unitc = cmd->tx_argv[3][0];
if (unitc == 'w')
r = w->w_screenArea;
else if (unitc == 'l')
r = *(w->w_bbox);
else
{
TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]);
TxError(" 'units' must be one of 'w' (window) or 'l' (layout);\n");
return;
}
if (sscanf(cmd->tx_argv[2], "%f", &amount) != 1)
{
TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]);
TxError(" 'amount' is a fractional value.\n");
return;
}
doFractional = TRUE;
}
if (doFractional)
{
xsize = (r.r_xtop - r.r_xbot) * amount;
ysize = (r.r_ytop - r.r_ybot) * amount;
}
else
{
/* Alternate syntax: parse for integer coordinate amount to scroll */
xsize = cmdParseCoord(w, cmd->tx_argv[2], TRUE, TRUE);
ysize = cmdParseCoord(w, cmd->tx_argv[2], TRUE, FALSE);
}
p.p_x = 0;
p.p_y = 0;
switch (pos)
{
case GEO_NORTH:
p.p_y = -ysize;
break;
case GEO_SOUTH:
p.p_y = ysize;
break;
case GEO_EAST:
p.p_x = -xsize;
break;
case GEO_WEST:
p.p_x = xsize;
break;
case GEO_NORTHEAST:
p.p_x = -xsize;
p.p_y = -ysize;
break;
case GEO_NORTHWEST:
p.p_x = xsize;
p.p_y = -ysize;
break;
case GEO_SOUTHEAST:
p.p_x = -xsize;
p.p_y = ysize;
break;
case GEO_SOUTHWEST:
p.p_x = xsize;
p.p_y = ysize;
break;
}
if (doFractional)
WindScroll(w, (Point *) NULL, &p);
else
{
/* Direction is reversed w/respect to above call to WindScroll() */
p.p_x = -p.p_x;
p.p_y = -p.p_y;
WindScroll(w, &p, (Point *) NULL);
}
return;
}
/*
* ----------------------------------------------------------------------------
* windSetpointCmd --
*
* Use the x, y specified as the location of the point tool for the
* next command.
*
* Results:
* None. Under the Tcl interpreter, returns the screen and layout
* coordinates as a list of four integers: sx sy lx ly.
*
* Side effects:
* global variables.
* ----------------------------------------------------------------------------
*/
void
windSetpointCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int wid;
Point rootPoint;
#ifdef MAGIC_WRAPPER
char *ptstr;
#endif
if ((cmd->tx_argc != 4) && (cmd->tx_argc != 3) && (cmd->tx_argc != 1))
goto usage;
if ((cmd->tx_argc != 1) && !
(StrIsInt(cmd->tx_argv[1]) && StrIsInt(cmd->tx_argv[2])) )
goto usage;
if (cmd->tx_argc == 4) {
if (StrIsInt(cmd->tx_argv[3]))
wid = atoi(cmd->tx_argv[3]);
else if (GrWindowIdPtr)
wid = (*GrWindowIdPtr)(cmd->tx_argv[3]);
else
wid = WIND_UNKNOWN_WINDOW;
}
else if (w != NULL)
wid = w->w_wid;
else {
windCheckOnlyWindow(&w, DBWclientID);
if (w != NULL)
wid = w->w_wid;
else
wid = WIND_UNKNOWN_WINDOW;
}
/* Ensure a valid window, if possible */
if (w == NULL) w = WindSearchWid(wid);
if (cmd->tx_argc == 1)
{
if (w != (MagWindow *) NULL)
{
WindPointToSurface(w, &cmd->tx_p, &rootPoint, (Rect *) NULL);
#ifdef MAGIC_WRAPPER
ptstr = (char *)Tcl_Alloc(50);
sprintf(ptstr, "%d %d %d %d", cmd->tx_p.p_x, cmd->tx_p.p_y,
rootPoint.p_x, rootPoint.p_y);
Tcl_SetResult(magicinterp, ptstr, TCL_DYNAMIC);
#else
TxPrintf("Point is at screen coordinates (%d, %d) in window %d.\n",
cmd->tx_p.p_x, cmd->tx_p.p_y, w->w_wid);
TxPrintf("Point is at layout coordinates (%d, %d)\n",
rootPoint.p_x, rootPoint.p_y);
#endif
} else {
TxPrintf("Point is at screen coordinates (%d, %d).\n",
cmd->tx_p.p_x, cmd->tx_p.p_y);
}
}
else {
int yval;
yval = atoi(cmd->tx_argv[2]);
/* Reinterpret coordinates according to the graphics package */
switch (WindPackageType)
{
case WIND_X_WINDOWS:
/* Windows have origin at lower-left corner */
yval = w->w_allArea.r_ytop - yval;
break;
}
TxSetPoint(atoi(cmd->tx_argv[1]), yval, wid);
}
return;
usage:
TxError("Usage: %s [x y [window ID|name]]\n", cmd->tx_argv[0]);
}
int
windSetPrintProc(name, val)
char *name;
char *val;
{
TxPrintf("%s = \"%s\"\n", name, val);
return 0;
}
/*
* ----------------------------------------------------------------------------
* windSleepCmd --
*
* Take a nap.
*
* Results:
* None.
*
* Side effects:
* None.
* ----------------------------------------------------------------------------
*/
void
windSleepCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int time;
if (cmd->tx_argc != 2)
{
TxError("Usage: %s seconds\n", cmd->tx_argv[0]);
return;
}
time = atoi(cmd->tx_argv[1]);
for ( ; time > 1; time--)
{
sleep(1);
if (SigInterruptPending) return;
}
}
#ifndef MAGIC_WRAPPER
/*
* ----------------------------------------------------------------------------
*
* windSourceCmd --
*
* Implement the "source" command.
* Process a file as a list of commands.
*
* Usage:
* source filename
*
* Results:
* None.
*
* Side effects:
* Whatever the commands request.
*
* ----------------------------------------------------------------------------
*/
void
windSourceCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
FILE *f;
if (cmd->tx_argc != 2)
{
TxError("Usage: %s filename\n", cmd->tx_argv[0]);
return;
}
f = PaOpen(cmd->tx_argv[1], "r", (char *) NULL, ".",
SysLibPath, (char **) NULL);
if (f == NULL)
TxError("Couldn't read from %s.\n", cmd->tx_argv[1]);
else {
TxDispatch(f);
(void) fclose(f);
};
}
#endif
/*
* ----------------------------------------------------------------------------
* windSpecialOpenCmd --
*
* Open a new window at the cursor position. Give it a default size,
* and take the client's name from the command line. Pass the rest of
* the command arguments off to the client.
*
* Results:
* None.
*
* Side effects:
* None.
* ----------------------------------------------------------------------------
*/
void
windSpecialOpenCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
WindClient wc;
Rect area;
bool haveCoords;
char *client;
haveCoords = FALSE;
if (cmd->tx_argc < 2) goto usage;
haveCoords = StrIsInt(cmd->tx_argv[1]);
if (haveCoords && (
(cmd->tx_argc < 6) ||
!StrIsInt(cmd->tx_argv[2]) ||
!StrIsInt(cmd->tx_argv[3]) ||
!StrIsInt(cmd->tx_argv[4])
)) goto usage;
if (haveCoords)
client = cmd->tx_argv[5];
else
client = cmd->tx_argv[1];
wc = WindGetClient(client, FALSE);
/* clients whose names begin with '*' are hidden */
if ((wc == (WindClient) NULL) || (client[0] == '*')) goto usage;
if (haveCoords) {
windCheckOnlyWindow(&w, wc);
area.r_xbot = atoi(cmd->tx_argv[1]);
area.r_ybot = atoi(cmd->tx_argv[2]);
area.r_xtop = MAX(atoi(cmd->tx_argv[3]), area.r_xbot + WIND_MIN_WIDTH);
area.r_ytop = MAX(atoi(cmd->tx_argv[4]), area.r_ybot + WIND_MIN_HEIGHT);
/* Assume that the client will print an error message if it fails */
(void) WindCreate(wc, &area, FALSE, cmd->tx_argc - 6, cmd->tx_argv + 6);
}
else {
area.r_xbot = cmd->tx_p.p_x - CREATE_WIDTH/2;
area.r_xtop = cmd->tx_p.p_x + CREATE_WIDTH/2;
area.r_ybot = cmd->tx_p.p_y - CREATE_HEIGHT/2;
area.r_ytop = cmd->tx_p.p_y + CREATE_HEIGHT/2;
/* Assume that the client will print an error message if it fails */
(void) WindCreate(wc, &area, TRUE, cmd->tx_argc - 2, cmd->tx_argv + 2);
}
return;
usage:
TxPrintf("Usage: specialopen [leftx bottomy rightx topy] type [args]\n");
TxPrintf("Valid window types are:\n");
WindPrintClientList(FALSE);
return;
}
/*
* ----------------------------------------------------------------------------
* windNamesCmd --
*
* Register or retrieve the name associated with the layout window
*
* Results:
* Returns the name as a Tcl string result. If "all" is selected,
* or if w is NULL and cannot be determined, returns a list of all
* window names. The first argument may also be a window client
* type, in which case only windows of that type are returned.
*
* Note:
* This routine can easily be made "generic", not Tcl-specific.
* However, of the graphics interfaces available, only Tcl/Tk keeps
* track of windows by name.
*
* ----------------------------------------------------------------------------
*/
void
windNamesCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
bool doforall = FALSE;
WindClient wc = (WindClient)NULL;
MagWindow *sw;
if (cmd->tx_argc > 2)
{
TxError("Usage: windownames [all | client_type]\n");
return;
}
if (cmd->tx_argc == 2)
{
if (!strncmp(cmd->tx_argv[1], "all", 3))
doforall = TRUE;
#ifndef THREE_D
else if (!strncmp(cmd->tx_argv[1], "wind3d", 6))
{
return; // do nothing
}
#endif /* THREE_D */
else
{
wc = WindGetClient(cmd->tx_argv[1], FALSE);
if (wc == (WindClient) NULL)
{
TxError("Usage: windownames [all | client_type]\n");
TxPrintf("Valid window types are:\n");
WindPrintClientList(FALSE);
return;
}
doforall = TRUE;
}
}
if (cmd->tx_argc == 1)
{
wc = DBWclientID;
windCheckOnlyWindow(&w, wc);
if (w == (MagWindow *)NULL)
doforall = TRUE;
}
#ifdef MAGIC_WRAPPER
if (doforall == TRUE)
{
Tcl_Obj *tlist;
tlist = Tcl_NewListObj(0, NULL);
for (sw = windTopWindow; sw != NULL; sw = sw->w_nextWindow)
if ((wc == NULL) || (sw->w_client == wc))
{
if (GrWindowNamePtr)
Tcl_ListObjAppendElement(magicinterp, tlist,
Tcl_NewStringObj((*GrWindowNamePtr)(sw), -1));
else
Tcl_ListObjAppendElement(magicinterp, tlist,
Tcl_NewIntObj(sw->w_wid));
}
Tcl_SetObjResult(magicinterp, tlist);
}
else
{
if (GrWindowNamePtr)
Tcl_SetResult(magicinterp, (*GrWindowNamePtr)(w), NULL);
else
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(w->w_wid));
}
#else
if (doforall == TRUE)
{
if (GrWindowNamePtr)
TxPrintf("Window ID Window Name\n");
else
TxPrintf("Window ID\n");
for (sw = windTopWindow; sw != NULL; sw = sw->w_nextWindow)
if ((wc == (WindClient)NULL) || (sw->w_client == wc))
{
if (GrWindowNamePtr)
TxPrintf("%d %s\n", sw->w_wid, (*GrWindowNamePtr)(sw));
else
TxPrintf("%d\n", sw->w_wid);
}
}
else
{
if (GrWindowNamePtr)
TxPrintf("Window ID = %d, Name = %s\n", w->w_wid,
(*GrWindowNamePtr)(w));
else
TxPrintf("Window ID = %d\n", w->w_wid);
}
#endif /* !MAGIC_WRAPPER */
}
/*
* ----------------------------------------------------------------------------
* windUnderCmd --
*
* Move a window underneath the other windows.
*
* Results:
* None.
*
* Side effects:
* Screen updates.
* ----------------------------------------------------------------------------
*/
void
windUnderCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
if (cmd->tx_argc != 1)
{
TxError("Usage: %s\n", cmd->tx_argv[0]);
}
if (w == NULL)
{
TxError("Point to a window first.\n");
return;
}
WindUnder(w);
}
/*
* ----------------------------------------------------------------------------
*
* windUndoCmd
*
* Implement the "undo" command.
*
* Usage:
* undo [count]
*
* If a count is supplied, the last count events are undone. The default
* count if none is given is 1.
*
* Results:
* None.
*
* Side effects:
* Calls the undo module.
*
* ----------------------------------------------------------------------------
*/
void
windUndoCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int count;
if (cmd->tx_argc > 3)
{
TxError("Usage: undo [count]\n");
TxError(" undo print [count]\n");
TxError(" undo enable|disable\n");
return;
}
else if (cmd->tx_argc == 3)
{
if (strncmp(cmd->tx_argv[1], "print", 5))
{
TxError("Usage: undo print count\n");
return;
}
else if (!StrIsInt(cmd->tx_argv[2]))
{
TxError("Usage: undo print count\n");
return;
}
else
{
/* Implement undo stack trace */
UndoStackTrace((-1) - atoi(cmd->tx_argv[2]));
return;
}
}
else if (cmd->tx_argc == 2)
{
if (!StrIsInt(cmd->tx_argv[1]))
{
if (!strcmp(cmd->tx_argv[1], "enable"))
UndoEnable();
else if (!strcmp(cmd->tx_argv[1], "disable"))
UndoDisable();
else
TxError("Option must be a count (integer)\n");
return;
}
count = atoi(cmd->tx_argv[1]);
if (count < 0)
{
TxError("Count must be a positive integer\n");
return;
}
}
else
count = 1;
if (count == 0)
{
UndoEnable();
}
else
{
if (UndoBackward(count) == 0)
TxPrintf("Nothing more to undo\n");
}
}
/*
* ----------------------------------------------------------------------------
* windUpdateCmd --
*
* Force an update of the graphics screen. This is usually only called
* from command scripts.
*
* Results:
* None.
*
* Side effects:
* Display updates.
* ----------------------------------------------------------------------------
*/
void
windUpdateCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
if (cmd->tx_argc == 1)
WindUpdate();
#ifdef MAGIC_WRAPPER
else if (cmd->tx_argc > 2)
goto badusage;
else if (!strcmp(cmd->tx_argv[1], "suspend"))
GrDisplayStatus = DISPLAY_SUSPEND;
else if (!strcmp(cmd->tx_argv[1], "resume"))
GrDisplayStatus = DISPLAY_IDLE;
else
goto badusage;
#else
else if (cmd->tx_argc >= 2)
goto badusage;
#endif
return;
badusage:
TxError("Usage: %s [suspend | resume]\n", cmd->tx_argv[0]);
return;
}
/*
* ----------------------------------------------------------------------------
*
* windVersionCmd --
*
* Print version information.
*
* Usage:
* version
*
* Results:
* None.
*
* Side effects:
* Prints on stdout.
*
* ----------------------------------------------------------------------------
*/
void
windVersionCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
if (cmd->tx_argc != 1) {
TxError("Usage: %s\n", cmd->tx_argv[0]);
return;
}
TxPrintf("Version %s revision %s. Compiled on %s.\n",
MagicVersion, MagicRevision, MagicCompileTime);
}
/*
* ----------------------------------------------------------------------------
*
* windViewCmd --
*
* Implement the "View" command.
* Change the view in the selected window so everything is visible.
*
* Usage:
* view
*
* Results:
* None.
*
* Side effects:
* The window underneath the cursor is changed.
* In Tcl version, if supplied with the argument "get", the
* interpreter return value is set to the current view position.
*
* ----------------------------------------------------------------------------
*/
void
windViewCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
if (w == NULL)
return;
if (cmd->tx_argc == 1)
{
if ((w->w_flags & WIND_SCROLLABLE) == 0) {
TxError("Sorry, can't zoom out this window.\n");
return;
}
WindView(w);
}
else if (cmd->tx_argc == 2)
{
#ifdef MAGIC_WRAPPER
Tcl_Obj *listxy, *fval;
listxy = Tcl_NewListObj(0, NULL);
#endif
if (!strncmp(cmd->tx_argv[1], "get", 3))
{
#ifndef MAGIC_WRAPPER
TxPrintf("(%d, %d) to (%d, %d)\n",
w->w_surfaceArea.r_xbot, w->w_surfaceArea.r_ybot,
w->w_surfaceArea.r_xtop, w->w_surfaceArea.r_ytop);
#else
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_surfaceArea.r_xbot));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_surfaceArea.r_ybot));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_surfaceArea.r_xtop));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_surfaceArea.r_ytop));
Tcl_SetObjResult(magicinterp, listxy);
#endif
}
else if (!strncmp(cmd->tx_argv[1], "bbox", 4))
{
#ifndef MAGIC_WRAPPER
TxPrintf("(%d, %d) to (%d, %d)\n",
w->w_bbox->r_xbot, w->w_bbox->r_ybot,
w->w_bbox->r_xtop, w->w_bbox->r_ytop);
#else
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_bbox->r_xbot));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_bbox->r_ybot));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_bbox->r_xtop));
Tcl_ListObjAppendElement(magicinterp, listxy,
Tcl_NewIntObj((int)w->w_bbox->r_ytop));
Tcl_SetObjResult(magicinterp, listxy);
#endif
}
else
{
char *sptr, *pptr;
Rect r;
// Parse out coordinates where all coordinates have been
// put into a single string argument, as happens when the
// coordinates are a Tcl list, e.g., from "[box values]"
sptr = cmd->tx_argv[1];
if ((pptr = strchr(sptr, ' ')) == NULL) return;
*pptr++ = '\0';
r.r_xbot = cmdParseCoord(w, sptr, FALSE, TRUE);
sptr = pptr;
if ((pptr = strchr(sptr, ' ')) == NULL) return;
*pptr++ = '\0';
r.r_ybot = cmdParseCoord(w, sptr, FALSE, TRUE);
sptr = pptr;
if ((pptr = strchr(sptr, ' ')) == NULL) return;
*pptr++ = '\0';
r.r_xtop = cmdParseCoord(w, sptr, FALSE, TRUE);
r.r_ytop = cmdParseCoord(w, pptr, FALSE, TRUE);
/* Redisplay */
WindMove(w, &r);
}
}
else if (cmd->tx_argc == 5)
{
Rect r;
r.r_xbot = cmdParseCoord(w, cmd->tx_argv[1], FALSE, TRUE);
r.r_ybot = cmdParseCoord(w, cmd->tx_argv[2], FALSE, FALSE);
r.r_xtop = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE);
r.r_ytop = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE);
/* Redisplay */
WindMove(w, &r);
}
else
{
TxError("Usage: view [get|bbox|llx lly urx ury]\n");
}
}
/*
* ----------------------------------------------------------------------------
*
* windXviewCmd --
*
* Implement the "Xview" command.
* Change the view in the selected window so everything is visible, but
* not expanded.
*
* Usage:
* xview
*
* Results:
* None.
*
* Side effects:
* The window underneath the cursor is changed. The root cell of the
* window is unexpanded.
*
* ----------------------------------------------------------------------------
*/
void
windXviewCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
CellUse *celluse;
int ViewUnexpandFunc();
if (w == NULL)
return;
if ((w->w_flags & WIND_SCROLLABLE) == 0) {
TxError("Sorry, can't zoom out this window.\n");
return;
};
celluse = (CellUse *) (w->w_surfaceID);
DBExpandAll(celluse, &(celluse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask, FALSE,
ViewUnexpandFunc,
(ClientData)(pointertype) (((DBWclientRec *)w->w_clientData)->dbw_bitmask));
WindView(w);
}
/* This function is called for each cell whose expansion status changed.
* It forces the cells area to be redisplayed, then returns 0 to keep
* looking for more cells to unexpand.
*/
int
ViewUnexpandFunc(use, windowMask)
CellUse *use; /* Use that was just unexpanded. */
int windowMask; /* Window where it was unexpanded. */
{
if (use->cu_parent == NULL) return 0;
DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask,
(TileTypeBitMask *) NULL);
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* windScrollBarsCmd --
*
* Change the flag which says whether new windows will have scroll bars.
*
* Usage:
* windscrollbars [on|off]
*
* Results:
* None.
*
* Side effects:
* A flag is changed.
*
* ----------------------------------------------------------------------------
*/
void
windScrollBarsCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int place;
static const char * const onoff[] = {"on", "off", 0};
static const bool truth[] = {TRUE, FALSE};
if (cmd->tx_argc != 2) goto usage;
place = Lookup(cmd->tx_argv[1], onoff);
if (place < 0) goto usage;
if (truth[place])
{
WindDefaultFlags |= WIND_SCROLLBARS;
TxPrintf("New windows will have scroll bars.\n");
}
else
{
WindDefaultFlags &= ~WIND_SCROLLBARS;
TxPrintf("New windows will not have scroll bars.\n");
}
return;
usage:
TxError("Usage: %s [on|off]\n", cmd->tx_argv[0]);
return;
}
#ifndef MAGIC_WRAPPER
/*
* ----------------------------------------------------------------------------
*
* windSendCmd --
*
* Send a command to a certain window type. If possible we will pass a
* arbitrarily chosen window of that type down to the client.
*
* Usage:
* send type command
*
* Results:
* None.
*
* Side effects:
* Whatever the client does
*
* ----------------------------------------------------------------------------
*/
void
windSendCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
MagWindow *toWindow;
WindClient client;
TxCommand newcmd;
extern int windSendCmdFunc();
if (cmd->tx_argc < 3) goto usage;
if (cmd->tx_argv[1][0] == '*') goto usage; /* hidden window client */
client = WindGetClient(cmd->tx_argv[1], FALSE);
if (client == (WindClient) NULL) goto usage;
toWindow = (MagWindow *) NULL;
(void) WindSearch(client, (ClientData) NULL, (Rect *) NULL,
windSendCmdFunc, (ClientData) &toWindow);
{
int i;
newcmd = *cmd;
newcmd.tx_argc -= 2;
for (i = 0; i < newcmd.tx_argc; i++) {
newcmd.tx_argv[i] = newcmd.tx_argv[i + 2];
};
}
newcmd.tx_wid = WIND_UNKNOWN_WINDOW;
if (toWindow != NULL) newcmd.tx_wid = toWindow->w_wid;
(void) WindSendCommand(toWindow, &newcmd, FALSE);
return;
usage:
TxError("Usage: send type command\n");
TxPrintf("Valid window types are:\n");
WindPrintClientList(FALSE);
return;
}
int
windSendCmdFunc(w, cd)
MagWindow *w;
ClientData cd;
{
*((MagWindow **) cd) = w;
return 1;
}
#endif
/* Structure used by "position" command to pass to WindSearch */
/* as client data. */
typedef struct _cdwpos {
FILE *file;
bool doFrame;
} cdwpos;
/*
* ----------------------------------------------------------------------------
*
* windPositionsCmd --
*
* Print out the positions of the windows.
*
* Usage:
* windowpositions [file]
*
* Results:
* None.
*
* Side effects:
* A file is written.
*
* ----------------------------------------------------------------------------
*/
void
windPositionsCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
extern int windPositionsFunc();
char *filename = NULL;
cdwpos windpos;
windpos.doFrame = FALSE;
windpos.file = stdout;
if (cmd->tx_argc > 3) goto usage;
if (cmd->tx_argc > 1)
{
if (!strncmp(cmd->tx_argv[1], "frame", 5))
{
windpos.doFrame = TRUE;
if (cmd->tx_argc == 3)
filename = cmd->tx_argv[2];
}
else if (cmd->tx_argc == 2)
filename = cmd->tx_argv[1];
else
goto usage;
}
if (filename) {
windpos.file = fopen(filename, "w");
if (windpos.file == (FILE *) NULL)
{
TxError("Could not open file %s for writing.\n", filename);
return;
};
}
(void) WindSearch((WindClient) NULL, (ClientData) NULL, (Rect *) NULL,
windPositionsFunc, (ClientData) &windpos);
if (filename) (void) fclose(windpos.file);
return;
usage:
TxError("Usage: windowpositions [file]\n");
return;
}
int
windPositionsFunc(w, cdata)
MagWindow *w;
ClientData cdata;
{
cdwpos *windpos = (cdwpos *)cdata;
Rect r;
if (windpos->doFrame)
r = w->w_frameArea;
else
r = w->w_screenArea;
if (windpos->file == stdout)
#ifdef MAGIC_WRAPPER
{
Tcl_Obj *lobj;
lobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_xbot));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_ybot));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_xtop));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_ytop));
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(((clientRec *)w->w_client)->w_clientName,
strlen(((clientRec *)w->w_client)->w_clientName)));
Tcl_SetObjResult(magicinterp, lobj);
}
#else
TxPrintf("specialopen %d %d %d %d %s\n",
r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop,
((clientRec *) w->w_client)->w_clientName);
#endif
else
fprintf((FILE *)cdata, "specialopen %d %d %d %d %s\n",
r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop,
((clientRec *) w->w_client)->w_clientName);
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* windZoomCmd --
*
* Implement the "zoom" command.
* Change the view in the selected window by the given scale factor.
*
* Usage:
* zoom amount
*
* Results:
* None.
*
* Side effects:
* The window underneath the cursor is changed.
*
* ----------------------------------------------------------------------------
*/
void
windZoomCmd(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
float factor;
if (w == NULL)
return;
if ((w->w_flags & WIND_SCROLLABLE) == 0) {
TxError("Sorry, can't zoom this window.\n");
return;
};
if (cmd->tx_argc != 2)
{
TxError("Usage: %s factor\n", cmd->tx_argv[0]);
return;
}
factor = MagAtof(cmd->tx_argv[1]);
if ((factor <= 0) || (factor >= 20))
{
TxError("zoom factor must be between 0 and 20.\n");
return;
}
WindZoom(w, factor);
}