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) PetscCall((*draw->ops->resizewindow)(draw,w,h)); 104 PetscFunctionReturn(0); 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: `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(0); 131 } 132 133 /*@ 134 PetscDrawCheckResizedWindow - Checks if the user has resized the window. 135 136 Collective on PetscDraw 137 138 Input Parameter: 139 . draw - the window 140 141 Level: advanced 142 143 .seealso: `PetscDrawResizeWindow()` 144 145 @*/ 146 PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw) 147 { 148 PetscFunctionBegin; 149 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 150 if (draw->ops->checkresizedwindow) PetscCall((*draw->ops->checkresizedwindow)(draw)); 151 PetscFunctionReturn(0); 152 } 153 154 /*@C 155 PetscDrawGetTitle - Gets pointer to title of a PetscDraw context. 156 157 Not collective 158 159 Input Parameter: 160 . draw - the graphics context 161 162 Output Parameter: 163 . title - the title 164 165 Level: intermediate 166 167 .seealso: `PetscDrawSetTitle()` 168 @*/ 169 PetscErrorCode PetscDrawGetTitle(PetscDraw draw,const char *title[]) 170 { 171 PetscFunctionBegin; 172 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 173 PetscValidPointer(title,2); 174 *title = draw->title; 175 PetscFunctionReturn(0); 176 } 177 178 /*@C 179 PetscDrawSetTitle - Sets the title of a PetscDraw context. 180 181 Collective on PetscDraw 182 183 Input Parameters: 184 + draw - the graphics context 185 - title - the title 186 187 Level: intermediate 188 189 Note: 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: `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 if (draw->ops->settitle) PetscCall((*draw->ops->settitle)(draw,draw->title)); 207 PetscFunctionReturn(0); 208 } 209 210 /*@C 211 PetscDrawAppendTitle - Appends to the title of a PetscDraw context. 212 213 Collective on PetscDraw 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: `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(0); 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 if (draw->ops->settitle) PetscCall((*draw->ops->settitle)(draw,draw->title)); 248 PetscFunctionReturn(0); 249 } 250 251 static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw) 252 { 253 PetscFunctionBegin; 254 if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 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(0); 263 } 264 265 /*@ 266 PetscDrawDestroy - Deletes a draw context. 267 268 Collective on PetscDraw 269 270 Input Parameters: 271 . draw - the drawing context 272 273 Level: beginner 274 275 .seealso: `PetscDrawCreate()` 276 277 @*/ 278 PetscErrorCode PetscDrawDestroy(PetscDraw *draw) 279 { 280 PetscFunctionBegin; 281 if (!*draw) PetscFunctionReturn(0); 282 PetscValidHeaderSpecific(*draw,PETSC_DRAW_CLASSID,1); 283 if (--((PetscObject)(*draw))->refct > 0) PetscFunctionReturn(0); 284 285 if ((*draw)->pause == -2) { 286 (*draw)->pause = -1; 287 PetscCall(PetscDrawPause(*draw)); 288 } 289 290 /* if memory was published then destroy it */ 291 PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw)); 292 293 PetscCall(PetscDrawDestroy_Private(*draw)); 294 295 if ((*draw)->ops->destroy) { 296 PetscCall((*(*draw)->ops->destroy)(*draw)); 297 } 298 PetscCall(PetscDrawDestroy(&(*draw)->popup)); 299 PetscCall(PetscFree((*draw)->title)); 300 PetscCall(PetscFree((*draw)->display)); 301 PetscCall(PetscFree((*draw)->savefilename)); 302 PetscCall(PetscFree((*draw)->saveimageext)); 303 PetscCall(PetscFree((*draw)->savemovieext)); 304 PetscCall(PetscFree((*draw)->savefinalfilename)); 305 PetscCall(PetscHeaderDestroy(draw)); 306 PetscFunctionReturn(0); 307 } 308 309 /*@ 310 PetscDrawGetPopup - Creates a popup window associated with a PetscDraw window. 311 312 Collective on PetscDraw 313 314 Input Parameter: 315 . draw - the original window 316 317 Output Parameter: 318 . popup - the new popup window 319 320 Level: advanced 321 322 .seealso: `PetscDrawScalePopup()`, `PetscDrawCreate()` 323 324 @*/ 325 PetscErrorCode PetscDrawGetPopup(PetscDraw draw,PetscDraw *popup) 326 { 327 PetscFunctionBegin; 328 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 329 PetscValidPointer(popup,2); 330 331 if (draw->popup) *popup = draw->popup; 332 else if (draw->ops->getpopup) { 333 PetscCall((*draw->ops->getpopup)(draw,popup)); 334 if (*popup) { 335 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_")); 336 (*popup)->pause = 0.0; 337 PetscCall(PetscDrawSetFromOptions(*popup)); 338 } 339 } else *popup = NULL; 340 PetscFunctionReturn(0); 341 } 342 343 /*@C 344 PetscDrawSetDisplay - Sets the display where a PetscDraw object will be displayed 345 346 Input Parameters: 347 + draw - the drawing context 348 - display - the X windows display 349 350 Level: advanced 351 352 .seealso: `PetscDrawCreate()` 353 354 @*/ 355 PetscErrorCode PetscDrawSetDisplay(PetscDraw draw,const char display[]) 356 { 357 PetscFunctionBegin; 358 PetscCall(PetscFree(draw->display)); 359 PetscCall(PetscStrallocpy(display,&draw->display)); 360 PetscFunctionReturn(0); 361 } 362 363 /*@ 364 PetscDrawSetDoubleBuffer - Sets a window to be double buffered. 365 366 Logically Collective on PetscDraw 367 368 Input Parameter: 369 . draw - the drawing context 370 371 Level: intermediate 372 373 @*/ 374 PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw) 375 { 376 PetscFunctionBegin; 377 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 378 if (draw->ops->setdoublebuffer) PetscCall((*draw->ops->setdoublebuffer)(draw)); 379 PetscFunctionReturn(0); 380 } 381 382 /*@C 383 PetscDrawGetSingleton - Gain access to a PetscDraw object as if it were owned 384 by the one process. 385 386 Collective on PetscDraw 387 388 Input Parameter: 389 . draw - the original window 390 391 Output Parameter: 392 . sdraw - the singleton window 393 394 Level: advanced 395 396 .seealso: `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 397 398 @*/ 399 PetscErrorCode PetscDrawGetSingleton(PetscDraw draw,PetscDraw *sdraw) 400 { 401 PetscMPIInt size; 402 403 PetscFunctionBegin; 404 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 405 PetscValidPointer(sdraw,2); 406 407 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size)); 408 if (size == 1) { 409 PetscCall(PetscObjectReference((PetscObject)draw)); 410 *sdraw = draw; 411 } else { 412 if (draw->ops->getsingleton) { 413 PetscCall((*draw->ops->getsingleton)(draw,sdraw)); 414 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get singleton for this type %s of draw object",((PetscObject)draw)->type_name); 415 } 416 PetscFunctionReturn(0); 417 } 418 419 /*@C 420 PetscDrawRestoreSingleton - Remove access to a PetscDraw object as if it were owned 421 by the one process. 422 423 Collective on PetscDraw 424 425 Input Parameters: 426 + draw - the original window 427 - sdraw - the singleton window 428 429 Level: advanced 430 431 .seealso: `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()` 432 433 @*/ 434 PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw,PetscDraw *sdraw) 435 { 436 PetscMPIInt size; 437 438 PetscFunctionBegin; 439 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 440 PetscValidPointer(sdraw,2); 441 PetscValidHeaderSpecific(*sdraw,PETSC_DRAW_CLASSID,2); 442 443 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size)); 444 if (size == 1) { 445 if (draw == *sdraw) { 446 PetscCall(PetscObjectDereference((PetscObject)draw)); 447 *sdraw = NULL; 448 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot restore singleton, it is not the parent draw"); 449 } else { 450 if (draw->ops->restoresingleton) { 451 PetscCall((*draw->ops->restoresingleton)(draw,sdraw)); 452 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore singleton for this type %s of draw object",((PetscObject)draw)->type_name); 453 } 454 PetscFunctionReturn(0); 455 } 456