xref: /petsc/src/sys/classes/draw/interface/draw.c (revision 21e3ffae2f3b73c0bd738cf6d0a809700fc04bb0)
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;
236     char  *newtitle;
237     PetscCall(PetscStrlen(title, &len1));
238     PetscCall(PetscStrlen(draw->title, &len2));
239     PetscCall(PetscMalloc1(len1 + len2 + 1, &newtitle));
240     PetscCall(PetscStrcpy(newtitle, draw->title));
241     PetscCall(PetscStrcat(newtitle, title));
242     PetscCall(PetscFree(draw->title));
243     draw->title = newtitle;
244   } else {
245     PetscCall(PetscStrallocpy(title, &draw->title));
246   }
247   PetscTryTypeMethod(draw, settitle, draw->title);
248   PetscFunctionReturn(PETSC_SUCCESS);
249 }
250 
251 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
252 {
253   PetscFunctionBegin;
254   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
255   PetscCall(PetscDrawSaveMovie(draw));
256   if (draw->savefinalfilename) {
257     draw->savesinglefile = PETSC_TRUE;
258     PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
259     PetscCall(PetscDrawSave(draw));
260   }
261   PetscCall(PetscBarrier((PetscObject)draw));
262   PetscFunctionReturn(PETSC_SUCCESS);
263 }
264 
265 /*@
266    PetscDrawDestroy - Deletes a draw context.
267 
268    Collective
269 
270    Input Parameters:
271 .  draw - the drawing context
272 
273    Level: beginner
274 
275 .seealso: `PetscDraw`, `PetscDrawCreate()`
276 @*/
277 PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
278 {
279   PetscFunctionBegin;
280   if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
281   PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1);
282   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
283 
284   if ((*draw)->pause == -2) {
285     (*draw)->pause = -1;
286     PetscCall(PetscDrawPause(*draw));
287   }
288 
289   /* if memory was published then destroy it */
290   PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
291 
292   PetscCall(PetscDrawDestroy_Private(*draw));
293 
294   if ((*draw)->ops->destroy) PetscCall((*(*draw)->ops->destroy)(*draw));
295   PetscCall(PetscDrawDestroy(&(*draw)->popup));
296   PetscCall(PetscFree((*draw)->title));
297   PetscCall(PetscFree((*draw)->display));
298   PetscCall(PetscFree((*draw)->savefilename));
299   PetscCall(PetscFree((*draw)->saveimageext));
300   PetscCall(PetscFree((*draw)->savemovieext));
301   PetscCall(PetscFree((*draw)->savefinalfilename));
302   PetscCall(PetscHeaderDestroy(draw));
303   PetscFunctionReturn(PETSC_SUCCESS);
304 }
305 
306 /*@
307    PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.
308 
309    Collective
310 
311    Input Parameter:
312 .  draw - the original window
313 
314    Output Parameter:
315 .  popup - the new popup window
316 
317    Level: advanced
318 
319 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
320 @*/
321 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
322 {
323   PetscFunctionBegin;
324   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
325   PetscValidPointer(popup, 2);
326 
327   if (draw->popup) *popup = draw->popup;
328   else if (draw->ops->getpopup) {
329     PetscUseTypeMethod(draw, getpopup, popup);
330     if (*popup) {
331       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
332       (*popup)->pause = 0.0;
333       PetscCall(PetscDrawSetFromOptions(*popup));
334     }
335   } else *popup = NULL;
336   PetscFunctionReturn(PETSC_SUCCESS);
337 }
338 
339 /*@C
340   PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed
341 
342   Input Parameters:
343 + draw - the drawing context
344 - display - the X windows display
345 
346   Level: advanced
347 
348 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
349 @*/
350 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
351 {
352   PetscFunctionBegin;
353   PetscCall(PetscFree(draw->display));
354   PetscCall(PetscStrallocpy(display, &draw->display));
355   PetscFunctionReturn(PETSC_SUCCESS);
356 }
357 
358 /*@
359    PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
360 
361    Logically Collective
362 
363    Input Parameter:
364 .  draw - the drawing context
365 
366    Level: intermediate
367 
368 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
369 @*/
370 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
371 {
372   PetscFunctionBegin;
373   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
374   PetscTryTypeMethod(draw, setdoublebuffer);
375   PetscFunctionReturn(PETSC_SUCCESS);
376 }
377 
378 /*@C
379    PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
380         by the one process.
381 
382    Collective
383 
384    Input Parameter:
385 .  draw - the original window
386 
387    Output Parameter:
388 .  sdraw - the singleton window
389 
390    Level: advanced
391 
392 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
393 @*/
394 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
395 {
396   PetscMPIInt size;
397 
398   PetscFunctionBegin;
399   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
400   PetscValidPointer(sdraw, 2);
401 
402   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
403   if (size == 1) {
404     PetscCall(PetscObjectReference((PetscObject)draw));
405     *sdraw = draw;
406   } else {
407     if (draw->ops->getsingleton) {
408       PetscUseTypeMethod(draw, getsingleton, sdraw);
409     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
410   }
411   PetscFunctionReturn(PETSC_SUCCESS);
412 }
413 
414 /*@C
415    PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
416         by the one process.
417 
418    Collective
419 
420    Input Parameters:
421 +  draw - the original window
422 -  sdraw - the singleton window
423 
424    Level: advanced
425 
426 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
427 @*/
428 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
429 {
430   PetscMPIInt size;
431 
432   PetscFunctionBegin;
433   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
434   PetscValidPointer(sdraw, 2);
435   PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2);
436 
437   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
438   if (size == 1) {
439     if (draw == *sdraw) {
440       PetscCall(PetscObjectDereference((PetscObject)draw));
441       *sdraw = NULL;
442     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
443   } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
444   PetscFunctionReturn(PETSC_SUCCESS);
445 }
446 
447 /*@C
448    PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.
449 
450    Input Parameters:
451 +  draw - the drawing window
452 -  visible - if the surface should be visible
453 
454 .seealso: `PetscDraw`
455 @*/
456 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
457 {
458   PetscFunctionBegin;
459   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
460   PetscTryTypeMethod(draw, setvisible, visible);
461   PetscFunctionReturn(PETSC_SUCCESS);
462 }
463