xref: /petsc/src/sys/classes/draw/interface/draw.c (revision e5ab1681210b093c2ee26b200f61e98eac43a430)
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   if (draw->ops->resizewindow) {
105     ierr = (*draw->ops->resizewindow)(draw,w,h);CHKERRQ(ierr);
106   }
107   PetscFunctionReturn(0);
108 }
109 
110 #undef __FUNCT__
111 #define __FUNCT__ "PetscDrawCheckResizedWindow"
112 /*@
113    PetscDrawCheckResizedWindow - Checks if the user has resized the window.
114 
115    Collective on PetscDraw
116 
117    Input Parameter:
118 .  draw - the window
119 
120    Level: advanced
121 
122 .seealso: PetscDrawResizeWindow()
123 
124 @*/
125 PetscErrorCode  PetscDrawCheckResizedWindow(PetscDraw draw)
126 {
127   PetscErrorCode ierr;
128 
129   PetscFunctionBegin;
130   if (draw->ops->checkresizedwindow) {
131     ierr = (*draw->ops->checkresizedwindow)(draw);CHKERRQ(ierr);
132   }
133   PetscFunctionReturn(0);
134 }
135 
136 #undef __FUNCT__
137 #define __FUNCT__ "PetscDrawGetTitle"
138 /*@C
139    PetscDrawGetTitle - Gets pointer to title of a PetscDraw context.
140 
141    Not collective
142 
143    Input Parameter:
144 .  draw - the graphics context
145 
146    Output Parameter:
147 .  title - the title
148 
149    Level: intermediate
150 
151 .seealso: PetscDrawSetTitle()
152 @*/
153 PetscErrorCode  PetscDrawGetTitle(PetscDraw draw,char **title)
154 {
155   PetscFunctionBegin;
156   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
157   PetscValidPointer(title,2);
158   *title = draw->title;
159   PetscFunctionReturn(0);
160 }
161 
162 #undef __FUNCT__
163 #define __FUNCT__ "PetscDrawSetTitle"
164 /*@C
165    PetscDrawSetTitle - Sets the title of a PetscDraw context.
166 
167    Collective on PetscDraw
168 
169    Input Parameters:
170 +  draw - the graphics context
171 -  title - the title
172 
173    Level: intermediate
174 
175    Note: The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
176    in the image.
177 
178    A copy of the string is made, so you may destroy the
179    title string after calling this routine.
180 
181    You can use PetscDrawAxisSetLabels() to indicate a title within the window
182 
183 .seealso: PetscDrawGetTitle(), PetscDrawAppendTitle()
184 @*/
185 PetscErrorCode  PetscDrawSetTitle(PetscDraw draw,const char title[])
186 {
187   PetscErrorCode ierr;
188 
189   PetscFunctionBegin;
190   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
191   PetscValidCharPointer(title,2);
192   ierr = PetscFree(draw->title);CHKERRQ(ierr);
193   ierr = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
194   if (draw->ops->settitle) {
195     ierr = (*draw->ops->settitle)(draw,draw->title);CHKERRQ(ierr);
196   }
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "PetscDrawAppendTitle"
202 /*@C
203    PetscDrawAppendTitle - Appends to the title of a PetscDraw context.
204 
205    Collective on PetscDraw
206 
207    Input Parameters:
208 +  draw - the graphics context
209 -  title - the title
210 
211    Note:
212    A copy of the string is made, so you may destroy the
213    title string after calling this routine.
214 
215    Level: advanced
216 
217 .seealso: PetscDrawSetTitle(), PetscDrawGetTitle()
218 @*/
219 PetscErrorCode  PetscDrawAppendTitle(PetscDraw draw,const char title[])
220 {
221   PetscErrorCode ierr;
222 
223   PetscFunctionBegin;
224   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
225   if (title) PetscValidCharPointer(title,2);
226   if (!title || !title[0]) PetscFunctionReturn(0);
227 
228   if (draw->title) {
229     size_t len1,len2;
230     char   *newtitle;
231     ierr = PetscStrlen(title,&len1);CHKERRQ(ierr);
232     ierr = PetscStrlen(draw->title,&len2);CHKERRQ(ierr);
233     ierr = PetscMalloc1(len1 + len2 + 1,&newtitle);CHKERRQ(ierr);
234     ierr = PetscStrcpy(newtitle,draw->title);CHKERRQ(ierr);
235     ierr = PetscStrcat(newtitle,title);CHKERRQ(ierr);
236     ierr = PetscFree(draw->title);CHKERRQ(ierr);
237     draw->title = newtitle;
238   } else {
239     ierr = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
240   }
241   if (draw->ops->settitle) {
242     ierr = (*draw->ops->settitle)(draw,draw->title);CHKERRQ(ierr);
243   }
244   PetscFunctionReturn(0);
245 }
246 
247 #undef __FUNCT__
248 #define __FUNCT__ "PetscDrawDestroy_Private"
249 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
250 {
251   PetscBool      match;
252   PetscErrorCode ierr;
253 
254   PetscFunctionBegin;
255   ierr = PetscObjectTypeCompare((PetscObject)draw,PETSC_DRAW_X,&match);CHKERRQ(ierr);
256   if (!match) PetscFunctionReturn(0);
257 #if defined(PETSC_HAVE_POPEN)
258   if (draw->savefilemovie && draw->savefilename && !draw->savesinglefile) {
259     PetscMPIInt rank;
260     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
261     if (!rank) {
262       char       command[PETSC_MAX_PATH_LEN];
263       const char *name = draw->savefilename;
264       const char *ext   = draw->savefilenameext;
265       FILE       *fd;
266       ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"ffmpeg -i %s/%s_%%d%s %s.m4v",name,name,ext,name);CHKERRQ(ierr);
267       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
268       ierr = PetscPClose(PETSC_COMM_SELF,fd,NULL);CHKERRQ(ierr);
269     }
270     ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
271   }
272 #endif
273   if (draw->savefinalfilename) {
274     draw->savesinglefile = PETSC_TRUE;
275     ierr = PetscDrawSetSave(draw,draw->savefinalfilename,PETSC_FALSE);CHKERRQ(ierr);
276     draw->savefilecount = 0;
277     ierr = PetscDrawSave(draw);CHKERRQ(ierr);
278   }
279   ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
280   PetscFunctionReturn(0);
281 }
282 
283 #undef __FUNCT__
284 #define __FUNCT__ "PetscDrawDestroy"
285 /*@
286    PetscDrawDestroy - Deletes a draw context.
287 
288    Collective on PetscDraw
289 
290    Input Parameters:
291 .  draw - the drawing context
292 
293    Level: beginner
294 
295 .seealso: PetscDrawCreate()
296 
297 @*/
298 PetscErrorCode  PetscDrawDestroy(PetscDraw *draw)
299 {
300   PetscErrorCode ierr;
301 
302   PetscFunctionBegin;
303   if (!*draw) PetscFunctionReturn(0);
304   PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1);
305   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0);
306 
307   if ((*draw)->pause == -2) {
308     (*draw)->pause = -1;
309     ierr = PetscDrawPause(*draw);CHKERRQ(ierr);
310   }
311 
312   /* if memory was published then destroy it */
313   ierr = PetscObjectSAWsViewOff((PetscObject)*draw);CHKERRQ(ierr);
314 
315   ierr = PetscDrawDestroy_Private(*draw);CHKERRQ(ierr);
316 
317   if ((*draw)->ops->destroy) {
318     ierr = (*(*draw)->ops->destroy)(*draw);CHKERRQ(ierr);
319   }
320   ierr = PetscDrawDestroy(&(*draw)->popup);CHKERRQ(ierr);
321   ierr = PetscFree((*draw)->title);CHKERRQ(ierr);
322   ierr = PetscFree((*draw)->display);CHKERRQ(ierr);
323   ierr = PetscFree((*draw)->savefilename);CHKERRQ(ierr);
324   ierr = PetscFree((*draw)->savefilenameext);CHKERRQ(ierr);
325   ierr = PetscFree((*draw)->savefinalfilename);CHKERRQ(ierr);
326   ierr = PetscHeaderDestroy(draw);CHKERRQ(ierr);
327   PetscFunctionReturn(0);
328 }
329 
330 #undef __FUNCT__
331 #define __FUNCT__ "PetscDrawGetPopup"
332 /*@
333    PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window.
334 
335    Collective on PetscDraw
336 
337    Input Parameter:
338 .  draw - the original window
339 
340    Output Parameter:
341 .  popup - the new popup window
342 
343    Level: advanced
344 
345 @*/
346 PetscErrorCode  PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup)
347 {
348   PetscErrorCode ierr;
349 
350   PetscFunctionBegin;
351   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
352   PetscValidPointer(popup,2);
353 
354   if (draw->popup) *popup = draw->popup;
355   else if (draw->ops->getpopup) {
356     ierr = (*draw->ops->getpopup)(draw,popup);CHKERRQ(ierr);
357     if (*popup) {
358       ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
359       (*popup)->pause = 0.0;
360       ierr = PetscDrawSetFromOptions(*popup);CHKERRQ(ierr);
361     }
362   } else *popup = NULL;
363   PetscFunctionReturn(0);
364 }
365 
366 #undef __FUNCT__
367 #define __FUNCT__ "PetscDrawDestroy_Null"
368 static PetscErrorCode PetscDrawDestroy_Null(PetscDraw draw)
369 {
370   PetscFunctionBegin;
371   PetscFunctionReturn(0);
372 }
373 
374 #undef __FUNCT__
375 #define __FUNCT__ "PetscDrawOpenNull"
376 /*
377   PetscDrawOpenNull - Opens a null drawing context. All draw commands to
378   it are ignored.
379 
380   Output Parameter:
381 . win - the drawing context
382 
383    Level: advanced
384 
385 */
386 PetscErrorCode  PetscDrawOpenNull(MPI_Comm comm,PetscDraw *win)
387 {
388   PetscErrorCode ierr;
389 
390   PetscFunctionBegin;
391   ierr = PetscDrawCreate(comm,NULL,NULL,0,0,1,1,win);CHKERRQ(ierr);
392   ierr = PetscDrawSetType(*win,PETSC_DRAW_NULL);CHKERRQ(ierr);
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "PetscDrawSetDisplay"
398 /*@
399   PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed
400 
401   Input Parameter:
402 + draw - the drawing context
403 - display - the X windows display
404 
405   Level: advanced
406 
407 @*/
408 PetscErrorCode  PetscDrawSetDisplay(PetscDraw draw,const char display[])
409 {
410   PetscErrorCode ierr;
411 
412   PetscFunctionBegin;
413   ierr = PetscFree(draw->display);CHKERRQ(ierr);
414   ierr = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
415   PetscFunctionReturn(0);
416 }
417 
418 #undef __FUNCT__
419 #define __FUNCT__ "PetscDrawCreate_Null"
420 /*
421   PetscDrawCreate_Null - Opens a null drawing context. All draw commands to
422   it are ignored.
423 
424   Input Parameter:
425 . win - the drawing context
426 */
427 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Null(PetscDraw draw)
428 {
429   PetscErrorCode ierr;
430 
431   PetscFunctionBegin;
432   ierr = PetscMemzero(draw->ops,sizeof(struct _PetscDrawOps));CHKERRQ(ierr);
433   draw->data         = NULL;
434   draw->ops->destroy = PetscDrawDestroy_Null;
435   draw->ops->view    = NULL;
436 
437   draw->pause        = 0.0;
438   draw->coor_xl      = 0.0;  draw->coor_xr = 1.0;
439   draw->coor_yl      = 0.0;  draw->coor_yr = 1.0;
440   draw->port_xl      = 0.0;  draw->port_xr = 1.0;
441   draw->port_yl      = 0.0;  draw->port_yr = 1.0;
442   draw->popup        = NULL;
443   PetscFunctionReturn(0);
444 }
445 
446 #undef __FUNCT__
447 #define __FUNCT__ "PetscDrawGetSingleton"
448 /*@C
449    PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned
450         by the one process.
451 
452    Collective on PetscDraw
453 
454    Input Parameter:
455 .  draw - the original window
456 
457    Output Parameter:
458 .  sdraw - the singleton window
459 
460    Level: advanced
461 
462 .seealso: PetscDrawRestoreSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
463 
464 @*/
465 PetscErrorCode  PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw)
466 {
467   PetscErrorCode ierr;
468   PetscMPIInt    size;
469 
470   PetscFunctionBegin;
471   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
472   PetscValidPointer(sdraw,2);
473 
474   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
475   if (size == 1) *sdraw = draw;
476   else {
477     if (draw->ops->getsingleton) {
478       ierr = (*draw->ops->getsingleton)(draw,sdraw);CHKERRQ(ierr);
479     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name);
480   }
481   PetscFunctionReturn(0);
482 }
483 
484 #undef __FUNCT__
485 #define __FUNCT__ "PetscDrawRestoreSingleton"
486 /*@C
487    PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned
488         by the one process.
489 
490    Collective on PetscDraw
491 
492    Input Parameters:
493 +  draw - the original window
494 -  sdraw - the singleton window
495 
496    Level: advanced
497 
498 .seealso: PetscDrawGetSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
499 
500 @*/
501 PetscErrorCode  PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw)
502 {
503   PetscErrorCode ierr;
504   PetscMPIInt    size;
505 
506   PetscFunctionBegin;
507   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
508   PetscValidPointer(sdraw,2);
509   PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2);
510 
511   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
512   if (size != 1) {
513     if (draw->ops->restoresingleton) {
514       ierr = (*draw->ops->restoresingleton)(draw,sdraw);CHKERRQ(ierr);
515     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name);
516   }
517   PetscFunctionReturn(0);
518 }
519