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