Actual source code: draw.c
2: /*
3: Provides the calling sequences for all the basic PetscDraw routines.
4: */
5: #include <petsc/private/drawimpl.h>
6: #include <petscviewer.h>
8: PetscClassId PETSC_DRAW_CLASSID;
10: static PetscBool PetscDrawPackageInitialized = PETSC_FALSE;
11: /*@C
12: PetscDrawFinalizePackage - This function destroys everything in the Petsc interface to the `PetscDraw` package. It is
13: called from `PetscFinalize()`.
15: Level: developer
17: .seealso: `PetscDraw`, `PetscFinalize()`
18: @*/
19: PetscErrorCode PetscDrawFinalizePackage(void)
20: {
21: PetscFunctionBegin;
22: PetscCall(PetscFunctionListDestroy(&PetscDrawList));
23: PetscDrawPackageInitialized = PETSC_FALSE;
24: PetscDrawRegisterAllCalled = PETSC_FALSE;
25: PetscFunctionReturn(PETSC_SUCCESS);
26: }
28: /*@C
29: PetscInitializeDrawPackage - This function initializes everything in the `PetscDraw` package. It is called
30: from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
31: when using shared or static libraries.
33: Level: developer
35: .seealso: `PetscDraw`, `PetscInitialize()`
36: @*/
37: PetscErrorCode PetscDrawInitializePackage(void)
38: {
39: char logList[256];
40: PetscBool opt, pkg;
42: PetscFunctionBegin;
43: if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
44: PetscDrawPackageInitialized = PETSC_TRUE;
45: /* Register Classes */
46: PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID));
47: PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID));
48: PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID));
49: PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID));
50: PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID));
51: PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID));
52: /* Register Constructors */
53: PetscCall(PetscDrawRegisterAll());
54: /* Process Info */
55: {
56: PetscClassId classids[6];
58: classids[0] = PETSC_DRAW_CLASSID;
59: classids[1] = PETSC_DRAWAXIS_CLASSID;
60: classids[2] = PETSC_DRAWLG_CLASSID;
61: classids[3] = PETSC_DRAWHG_CLASSID;
62: classids[4] = PETSC_DRAWBAR_CLASSID;
63: classids[5] = PETSC_DRAWSP_CLASSID;
64: PetscCall(PetscInfoProcessClass("draw", 6, classids));
65: }
66: /* Process summary exclusions */
67: PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
68: if (opt) {
69: PetscCall(PetscStrInList("draw", logList, ',', &pkg));
70: if (pkg) {
71: PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID));
72: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID));
73: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID));
74: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID));
75: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID));
76: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID));
77: }
78: }
79: /* Register package finalizer */
80: PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage));
81: PetscFunctionReturn(PETSC_SUCCESS);
82: }
84: /*@
85: PetscDrawResizeWindow - Allows one to resize a window from a program.
87: Collective
89: Input Parameters:
90: + draw - the window
91: - w,h - the new width and height of the window
93: Level: intermediate
95: .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
96: @*/
97: PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
98: {
99: PetscFunctionBegin;
103: PetscTryTypeMethod(draw, resizewindow, w, h);
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }
107: /*@
108: PetscDrawGetWindowSize - Gets the size of the window.
110: Not collective
112: Input Parameter:
113: . draw - the window
115: Output Parameters:
116: . w,h - the window width and height
118: Level: intermediate
120: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
121: @*/
122: PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
123: {
124: PetscFunctionBegin;
128: if (w) *w = draw->w;
129: if (h) *h = draw->h;
130: PetscFunctionReturn(PETSC_SUCCESS);
131: }
133: /*@
134: PetscDrawCheckResizedWindow - Checks if the user has resized the window.
136: Collective
138: Input Parameter:
139: . draw - the window
141: Level: advanced
143: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
144: @*/
145: PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
146: {
147: PetscFunctionBegin;
149: PetscTryTypeMethod(draw, checkresizedwindow);
150: PetscFunctionReturn(PETSC_SUCCESS);
151: }
153: /*@C
154: PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.
156: Not collective
158: Input Parameter:
159: . draw - the graphics context
161: Output Parameter:
162: . title - the title
164: Level: intermediate
166: .seealso: `PetscDraw`, `PetscDrawSetTitle()`
167: @*/
168: PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
169: {
170: PetscFunctionBegin;
173: *title = draw->title;
174: PetscFunctionReturn(PETSC_SUCCESS);
175: }
177: /*@C
178: PetscDrawSetTitle - Sets the title of a `PetscDraw` context.
180: Collective
182: Input Parameters:
183: + draw - the graphics context
184: - title - the title
186: Level: intermediate
188: Notes:
189: The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
190: in the image.
192: A copy of the string is made, so you may destroy the
193: title string after calling this routine.
195: You can use `PetscDrawAxisSetLabels()` to indicate a title within the window
197: .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
198: @*/
199: PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
200: {
201: PetscFunctionBegin;
204: PetscCall(PetscFree(draw->title));
205: PetscCall(PetscStrallocpy(title, &draw->title));
206: PetscTryTypeMethod(draw, settitle, draw->title);
207: PetscFunctionReturn(PETSC_SUCCESS);
208: }
210: /*@C
211: PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.
213: Collective
215: Input Parameters:
216: + draw - the graphics context
217: - title - the title
219: Note:
220: A copy of the string is made, so you may destroy the
221: title string after calling this routine.
223: Level: advanced
225: .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
226: @*/
227: PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
228: {
229: PetscFunctionBegin;
232: if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS);
234: if (draw->title) {
235: size_t len1, len2;
236: char *newtitle;
237: PetscCall(PetscStrlen(title, &len1));
238: PetscCall(PetscStrlen(draw->title, &len2));
239: PetscCall(PetscMalloc1(len1 + len2 + 1, &newtitle));
240: PetscCall(PetscStrcpy(newtitle, draw->title));
241: PetscCall(PetscStrcat(newtitle, title));
242: PetscCall(PetscFree(draw->title));
243: draw->title = newtitle;
244: } else {
245: PetscCall(PetscStrallocpy(title, &draw->title));
246: }
247: PetscTryTypeMethod(draw, settitle, draw->title);
248: PetscFunctionReturn(PETSC_SUCCESS);
249: }
251: static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
252: {
253: PetscFunctionBegin;
254: if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
255: PetscCall(PetscDrawSaveMovie(draw));
256: if (draw->savefinalfilename) {
257: draw->savesinglefile = PETSC_TRUE;
258: PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
259: PetscCall(PetscDrawSave(draw));
260: }
261: PetscCall(PetscBarrier((PetscObject)draw));
262: PetscFunctionReturn(PETSC_SUCCESS);
263: }
265: /*@
266: PetscDrawDestroy - Deletes a draw context.
268: Collective
270: Input Parameters:
271: . draw - the drawing context
273: Level: beginner
275: .seealso: `PetscDraw`, `PetscDrawCreate()`
276: @*/
277: PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
278: {
279: PetscFunctionBegin;
280: if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
282: if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
284: if ((*draw)->pause == -2) {
285: (*draw)->pause = -1;
286: PetscCall(PetscDrawPause(*draw));
287: }
289: /* if memory was published then destroy it */
290: PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
292: PetscCall(PetscDrawDestroy_Private(*draw));
294: if ((*draw)->ops->destroy) PetscCall((*(*draw)->ops->destroy)(*draw));
295: PetscCall(PetscDrawDestroy(&(*draw)->popup));
296: PetscCall(PetscFree((*draw)->title));
297: PetscCall(PetscFree((*draw)->display));
298: PetscCall(PetscFree((*draw)->savefilename));
299: PetscCall(PetscFree((*draw)->saveimageext));
300: PetscCall(PetscFree((*draw)->savemovieext));
301: PetscCall(PetscFree((*draw)->savefinalfilename));
302: PetscCall(PetscHeaderDestroy(draw));
303: PetscFunctionReturn(PETSC_SUCCESS);
304: }
306: /*@
307: PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.
309: Collective
311: Input Parameter:
312: . draw - the original window
314: Output Parameter:
315: . popup - the new popup window
317: Level: advanced
319: .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
320: @*/
321: PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
322: {
323: PetscFunctionBegin;
327: if (draw->popup) *popup = draw->popup;
328: else if (draw->ops->getpopup) {
329: PetscUseTypeMethod(draw, getpopup, popup);
330: if (*popup) {
331: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
332: (*popup)->pause = 0.0;
333: PetscCall(PetscDrawSetFromOptions(*popup));
334: }
335: } else *popup = NULL;
336: PetscFunctionReturn(PETSC_SUCCESS);
337: }
339: /*@C
340: PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed
342: Input Parameters:
343: + draw - the drawing context
344: - display - the X windows display
346: Level: advanced
348: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
349: @*/
350: PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
351: {
352: PetscFunctionBegin;
353: PetscCall(PetscFree(draw->display));
354: PetscCall(PetscStrallocpy(display, &draw->display));
355: PetscFunctionReturn(PETSC_SUCCESS);
356: }
358: /*@
359: PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
361: Logically Collective
363: Input Parameter:
364: . draw - the drawing context
366: Level: intermediate
368: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
369: @*/
370: PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
371: {
372: PetscFunctionBegin;
374: PetscTryTypeMethod(draw, setdoublebuffer);
375: PetscFunctionReturn(PETSC_SUCCESS);
376: }
378: /*@C
379: PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
380: by the one process.
382: Collective
384: Input Parameter:
385: . draw - the original window
387: Output Parameter:
388: . sdraw - the singleton window
390: Level: advanced
392: .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
393: @*/
394: PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
395: {
396: PetscMPIInt size;
398: PetscFunctionBegin;
402: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
403: if (size == 1) {
404: PetscCall(PetscObjectReference((PetscObject)draw));
405: *sdraw = draw;
406: } else {
407: if (draw->ops->getsingleton) {
408: PetscUseTypeMethod(draw, getsingleton, sdraw);
409: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
410: }
411: PetscFunctionReturn(PETSC_SUCCESS);
412: }
414: /*@C
415: PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
416: by the one process.
418: Collective
420: Input Parameters:
421: + draw - the original window
422: - sdraw - the singleton window
424: Level: advanced
426: .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
427: @*/
428: PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
429: {
430: PetscMPIInt size;
432: PetscFunctionBegin;
437: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
438: if (size == 1) {
439: if (draw == *sdraw) {
440: PetscCall(PetscObjectDereference((PetscObject)draw));
441: *sdraw = NULL;
442: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
443: } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
444: PetscFunctionReturn(PETSC_SUCCESS);
445: }
447: /*@C
448: PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.
450: Input Parameters:
451: + draw - the drawing window
452: - visible - if the surface should be visible
454: Level: intermediate
456: .seealso: `PetscDraw`
457: @*/
458: PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
459: {
460: PetscFunctionBegin;
462: PetscTryTypeMethod(draw, setvisible, visible);
463: PetscFunctionReturn(PETSC_SUCCESS);
464: }