/* 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 #include #include /* for sleep() */ #include #include #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 char *onoff[] = {"on", "off", 0}; static 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); }