xref: /petsc/src/sys/classes/draw/interface/draw.c (revision 412a4547dd7e89e3215c18267240f803e3e1331c)
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 Draw package. It is
13   called from PetscFinalize().
14 
15   Level: developer
16 
17 .seealso: `PetscFinalize()`
18 @*/
19 PetscErrorCode  PetscDrawFinalizePackage(void)
20 {
21   PetscFunctionBegin;
22   PetscCall(PetscFunctionListDestroy(&PetscDrawList));
23   PetscDrawPackageInitialized = PETSC_FALSE;
24   PetscDrawRegisterAllCalled  = PETSC_FALSE;
25   PetscFunctionReturn(0);
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: `PetscInitialize()`
36 @*/
37 PetscErrorCode  PetscDrawInitializePackage(void)
38 {
39   char           logList[256];
40   PetscBool      opt,pkg;
41 
42   PetscFunctionBegin;
43   if (PetscDrawPackageInitialized) PetscFunctionReturn(0);
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(0);
82 }
83 
84 /*@
85    PetscDrawResizeWindow - Allows one to resize a window from a program.
86 
87    Collective on PetscDraw
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: `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   if (draw->ops->resizewindow) PetscCall((*draw->ops->resizewindow)(draw,w,h));
104   PetscFunctionReturn(0);
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: `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(0);
131 }
132 
133 /*@
134    PetscDrawCheckResizedWindow - Checks if the user has resized the window.
135 
136    Collective on PetscDraw
137 
138    Input Parameter:
139 .  draw - the window
140 
141    Level: advanced
142 
143 .seealso: `PetscDrawResizeWindow()`
144 
145 @*/
146 PetscErrorCode  PetscDrawCheckResizedWindow(PetscDraw draw)
147 {
148   PetscFunctionBegin;
149   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
150   if (draw->ops->checkresizedwindow) PetscCall((*draw->ops->checkresizedwindow)(draw));
151   PetscFunctionReturn(0);
152 }
153 
154 /*@C
155    PetscDrawGetTitle - Gets pointer to title of a PetscDraw context.
156 
157    Not collective
158 
159    Input Parameter:
160 .  draw - the graphics context
161 
162    Output Parameter:
163 .  title - the title
164 
165    Level: intermediate
166 
167 .seealso: `PetscDrawSetTitle()`
168 @*/
169 PetscErrorCode  PetscDrawGetTitle(PetscDraw draw,const char *title[])
170 {
171   PetscFunctionBegin;
172   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
173   PetscValidPointer(title,2);
174   *title = draw->title;
175   PetscFunctionReturn(0);
176 }
177 
178 /*@C
179    PetscDrawSetTitle - Sets the title of a PetscDraw context.
180 
181    Collective on PetscDraw
182 
183    Input Parameters:
184 +  draw - the graphics context
185 -  title - the title
186 
187    Level: intermediate
188 
189    Note: 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: `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   if (draw->ops->settitle) PetscCall((*draw->ops->settitle)(draw,draw->title));
207   PetscFunctionReturn(0);
208 }
209 
210 /*@C
211    PetscDrawAppendTitle - Appends to the title of a PetscDraw context.
212 
213    Collective on PetscDraw
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: `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(0);
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   if (draw->ops->settitle) PetscCall((*draw->ops->settitle)(draw,draw->title));
248   PetscFunctionReturn(0);
249 }
250 
251 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
252 {
253   PetscFunctionBegin;
254   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
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(0);
263 }
264 
265 /*@
266    PetscDrawDestroy - Deletes a draw context.
267 
268    Collective on PetscDraw
269 
270    Input Parameters:
271 .  draw - the drawing context
272 
273    Level: beginner
274 
275 .seealso: `PetscDrawCreate()`
276 
277 @*/
278 PetscErrorCode  PetscDrawDestroy(PetscDraw *draw)
279 {
280   PetscFunctionBegin;
281   if (!*draw) PetscFunctionReturn(0);
282   PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1);
283   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0);
284 
285   if ((*draw)->pause == -2) {
286     (*draw)->pause = -1;
287     PetscCall(PetscDrawPause(*draw));
288   }
289 
290   /* if memory was published then destroy it */
291   PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
292 
293   PetscCall(PetscDrawDestroy_Private(*draw));
294 
295   if ((*draw)->ops->destroy) {
296     PetscCall((*(*draw)->ops->destroy)(*draw));
297   }
298   PetscCall(PetscDrawDestroy(&(*draw)->popup));
299   PetscCall(PetscFree((*draw)->title));
300   PetscCall(PetscFree((*draw)->display));
301   PetscCall(PetscFree((*draw)->savefilename));
302   PetscCall(PetscFree((*draw)->saveimageext));
303   PetscCall(PetscFree((*draw)->savemovieext));
304   PetscCall(PetscFree((*draw)->savefinalfilename));
305   PetscCall(PetscHeaderDestroy(draw));
306   PetscFunctionReturn(0);
307 }
308 
309 /*@
310    PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window.
311 
312    Collective on PetscDraw
313 
314    Input Parameter:
315 .  draw - the original window
316 
317    Output Parameter:
318 .  popup - the new popup window
319 
320    Level: advanced
321 
322 .seealso: `PetscDrawScalePopup()`, `PetscDrawCreate()`
323 
324 @*/
325 PetscErrorCode  PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup)
326 {
327   PetscFunctionBegin;
328   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
329   PetscValidPointer(popup,2);
330 
331   if (draw->popup) *popup = draw->popup;
332   else if (draw->ops->getpopup) {
333     PetscCall((*draw->ops->getpopup)(draw,popup));
334     if (*popup) {
335       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_"));
336       (*popup)->pause = 0.0;
337       PetscCall(PetscDrawSetFromOptions(*popup));
338     }
339   } else *popup = NULL;
340   PetscFunctionReturn(0);
341 }
342 
343 /*@C
344   PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed
345 
346   Input Parameters:
347 + draw - the drawing context
348 - display - the X windows display
349 
350   Level: advanced
351 
352 .seealso: `PetscDrawCreate()`
353 
354 @*/
355 PetscErrorCode  PetscDrawSetDisplay(PetscDraw draw,const char display[])
356 {
357   PetscFunctionBegin;
358   PetscCall(PetscFree(draw->display));
359   PetscCall(PetscStrallocpy(display,&draw->display));
360   PetscFunctionReturn(0);
361 }
362 
363 /*@
364    PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
365 
366    Logically Collective on PetscDraw
367 
368    Input Parameter:
369 .  draw - the drawing context
370 
371    Level: intermediate
372 
373 @*/
374 PetscErrorCode  PetscDrawSetDoubleBuffer(PetscDraw draw)
375 {
376   PetscFunctionBegin;
377   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
378   if (draw->ops->setdoublebuffer) PetscCall((*draw->ops->setdoublebuffer)(draw));
379   PetscFunctionReturn(0);
380 }
381 
382 /*@C
383    PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned
384         by the one process.
385 
386    Collective on PetscDraw
387 
388    Input Parameter:
389 .  draw - the original window
390 
391    Output Parameter:
392 .  sdraw - the singleton window
393 
394    Level: advanced
395 
396 .seealso: `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
397 
398 @*/
399 PetscErrorCode  PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw)
400 {
401   PetscMPIInt    size;
402 
403   PetscFunctionBegin;
404   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
405   PetscValidPointer(sdraw,2);
406 
407   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size));
408   if (size == 1) {
409     PetscCall(PetscObjectReference((PetscObject)draw));
410     *sdraw = draw;
411   } else {
412     if (draw->ops->getsingleton) {
413       PetscCall((*draw->ops->getsingleton)(draw,sdraw));
414     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name);
415   }
416   PetscFunctionReturn(0);
417 }
418 
419 /*@C
420    PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned
421         by the one process.
422 
423    Collective on PetscDraw
424 
425    Input Parameters:
426 +  draw - the original window
427 -  sdraw - the singleton window
428 
429    Level: advanced
430 
431 .seealso: `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
432 
433 @*/
434 PetscErrorCode  PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw)
435 {
436   PetscMPIInt    size;
437 
438   PetscFunctionBegin;
439   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
440   PetscValidPointer(sdraw,2);
441   PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2);
442 
443   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size));
444   if (size == 1) {
445     if (draw == *sdraw) {
446       PetscCall(PetscObjectDereference((PetscObject)draw));
447       *sdraw = NULL;
448     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw");
449   } else {
450     if (draw->ops->restoresingleton) {
451       PetscCall((*draw->ops->restoresingleton)(draw,sdraw));
452     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name);
453   }
454   PetscFunctionReturn(0);
455 }
456