xref: /petsc/src/sys/classes/draw/interface/draw.c (revision 834855d6effb0d027771461c8e947ee1ce5a1e17)
1 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/
2 #include <petscviewer.h>
3 
4 PetscClassId PETSC_DRAW_CLASSID;
5 
6 static PetscBool PetscDrawPackageInitialized = PETSC_FALSE;
7 /*@C
8   PetscDrawFinalizePackage - This function destroys everything in the PETSc interface to the `PetscDraw` package. It is
9   called from `PetscFinalize()`.
10 
11   Level: developer
12 
13 .seealso: `PetscDraw`, `PetscFinalize()`
14 @*/
PetscDrawFinalizePackage(void)15 PetscErrorCode PetscDrawFinalizePackage(void)
16 {
17   PetscFunctionBegin;
18   PetscCall(PetscFunctionListDestroy(&PetscDrawList));
19   PetscDrawPackageInitialized = PETSC_FALSE;
20   PetscDrawRegisterAllCalled  = PETSC_FALSE;
21   PetscFunctionReturn(PETSC_SUCCESS);
22 }
23 
24 /*@C
25   PetscDrawInitializePackage - This function initializes everything in the `PetscDraw` package. It is called
26   from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
27   when using shared or static libraries.
28 
29   Level: developer
30 
31 .seealso: `PetscDraw`, `PetscInitialize()`
32 @*/
PetscDrawInitializePackage(void)33 PetscErrorCode PetscDrawInitializePackage(void)
34 {
35   char      logList[256];
36   PetscBool opt, pkg;
37 
38   PetscFunctionBegin;
39   if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
40   PetscDrawPackageInitialized = PETSC_TRUE;
41   /* Register Classes */
42   PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID));
43   PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID));
44   PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID));
45   PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID));
46   PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID));
47   PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID));
48   /* Register Constructors */
49   PetscCall(PetscDrawRegisterAll());
50   /* Process Info */
51   {
52     PetscClassId classids[6];
53 
54     classids[0] = PETSC_DRAW_CLASSID;
55     classids[1] = PETSC_DRAWAXIS_CLASSID;
56     classids[2] = PETSC_DRAWLG_CLASSID;
57     classids[3] = PETSC_DRAWHG_CLASSID;
58     classids[4] = PETSC_DRAWBAR_CLASSID;
59     classids[5] = PETSC_DRAWSP_CLASSID;
60     PetscCall(PetscInfoProcessClass("draw", 6, classids));
61   }
62   /* Process summary exclusions */
63   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
64   if (opt) {
65     PetscCall(PetscStrInList("draw", logList, ',', &pkg));
66     if (pkg) {
67       PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID));
68       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID));
69       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID));
70       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID));
71       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID));
72       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID));
73     }
74   }
75   /* Register package finalizer */
76   PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage));
77   PetscFunctionReturn(PETSC_SUCCESS);
78 }
79 
80 /*@
81   PetscDrawResizeWindow - Allows one to resize a window from a program.
82 
83   Collective
84 
85   Input Parameters:
86 + draw - the window
87 . w    - the new width of the window
88 - h    - the new height of the window
89 
90   Level: intermediate
91 
92 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
93 @*/
PetscDrawResizeWindow(PetscDraw draw,int w,int h)94 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
95 {
96   PetscFunctionBegin;
97   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
98   PetscValidLogicalCollectiveInt(draw, w, 2);
99   PetscValidLogicalCollectiveInt(draw, h, 3);
100   PetscTryTypeMethod(draw, resizewindow, w, h);
101   PetscFunctionReturn(PETSC_SUCCESS);
102 }
103 
104 /*@
105   PetscDrawGetWindowSize - Gets the size of the window.
106 
107   Not Collective
108 
109   Input Parameter:
110 . draw - the window
111 
112   Output Parameters:
113 + w - the window width
114 - h - the window height
115 
116   Level: intermediate
117 
118 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
119 @*/
PetscDrawGetWindowSize(PetscDraw draw,int * w,int * h)120 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
121 {
122   PetscFunctionBegin;
123   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
124   if (w) PetscAssertPointer(w, 2);
125   if (h) PetscAssertPointer(h, 3);
126   if (w) *w = draw->w;
127   if (h) *h = draw->h;
128   PetscFunctionReturn(PETSC_SUCCESS);
129 }
130 
131 /*@
132   PetscDrawCheckResizedWindow - Checks if the user has resized the window.
133 
134   Collective
135 
136   Input Parameter:
137 . draw - the window
138 
139   Level: advanced
140 
141 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
142 @*/
PetscDrawCheckResizedWindow(PetscDraw draw)143 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
144 {
145   PetscFunctionBegin;
146   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
147   PetscTryTypeMethod(draw, checkresizedwindow);
148   PetscFunctionReturn(PETSC_SUCCESS);
149 }
150 
151 /*@
152   PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.
153 
154   Not Collective
155 
156   Input Parameter:
157 . draw - the graphics context
158 
159   Output Parameter:
160 . title - the title
161 
162   Level: intermediate
163 
164 .seealso: `PetscDraw`, `PetscDrawSetTitle()`
165 @*/
PetscDrawGetTitle(PetscDraw draw,const char * title[])166 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
167 {
168   PetscFunctionBegin;
169   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
170   PetscAssertPointer(title, 2);
171   *title = draw->title;
172   PetscFunctionReturn(PETSC_SUCCESS);
173 }
174 
175 /*@
176   PetscDrawSetTitle - Sets the title of a `PetscDraw` context.
177 
178   Collective
179 
180   Input Parameters:
181 + draw  - the graphics context
182 - title - the title
183 
184   Level: intermediate
185 
186   Notes:
187   The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
188   in the image.
189 
190   A copy of the string is made, so you may destroy the
191   title string after calling this routine.
192 
193   You can use `PetscDrawAxisSetLabels()` to indicate a title within the window
194 
195 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
196 @*/
PetscDrawSetTitle(PetscDraw draw,const char title[])197 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
198 {
199   PetscFunctionBegin;
200   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
201   PetscAssertPointer(title, 2);
202   PetscCall(PetscFree(draw->title));
203   PetscCall(PetscStrallocpy(title, &draw->title));
204   PetscTryTypeMethod(draw, settitle, draw->title);
205   PetscFunctionReturn(PETSC_SUCCESS);
206 }
207 
208 /*@
209   PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.
210 
211   Collective
212 
213   Input Parameters:
214 + draw  - the graphics context
215 - title - the title
216 
217   Level: advanced
218 
219   Note:
220   A copy of the string is made, so you may destroy the
221   title string after calling this routine.
222 
223 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
224 @*/
PetscDrawAppendTitle(PetscDraw draw,const char title[])225 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
226 {
227   PetscFunctionBegin;
228   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
229   if (title) PetscAssertPointer(title, 2);
230   if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS);
231 
232   if (draw->title) {
233     size_t len1, len2, new_len;
234     PetscCall(PetscStrlen(draw->title, &len1));
235     PetscCall(PetscStrlen(title, &len2));
236     new_len = len1 + len2 + 1;
237     PetscCall(PetscRealloc(new_len * sizeof(*draw->title), &draw->title));
238     PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1));
239   } else {
240     PetscCall(PetscStrallocpy(title, &draw->title));
241   }
242   PetscTryTypeMethod(draw, settitle, draw->title);
243   PetscFunctionReturn(PETSC_SUCCESS);
244 }
245 
PetscDrawDestroy_Private(PetscDraw draw)246 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
247 {
248   PetscFunctionBegin;
249   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
250   PetscCall(PetscDrawSaveMovie(draw));
251   if (draw->savefinalfilename) {
252     draw->savesinglefile = PETSC_TRUE;
253     PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
254     PetscCall(PetscDrawSave(draw));
255   }
256   PetscCall(PetscBarrier((PetscObject)draw));
257   PetscFunctionReturn(PETSC_SUCCESS);
258 }
259 
260 /*@
261   PetscDrawDestroy - Deletes a draw context.
262 
263   Collective
264 
265   Input Parameter:
266 . draw - the drawing context
267 
268   Level: beginner
269 
270 .seealso: `PetscDraw`, `PetscDrawCreate()`
271 @*/
PetscDrawDestroy(PetscDraw * draw)272 PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
273 {
274   PetscFunctionBegin;
275   if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
276   PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1);
277   if (--((PetscObject)*draw)->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
278 
279   if ((*draw)->pause == -2) {
280     (*draw)->pause = -1;
281     PetscCall(PetscDrawPause(*draw));
282   }
283 
284   /* if memory was published then destroy it */
285   PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
286 
287   PetscCall(PetscDrawDestroy_Private(*draw));
288 
289   PetscTryTypeMethod(*draw, destroy);
290   PetscCall(PetscDrawDestroy(&(*draw)->popup));
291   PetscCall(PetscFree((*draw)->title));
292   PetscCall(PetscFree((*draw)->display));
293   PetscCall(PetscFree((*draw)->savefilename));
294   PetscCall(PetscFree((*draw)->saveimageext));
295   PetscCall(PetscFree((*draw)->savemovieext));
296   PetscCall(PetscFree((*draw)->savefinalfilename));
297   PetscCall(PetscHeaderDestroy(draw));
298   PetscFunctionReturn(PETSC_SUCCESS);
299 }
300 
301 /*@
302   PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.
303 
304   Collective
305 
306   Input Parameter:
307 . draw - the original window
308 
309   Output Parameter:
310 . popup - the new popup window
311 
312   Level: advanced
313 
314 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
315 @*/
PetscDrawGetPopup(PetscDraw draw,PetscDraw * popup)316 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
317 {
318   PetscFunctionBegin;
319   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
320   PetscAssertPointer(popup, 2);
321 
322   if (draw->popup) *popup = draw->popup;
323   else if (draw->ops->getpopup) {
324     PetscUseTypeMethod(draw, getpopup, popup);
325     if (*popup) {
326       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
327       (*popup)->pause = 0.0;
328       PetscCall(PetscDrawSetFromOptions(*popup));
329     }
330   } else *popup = NULL;
331   PetscFunctionReturn(PETSC_SUCCESS);
332 }
333 
334 /*@
335   PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed
336 
337   Input Parameters:
338 + draw    - the drawing context
339 - display - the X windows display
340 
341   Level: advanced
342 
343 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
344 @*/
PetscDrawSetDisplay(PetscDraw draw,const char display[])345 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
346 {
347   PetscFunctionBegin;
348   PetscCall(PetscFree(draw->display));
349   PetscCall(PetscStrallocpy(display, &draw->display));
350   PetscFunctionReturn(PETSC_SUCCESS);
351 }
352 
353 /*@
354   PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
355 
356   Logically Collective
357 
358   Input Parameter:
359 . draw - the drawing context
360 
361   Level: intermediate
362 
363 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
364 @*/
PetscDrawSetDoubleBuffer(PetscDraw draw)365 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
366 {
367   PetscFunctionBegin;
368   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
369   PetscTryTypeMethod(draw, setdoublebuffer);
370   PetscFunctionReturn(PETSC_SUCCESS);
371 }
372 
373 /*@
374   PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
375   by the one process.
376 
377   Collective
378 
379   Input Parameter:
380 . draw - the original window
381 
382   Output Parameter:
383 . sdraw - the singleton window
384 
385   Level: advanced
386 
387 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
388 @*/
PetscDrawGetSingleton(PetscDraw draw,PetscDraw * sdraw)389 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
390 {
391   PetscMPIInt size;
392 
393   PetscFunctionBegin;
394   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
395   PetscAssertPointer(sdraw, 2);
396 
397   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
398   if (size == 1) {
399     PetscCall(PetscObjectReference((PetscObject)draw));
400     *sdraw = draw;
401   } else PetscUseTypeMethod(draw, getsingleton, sdraw);
402   PetscFunctionReturn(PETSC_SUCCESS);
403 }
404 
405 /*@
406   PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
407   by the one process.
408 
409   Collective
410 
411   Input Parameters:
412 + draw  - the original window
413 - sdraw - the singleton window
414 
415   Level: advanced
416 
417 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
418 @*/
PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw * sdraw)419 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
420 {
421   PetscMPIInt size;
422 
423   PetscFunctionBegin;
424   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
425   PetscAssertPointer(sdraw, 2);
426   PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2);
427 
428   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
429   if (size == 1) {
430     PetscCheck(draw == *sdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
431     PetscCall(PetscObjectDereference((PetscObject)draw));
432     *sdraw = NULL;
433   } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
434   PetscFunctionReturn(PETSC_SUCCESS);
435 }
436 
437 /*@
438   PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.
439 
440   Input Parameters:
441 + draw    - the drawing window
442 - visible - if the surface should be visible
443 
444   Level: intermediate
445 
446 .seealso: `PetscDraw`
447 @*/
PetscDrawSetVisible(PetscDraw draw,PetscBool visible)448 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
449 {
450   PetscFunctionBegin;
451   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
452   PetscTryTypeMethod(draw, setvisible, visible);
453   PetscFunctionReturn(PETSC_SUCCESS);
454 }
455