diff --git a/ChangeLog b/ChangeLog index ef111e58d..14cea393e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-02-10 Holger Vogt + * windisp.c, X11.c, postcom.c + 'destroy plot1' now deletes all graphs (plot windows) + associated with the plot 'plot1' before the data of plot1 + are deleted, to prevent a crash due to unsuccessful redrawing + 2009-02-07 Holger Vogt * device.c, inpcom.c alter and altermod commands reinstated and improved diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 98448b18a..355c6d1db 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -819,6 +819,20 @@ killwin(Widget w, caddr_t client_data, caddr_t call_data) } +/* called from postcoms.c + In the command 'destroy ac2' Will remove window associated with + the plot (e.g. ac2) just before data of the plot are deleted.*/ +void +RemoveWindow(GRAPH *graph) +{ + /* Iplots are done asynchronously */ + DEVDEP(graph).isopen = 0; + /* MW. Not sure but DestroyGraph might free() to much - try Xt...() first */ + XtDestroyWidget(DEVDEP(graph).shell); + DestroyGraph(graph->graphid); +} + + /* call higher gr_redraw routine */ void redraw(Widget w, caddr_t client_data, caddr_t call_data) diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 42e20c74b..2af4457b7 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -13,6 +13,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include #include +#include +#include "plotting/graphdb.h" #include "completion.h" #include "postcoms.h" @@ -22,9 +24,14 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group /* static declarations */ static void killplot(struct plot *pl); +static void DelPlotWindows(struct plot *pl); - -/* Undefine vectors. */ +/* External function */ +/* Either defined in windisp.c or in x11.c */ +/* Do this only if Windows or X11 is defined. */ +#if defined(HAS_WINDOWS) || !defined(X_DISPLAY_MISSING) +extern void RemoveWindow(GRAPH*); +#endif void com_unlet(wordlist *wl) @@ -633,19 +640,22 @@ com_destroy(wordlist *wl) { struct plot *pl, *npl = NULL; - if (!wl) - killplot(plot_cur); + if (!wl) { + DelPlotWindows(plot_cur); + killplot(plot_cur); + } else if (eq(wl->wl_word, "all")) { for (pl = plot_list; pl; pl = npl) { npl = pl->pl_next; if (!eq(pl->pl_typename, "const")) - { - killplot(pl); - } - else - { - plot_num=1; - } + { + DelPlotWindows(pl); + killplot(pl); + } + else + { + plot_num=1; + } } } else { while (wl) { @@ -653,13 +663,13 @@ com_destroy(wordlist *wl) if (eq(pl->pl_typename, wl->wl_word)) break; if (pl) - { + { + DelPlotWindows(pl); killplot(pl); - plot_num--; - } + plot_num--; + } else - fprintf(cp_err, "Error: no such plot %s\n", - wl->wl_word); + fprintf(cp_err, "Error: no such plot %s\n", wl->wl_word); wl = wl->wl_next; } } @@ -717,6 +727,29 @@ killplot(struct plot *pl) return; } +/* delete all windows with graphs dedrived from a given plot */ +static void +DelPlotWindows(struct plot *pl) +{ +/* do this only if windows or X11 is defined */ +#if defined(HAS_WINDOWS) || !defined(X_DISPLAY_MISSING) + GRAPH *dgraph; + int n; + /* find and remove all graph structures derived from a given plot */ + for (n=1; n < 100; n++) { /* should be no more than 100 */ + dgraph = FindGraph(n); + if(dgraph) { + if (ciprefix(pl->pl_typename, dgraph->plotname)) + RemoveWindow(dgraph); + } +/* We have to run through all potential graph ids. If some numbers are + already missing, 'else break;' might miss the plotwindow to be removed. */ +/* else + break; */ + } +#endif +} + void com_splot(wordlist *wl) { diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 3e118aef3..4d7d5a21b 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -47,6 +47,7 @@ LRESULT CALLBACK PlotWindowProc( HWND hwnd, /* window procedure */ UINT uMsg, WPARAM wParam, LPARAM lParam); void WPRINT_PrintInit( HWND hwnd); /* Windows printer init */ void WaitForIdle(void); /* wait until no more events */ +void RemoveWindow(GRAPH *pgraph); static void WIN_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy); /* get new plot size coordinates */ @@ -738,6 +739,14 @@ int WIN_DiagramReady() return 0; } +void RemoveWindow(GRAPH* dgraph) +{ + tpWindowData wd; + wd = pWindowData(dgraph); + if (!wd) return 0; + SendMessage( wd->wnd, WM_CLOSE, (WPARAM) wd->hDC, 0); +} + /* Function borrowed from x11.c */ static void WIN_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy) {