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