xref: /petsc/src/sys/classes/draw/interface/draw.c (revision c598d79dbe721bc07f31101454487c099ce1a833)
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_petsc() when using dynamic libraries, and on the call to PetscInitialize()
34   when using shared or 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 = PetscLogEventExcludeClass(PETSC_DRAW_CLASSID);CHKERRQ(ierr);
78       ierr = PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID);CHKERRQ(ierr);
79       ierr = PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID);CHKERRQ(ierr);
80       ierr = PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID);CHKERRQ(ierr);
81       ierr = PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID);CHKERRQ(ierr);
82       ierr = PetscLogEventExcludeClass(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