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: }