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