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