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 /*@C 12 PetscDrawFinalizePackage - This function destroys everything in the Petsc interface to the `PetscDraw` package. It is 13 called from `PetscFinalize()`. 14 15 Level: developer 16 17 .seealso: `PetscDraw`, `PetscFinalize()` 18 @*/ 19 PetscErrorCode PetscDrawFinalizePackage(void) { 20 PetscFunctionBegin; 21 PetscCall(PetscFunctionListDestroy(&PetscDrawList)); 22 PetscDrawPackageInitialized = PETSC_FALSE; 23 PetscDrawRegisterAllCalled = PETSC_FALSE; 24 PetscFunctionReturn(0); 25 } 26 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. 31 32 Level: developer 33 34 .seealso: `PetscDraw`, `PetscInitialize()` 35 @*/ 36 PetscErrorCode PetscDrawInitializePackage(void) { 37 char logList[256]; 38 PetscBool opt, pkg; 39 40 PetscFunctionBegin; 41 if (PetscDrawPackageInitialized) PetscFunctionReturn(0); 42 PetscDrawPackageInitialized = PETSC_TRUE; 43 /* Register Classes */ 44 PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID)); 45 PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID)); 46 PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID)); 47 PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID)); 48 PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID)); 49 PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID)); 50 /* Register Constructors */ 51 PetscCall(PetscDrawRegisterAll()); 52 /* Process Info */ 53 { 54 PetscClassId classids[6]; 55 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 PetscCall(PetscInfoProcessClass("draw", 6, classids)); 63 } 64 /* Process summary exclusions */ 65 PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt)); 66 if (opt) { 67 PetscCall(PetscStrInList("draw", logList, ',', &pkg)); 68 if (pkg) { 69 PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID)); 70 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID)); 71 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID)); 72 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID)); 73 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID)); 74 PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID)); 75 } 76 } 77 /* Register package finalizer */ 78 PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage)); 79 PetscFunctionReturn(0); 80 } 81 82 /*@ 83 PetscDrawResizeWindow - Allows one to resize a window from a program. 84 85 Collective on draw 86 87 Input Parameters: 88 + draw - the window 89 - w,h - the new width and height of the window 90 91 Level: intermediate 92 93 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()` 94 @*/ 95 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h) { 96 PetscFunctionBegin; 97 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 98 PetscValidLogicalCollectiveInt(draw, w, 2); 99 PetscValidLogicalCollectiveInt(draw, h, 3); 100 PetscTryTypeMethod(draw, resizewindow, w, h); 101 PetscFunctionReturn(0); 102 } 103 104 /*@ 105 PetscDrawGetWindowSize - Gets the size of the window. 106 107 Not collective 108 109 Input Parameter: 110 . draw - the window 111 112 Output Parameters: 113 . w,h - the window width and height 114 115 Level: intermediate 116 117 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()` 118 @*/ 119 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h) { 120 PetscFunctionBegin; 121 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 122 if (w) PetscValidPointer(w, 2); 123 if (h) PetscValidPointer(h, 3); 124 if (w) *w = draw->w; 125 if (h) *h = draw->h; 126 PetscFunctionReturn(0); 127 } 128 129 /*@ 130 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 131 132 Collective on draw 133 134 Input Parameter: 135 . draw - the window 136 137 Level: advanced 138 139 .seealso: `PetscDraw`, `PetscDrawResizeWindow()` 140 @*/ 141 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) { 142 PetscFunctionBegin; 143 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 144 PetscTryTypeMethod(draw, checkresizedwindow); 145 PetscFunctionReturn(0); 146 } 147 148 /*@C 149 PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context. 150 151 Not collective 152 153 Input Parameter: 154 . draw - the graphics context 155 156 Output Parameter: 157 . title - the title 158 159 Level: intermediate 160 161 .seealso: `PetscDraw`, `PetscDrawSetTitle()` 162 @*/ 163 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[]) { 164 PetscFunctionBegin; 165 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 166 PetscValidPointer(title, 2); 167 *title = draw->title; 168 PetscFunctionReturn(0); 169 } 170 171 /*@C 172 PetscDrawSetTitle - Sets the title of a `PetscDraw` context. 173 174 Collective on draw 175 176 Input Parameters: 177 + draw - the graphics context 178 - title - the title 179 180 Level: intermediate 181 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. 185 186 A copy of the string is made, so you may destroy the 187 title string after calling this routine. 188 189 You can use `PetscDrawAxisSetLabels()` to indicate a title within the window 190 191 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()` 192 @*/ 193 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[]) { 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 196 PetscValidCharPointer(title, 2); 197 PetscCall(PetscFree(draw->title)); 198 PetscCall(PetscStrallocpy(title, &draw->title)); 199 PetscTryTypeMethod(draw, settitle, draw->title); 200 PetscFunctionReturn(0); 201 } 202 203 /*@C 204 PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context. 205 206 Collective on draw 207 208 Input Parameters: 209 + draw - the graphics context 210 - title - the title 211 212 Note: 213 A copy of the string is made, so you may destroy the 214 title string after calling this routine. 215 216 Level: advanced 217 218 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()` 219 @*/ 220 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[]) { 221 PetscFunctionBegin; 222 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 223 if (title) PetscValidCharPointer(title, 2); 224 if (!title || !title[0]) PetscFunctionReturn(0); 225 226 if (draw->title) { 227 size_t len1, len2; 228 char *newtitle; 229 PetscCall(PetscStrlen(title, &len1)); 230 PetscCall(PetscStrlen(draw->title, &len2)); 231 PetscCall(PetscMalloc1(len1 + len2 + 1, &newtitle)); 232 PetscCall(PetscStrcpy(newtitle, draw->title)); 233 PetscCall(PetscStrcat(newtitle, title)); 234 PetscCall(PetscFree(draw->title)); 235 draw->title = newtitle; 236 } else { 237 PetscCall(PetscStrallocpy(title, &draw->title)); 238 } 239 PetscTryTypeMethod(draw, settitle, draw->title); 240 PetscFunctionReturn(0); 241 } 242 243 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw) { 244 PetscFunctionBegin; 245 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 246 PetscCall(PetscDrawSaveMovie(draw)); 247 if (draw->savefinalfilename) { 248 draw->savesinglefile = PETSC_TRUE; 249 PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename)); 250 PetscCall(PetscDrawSave(draw)); 251 } 252 PetscCall(PetscBarrier((PetscObject)draw)); 253 PetscFunctionReturn(0); 254 } 255 256 /*@ 257 PetscDrawDestroy - Deletes a draw context. 258 259 Collective on draw 260 261 Input Parameters: 262 . draw - the drawing context 263 264 Level: beginner 265 266 .seealso: `PetscDraw`, `PetscDrawCreate()` 267 @*/ 268 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) { 269 PetscFunctionBegin; 270 if (!*draw) PetscFunctionReturn(0); 271 PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1); 272 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0); 273 274 if ((*draw)->pause == -2) { 275 (*draw)->pause = -1; 276 PetscCall(PetscDrawPause(*draw)); 277 } 278 279 /* if memory was published then destroy it */ 280 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 281 282 PetscCall(PetscDrawDestroy_Private(*draw)); 283 284 if ((*draw)->ops->destroy) PetscCall((*(*draw)->ops->destroy)(*draw)); 285 PetscCall(PetscDrawDestroy(&(*draw)->popup)); 286 PetscCall(PetscFree((*draw)->title)); 287 PetscCall(PetscFree((*draw)->display)); 288 PetscCall(PetscFree((*draw)->savefilename)); 289 PetscCall(PetscFree((*draw)->saveimageext)); 290 PetscCall(PetscFree((*draw)->savemovieext)); 291 PetscCall(PetscFree((*draw)->savefinalfilename)); 292 PetscCall(PetscHeaderDestroy(draw)); 293 PetscFunctionReturn(0); 294 } 295 296 /*@ 297 PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window. 298 299 Collective on draw 300 301 Input Parameter: 302 . draw - the original window 303 304 Output Parameter: 305 . popup - the new popup window 306 307 Level: advanced 308 309 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()` 310 @*/ 311 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup) { 312 PetscFunctionBegin; 313 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 314 PetscValidPointer(popup, 2); 315 316 if (draw->popup) *popup = draw->popup; 317 else if (draw->ops->getpopup) { 318 PetscUseTypeMethod(draw, getpopup, popup); 319 if (*popup) { 320 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_")); 321 (*popup)->pause = 0.0; 322 PetscCall(PetscDrawSetFromOptions(*popup)); 323 } 324 } else *popup = NULL; 325 PetscFunctionReturn(0); 326 } 327 328 /*@C 329 PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed 330 331 Input Parameters: 332 + draw - the drawing context 333 - display - the X windows display 334 335 Level: advanced 336 337 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 338 @*/ 339 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[]) { 340 PetscFunctionBegin; 341 PetscCall(PetscFree(draw->display)); 342 PetscCall(PetscStrallocpy(display, &draw->display)); 343 PetscFunctionReturn(0); 344 } 345 346 /*@ 347 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 348 349 Logically Collective on draw 350 351 Input Parameter: 352 . draw - the drawing context 353 354 Level: intermediate 355 356 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 357 @*/ 358 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) { 359 PetscFunctionBegin; 360 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 361 PetscTryTypeMethod(draw, setdoublebuffer); 362 PetscFunctionReturn(0); 363 } 364 365 /*@C 366 PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned 367 by the one process. 368 369 Collective on draw 370 371 Input Parameter: 372 . draw - the original window 373 374 Output Parameter: 375 . sdraw - the singleton window 376 377 Level: advanced 378 379 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 380 @*/ 381 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw) { 382 PetscMPIInt size; 383 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 386 PetscValidPointer(sdraw, 2); 387 388 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 389 if (size == 1) { 390 PetscCall(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 PetscFunctionReturn(0); 398 } 399 400 /*@C 401 PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()` 402 by the one process. 403 404 Collective on draw 405 406 Input Parameters: 407 + draw - the original window 408 - sdraw - the singleton window 409 410 Level: advanced 411 412 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 413 @*/ 414 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw) { 415 PetscMPIInt size; 416 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 419 PetscValidPointer(sdraw, 2); 420 PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2); 421 422 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); 423 if (size == 1) { 424 if (draw == *sdraw) { 425 PetscCall(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 PetscFunctionReturn(0); 430 } 431