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