xref: /petsc/src/sys/classes/draw/interface/draw.c (revision e611a964e9853b74d61a56642fe9d06a6e51780f)
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("Draw 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 Graph",&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   PetscErrorCode ierr;
284 
285   PetscFunctionBegin;
286   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
287   ierr = PetscDrawSaveMovie(draw);CHKERRQ(ierr);
288   if (draw->savefinalfilename) {
289     draw->savesinglefile = PETSC_TRUE;
290     ierr = PetscDrawSetSave(draw,draw->savefinalfilename);CHKERRQ(ierr);
291     ierr = PetscDrawSave(draw);CHKERRQ(ierr);
292   }
293   ierr = PetscBarrier((PetscObject)draw);CHKERRQ(ierr);
294   PetscFunctionReturn(0);
295 }
296 
297 #undef __FUNCT__
298 #define __FUNCT__ "PetscDrawDestroy"
299 /*@
300    PetscDrawDestroy - Deletes a draw context.
301 
302    Collective on PetscDraw
303 
304    Input Parameters:
305 .  draw - the drawing context
306 
307    Level: beginner
308 
309 .seealso: PetscDrawCreate()
310 
311 @*/
312 PetscErrorCode  PetscDrawDestroy(PetscDraw *draw)
313 {
314   PetscErrorCode ierr;
315 
316   PetscFunctionBegin;
317   if (!*draw) PetscFunctionReturn(0);
318   PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1);
319   if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0);
320 
321   if ((*draw)->pause == -2) {
322     (*draw)->pause = -1;
323     ierr = PetscDrawPause(*draw);CHKERRQ(ierr);
324   }
325 
326   /* if memory was published then destroy it */
327   ierr = PetscObjectSAWsViewOff((PetscObject)*draw);CHKERRQ(ierr);
328 
329   ierr = PetscDrawDestroy_Private(*draw);CHKERRQ(ierr);
330 
331   if ((*draw)->ops->destroy) {
332     ierr = (*(*draw)->ops->destroy)(*draw);CHKERRQ(ierr);
333   }
334   ierr = PetscDrawDestroy(&(*draw)->popup);CHKERRQ(ierr);
335   ierr = PetscFree((*draw)->title);CHKERRQ(ierr);
336   ierr = PetscFree((*draw)->display);CHKERRQ(ierr);
337   ierr = PetscFree((*draw)->savefilename);CHKERRQ(ierr);
338   ierr = PetscFree((*draw)->saveimageext);CHKERRQ(ierr);
339   ierr = PetscFree((*draw)->savemovieext);CHKERRQ(ierr);
340   ierr = PetscFree((*draw)->savefinalfilename);CHKERRQ(ierr);
341   ierr = PetscHeaderDestroy(draw);CHKERRQ(ierr);
342   PetscFunctionReturn(0);
343 }
344 
345 #undef __FUNCT__
346 #define __FUNCT__ "PetscDrawGetPopup"
347 /*@
348    PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window.
349 
350    Collective on PetscDraw
351 
352    Input Parameter:
353 .  draw - the original window
354 
355    Output Parameter:
356 .  popup - the new popup window
357 
358    Level: advanced
359 
360 @*/
361 PetscErrorCode  PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup)
362 {
363   PetscErrorCode ierr;
364 
365   PetscFunctionBegin;
366   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
367   PetscValidPointer(popup,2);
368 
369   if (draw->popup) *popup = draw->popup;
370   else if (draw->ops->getpopup) {
371     ierr = (*draw->ops->getpopup)(draw,popup);CHKERRQ(ierr);
372     if (*popup) {
373       ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
374       (*popup)->pause = 0.0;
375       ierr = PetscDrawSetFromOptions(*popup);CHKERRQ(ierr);
376     }
377   } else *popup = NULL;
378   PetscFunctionReturn(0);
379 }
380 
381 #undef __FUNCT__
382 #define __FUNCT__ "PetscDrawSetDisplay"
383 /*@
384   PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed
385 
386   Input Parameter:
387 + draw - the drawing context
388 - display - the X windows display
389 
390   Level: advanced
391 
392 @*/
393 PetscErrorCode  PetscDrawSetDisplay(PetscDraw draw,const char display[])
394 {
395   PetscErrorCode ierr;
396 
397   PetscFunctionBegin;
398   ierr = PetscFree(draw->display);CHKERRQ(ierr);
399   ierr = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
400   PetscFunctionReturn(0);
401 }
402 
403 
404 #undef __FUNCT__
405 #define __FUNCT__ "PetscDrawSetDoubleBuffer"
406 /*@
407    PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
408 
409    Logically Collective on PetscDraw
410 
411    Input Parameter:
412 .  draw - the drawing context
413 
414    Level: intermediate
415 
416    Concepts: drawing^double buffer
417    Concepts: graphics^double buffer
418    Concepts: double buffer
419 
420 @*/
421 PetscErrorCode  PetscDrawSetDoubleBuffer(PetscDraw draw)
422 {
423   PetscErrorCode ierr;
424 
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
427   if (draw->ops->setdoublebuffer) {
428     ierr = (*draw->ops->setdoublebuffer)(draw);CHKERRQ(ierr);
429   }
430   PetscFunctionReturn(0);
431 }
432 
433 #undef __FUNCT__
434 #define __FUNCT__ "PetscDrawGetSingleton"
435 /*@C
436    PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned
437         by the one process.
438 
439    Collective on PetscDraw
440 
441    Input Parameter:
442 .  draw - the original window
443 
444    Output Parameter:
445 .  sdraw - the singleton window
446 
447    Level: advanced
448 
449 .seealso: PetscDrawRestoreSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
450 
451 @*/
452 PetscErrorCode  PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw)
453 {
454   PetscErrorCode ierr;
455   PetscMPIInt    size;
456 
457   PetscFunctionBegin;
458   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
459   PetscValidPointer(sdraw,2);
460 
461   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
462   if (size == 1) {
463     ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
464     *sdraw = draw;
465   } else {
466     if (draw->ops->getsingleton) {
467       ierr = (*draw->ops->getsingleton)(draw,sdraw);CHKERRQ(ierr);
468     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name);
469   }
470   PetscFunctionReturn(0);
471 }
472 
473 #undef __FUNCT__
474 #define __FUNCT__ "PetscDrawRestoreSingleton"
475 /*@C
476    PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned
477         by the one process.
478 
479    Collective on PetscDraw
480 
481    Input Parameters:
482 +  draw - the original window
483 -  sdraw - the singleton window
484 
485    Level: advanced
486 
487 .seealso: PetscDrawGetSingleton(), PetscViewerGetSingleton(), PetscViewerRestoreSingleton()
488 
489 @*/
490 PetscErrorCode  PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw)
491 {
492   PetscErrorCode ierr;
493   PetscMPIInt    size;
494 
495   PetscFunctionBegin;
496   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
497   PetscValidPointer(sdraw,2);
498   PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2);
499 
500   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
501   if (size == 1) {
502     if (draw == *sdraw) {
503       ierr = PetscObjectDereference((PetscObject)draw);CHKERRQ(ierr);
504       *sdraw = NULL;
505     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw");
506   } else {
507     if (draw->ops->restoresingleton) {
508       ierr = (*draw->ops->restoresingleton)(draw,sdraw);CHKERRQ(ierr);
509     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name);
510   }
511   PetscFunctionReturn(0);
512 }
513