xref: /petsc/src/sys/classes/draw/interface/draw.c (revision 8067a7d5d1c29607366ed2aff819d529007817c0)
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 #undef __FUNCT__
12 #define __FUNCT__ "PetscDrawFinalizePackage"
13 /*@C
14   PetscDrawFinalizePackage - This function destroys everything in the Petsc interface to the Draw package. It is
15   called from PetscFinalize().
16 
17   Level: developer
18 
19 .keywords: Petsc, destroy, package, mathematica
20 .seealso: PetscFinalize()
21 @*/
22 PetscErrorCode  PetscDrawFinalizePackage(void)
23 {
24   PetscErrorCode ierr;
25 
26   PetscFunctionBegin;
27   ierr = PetscFunctionListDestroy(&PetscDrawList);CHKERRQ(ierr);
28   PetscDrawPackageInitialized = PETSC_FALSE;
29   PetscDrawRegisterAllCalled  = PETSC_FALSE;
30   PetscFunctionReturn(0);
31 }
32 
33 #undef __FUNCT__
34 #define __FUNCT__ "PetscDrawInitializePackage"
35 /*@C
36   PetscInitializeDrawPackage - This function initializes everything in the PetscDraw package. It is called
37   from PetscDLLibraryRegister() when using dynamic libraries, and on the call to PetscInitialize()
38   when using static libraries.
39 
40   Level: developer
41 
42 .keywords: Petsc, initialize, package
43 .seealso: PetscInitialize()
44 @*/
45 PetscErrorCode  PetscDrawInitializePackage(void)
46 {
47   char           logList[256];
48   char           *className;
49   PetscBool      opt;
50   PetscErrorCode ierr;
51 
52   PetscFunctionBegin;
53   if (PetscDrawPackageInitialized) PetscFunctionReturn(0);
54   PetscDrawPackageInitialized = PETSC_TRUE;
55   /* Register Classes */
56   ierr = PetscClassIdRegister("Draw",&PETSC_DRAW_CLASSID);CHKERRQ(ierr);
57   ierr = PetscClassIdRegister("Axis",&PETSC_DRAWAXIS_CLASSID);CHKERRQ(ierr);
58   ierr = PetscClassIdRegister("Line Graph",&PETSC_DRAWLG_CLASSID);CHKERRQ(ierr);
59   ierr = PetscClassIdRegister("Histogram",&PETSC_DRAWHG_CLASSID);CHKERRQ(ierr);
60   ierr = PetscClassIdRegister("Bar Grap",&PETSC_DRAWBAR_CLASSID);CHKERRQ(ierr);
61   ierr = PetscClassIdRegister("Scatter Plot",&PETSC_DRAWSP_CLASSID);CHKERRQ(ierr);
62   /* Register Constructors */
63   ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
64   /* Process info exclusions */
65   ierr = PetscOptionsGetString(NULL,NULL, "-info_exclude", logList, 256, &opt);CHKERRQ(ierr);
66   if (opt) {
67     ierr = PetscStrstr(logList, "draw", &className);CHKERRQ(ierr);
68     if (className) {
69       ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr);
70     }
71   }
72   /* Process summary exclusions */
73   ierr = PetscOptionsGetString(NULL,NULL, "-log_summary_exclude", logList, 256, &opt);CHKERRQ(ierr);
74   if (opt) {
75     ierr = PetscStrstr(logList, "draw", &className);CHKERRQ(ierr);
76     if (className) {
77       ierr = PetscLogEventDeactivateClass(0);CHKERRQ(ierr);
78     }
79   }
80   ierr = PetscRegisterFinalize(PetscDrawFinalizePackage);CHKERRQ(ierr);
81   PetscFunctionReturn(0);
82 }
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "PetscDrawResizeWindow"
86 /*@
87    PetscDrawResizeWindow - Allows one to resize a window from a program.
88 
89    Collective on PetscDraw
90 
91    Input Parameter:
92 +  draw - the window
93 -  w,h - the new width and height of the window
94 
95    Level: intermediate
96 
97 .seealso: PetscDrawCheckResizedWindow()
98 @*/
99 PetscErrorCode  PetscDrawResizeWindow(PetscDraw draw,int w,int h)
100 {
101   PetscErrorCode ierr;
102 
103   PetscFunctionBegin;
104   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
105   PetscValidLogicalCollectiveInt(draw,w,2);
106   PetscValidLogicalCollectiveInt(draw,h,3);
107   if (draw->ops->resizewindow) {
108     ierr = (*draw->ops->resizewindow)(draw,w,h);CHKERRQ(ierr);
109   }
110   PetscFunctionReturn(0);
111 }
112 
113 #undef __FUNCT__
114 #define __FUNCT__ "PetscDrawGetWindowSize"
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 #undef __FUNCT__
142 #define __FUNCT__ "PetscDrawCheckResizedWindow"
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 #undef __FUNCT__
169 #define __FUNCT__ "PetscDrawGetTitle"
170 /*@C
171    PetscDrawGetTitle - Gets pointer to title of a PetscDraw context.
172 
173    Not collective
174 
175    Input Parameter:
176 .  draw - the graphics context
177 
178    Output Parameter:
179 .  title - the title
180 
181    Level: intermediate
182 
183 .seealso: PetscDrawSetTitle()
184 @*/
185 PetscErrorCode  PetscDrawGetTitle(PetscDraw draw,char **title)
186 {
187   PetscFunctionBegin;
188   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
189   PetscValidPointer(title,2);
190   *title = draw->title;
191   PetscFunctionReturn(0);
192 }
193 
194 #undef __FUNCT__
195 #define __FUNCT__ "PetscDrawSetTitle"
196 /*@C
197    PetscDrawSetTitle - Sets the title of a PetscDraw context.
198 
199    Collective on PetscDraw
200 
201    Input Parameters:
202 +  draw - the graphics context
203 -  title - the title
204 
205    Level: intermediate
206 
207    Note: The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
208    in the image.
209 
210    A copy of the string is made, so you may destroy the
211    title string after calling this routine.
212 
213    You can use PetscDrawAxisSetLabels() to indicate a title within the window
214 
215 .seealso: PetscDrawGetTitle(), PetscDrawAppendTitle()
216 @*/
217 PetscErrorCode  PetscDrawSetTitle(PetscDraw draw,const char title[])
218 {
219   PetscErrorCode ierr;
220 
221   PetscFunctionBegin;
222   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
223   PetscValidCharPointer(title,2);
224   ierr = PetscFree(draw->title);CHKERRQ(ierr);
225   ierr = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
226   if (draw->ops->settitle) {
227     ierr = (*draw->ops->settitle)(draw,draw->title);CHKERRQ(ierr);
228   }
229   PetscFunctionReturn(0);
230 }
231 
232 #undef __FUNCT__
233 #define __FUNCT__ "PetscDrawAppendTitle"
234 /*@C
235    PetscDrawAppendTitle - Appends to the title of a PetscDraw context.
236 
237    Collective on PetscDraw
238 
239    Input Parameters:
240 +  draw - the graphics context
241 -  title - the title
242 
243    Note:
244    A copy of the string is made, so you may destroy the
245    title string after calling this routine.
246 
247    Level: advanced
248 
249 .seealso: PetscDrawSetTitle(), PetscDrawGetTitle()
250 @*/
251 PetscErrorCode  PetscDrawAppendTitle(PetscDraw draw,const char title[])
252 {
253   PetscErrorCode ierr;
254 
255   PetscFunctionBegin;
256   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
257   if (title) PetscValidCharPointer(title,2);
258   if (!title || !title[0]) PetscFunctionReturn(0);
259 
260   if (draw->title) {
261     size_t len1,len2;
262     char   *newtitle;
263     ierr = PetscStrlen(title,&len1);CHKERRQ(ierr);
264     ierr = PetscStrlen(draw->title,&len2);CHKERRQ(ierr);
265     ierr = PetscMalloc1(len1 + len2 + 1,&newtitle);CHKERRQ(ierr);
266     ierr = PetscStrcpy(newtitle,draw->title);CHKERRQ(ierr);
267     ierr = PetscStrcat(newtitle,title);CHKERRQ(ierr);
268     ierr = PetscFree(draw->title);CHKERRQ(ierr);
269     draw->title = newtitle;
270   } else {
271     ierr = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
272   }
273   if (draw->ops->settitle) {
274     ierr = (*draw->ops->settitle)(draw,draw->title);CHKERRQ(ierr);
275   }
276   PetscFunctionReturn(0);
277 }
278 
279 PETSC_EXTERN PetscErrorCode PetscDrawMovieSave(const char[],PetscInt,const char[],const char[]);
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "PetscDrawDestroy_Private"
283 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
284 {
285   PetscMPIInt    rank;
286   PetscErrorCode ierr;
287 
288   PetscFunctionBegin;
289   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
290   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
291   if (draw->savefilename && draw->savemovieext) {
292     if (!rank) {
293       const char *fname = draw->savefilename;
294       const char *imext = draw->saveimageext;
295       const char *mvext = draw->savemovieext;
296       ierr = PetscDrawMovieSave(fname,draw->savefilecount,imext,mvext);CHKERRQ(ierr);
297     }
298     ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
299   }
300   if (draw->savefinalfilename) {
301     draw->savesinglefile = PETSC_TRUE;
302     ierr = PetscDrawSetSave(draw,draw->savefinalfilename,NULL);CHKERRQ(ierr);
303     ierr = PetscDrawSave(draw);CHKERRQ(ierr);
304   }
305   ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
306   PetscFunctionReturn(0);
307 }
308 
309 #undef __FUNCT__
310 #define __FUNCT__ "PetscDrawDestroy"
311 /*@
312    PetscDrawDestroy - Deletes a draw context.
313 
314    Collective on PetscDraw
315 
316    Input Parameters:
317 .  draw - the drawing context
318 
319    Level: beginner
320 
321 .seealso: PetscDrawCreate()
322 
323 @*/
324 PetscErrorCode  PetscDrawDestroy(PetscDraw *draw)
325 {
326   PetscErrorCode ierr;
327 
328   PetscFunctionBegin;
329   if (!*draw) PetscFunctionReturn(0);
330   PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1);
331   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0);
332 
333   if ((*draw)->pause == -2) {
334     (*draw)->pause = -1;
335     ierr = PetscDrawPause(*draw);CHKERRQ(ierr);
336   }
337 
338   /* if memory was published then destroy it */
339   ierr = PetscObjectSAWsViewOff((PetscObject)*draw);CHKERRQ(ierr);
340 
341   ierr = PetscDrawDestroy_Private(*draw);CHKERRQ(ierr);
342 
343   if ((*draw)->ops->destroy) {
344     ierr = (*(*draw)->ops->destroy)(*draw);CHKERRQ(ierr);
345   }
346   ierr = PetscDrawDestroy(&(*draw)->popup);CHKERRQ(ierr);
347   ierr = PetscFree((*draw)->title);CHKERRQ(ierr);
348   ierr = PetscFree((*draw)->display);CHKERRQ(ierr);
349   ierr = PetscFree((*draw)->savefilename);CHKERRQ(ierr);
350   ierr = PetscFree((*draw)->saveimageext);CHKERRQ(ierr);
351   ierr = PetscFree((*draw)->savemovieext);CHKERRQ(ierr);
352   ierr = PetscFree((*draw)->savefinalfilename);CHKERRQ(ierr);
353   ierr = PetscHeaderDestroy(draw);CHKERRQ(ierr);
354   PetscFunctionReturn(0);
355 }
356 
357 #undef __FUNCT__
358 #define __FUNCT__ "PetscDrawGetPopup"
359 /*@
360    PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window.
361 
362    Collective on PetscDraw
363 
364    Input Parameter:
365 .  draw - the original window
366 
367    Output Parameter:
368 .  popup - the new popup window
369 
370    Level: advanced
371 
372 @*/
373 PetscErrorCode  PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup)
374 {
375   PetscErrorCode ierr;
376 
377   PetscFunctionBegin;
378   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
379   PetscValidPointer(popup,2);
380 
381   if (draw->popup) *popup = draw->popup;
382   else if (draw->ops->getpopup) {
383     ierr = (*draw->ops->getpopup)(draw,popup);CHKERRQ(ierr);
384     if (*popup) {
385       ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
386       (*popup)->pause = 0.0;
387       ierr = PetscDrawSetFromOptions(*popup);CHKERRQ(ierr);
388     }
389   } else *popup = NULL;
390   PetscFunctionReturn(0);
391 }
392 
393 #undef __FUNCT__
394 #define __FUNCT__ "PetscDrawDestroy_Null"
395 static PetscErrorCode PetscDrawDestroy_Null(PetscDraw draw)
396 {
397   PetscFunctionBegin;
398   PetscFunctionReturn(0);
399 }
400 
401 #undef __FUNCT__
402 #define __FUNCT__ "PetscDrawOpenNull"
403 /*
404   PetscDrawOpenNull - Opens a null drawing context. All draw commands to
405   it are ignored.
406 
407   Output Parameter:
408 . win - the drawing context
409 
410    Level: advanced
411 
412 */
413 PetscErrorCode  PetscDrawOpenNull(MPI_Comm comm,PetscDraw *win)
414 {
415   PetscErrorCode ierr;
416 
417   PetscFunctionBegin;
418   ierr = PetscDrawCreate(comm,NULL,NULL,0,0,1,1,win);CHKERRQ(ierr);
419   ierr = PetscDrawSetType(*win,PETSC_DRAW_NULL);CHKERRQ(ierr);
420   PetscFunctionReturn(0);
421 }
422 
423 #undef __FUNCT__
424 #define __FUNCT__ "PetscDrawSetDisplay"
425 /*@
426   PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed
427 
428   Input Parameter:
429 + draw - the drawing context
430 - display - the X windows display
431 
432   Level: advanced
433 
434 @*/
435 PetscErrorCode  PetscDrawSetDisplay(PetscDraw draw,const char display[])
436 {
437   PetscErrorCode ierr;
438 
439   PetscFunctionBegin;
440   ierr = PetscFree(draw->display);CHKERRQ(ierr);
441   ierr = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
442   PetscFunctionReturn(0);
443 }
444 
445 #undef __FUNCT__
446 #define __FUNCT__ "PetscDrawCreate_Null"
447 /*
448   PetscDrawCreate_Null - Opens a null drawing context. All draw commands to
449   it are ignored.
450 
451   Input Parameter:
452 . win - the drawing context
453 */
454 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Null(PetscDraw draw)
455 {
456   PetscErrorCode ierr;
457 
458   PetscFunctionBegin;
459   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
460   draw->data         = NULL;
461   draw->ops->destroy = PetscDrawDestroy_Null;
462   draw->ops->view    = NULL;
463 
464   draw->pause        = 0.0;
465   draw->coor_xl      = 0.0;  draw->coor_xr = 1.0;
466   draw->coor_yl      = 0.0;  draw->coor_yr = 1.0;
467   draw->port_xl      = 0.0;  draw->port_xr = 1.0;
468   draw->port_yl      = 0.0;  draw->port_yr = 1.0;
469   draw->popup        = NULL;
470   PetscFunctionReturn(0);
471 }
472 
473 #undef __FUNCT__
474 #define __FUNCT__ "PetscDrawGetSingleton"
475 /*@C
476    PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned
477         by the one process.
478 
479    Collective on PetscDraw
480 
481    Input Parameter:
482 .  draw - the original window
483 
484    Output Parameter:
485 .  sdraw - the singleton window
486 
487    Level: advanced
488 
489 .seealso: PetscDrawRestoreSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
490 
491 @*/
492 PetscErrorCode  PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw)
493 {
494   PetscErrorCode ierr;
495   PetscMPIInt    size;
496 
497   PetscFunctionBegin;
498   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
499   PetscValidPointer(sdraw,2);
500 
501   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
502   if (size == 1) {
503     ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
504     *sdraw = draw;
505   } else {
506     if (draw->ops->getsingleton) {
507       ierr = (*draw->ops->getsingleton)(draw,sdraw);CHKERRQ(ierr);
508     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name);
509   }
510   PetscFunctionReturn(0);
511 }
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "PetscDrawRestoreSingleton"
515 /*@C
516    PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned
517         by the one process.
518 
519    Collective on PetscDraw
520 
521    Input Parameters:
522 +  draw - the original window
523 -  sdraw - the singleton window
524 
525    Level: advanced
526 
527 .seealso: PetscDrawGetSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
528 
529 @*/
530 PetscErrorCode  PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw)
531 {
532   PetscErrorCode ierr;
533   PetscMPIInt    size;
534 
535   PetscFunctionBegin;
536   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
537   PetscValidPointer(sdraw,2);
538   PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2);
539 
540   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
541   if (size == 1) {
542     if (draw == *sdraw) {
543       ierr = PetscObjectDereference((PetscObject)draw);CHKERRQ(ierr);
544       *sdraw = NULL;
545     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw");
546   } else {
547     if (draw->ops->restoresingleton) {
548       ierr = (*draw->ops->restoresingleton)(draw,sdraw);CHKERRQ(ierr);
549     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name);
550   }
551   PetscFunctionReturn(0);
552 }
553