xref: /petsc/src/sys/classes/draw/interface/drawreg.c (revision 607a6623fc3ebf1ec03868e90ff90ff3b0120740)
1 
2 /*
3        Provides the registration process for PETSc PetscDraw routines
4 */
5 #include <petsc-private/drawimpl.h>  /*I "petscdraw.h" I*/
6 
7 /*
8    Contains the list of registered PetscDraw routines
9 */
10 PetscFunctionList PetscDrawList = 0;
11 
12 #undef __FUNCT__
13 #define __FUNCT__ "PetscDrawCreate"
14 /*@C
15    PetscDrawCreate - Creates a graphics context.
16 
17    Collective on MPI_Comm
18 
19    Input Parameter:
20 +  comm - MPI communicator
21 .  display - X display when using X windows
22 .  title - optional title added to top of window
23 .  x,y - coordinates of lower left corner of window or PETSC_DECIDE
24 -  w, h - width and height of window or PETSC_DECIDE or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
25           or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
26 
27    Output Parameter:
28 .  draw - location to put the PetscDraw context
29 
30    Level: beginner
31 
32    Concepts: graphics^creating context
33    Concepts: drawing^creating context
34 
35 .seealso: PetscDrawSetFromOptions(), PetscDrawDestroy(), PetscDrawSetType()
36 @*/
37 PetscErrorCode  PetscDrawCreate(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *indraw)
38 {
39   PetscDraw      draw;
40   PetscErrorCode ierr;
41   PetscReal      dpause;
42   PetscBool      flag;
43 
44   PetscFunctionBegin;
45 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
46   ierr = PetscDrawInitializePackage();CHKERRQ(ierr);
47 #endif
48   *indraw = 0;
49   ierr = PetscHeaderCreate(draw,_p_PetscDraw,struct _PetscDrawOps,PETSC_DRAW_CLASSID,"Draw","Graphics","Draw",comm,PetscDrawDestroy,0);CHKERRQ(ierr);
50 
51   draw->data    = 0;
52   ierr          = PetscStrallocpy(title,&draw->title);CHKERRQ(ierr);
53   ierr          = PetscStrallocpy(display,&draw->display);CHKERRQ(ierr);
54   draw->x       = x;
55   draw->y       = y;
56   draw->w       = w;
57   draw->h       = h;
58   draw->pause   = 0.0;
59   draw->coor_xl = 0.0;
60   draw->coor_xr = 1.0;
61   draw->coor_yl = 0.0;
62   draw->coor_yr = 1.0;
63   draw->port_xl = 0.0;
64   draw->port_xr = 1.0;
65   draw->port_yl = 0.0;
66   draw->port_yr = 1.0;
67   draw->popup   = 0;
68 
69   ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flag);CHKERRQ(ierr);
70   if (flag) draw->pause = dpause;
71   draw->savefilename  = NULL;
72   draw->savefilemovie = PETSC_FALSE;
73   draw->savefilecount = -1;
74 
75   ierr = PetscDrawSetCurrentPoint(draw,.5,.9);CHKERRQ(ierr);
76 
77   draw->boundbox_xl  = .5;
78   draw->boundbox_xr  = .5;
79   draw->boundbox_yl  = .9;
80   draw->boundbox_yr  = .9;
81 
82   *indraw = draw;
83   PetscFunctionReturn(0);
84 }
85 
86 #undef __FUNCT__
87 #define __FUNCT__ "PetscDrawSetType"
88 /*@C
89    PetscDrawSetType - Builds graphics object for a particular implementation
90 
91    Collective on PetscDraw
92 
93    Input Parameter:
94 +  draw      - the graphics context
95 -  type      - for example, PETSC_DRAW_X
96 
97    Options Database Command:
98 .  -draw_type  <type> - Sets the type; use -help for a list
99     of available methods (for instance, x)
100 
101    Level: intermediate
102 
103    Notes:
104    See "petsc/include/petscdraw.h" for available methods (for instance,
105    PETSC_DRAW_X)
106 
107    Concepts: drawing^X windows
108    Concepts: X windows^graphics
109    Concepts: drawing^Microsoft Windows
110 
111 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
112 @*/
113 PetscErrorCode  PetscDrawSetType(PetscDraw draw,PetscDrawType type)
114 {
115   PetscErrorCode ierr,(*r)(PetscDraw);
116   PetscBool      match;
117   PetscBool      flg=PETSC_FALSE;
118 
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
121   PetscValidCharPointer(type,2);
122 
123   ierr = PetscObjectTypeCompare((PetscObject)draw,type,&match);CHKERRQ(ierr);
124   if (match) PetscFunctionReturn(0);
125 
126   /*  User requests no graphics */
127   ierr = PetscOptionsHasName(NULL,"-nox",&flg);CHKERRQ(ierr);
128 
129   /*
130      This is not ideal, but it allows codes to continue to run if X graphics
131    was requested but is not installed on this machine. Mostly this is for
132    testing.
133    */
134 #if !defined(PETSC_HAVE_X)
135   if (!flg) {
136     ierr = PetscStrcmp(type,PETSC_DRAW_X,&match);CHKERRQ(ierr);
137     if (match) {
138       PetscBool dontwarn = PETSC_TRUE;
139       flg  = PETSC_TRUE;
140       ierr = PetscOptionsHasName(NULL,"-nox_warning",&dontwarn);CHKERRQ(ierr);
141       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X windows on this machine\nproceeding without graphics\n");
142     }
143   }
144 #endif
145   if (flg) type = PETSC_DRAW_NULL;
146 
147   if (draw->data) {
148     /* destroy the old private PetscDraw context */
149     ierr               = (*draw->ops->destroy)(draw);CHKERRQ(ierr);
150     draw->ops->destroy = NULL;
151     draw->data         = 0;
152   }
153 
154   ierr =  PetscFunctionListFind(PetscObjectComm((PetscObject)draw),PetscDrawList,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
155   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscDraw type given: %s",type);
156   ierr       = PetscObjectChangeTypeName((PetscObject)draw,type);CHKERRQ(ierr);
157   draw->data = 0;
158   ierr       = (*r)(draw);CHKERRQ(ierr);
159   PetscFunctionReturn(0);
160 }
161 
162 #undef __FUNCT__
163 #define __FUNCT__ "PetscDrawRegisterDestroy"
164 /*@C
165    PetscDrawRegisterDestroy - Frees the list of PetscDraw methods that were
166    registered by PetscDrawRegister().
167 
168    Not Collective
169 
170    Level: developer
171 
172 .seealso: PetscDrawRegister(), PetscDrawRegisterAll()
173 @*/
174 PetscErrorCode  PetscDrawRegisterDestroy(void)
175 {
176   PetscErrorCode ierr;
177 
178   PetscFunctionBegin;
179   ierr = PetscFunctionListDestroy(&PetscDrawList);CHKERRQ(ierr);
180   PetscFunctionReturn(0);
181 }
182 
183 #undef __FUNCT__
184 #define __FUNCT__ "PetscDrawGetType"
185 /*@C
186    PetscDrawGetType - Gets the PetscDraw type as a string from the PetscDraw object.
187 
188    Not Collective
189 
190    Input Parameter:
191 .  draw - Krylov context
192 
193    Output Parameters:
194 .  name - name of PetscDraw method
195 
196    Level: advanced
197 
198 @*/
199 PetscErrorCode  PetscDrawGetType(PetscDraw draw,PetscDrawType *type)
200 {
201   PetscFunctionBegin;
202   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
203   PetscValidPointer(type,2);
204   *type = ((PetscObject)draw)->type_name;
205   PetscFunctionReturn(0);
206 }
207 
208 #undef __FUNCT__
209 #define __FUNCT__ "PetscDrawRegister"
210 /*@C
211    PetscDrawRegister - Adds a method to the graphics package.
212 
213    Not Collective
214 
215    Input Parameters:
216 +  name_solver - name of a new user-defined solver
217 .  name_create - name of routine to create method context
218 -  routine_create - routine to create method context
219 
220    Level: developer
221 
222    Notes:
223    PetscDrawRegister() may be called multiple times to add several user-defined solvers.
224 
225    Sample usage:
226 .vb
227    PetscDrawRegister("my_draw_type", "MyDrawCreate",MyDrawCreate);
228 .ve
229 
230    Then, your solver can be chosen with the procedural interface via
231 $     PetscDrawSetType(ksp,"my_draw_type")
232    or at runtime via the option
233 $     -draw_type my_draw_type
234 
235    Concepts: graphics^registering new draw classes
236    Concepts: PetscDraw^registering new draw classes
237 
238 .seealso: PetscDrawRegisterAll(), PetscDrawRegisterDestroy()
239 @*/
240 PetscErrorCode  PetscDrawRegister(const char *sname,const char *name,PetscErrorCode (*function)(PetscDraw))
241 {
242   PetscErrorCode ierr;
243 
244   PetscFunctionBegin;
245   ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,&PetscDrawList,sname,name,(void (*)(void))function);CHKERRQ(ierr);
246   PetscFunctionReturn(0);
247 }
248 
249 #undef __FUNCT__
250 #define __FUNCT__ "PetscDrawSetFromOptions"
251 /*@
252    PetscDrawSetFromOptions - Sets the graphics type from the options database.
253       Defaults to a PETSc X windows graphics.
254 
255    Collective on PetscDraw
256 
257    Input Parameter:
258 .     draw - the graphics context
259 
260    Options Database Keys:
261 +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
262 .   -nox_warning - when X windows support is not installed this prevents the warning message
263                    from being printed
264 .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
265 .   -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file
266 .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
267 -   -draw_save_on_flush - saves an image on each flush in addition to each clear
268 
269    Level: intermediate
270 
271    Notes:
272     Must be called after PetscDrawCreate() before the PetscDrawtor is used.
273 
274     Concepts: drawing^setting options
275     Concepts: graphics^setting options
276 
277 .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave()
278 
279 @*/
280 PetscErrorCode  PetscDrawSetFromOptions(PetscDraw draw)
281 {
282   PetscErrorCode ierr;
283   PetscBool      flg,nox;
284   char           vtype[256];
285   const char     *def;
286   PetscReal      dpause;
287 #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
288   PetscBool      warn;
289 #endif
290 
291   PetscFunctionBegin;
292   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
293 
294   if (!PetscDrawList) {
295     ierr = PetscDrawRegisterAll();CHKERRQ(ierr);
296   }
297 
298   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
299   else {
300     ierr = PetscOptionsHasName(NULL,"-nox",&nox);CHKERRQ(ierr);
301     def  = PETSC_DRAW_NULL;
302 #if defined(PETSC_USE_WINDOWS_GRAPHICS)
303     if (!nox) def = PETSC_DRAW_WIN32;
304 #elif defined(PETSC_HAVE_X)
305     if (!nox) def = PETSC_DRAW_X;
306 #elif defined(PETSC_HAVE_GLUT)
307     if (!nox) def = PETSC_DRAW_GLUT;
308 #elif defined(PETSC_HAVE_OPENGLES)
309     if (!nox) def = PETSC_DRAW_OPENGLES;
310 #else
311     ierr = PetscOptionsHasName(NULL,"-nox_warning",&warn);CHKERRQ(ierr);
312     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n");
313 #endif
314   }
315   ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr);
316   ierr = PetscOptionsList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr);
317   if (flg) {
318     ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr);
319   } else if (!((PetscObject)draw)->type_name) {
320     ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr);
321   }
322   ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr);
323 #if defined(PETSC_HAVE_X)
324   {
325     char      filename[PETSC_MAX_PATH_LEN];
326     PetscBool save,movie = PETSC_FALSE;
327     ierr = PetscOptionsBool("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movie,&movie,NULL);CHKERRQ(ierr);
328     ierr = PetscOptionsString("-draw_save","Save graphics to file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr);
329     if (save) {
330       ierr = PetscDrawSetSave(draw,filename,movie);CHKERRQ(ierr);
331     }
332     ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file (X Windows only) on each flush","PetscDrawSetSave",draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr);
333   }
334 #endif
335   ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flg);CHKERRQ(ierr);
336   if (flg) draw->pause = dpause;
337 
338   /* process any options handlers added with PetscObjectAddOptionsHandler() */
339   ierr = PetscObjectProcessOptionsHandlers((PetscObject)draw);CHKERRQ(ierr);
340   ierr = PetscOptionsEnd();CHKERRQ(ierr);
341   PetscFunctionReturn(0);
342 }
343 
344 #undef __FUNCT__
345 #define __FUNCT__ "PetscDrawSetSave"
346 /*@C
347    PetscDrawSetSave - Saves images produced in a PetscDraw into a file as a Gif file using AfterImage
348 
349    Collective on PetscDraw
350 
351    Input Parameter:
352 +  draw      - the graphics context
353 .  filename  - name of the file, if NULL uses name of draw object
354 -  movie - produce a movie of all the images
355 
356    Options Database Command:
357 +  -draw_save  <filename>
358 -  -draw_save_movie
359 
360    Level: intermediate
361 
362    Concepts: X windows^graphics
363 
364    Notes: You should call this BEFORE calling PetscDrawClear() and creating your image.
365 
366    Requires that PETSc be configured with the option --with-afterimage to save the images and ffmpeg must be in your path to make the movie
367 
368    If X windows generates an error message about X_CreateWindow() failing then Afterimage was installed without X windows. Reinstall Afterimage using the
369    ./configure flags --x-includes=/pathtoXincludes --x-libraries=/pathtoXlibraries   For example under Mac OS X Mountain Lion --x-includes=/opt/X11/include -x-libraries=/opt/X11/lib
370 
371 
372 .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
373 @*/
374 PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char *filename,PetscBool movie)
375 {
376   PetscErrorCode ierr;
377 
378   PetscFunctionBegin;
379   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
380   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
381 
382   draw->savefilemovie = movie;
383   if (filename && filename[0]) {
384     ierr = PetscStrallocpy(filename,&draw->savefilename);CHKERRQ(ierr);
385   } else {
386     const char *name;
387     ierr = PetscObjectGetName((PetscObject)draw,&name);CHKERRQ(ierr);
388     ierr = PetscStrallocpy(name,&draw->savefilename);CHKERRQ(ierr);
389   }
390   if (draw->ops->setsave) {
391     ierr = (*draw->ops->setsave)(draw,filename);CHKERRQ(ierr);
392   }
393   PetscFunctionReturn(0);
394 }
395