xref: /petsc/src/sys/classes/draw/interface/draw.c (revision 73ecf448920118c3addf6065a815eb40e5fb84d2)
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 #undef __FUNCT__
280 #define __FUNCT__ "PetscDrawDestroy_Private"
281 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
282 {
283   PetscBool      match;
284   PetscErrorCode ierr;
285 
286   PetscFunctionBegin;
287   ierr = PetscObjectTypeCompare((PetscObject)draw,PETSC_DRAW_X,&match);CHKERRQ(ierr);
288   if (!match) PetscFunctionReturn(0);
289 #if defined(PETSC_HAVE_POPEN)
290   if (draw->savefilemovie && draw->savefilename && !draw->savesinglefile) {
291     PetscMPIInt rank;
292     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
293     if (!rank) {
294       char       command[PETSC_MAX_PATH_LEN];
295       const char *name = draw->savefilename;
296       const char *ext   = draw->savefilenameext;
297       FILE       *fd;
298       ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"ffmpeg -i %s/%s_%%d%s %s.m4v",name,name,ext,name);CHKERRQ(ierr);
299       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
300       ierr = PetscPClose(PETSC_COMM_SELF,fd,NULL);CHKERRQ(ierr);
301     }
302     ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
303   }
304 #endif
305   if (draw->savefinalfilename) {
306     draw->savesinglefile = PETSC_TRUE;
307     ierr = PetscDrawSetSave(draw,draw->savefinalfilename,PETSC_FALSE);CHKERRQ(ierr);
308     draw->savefilecount = 0;
309     ierr = PetscDrawSave(draw);CHKERRQ(ierr);
310   }
311   ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
312   PetscFunctionReturn(0);
313 }
314 
315 #undef __FUNCT__
316 #define __FUNCT__ "PetscDrawDestroy"
317 /*@
318    PetscDrawDestroy - Deletes a draw context.
319 
320    Collective on PetscDraw
321 
322    Input Parameters:
323 .  draw - the drawing context
324 
325    Level: beginner
326 
327 .seealso: PetscDrawCreate()
328 
329 @*/
330 PetscErrorCode  PetscDrawDestroy(PetscDraw *draw)
331 {
332   PetscErrorCode ierr;
333 
334   PetscFunctionBegin;
335   if (!*draw) PetscFunctionReturn(0);
336   PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1);
337   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0);
338 
339   if ((*draw)->pause == -2) {
340     (*draw)->pause = -1;
341     ierr = PetscDrawPause(*draw);CHKERRQ(ierr);
342   }
343 
344   /* if memory was published then destroy it */
345   ierr = PetscObjectSAWsViewOff((PetscObject)*draw);CHKERRQ(ierr);
346 
347   ierr = PetscDrawDestroy_Private(*draw);CHKERRQ(ierr);
348 
349   if ((*draw)->ops->destroy) {
350     ierr = (*(*draw)->ops->destroy)(*draw);CHKERRQ(ierr);
351   }
352   ierr = PetscDrawDestroy(&(*draw)->popup);CHKERRQ(ierr);
353   ierr = PetscFree((*draw)->title);CHKERRQ(ierr);
354   ierr = PetscFree((*draw)->display);CHKERRQ(ierr);
355   ierr = PetscFree((*draw)->savefilename);CHKERRQ(ierr);
356   ierr = PetscFree((*draw)->savefilenameext);CHKERRQ(ierr);
357   ierr = PetscFree((*draw)->savefinalfilename);CHKERRQ(ierr);
358   ierr = PetscHeaderDestroy(draw);CHKERRQ(ierr);
359   PetscFunctionReturn(0);
360 }
361 
362 #undef __FUNCT__
363 #define __FUNCT__ "PetscDrawGetPopup"
364 /*@
365    PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window.
366 
367    Collective on PetscDraw
368 
369    Input Parameter:
370 .  draw - the original window
371 
372    Output Parameter:
373 .  popup - the new popup window
374 
375    Level: advanced
376 
377 @*/
378 PetscErrorCode  PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup)
379 {
380   PetscErrorCode ierr;
381 
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
384   PetscValidPointer(popup,2);
385 
386   if (draw->popup) *popup = draw->popup;
387   else if (draw->ops->getpopup) {
388     ierr = (*draw->ops->getpopup)(draw,popup);CHKERRQ(ierr);
389     if (*popup) {
390       ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
391       (*popup)->pause = 0.0;
392       ierr = PetscDrawSetFromOptions(*popup);CHKERRQ(ierr);
393     }
394   } else *popup = NULL;
395   PetscFunctionReturn(0);
396 }
397 
398 #undef __FUNCT__
399 #define __FUNCT__ "PetscDrawDestroy_Null"
400 static PetscErrorCode PetscDrawDestroy_Null(PetscDraw draw)
401 {
402   PetscFunctionBegin;
403   PetscFunctionReturn(0);
404 }
405 
406 #undef __FUNCT__
407 #define __FUNCT__ "PetscDrawOpenNull"
408 /*
409   PetscDrawOpenNull - Opens a null drawing context. All draw commands to
410   it are ignored.
411 
412   Output Parameter:
413 . win - the drawing context
414 
415    Level: advanced
416 
417 */
418 PetscErrorCode  PetscDrawOpenNull(MPI_Comm comm,PetscDraw *win)
419 {
420   PetscErrorCode ierr;
421 
422   PetscFunctionBegin;
423   ierr = PetscDrawCreate(comm,NULL,NULL,0,0,1,1,win);CHKERRQ(ierr);
424   ierr = PetscDrawSetType(*win,PETSC_DRAW_NULL);CHKERRQ(ierr);
425   PetscFunctionReturn(0);
426 }
427 
428 #undef __FUNCT__
429 #define __FUNCT__ "PetscDrawSetDisplay"
430 /*@
431   PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed
432 
433   Input Parameter:
434 + draw - the drawing context
435 - display - the X windows display
436 
437   Level: advanced
438 
439 @*/
440 PetscErrorCode  PetscDrawSetDisplay(PetscDraw draw,const char display[])
441 {
442   PetscErrorCode ierr;
443 
444   PetscFunctionBegin;
445   ierr = PetscFree(draw->display);CHKERRQ(ierr);
446   ierr = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
447   PetscFunctionReturn(0);
448 }
449 
450 #undef __FUNCT__
451 #define __FUNCT__ "PetscDrawCreate_Null"
452 /*
453   PetscDrawCreate_Null - Opens a null drawing context. All draw commands to
454   it are ignored.
455 
456   Input Parameter:
457 . win - the drawing context
458 */
459 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Null(PetscDraw draw)
460 {
461   PetscErrorCode ierr;
462 
463   PetscFunctionBegin;
464   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
465   draw->data         = NULL;
466   draw->ops->destroy = PetscDrawDestroy_Null;
467   draw->ops->view    = NULL;
468 
469   draw->pause        = 0.0;
470   draw->coor_xl      = 0.0;  draw->coor_xr = 1.0;
471   draw->coor_yl      = 0.0;  draw->coor_yr = 1.0;
472   draw->port_xl      = 0.0;  draw->port_xr = 1.0;
473   draw->port_yl      = 0.0;  draw->port_yr = 1.0;
474   draw->popup        = NULL;
475   PetscFunctionReturn(0);
476 }
477 
478 #undef __FUNCT__
479 #define __FUNCT__ "PetscDrawGetSingleton"
480 /*@C
481    PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned
482         by the one process.
483 
484    Collective on PetscDraw
485 
486    Input Parameter:
487 .  draw - the original window
488 
489    Output Parameter:
490 .  sdraw - the singleton window
491 
492    Level: advanced
493 
494 .seealso: PetscDrawRestoreSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
495 
496 @*/
497 PetscErrorCode  PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw)
498 {
499   PetscErrorCode ierr;
500   PetscMPIInt    size;
501 
502   PetscFunctionBegin;
503   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
504   PetscValidPointer(sdraw,2);
505 
506   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
507   if (size == 1) {
508     ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
509     *sdraw = draw;
510   } else {
511     if (draw->ops->getsingleton) {
512       ierr = (*draw->ops->getsingleton)(draw,sdraw);CHKERRQ(ierr);
513     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name);
514   }
515   PetscFunctionReturn(0);
516 }
517 
518 #undef __FUNCT__
519 #define __FUNCT__ "PetscDrawRestoreSingleton"
520 /*@C
521    PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned
522         by the one process.
523 
524    Collective on PetscDraw
525 
526    Input Parameters:
527 +  draw - the original window
528 -  sdraw - the singleton window
529 
530    Level: advanced
531 
532 .seealso: PetscDrawGetSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
533 
534 @*/
535 PetscErrorCode  PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw)
536 {
537   PetscErrorCode ierr;
538   PetscMPIInt    size;
539 
540   PetscFunctionBegin;
541   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
542   PetscValidPointer(sdraw,2);
543   PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2);
544 
545   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
546   if (size == 1) {
547     if (draw == *sdraw) {
548       ierr = PetscObjectDereference((PetscObject)draw);CHKERRQ(ierr);
549       *sdraw = NULL;
550     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw");
551   } else {
552     if (draw->ops->restoresingleton) {
553       ierr = (*draw->ops->restoresingleton)(draw,sdraw);CHKERRQ(ierr);
554     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name);
555   }
556   PetscFunctionReturn(0);
557 }
558