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