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:   PetscFunctionListDestroy(&PetscDrawList);
 22:   PetscDrawPackageInitialized = PETSC_FALSE;
 23:   PetscDrawRegisterAllCalled  = PETSC_FALSE;
 24:   return 0;
 25: }

 27: /*@C
 28:   PetscInitializeDrawPackage - This function initializes everything in the `PetscDraw` package. It is called
 29:   from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
 30:   when using shared or static libraries.

 32:   Level: developer

 34: .seealso: `PetscDraw`, `PetscInitialize()`
 35: @*/
 36: PetscErrorCode PetscDrawInitializePackage(void)
 37: {
 38:   char      logList[256];
 39:   PetscBool opt, pkg;

 41:   if (PetscDrawPackageInitialized) return 0;
 42:   PetscDrawPackageInitialized = PETSC_TRUE;
 43:   /* Register Classes */
 44:   PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID);
 45:   PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID);
 46:   PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID);
 47:   PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID);
 48:   PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID);
 49:   PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID);
 50:   /* Register Constructors */
 51:   PetscDrawRegisterAll();
 52:   /* Process Info */
 53:   {
 54:     PetscClassId classids[6];

 56:     classids[0] = PETSC_DRAW_CLASSID;
 57:     classids[1] = PETSC_DRAWAXIS_CLASSID;
 58:     classids[2] = PETSC_DRAWLG_CLASSID;
 59:     classids[3] = PETSC_DRAWHG_CLASSID;
 60:     classids[4] = PETSC_DRAWBAR_CLASSID;
 61:     classids[5] = PETSC_DRAWSP_CLASSID;
 62:     PetscInfoProcessClass("draw", 6, classids);
 63:   }
 64:   /* Process summary exclusions */
 65:   PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt);
 66:   if (opt) {
 67:     PetscStrInList("draw", logList, ',', &pkg);
 68:     if (pkg) {
 69:       PetscLogEventExcludeClass(PETSC_DRAW_CLASSID);
 70:       PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID);
 71:       PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID);
 72:       PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID);
 73:       PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID);
 74:       PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID);
 75:     }
 76:   }
 77:   /* Register package finalizer */
 78:   PetscRegisterFinalize(PetscDrawFinalizePackage);
 79:   return 0;
 80: }

 82: /*@
 83:    PetscDrawResizeWindow - Allows one to resize a window from a program.

 85:    Collective

 87:    Input Parameters:
 88: +  draw - the window
 89: -  w,h - the new width and height of the window

 91:    Level: intermediate

 93: .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
 94: @*/
 95: PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
 96: {
100:   PetscTryTypeMethod(draw, resizewindow, w, h);
101:   return 0;
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,h - the window width and height

115:    Level: intermediate

117: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
118: @*/
119: PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
120: {
124:   if (w) *w = draw->w;
125:   if (h) *h = draw->h;
126:   return 0;
127: }

129: /*@
130:    PetscDrawCheckResizedWindow - Checks if the user has resized the window.

132:    Collective

134:    Input Parameter:
135: .  draw - the window

137:    Level: advanced

139: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
140: @*/
141: PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
142: {
144:   PetscTryTypeMethod(draw, checkresizedwindow);
145:   return 0;
146: }

148: /*@C
149:    PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.

151:    Not collective

153:    Input Parameter:
154: .  draw - the graphics context

156:    Output Parameter:
157: .  title - the title

159:    Level: intermediate

161: .seealso: `PetscDraw`, `PetscDrawSetTitle()`
162: @*/
163: PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
164: {
167:   *title = draw->title;
168:   return 0;
169: }

171: /*@C
172:    PetscDrawSetTitle - Sets the title of a `PetscDraw` context.

174:    Collective

176:    Input Parameters:
177: +  draw - the graphics context
178: -  title - the title

180:    Level: intermediate

182:    Notes:
183:    The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
184:    in the image.

186:    A copy of the string is made, so you may destroy the
187:    title string after calling this routine.

189:    You can use `PetscDrawAxisSetLabels()` to indicate a title within the window

191: .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
192: @*/
193: PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
194: {
197:   PetscFree(draw->title);
198:   PetscStrallocpy(title, &draw->title);
199:   PetscTryTypeMethod(draw, settitle, draw->title);
200:   return 0;
201: }

203: /*@C
204:    PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.

206:    Collective

208:    Input Parameters:
209: +  draw - the graphics context
210: -  title - the title

212:    Note:
213:    A copy of the string is made, so you may destroy the
214:    title string after calling this routine.

216:    Level: advanced

218: .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
219: @*/
220: PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
221: {
224:   if (!title || !title[0]) return 0;

226:   if (draw->title) {
227:     size_t len1, len2;
228:     char  *newtitle;
229:     PetscStrlen(title, &len1);
230:     PetscStrlen(draw->title, &len2);
231:     PetscMalloc1(len1 + len2 + 1, &newtitle);
232:     PetscStrcpy(newtitle, draw->title);
233:     PetscStrcat(newtitle, title);
234:     PetscFree(draw->title);
235:     draw->title = newtitle;
236:   } else {
237:     PetscStrallocpy(title, &draw->title);
238:   }
239:   PetscTryTypeMethod(draw, settitle, draw->title);
240:   return 0;
241: }

243: static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
244: {
245:   if (!draw->ops->save && !draw->ops->getimage) return 0;
246:   PetscDrawSaveMovie(draw);
247:   if (draw->savefinalfilename) {
248:     draw->savesinglefile = PETSC_TRUE;
249:     PetscDrawSetSave(draw, draw->savefinalfilename);
250:     PetscDrawSave(draw);
251:   }
252:   PetscBarrier((PetscObject)draw);
253:   return 0;
254: }

256: /*@
257:    PetscDrawDestroy - Deletes a draw context.

259:    Collective

261:    Input Parameters:
262: .  draw - the drawing context

264:    Level: beginner

266: .seealso: `PetscDraw`, `PetscDrawCreate()`
267: @*/
268: PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
269: {
270:   if (!*draw) return 0;
272:   if (--((PetscObject)(*draw))->refct > 0) return 0;

274:   if ((*draw)->pause == -2) {
275:     (*draw)->pause = -1;
276:     PetscDrawPause(*draw);
277:   }

279:   /* if memory was published then destroy it */
280:   PetscObjectSAWsViewOff((PetscObject)*draw);

282:   PetscDrawDestroy_Private(*draw);

284:   if ((*draw)->ops->destroy) (*(*draw)->ops->destroy)(*draw);
285:   PetscDrawDestroy(&(*draw)->popup);
286:   PetscFree((*draw)->title);
287:   PetscFree((*draw)->display);
288:   PetscFree((*draw)->savefilename);
289:   PetscFree((*draw)->saveimageext);
290:   PetscFree((*draw)->savemovieext);
291:   PetscFree((*draw)->savefinalfilename);
292:   PetscHeaderDestroy(draw);
293:   return 0;
294: }

296: /*@
297:    PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.

299:    Collective

301:    Input Parameter:
302: .  draw - the original window

304:    Output Parameter:
305: .  popup - the new popup window

307:    Level: advanced

309: .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
310: @*/
311: PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
312: {

316:   if (draw->popup) *popup = draw->popup;
317:   else if (draw->ops->getpopup) {
318:     PetscUseTypeMethod(draw, getpopup, popup);
319:     if (*popup) {
320:       PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_");
321:       (*popup)->pause = 0.0;
322:       PetscDrawSetFromOptions(*popup);
323:     }
324:   } else *popup = NULL;
325:   return 0;
326: }

328: /*@C
329:   PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed

331:   Input Parameters:
332: + draw - the drawing context
333: - display - the X windows display

335:   Level: advanced

337: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
338: @*/
339: PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
340: {
341:   PetscFree(draw->display);
342:   PetscStrallocpy(display, &draw->display);
343:   return 0;
344: }

346: /*@
347:    PetscDrawSetDoubleBuffer - Sets a window to be double buffered.

349:    Logically Collective

351:    Input Parameter:
352: .  draw - the drawing context

354:    Level: intermediate

356: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
357: @*/
358: PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
359: {
361:   PetscTryTypeMethod(draw, setdoublebuffer);
362:   return 0;
363: }

365: /*@C
366:    PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
367:         by the one process.

369:    Collective

371:    Input Parameter:
372: .  draw - the original window

374:    Output Parameter:
375: .  sdraw - the singleton window

377:    Level: advanced

379: .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
380: @*/
381: PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
382: {
383:   PetscMPIInt size;


388:   MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size);
389:   if (size == 1) {
390:     PetscObjectReference((PetscObject)draw);
391:     *sdraw = draw;
392:   } else {
393:     if (draw->ops->getsingleton) {
394:       PetscUseTypeMethod(draw, getsingleton, sdraw);
395:     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
396:   }
397:   return 0;
398: }

400: /*@C
401:    PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
402:         by the one process.

404:    Collective

406:    Input Parameters:
407: +  draw - the original window
408: -  sdraw - the singleton window

410:    Level: advanced

412: .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
413: @*/
414: PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
415: {
416:   PetscMPIInt size;


422:   MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size);
423:   if (size == 1) {
424:     if (draw == *sdraw) {
425:       PetscObjectDereference((PetscObject)draw);
426:       *sdraw = NULL;
427:     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
428:   } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
429:   return 0;
430: }