From 2914286921ad299dc14c9d9a3ddfb3c62d87bf01 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 17 Oct 2018 10:30:55 -0400 Subject: [PATCH] Resolved a tricky issue with the crosshair drawing. The crosshair routine was erasing and redrawing in one step, which ignored the possibility of having to erase from one window and redraw in another if the cursor moved focus from one window to another. This led to crosshairs being improperly drawn and erased when multiple windows were present, if the windows had different cells loaded. --- commands/CmdCD.c | 11 ++++-- dbwind/DBWtools.c | 87 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 0866cef5..17b1467f 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -2954,17 +2954,24 @@ CmdCrosshair(w, cmd) { /* Erase and turn off */ pos.p_x = pos.p_y = MINFINITY; - DBWSetCrosshair(w, &pos); + } + else + { + TxError("Usage: %s off|x y \n", cmd->tx_argv[0]); + return; } } else if (cmd->tx_argc == 3) { pos.p_x = cmdParseCoord(w, cmd->tx_argv[1], FALSE, TRUE); pos.p_y = cmdParseCoord(w, cmd->tx_argv[2], FALSE, FALSE); - DBWSetCrosshair(w, &pos); } else + { TxError("Usage: %s off|x y \n", cmd->tx_argv[0]); + return; + } + DBWSetCrosshair(w, &pos); } diff --git a/dbwind/DBWtools.c b/dbwind/DBWtools.c index b6b14f87..19361fd1 100644 --- a/dbwind/DBWtools.c +++ b/dbwind/DBWtools.c @@ -56,7 +56,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ static CellDef *boxRootDef = NULL; /* CellDef for the box */ static Rect boxRootArea; /* Root def coords */ -static Point crosshairPos; /* Crosshair position */ + +typedef struct _crosshairRec { + Point pos; /* Crosshair position */ + CellDef *def; /* CellDef that crosshair position references */ +} CrosshairRec; + +static CrosshairRec curCrosshair; /* Crosshair position */ /* * If the following is DBW_SNAP_USER, the box gets snapped to the user's @@ -390,8 +396,9 @@ ToolGetCorner(screenPoint) void dbwCrosshairInit() { - crosshairPos.p_x = MINFINITY; - crosshairPos.p_y = MINFINITY; + curCrosshair.pos.p_x = MINFINITY; + curCrosshair.pos.p_y = MINFINITY; + curCrosshair.def = (CellDef *)NULL; DBWHLAddClient(DBWDrawCrosshair); } @@ -411,8 +418,8 @@ dbwCrosshairInit() */ void -dbwRecordCrosshairYPos(window, erase) - MagWindow *window; +dbwRecordCrosshairYPos(def, erase) + CellDef *def; bool erase; /* TRUE means crossair is being erased from its * current position. FALSE means the crosshair * is being added at a new position. @@ -422,13 +429,13 @@ dbwRecordCrosshairYPos(window, erase) xwire.r_xbot = MINFINITY; xwire.r_xtop = INFINITY; - xwire.r_ybot = xwire.r_ytop = crosshairPos.p_y; - DBWHLRedraw(WINDOW_DEF(window), &xwire, erase); + xwire.r_ybot = xwire.r_ytop = curCrosshair.pos.p_y; + DBWHLRedraw(def, &xwire, erase); } void -dbwRecordCrosshairXPos(window, erase) - MagWindow *window; +dbwRecordCrosshairXPos(def, erase) + CellDef *def; bool erase; /* TRUE means crossair is being erased from its * current position. FALSE means the crosshair * is being added at a new position. @@ -438,8 +445,8 @@ dbwRecordCrosshairXPos(window, erase) xwire.r_ybot = MINFINITY; xwire.r_ytop = INFINITY; - xwire.r_xbot = xwire.r_xtop = crosshairPos.p_x; - DBWHLRedraw(WINDOW_DEF(window), &xwire, erase); + xwire.r_xbot = xwire.r_xtop = curCrosshair.pos.p_x; + DBWHLRedraw(def, &xwire, erase); } /* @@ -469,10 +476,17 @@ DBWDrawCrosshair(window, plane) { Point p; - /* Crosshair is disabled by setting to MINFINITY */ - if (crosshairPos.p_x == MINFINITY) return; + /* Unlike most highlights, which are related to the database and */ + /* therefore drawn on all windows, the crosshair only exists in */ + /* the cell where the pointer is active, and in any other window */ + /* with the same root cell. It is therefore necessary to check */ + /* if the root def of the window matches the root def of the window */ + /* with active focus. Otherwise, translating the crosshair */ + /* position to window coordinates makes no sense. */ - WindPointToScreen(window, &crosshairPos, &p); + if (WINDOW_DEF(window) != curCrosshair.def) return; + + WindPointToScreen(window, &(curCrosshair.pos), &p); GrSetStuff(STYLE_YELLOW1); if (p.p_x > window->w_screenArea.r_xbot && @@ -493,7 +507,7 @@ DBWScaleCrosshair(scalen, scaled) int scalen; int scaled; { - DBScalePoint(&crosshairPos, scalen, scaled); + DBScalePoint(&(curCrosshair.pos), scalen, scaled); } /* @@ -515,24 +529,43 @@ DBWSetCrosshair(window, pos) MagWindow *window; Point *pos; /* New crosshair location in coords of rootDef. */ { - if (crosshairPos.p_x != pos->p_x) + bool needUpdate = FALSE; + + if (WINDOW_DEF(window) != curCrosshair.def) needUpdate = TRUE; + + /* Erase */ + + if (needUpdate || (curCrosshair.pos.p_x != pos->p_x)) { /* Record the old and area of the vertical line for redisplay. */ - dbwRecordCrosshairXPos(window, TRUE); - - /* Update the crosshair location. */ - crosshairPos.p_x = pos->p_x; - - /* Record the new area for redisplay. */ - dbwRecordCrosshairXPos(window, FALSE); + dbwRecordCrosshairXPos(curCrosshair.def, TRUE); } /* Do the same thing for the horizontal crosshair line */ - if (crosshairPos.p_y != pos->p_y) + if (needUpdate || (curCrosshair.pos.p_y != pos->p_y)) { - dbwRecordCrosshairYPos(window, TRUE); - crosshairPos.p_y = pos->p_y; - dbwRecordCrosshairYPos(window, FALSE); + dbwRecordCrosshairYPos(curCrosshair.def, TRUE); + } + + /* Record the CellDef that this position is referenced to. */ + if (needUpdate) curCrosshair.def = WINDOW_DEF(window); + + /* Draw */ + + if (curCrosshair.pos.p_x != pos->p_x) + { + /* Update the crosshair location. */ + curCrosshair.pos.p_x = pos->p_x; + + /* Record the new area for redisplay. */ + dbwRecordCrosshairXPos(curCrosshair.def, FALSE); + } + + /* Do the same thing for the horizontal crosshair line */ + if (curCrosshair.pos.p_y != pos->p_y) + { + curCrosshair.pos.p_y = pos->p_y; + dbwRecordCrosshairYPos(curCrosshair.def, FALSE); } }