Actual source code: draw.c
1: #include <petsc/private/drawimpl.h>
2: #include <petscviewer.h>
4: PetscClassId PETSC_DRAW_CLASSID;
6: static PetscBool PetscDrawPackageInitialized = PETSC_FALSE;
7: /*@C
8: PetscDrawFinalizePackage - This function destroys everything in the Petsc interface to the `PetscDraw` package. It is
9: called from `PetscFinalize()`.
11: Level: developer
13: .seealso: `PetscDraw`, `PetscFinalize()`
14: @*/
15: PetscErrorCode PetscDrawFinalizePackage(void)
16: {
17: PetscFunctionBegin;
18: PetscCall(PetscFunctionListDestroy(&PetscDrawList));
19: PetscDrawPackageInitialized = PETSC_FALSE;
20: PetscDrawRegisterAllCalled = PETSC_FALSE;
21: PetscFunctionReturn(PETSC_SUCCESS);
22: }
24: /*@C
25: PetscDrawInitializePackage - This function initializes everything in the `PetscDraw` package. It is called
26: from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
27: when using shared or static libraries.
29: Level: developer
31: .seealso: `PetscDraw`, `PetscInitialize()`
32: @*/
33: PetscErrorCode PetscDrawInitializePackage(void)
34: {
35: char logList[256];
36: PetscBool opt, pkg;
38: PetscFunctionBegin;
39: if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
40: PetscDrawPackageInitialized = PETSC_TRUE;
41: /* Register Classes */
42: PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID));
43: PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID));
44: PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID));
45: PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID));
46: PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID));
47: PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID));
48: /* Register Constructors */
49: PetscCall(PetscDrawRegisterAll());
50: /* Process Info */
51: {
52: PetscClassId classids[6];
54: classids[0] = PETSC_DRAW_CLASSID;
55: classids[1] = PETSC_DRAWAXIS_CLASSID;
56: classids[2] = PETSC_DRAWLG_CLASSID;
57: classids[3] = PETSC_DRAWHG_CLASSID;
58: classids[4] = PETSC_DRAWBAR_CLASSID;
59: classids[5] = PETSC_DRAWSP_CLASSID;
60: PetscCall(PetscInfoProcessClass("draw", 6, classids));
61: }
62: /* Process summary exclusions */
63: PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
64: if (opt) {
65: PetscCall(PetscStrInList("draw", logList, ',', &pkg));
66: if (pkg) {
67: PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID));
68: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID));
69: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID));
70: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID));
71: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID));
72: PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID));
73: }
74: }
75: /* Register package finalizer */
76: PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage));
77: PetscFunctionReturn(PETSC_SUCCESS);
78: }
80: /*@
81: PetscDrawResizeWindow - Allows one to resize a window from a program.
83: Collective
85: Input Parameters:
86: + draw - the window
87: . w - the new width of the window
88: - h - the new height of the window
90: Level: intermediate
92: .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
93: @*/
94: PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
95: {
96: PetscFunctionBegin;
100: PetscTryTypeMethod(draw, resizewindow, w, h);
101: PetscFunctionReturn(PETSC_SUCCESS);
102: }
104: /*@
105: PetscDrawGetWindowSize - Gets the size of the window.
107: Not Collective
109: Input Parameter:
110: . draw - the window
112: Output Parameters:
113: + w - the window width
114: - h - the window height
116: Level: intermediate
118: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
119: @*/
120: PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
121: {
122: PetscFunctionBegin;
124: if (w) PetscAssertPointer(w, 2);
125: if (h) PetscAssertPointer(h, 3);
126: if (w) *w = draw->w;
127: if (h) *h = draw->h;
128: PetscFunctionReturn(PETSC_SUCCESS);
129: }
131: /*@
132: PetscDrawCheckResizedWindow - Checks if the user has resized the window.
134: Collective
136: Input Parameter:
137: . draw - the window
139: Level: advanced
141: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
142: @*/
143: PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
144: {
145: PetscFunctionBegin;
147: PetscTryTypeMethod(draw, checkresizedwindow);
148: PetscFunctionReturn(PETSC_SUCCESS);
149: }
151: /*@
152: PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.
154: Not Collective
156: Input Parameter:
157: . draw - the graphics context
159: Output Parameter:
160: . title - the title
162: Level: intermediate
164: .seealso: `PetscDraw`, `PetscDrawSetTitle()`
165: @*/
166: PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
167: {
168: PetscFunctionBegin;
170: PetscAssertPointer(title, 2);
171: *title = draw->title;
172: PetscFunctionReturn(PETSC_SUCCESS);
173: }
175: /*@
176: PetscDrawSetTitle - Sets the title of a `PetscDraw` context.
178: Collective
180: Input Parameters:
181: + draw - the graphics context
182: - title - the title
184: Level: intermediate
186: Notes:
187: The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
188: in the image.
190: A copy of the string is made, so you may destroy the
191: title string after calling this routine.
193: You can use `PetscDrawAxisSetLabels()` to indicate a title within the window
195: .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
196: @*/
197: PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
198: {
199: PetscFunctionBegin;
201: PetscAssertPointer(title, 2);
202: PetscCall(PetscFree(draw->title));
203: PetscCall(PetscStrallocpy(title, &draw->title));
204: PetscTryTypeMethod(draw, settitle, draw->title);
205: PetscFunctionReturn(PETSC_SUCCESS);
206: }
208: /*@
209: PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.
211: Collective
213: Input Parameters:
214: + draw - the graphics context
215: - title - the title
217: Level: advanced
219: Note:
220: A copy of the string is made, so you may destroy the
221: title string after calling this routine.
223: .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
224: @*/
225: PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
226: {
227: PetscFunctionBegin;
229: if (title) PetscAssertPointer(title, 2);
230: if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS);
232: if (draw->title) {
233: size_t len1, len2, new_len;
234: PetscCall(PetscStrlen(draw->title, &len1));
235: PetscCall(PetscStrlen(title, &len2));
236: new_len = len1 + len2 + 1;
237: PetscCall(PetscRealloc(new_len * sizeof(*draw->title), &draw->title));
238: PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1));
239: } else {
240: PetscCall(PetscStrallocpy(title, &draw->title));
241: }
242: PetscTryTypeMethod(draw, settitle, draw->title);
243: PetscFunctionReturn(PETSC_SUCCESS);
244: }
246: static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
247: {
248: PetscFunctionBegin;
249: if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
250: PetscCall(PetscDrawSaveMovie(draw));
251: if (draw->savefinalfilename) {
252: draw->savesinglefile = PETSC_TRUE;
253: PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
254: PetscCall(PetscDrawSave(draw));
255: }
256: PetscCall(PetscBarrier((PetscObject)draw));
257: PetscFunctionReturn(PETSC_SUCCESS);
258: }
260: /*@
261: PetscDrawDestroy - Deletes a draw context.
263: Collective
265: Input Parameter:
266: . draw - the drawing context
268: Level: beginner
270: .seealso: `PetscDraw`, `PetscDrawCreate()`
271: @*/
272: PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
273: {
274: PetscFunctionBegin;
275: if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
277: if (--((PetscObject)*draw)->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
279: if ((*draw)->pause == -2) {
280: (*draw)->pause = -1;
281: PetscCall(PetscDrawPause(*draw));
282: }
284: /* if memory was published then destroy it */
285: PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));
287: PetscCall(PetscDrawDestroy_Private(*draw));
289: PetscTryTypeMethod(*draw, destroy);
290: PetscCall(PetscDrawDestroy(&(*draw)->popup));
291: PetscCall(PetscFree((*draw)->title));
292: PetscCall(PetscFree((*draw)->display));
293: PetscCall(PetscFree((*draw)->savefilename));
294: PetscCall(PetscFree((*draw)->saveimageext));
295: PetscCall(PetscFree((*draw)->savemovieext));
296: PetscCall(PetscFree((*draw)->savefinalfilename));
297: PetscCall(PetscHeaderDestroy(draw));
298: PetscFunctionReturn(PETSC_SUCCESS);
299: }
301: /*@
302: PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.
304: Collective
306: Input Parameter:
307: . draw - the original window
309: Output Parameter:
310: . popup - the new popup window
312: Level: advanced
314: .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
315: @*/
316: PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
317: {
318: PetscFunctionBegin;
320: PetscAssertPointer(popup, 2);
322: if (draw->popup) *popup = draw->popup;
323: else if (draw->ops->getpopup) {
324: PetscUseTypeMethod(draw, getpopup, popup);
325: if (*popup) {
326: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
327: (*popup)->pause = 0.0;
328: PetscCall(PetscDrawSetFromOptions(*popup));
329: }
330: } else *popup = NULL;
331: PetscFunctionReturn(PETSC_SUCCESS);
332: }
334: /*@
335: PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed
337: Input Parameters:
338: + draw - the drawing context
339: - display - the X windows display
341: Level: advanced
343: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
344: @*/
345: PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
346: {
347: PetscFunctionBegin;
348: PetscCall(PetscFree(draw->display));
349: PetscCall(PetscStrallocpy(display, &draw->display));
350: PetscFunctionReturn(PETSC_SUCCESS);
351: }
353: /*@
354: PetscDrawSetDoubleBuffer - Sets a window to be double buffered.
356: Logically Collective
358: Input Parameter:
359: . draw - the drawing context
361: Level: intermediate
363: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
364: @*/
365: PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
366: {
367: PetscFunctionBegin;
369: PetscTryTypeMethod(draw, setdoublebuffer);
370: PetscFunctionReturn(PETSC_SUCCESS);
371: }
373: /*@
374: PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
375: by the one process.
377: Collective
379: Input Parameter:
380: . draw - the original window
382: Output Parameter:
383: . sdraw - the singleton window
385: Level: advanced
387: .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
388: @*/
389: PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
390: {
391: PetscMPIInt size;
393: PetscFunctionBegin;
395: PetscAssertPointer(sdraw, 2);
397: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
398: if (size == 1) {
399: PetscCall(PetscObjectReference((PetscObject)draw));
400: *sdraw = draw;
401: } else {
402: if (draw->ops->getsingleton) {
403: PetscUseTypeMethod(draw, getsingleton, sdraw);
404: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
405: }
406: PetscFunctionReturn(PETSC_SUCCESS);
407: }
409: /*@
410: PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
411: by the one process.
413: Collective
415: Input Parameters:
416: + draw - the original window
417: - sdraw - the singleton window
419: Level: advanced
421: .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
422: @*/
423: PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
424: {
425: PetscMPIInt size;
427: PetscFunctionBegin;
429: PetscAssertPointer(sdraw, 2);
432: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
433: if (size == 1) {
434: if (draw == *sdraw) {
435: PetscCall(PetscObjectDereference((PetscObject)draw));
436: *sdraw = NULL;
437: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
438: } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
439: PetscFunctionReturn(PETSC_SUCCESS);
440: }
442: /*@
443: PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.
445: Input Parameters:
446: + draw - the drawing window
447: - visible - if the surface should be visible
449: Level: intermediate
451: .seealso: `PetscDraw`
452: @*/
453: PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
454: {
455: PetscFunctionBegin;
457: PetscTryTypeMethod(draw, setvisible, visible);
458: PetscFunctionReturn(PETSC_SUCCESS);
459: }