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 { 21 PetscFunctionBegin; 22 PetscCall(PetscFunctionListDestroy(&PetscDrawList)); 23 PetscDrawPackageInitialized = PETSC_FALSE; 24 PetscDrawRegisterAllCalled = PETSC_FALSE; 25 PetscFunctionReturn(PETSC_SUCCESS); 26 } 27 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. 32 33 Level: developer 34 35 .seealso: `PetscDraw`, `PetscInitialize()` 36 @*/ 37 PetscErrorCode PetscDrawInitializePackage(void) 38 { 39 char logList[256]; 40 PetscBool opt, pkg; 41 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]; 57 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 } 83 84 /*@ 85 PetscDrawResizeWindow - Allows one to resize a window from a program. 86 87 Collective 88 89 Input Parameters: 90 + draw - the window 91 - w,h - the new width and height of the window 92 93 Level: intermediate 94 95 .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()` 96 @*/ 97 PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h) 98 { 99 PetscFunctionBegin; 100 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 101 PetscValidLogicalCollectiveInt(draw, w, 2); 102 PetscValidLogicalCollectiveInt(draw, h, 3); 103 PetscTryTypeMethod(draw, resizewindow, w, h); 104 PetscFunctionReturn(PETSC_SUCCESS); 105 } 106 107 /*@ 108 PetscDrawGetWindowSize - Gets the size of the window. 109 110 Not collective 111 112 Input Parameter: 113 . draw - the window 114 115 Output Parameters: 116 . w,h - the window width and height 117 118 Level: intermediate 119 120 .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()` 121 @*/ 122 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 126 if (w) PetscValidPointer(w, 2); 127 if (h) PetscValidPointer(h, 3); 128 if (w) *w = draw->w; 129 if (h) *h = draw->h; 130 PetscFunctionReturn(PETSC_SUCCESS); 131 } 132 133 /*@ 134 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 135 136 Collective 137 138 Input Parameter: 139 . draw - the window 140 141 Level: advanced 142 143 .seealso: `PetscDraw`, `PetscDrawResizeWindow()` 144 @*/ 145 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) 146 { 147 PetscFunctionBegin; 148 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 149 PetscTryTypeMethod(draw, checkresizedwindow); 150 PetscFunctionReturn(PETSC_SUCCESS); 151 } 152 153 /*@C 154 PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context. 155 156 Not collective 157 158 Input Parameter: 159 . draw - the graphics context 160 161 Output Parameter: 162 . title - the title 163 164 Level: intermediate 165 166 .seealso: `PetscDraw`, `PetscDrawSetTitle()` 167 @*/ 168 PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[]) 169 { 170 PetscFunctionBegin; 171 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 172 PetscValidPointer(title, 2); 173 *title = draw->title; 174 PetscFunctionReturn(PETSC_SUCCESS); 175 } 176 177 /*@C 178 PetscDrawSetTitle - Sets the title of a `PetscDraw` context. 179 180 Collective 181 182 Input Parameters: 183 + draw - the graphics context 184 - title - the title 185 186 Level: intermediate 187 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. 191 192 A copy of the string is made, so you may destroy the 193 title string after calling this routine. 194 195 You can use `PetscDrawAxisSetLabels()` to indicate a title within the window 196 197 .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()` 198 @*/ 199 PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[]) 200 { 201 PetscFunctionBegin; 202 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 203 PetscValidCharPointer(title, 2); 204 PetscCall(PetscFree(draw->title)); 205 PetscCall(PetscStrallocpy(title, &draw->title)); 206 PetscTryTypeMethod(draw, settitle, draw->title); 207 PetscFunctionReturn(PETSC_SUCCESS); 208 } 209 210 /*@C 211 PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context. 212 213 Collective 214 215 Input Parameters: 216 + draw - the graphics context 217 - title - the title 218 219 Note: 220 A copy of the string is made, so you may destroy the 221 title string after calling this routine. 222 223 Level: advanced 224 225 .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()` 226 @*/ 227 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[]) 228 { 229 PetscFunctionBegin; 230 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 231 if (title) PetscValidCharPointer(title, 2); 232 if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS); 233 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 } 250 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 } 264 265 /*@ 266 PetscDrawDestroy - Deletes a draw context. 267 268 Collective 269 270 Input Parameters: 271 . draw - the drawing context 272 273 Level: beginner 274 275 .seealso: `PetscDraw`, `PetscDrawCreate()` 276 @*/ 277 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) 278 { 279 PetscFunctionBegin; 280 if (!*draw) PetscFunctionReturn(PETSC_SUCCESS); 281 PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 1); 282 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(PETSC_SUCCESS); 283 284 if ((*draw)->pause == -2) { 285 (*draw)->pause = -1; 286 PetscCall(PetscDrawPause(*draw)); 287 } 288 289 /* if memory was published then destroy it */ 290 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 291 292 PetscCall(PetscDrawDestroy_Private(*draw)); 293 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 } 305 306 /*@ 307 PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window. 308 309 Collective 310 311 Input Parameter: 312 . draw - the original window 313 314 Output Parameter: 315 . popup - the new popup window 316 317 Level: advanced 318 319 .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()` 320 @*/ 321 PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup) 322 { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 325 PetscValidPointer(popup, 2); 326 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 } 338 339 /*@C 340 PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed 341 342 Input Parameters: 343 + draw - the drawing context 344 - display - the X windows display 345 346 Level: advanced 347 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 } 357 358 /*@ 359 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 360 361 Logically Collective 362 363 Input Parameter: 364 . draw - the drawing context 365 366 Level: intermediate 367 368 .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()` 369 @*/ 370 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) 371 { 372 PetscFunctionBegin; 373 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 374 PetscTryTypeMethod(draw, setdoublebuffer); 375 PetscFunctionReturn(PETSC_SUCCESS); 376 } 377 378 /*@C 379 PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned 380 by the one process. 381 382 Collective 383 384 Input Parameter: 385 . draw - the original window 386 387 Output Parameter: 388 . sdraw - the singleton window 389 390 Level: advanced 391 392 .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 393 @*/ 394 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw) 395 { 396 PetscMPIInt size; 397 398 PetscFunctionBegin; 399 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 400 PetscValidPointer(sdraw, 2); 401 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 } 413 414 /*@C 415 PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()` 416 by the one process. 417 418 Collective 419 420 Input Parameters: 421 + draw - the original window 422 - sdraw - the singleton window 423 424 Level: advanced 425 426 .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 427 @*/ 428 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw) 429 { 430 PetscMPIInt size; 431 432 PetscFunctionBegin; 433 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 434 PetscValidPointer(sdraw, 2); 435 PetscValidHeaderSpecific(*sdraw, PETSC_DRAW_CLASSID, 2); 436 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 } 446 447 /*@C 448 PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display. 449 450 Input Parameters: 451 + draw - the drawing window 452 - visible - if the surface should be visible 453 454 Level: intermediate 455 456 .seealso: `PetscDraw` 457 @*/ 458 PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible) 459 { 460 PetscFunctionBegin; 461 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 462 PetscTryTypeMethod(draw, setvisible, visible); 463 PetscFunctionReturn(PETSC_SUCCESS); 464 } 465