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 Draw package. It is 13 called from PetscFinalize(). 14 15 Level: developer 16 17 .seealso: `PetscFinalize()` 18 @*/ 19 PetscErrorCode PetscDrawFinalizePackage(void) 20 { 21 PetscFunctionBegin; 22 PetscCall(PetscFunctionListDestroy(&PetscDrawList)); 23 PetscDrawPackageInitialized = PETSC_FALSE; 24 PetscDrawRegisterAllCalled = PETSC_FALSE; 25 PetscFunctionReturn(0); 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: `PetscInitialize()` 36 @*/ 37 PetscErrorCode PetscDrawInitializePackage(void) 38 { 39 char logList[256]; 40 PetscBool opt,pkg; 41 42 PetscFunctionBegin; 43 if (PetscDrawPackageInitialized) PetscFunctionReturn(0); 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(0); 82 } 83 84 /*@ 85 PetscDrawResizeWindow - Allows one to resize a window from a program. 86 87 Collective on PetscDraw 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: `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 if (draw->ops->resizewindow) { 104 PetscCall((*draw->ops->resizewindow)(draw,w,h)); 105 } 106 PetscFunctionReturn(0); 107 } 108 109 /*@ 110 PetscDrawGetWindowSize - Gets the size of the window. 111 112 Not collective 113 114 Input Parameter: 115 . draw - the window 116 117 Output Parameters: 118 . w,h - the window width and height 119 120 Level: intermediate 121 122 .seealso: `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()` 123 @*/ 124 PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw,int *w,int *h) 125 { 126 PetscFunctionBegin; 127 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 128 if (w) PetscValidPointer(w,2); 129 if (h) PetscValidPointer(h,3); 130 if (w) *w = draw->w; 131 if (h) *h = draw->h; 132 PetscFunctionReturn(0); 133 } 134 135 /*@ 136 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 137 138 Collective on PetscDraw 139 140 Input Parameter: 141 . draw - the window 142 143 Level: advanced 144 145 .seealso: `PetscDrawResizeWindow()` 146 147 @*/ 148 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) 149 { 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 152 if (draw->ops->checkresizedwindow) { 153 PetscCall((*draw->ops->checkresizedwindow)(draw)); 154 } 155 PetscFunctionReturn(0); 156 } 157 158 /*@C 159 PetscDrawGetTitle - Gets pointer to title of a PetscDraw context. 160 161 Not collective 162 163 Input Parameter: 164 . draw - the graphics context 165 166 Output Parameter: 167 . title - the title 168 169 Level: intermediate 170 171 .seealso: `PetscDrawSetTitle()` 172 @*/ 173 PetscErrorCode PetscDrawGetTitle(PetscDraw draw,const char *title[]) 174 { 175 PetscFunctionBegin; 176 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 177 PetscValidPointer(title,2); 178 *title = draw->title; 179 PetscFunctionReturn(0); 180 } 181 182 /*@C 183 PetscDrawSetTitle - Sets the title of a PetscDraw context. 184 185 Collective on PetscDraw 186 187 Input Parameters: 188 + draw - the graphics context 189 - title - the title 190 191 Level: intermediate 192 193 Note: The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save 194 in the image. 195 196 A copy of the string is made, so you may destroy the 197 title string after calling this routine. 198 199 You can use PetscDrawAxisSetLabels() to indicate a title within the window 200 201 .seealso: `PetscDrawGetTitle()`, `PetscDrawAppendTitle()` 202 @*/ 203 PetscErrorCode PetscDrawSetTitle(PetscDraw draw,const char title[]) 204 { 205 PetscFunctionBegin; 206 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 207 PetscValidCharPointer(title,2); 208 PetscCall(PetscFree(draw->title)); 209 PetscCall(PetscStrallocpy(title,&draw->title)); 210 if (draw->ops->settitle) { 211 PetscCall((*draw->ops->settitle)(draw,draw->title)); 212 } 213 PetscFunctionReturn(0); 214 } 215 216 /*@C 217 PetscDrawAppendTitle - Appends to the title of a PetscDraw context. 218 219 Collective on PetscDraw 220 221 Input Parameters: 222 + draw - the graphics context 223 - title - the title 224 225 Note: 226 A copy of the string is made, so you may destroy the 227 title string after calling this routine. 228 229 Level: advanced 230 231 .seealso: `PetscDrawSetTitle()`, `PetscDrawGetTitle()` 232 @*/ 233 PetscErrorCode PetscDrawAppendTitle(PetscDraw draw,const char title[]) 234 { 235 PetscFunctionBegin; 236 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 237 if (title) PetscValidCharPointer(title,2); 238 if (!title || !title[0]) PetscFunctionReturn(0); 239 240 if (draw->title) { 241 size_t len1,len2; 242 char *newtitle; 243 PetscCall(PetscStrlen(title,&len1)); 244 PetscCall(PetscStrlen(draw->title,&len2)); 245 PetscCall(PetscMalloc1(len1 + len2 + 1,&newtitle)); 246 PetscCall(PetscStrcpy(newtitle,draw->title)); 247 PetscCall(PetscStrcat(newtitle,title)); 248 PetscCall(PetscFree(draw->title)); 249 draw->title = newtitle; 250 } else { 251 PetscCall(PetscStrallocpy(title,&draw->title)); 252 } 253 if (draw->ops->settitle) { 254 PetscCall((*draw->ops->settitle)(draw,draw->title)); 255 } 256 PetscFunctionReturn(0); 257 } 258 259 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw) 260 { 261 PetscFunctionBegin; 262 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 263 PetscCall(PetscDrawSaveMovie(draw)); 264 if (draw->savefinalfilename) { 265 draw->savesinglefile = PETSC_TRUE; 266 PetscCall(PetscDrawSetSave(draw,draw->savefinalfilename)); 267 PetscCall(PetscDrawSave(draw)); 268 } 269 PetscCall(PetscBarrier((PetscObject)draw)); 270 PetscFunctionReturn(0); 271 } 272 273 /*@ 274 PetscDrawDestroy - Deletes a draw context. 275 276 Collective on PetscDraw 277 278 Input Parameters: 279 . draw - the drawing context 280 281 Level: beginner 282 283 .seealso: `PetscDrawCreate()` 284 285 @*/ 286 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) 287 { 288 PetscFunctionBegin; 289 if (!*draw) PetscFunctionReturn(0); 290 PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1); 291 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0); 292 293 if ((*draw)->pause == -2) { 294 (*draw)->pause = -1; 295 PetscCall(PetscDrawPause(*draw)); 296 } 297 298 /* if memory was published then destroy it */ 299 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 300 301 PetscCall(PetscDrawDestroy_Private(*draw)); 302 303 if ((*draw)->ops->destroy) { 304 PetscCall((*(*draw)->ops->destroy)(*draw)); 305 } 306 PetscCall(PetscDrawDestroy(&(*draw)->popup)); 307 PetscCall(PetscFree((*draw)->title)); 308 PetscCall(PetscFree((*draw)->display)); 309 PetscCall(PetscFree((*draw)->savefilename)); 310 PetscCall(PetscFree((*draw)->saveimageext)); 311 PetscCall(PetscFree((*draw)->savemovieext)); 312 PetscCall(PetscFree((*draw)->savefinalfilename)); 313 PetscCall(PetscHeaderDestroy(draw)); 314 PetscFunctionReturn(0); 315 } 316 317 /*@ 318 PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window. 319 320 Collective on PetscDraw 321 322 Input Parameter: 323 . draw - the original window 324 325 Output Parameter: 326 . popup - the new popup window 327 328 Level: advanced 329 330 .seealso: `PetscDrawScalePopup()`, `PetscDrawCreate()` 331 332 @*/ 333 PetscErrorCode PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup) 334 { 335 PetscFunctionBegin; 336 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 337 PetscValidPointer(popup,2); 338 339 if (draw->popup) *popup = draw->popup; 340 else if (draw->ops->getpopup) { 341 PetscCall((*draw->ops->getpopup)(draw,popup)); 342 if (*popup) { 343 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_")); 344 (*popup)->pause = 0.0; 345 PetscCall(PetscDrawSetFromOptions(*popup)); 346 } 347 } else *popup = NULL; 348 PetscFunctionReturn(0); 349 } 350 351 /*@C 352 PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed 353 354 Input Parameters: 355 + draw - the drawing context 356 - display - the X windows display 357 358 Level: advanced 359 360 .seealso: `PetscDrawCreate()` 361 362 @*/ 363 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw,const char display[]) 364 { 365 PetscFunctionBegin; 366 PetscCall(PetscFree(draw->display)); 367 PetscCall(PetscStrallocpy(display,&draw->display)); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 373 374 Logically Collective on PetscDraw 375 376 Input Parameter: 377 . draw - the drawing context 378 379 Level: intermediate 380 381 @*/ 382 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) 383 { 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 386 if (draw->ops->setdoublebuffer) { 387 PetscCall((*draw->ops->setdoublebuffer)(draw)); 388 } 389 PetscFunctionReturn(0); 390 } 391 392 /*@C 393 PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned 394 by the one process. 395 396 Collective on PetscDraw 397 398 Input Parameter: 399 . draw - the original window 400 401 Output Parameter: 402 . sdraw - the singleton window 403 404 Level: advanced 405 406 .seealso: `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 407 408 @*/ 409 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw) 410 { 411 PetscMPIInt size; 412 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 415 PetscValidPointer(sdraw,2); 416 417 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size)); 418 if (size == 1) { 419 PetscCall(PetscObjectReference((PetscObject)draw)); 420 *sdraw = draw; 421 } else { 422 if (draw->ops->getsingleton) { 423 PetscCall((*draw->ops->getsingleton)(draw,sdraw)); 424 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name); 425 } 426 PetscFunctionReturn(0); 427 } 428 429 /*@C 430 PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned 431 by the one process. 432 433 Collective on PetscDraw 434 435 Input Parameters: 436 + draw - the original window 437 - sdraw - the singleton window 438 439 Level: advanced 440 441 .seealso: `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 442 443 @*/ 444 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw) 445 { 446 PetscMPIInt size; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 450 PetscValidPointer(sdraw,2); 451 PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2); 452 453 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size)); 454 if (size == 1) { 455 if (draw == *sdraw) { 456 PetscCall(PetscObjectDereference((PetscObject)draw)); 457 *sdraw = NULL; 458 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw"); 459 } else { 460 if (draw->ops->restoresingleton) { 461 PetscCall((*draw->ops->restoresingleton)(draw,sdraw)); 462 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name); 463 } 464 PetscFunctionReturn(0); 465 } 466