1 /*
2  * Copyright (C) 1997-2005, R3vis Corporation.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18  *
19  * Original Contributor:
20  *   Wes Bethel, R3vis Corporation, Marin County, California
21  * Additional Contributor(s):
22  *
23  * The OpenRM project is located at http://openrm.sourceforge.net/.
24  */
25 /*
26  * $Id: rmdefs.h,v 1.13 2005/06/15 02:10:29 wes Exp $
27  * Version: $Name: OpenRM-1-6-0-2-RC2 $
28  * $Revision: 1.13 $
29  * $Log: rmdefs.h,v $
30  * Revision 1.13  2005/06/15 02:10:29  wes
31  * Added initial support for application-settable defaults. Apps
32  * will use rmSetEnum/rmGetEnum to set or get defaults that are RMenums.
33  * The first round of variables that can be set/get by apps are
34  * RMnode traversal masks assigned to new scene graph nodes by rmNodeNew.
35  *
36  * Revision 1.12  2005/05/16 01:07:57  wes
37  * Add RM_PIPE_NOPLATFORM definition
38  *
39  * Revision 1.11  2005/03/19 17:20:10  wes
40  * PS code merge.
41  *
42  * Revision 1.10  2005/02/27 19:32:55  wes
43  * Added support for application supplied texture object IDs and display lists.
44  *
45  * Revision 1.9  2005/02/19 16:47:24  wes
46  * Distro sync and consolidation.
47  *
48  * Revision 1.8  2005/01/23 17:17:34  wes
49  * Copyright update to 2005.
50  * Updates to support use of extensions: multitexturing on all platforms,
51  * 3d texturing (for volume rendering support) on Win32
52  *
53  * Revision 1.7  2004/03/10 01:48:50  wes
54  * Updated minor version to 1.5.2, added RM_INDEXED_QUAD_STRIP def.
55  *
56  * Revision 1.6  2004/02/23 03:04:29  wes
57  * New primitives: RM_QUAD_STRIP, RM_INDEXED_TRIANGLES, RM_INDEXED_QUADS,
58  * RM_INDEXED_TRIANGLE_STRIP.
59  *
60  * Revision 1.5  2004/01/17 04:05:41  wes
61  * Updated copyright line for 2004.
62  *
63  * Revision 1.4  2003/07/23 13:31:08  wes
64  * Moved unistd.h include - it doesn't exist on windoze.
65  *
66  * Revision 1.3  2003/07/20 14:55:18  wes
67  * Added unistd.h to avoid some compile warnings on Solaris.
68  *
69  * Revision 1.2  2003/02/02 02:07:14  wes
70  * Updated copyright to 2003.
71  *
72  * Revision 1.1.1.1  2003/01/28 02:15:23  wes
73  * Manual rebuild of rm150 repository.
74  *
75  * Revision 1.10  2003/01/27 05:04:27  wes
76  * Changes to RMpipe API and initialization sequence to unify GLX, WGL and CR
77  * platforms w/o too much disruption to existing apps.
78  *
79  * Revision 1.9  2003/01/16 22:21:15  wes
80  * Updated all source files to reflect new organization of header files:
81  * all header files formerly located in include/rmaux, include/rmi, include/rmv
82  * are now located in include/rm.
83  *
84  * Revision 1.8  2002/04/30 19:42:33  wes
85  * Updated copyright dates.
86  *
87  * Revision 1.7  2001/03/31 17:13:59  wes
88  * v1.4.0-alpha-2 checkin
89  *
90  * Revision 1.6  2000/12/03 23:20:22  wes
91  * Thread-safety mods.
92  *
93  * Revision 1.5  2000/08/28 01:33:37  wes
94  * Changed version number to RM_130.
95  *
96  * Revision 1.4  2000/05/17 14:30:36  wes
97  * Added RM_POLYS (thanks to Matt and Todd from VRCO).
98  *
99  * Revision 1.3  2000/04/20 17:41:46  wes
100  * Minor CVS tag changes.
101  *
102  * Revision 1.2  2000/04/20 16:30:23  wes
103  * Added copyright info.
104  *
105  * Revision 1.1.1.1  2000/02/28 21:29:40  wes
106  * OpenRM 1.2 Checkin
107  *
108  * Revision 1.1.1.1  2000/02/28 17:18:48  wes
109  * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
110  *
111  */
112 
113 #ifndef _rmdefs_h
114 #define _rmdefs_h
115 
116 #include <stdio.h>
117 #include <string.h>
118 #include <math.h>
119 #include <stdlib.h>
120 #include <limits.h>
121 
122 #ifdef RM_X
123 #include <unistd.h>
124 #include <X11/X.h>
125 #include <X11/Xlib.h>
126 #include <X11/Xatom.h>
127 #include <X11/Xutil.h>
128 #include <X11/keysym.h>
129 #endif
130 
131 
132 /* RM version */
133 #define RM_VERSION_MAJOR 1
134 #define RM_VERSION_MINOR 5
135 #define RM_VERSION_REV   2
136 
137 #ifdef __cplusplus
138 extern "C" {
139 #endif
140 
141 typedef enum
142 {
143     /* booleans */
144     RM_WHACKED          = -1,
145     RM_FALSE            = 0,
146     RM_TRUE             = 1,
147     RM_CHILL            = 1,
148     RM_MUTEX_UNLOCK     = 0,
149     RM_MUTEX_LOCK       = 1,
150     RM_MUTEX_BUSY       = 2,
151 
152     /* ragtag stuff */
153     RM_NATIVE_OPENGL    = 0x010,
154     RM_MESA_OPENGL      = 0x011,
155 
156     RM_HARDWARE         = 0x020,
157     RM_SOFTWARE         = 0x021,
158 
159     RM_OR               = 0x030,
160     RM_AND              = 0x031,
161     RM_SET              = 0x032,
162 
163     /* ps enumerators */
164     RM_PS_PORTRAIT      = 0x0100,
165     RM_PS_LANDSCAPE     = 0x0101,
166 
167     RM_PS_REGULAR       = 0x0102,
168     RM_PS_EPS           = 0x0103,
169 
170     RM_PS_VECTOR        = 0x0106,
171     RM_PS_RASTER        = 0x0107,
172 
173     RM_PS_SORT_FAST              = 0x0110, /* centroid sort - fastest and least memory consumption, may produce rendering errors.  */
174     RM_PS_SORT_BSP               = 0x0111, /* full scene BSP sort - slowest and largest memory consumption, no rendering issues. */
175     RM_PS_SORT_FULL              = 0x0111, /* synonym with RM_PS_SORT_BSP */
176     RM_PS_SORT_HYBRID_SCREEN_BSP = 0x0112, /* hybrid screen-space/object-space sort - has limitations, but is faster and requires less memory than SORT_FULL*/
177     RM_PS_SORT_HYBRID_DEPTH_BSP  = 0x0113, /* depth-layering hybrid BSP subdivisions. Faster and less memory use than SORT_FULL but more than HYBRID_SCREEN, ought to not have same rendering limitations as HYBRID_SCREEN. Not yet implemented 9/11/04. */
178 
179     /* scene parms: these typically won't be accessed directly by the application */
180     RM_SCENE_CAMERA3D              = 0x0121,
181     RM_SCENE_VIEWPORT              = 0x0122,
182     RM_SCENE_BACKGROUND_COLOR      = 0x0123,
183     RM_SCENE_CAMERA2D              = 0x0124,
184     RM_SCENE_BACKGROUND_IMAGE_TILE = 0x0125,
185 
186     RM_SCENE_CLIP_PLANE0 = 0x0126,
187     RM_SCENE_CLIP_PLANE1 = 0x0127,
188     RM_SCENE_CLIP_PLANE2 = 0x0128,
189     RM_SCENE_CLIP_PLANE3 = 0x0129,
190     RM_SCENE_CLIP_PLANE4 = 0x012A,
191     RM_SCENE_CLIP_PLANE5 = 0x012B,
192 
193     RM_SCENE_INV_PROJECTION   = 0x012C, /* private */
194 
195     RM_SCENE_TEXTURE2D        = 0x012D,
196     RM_SCENE_TEXTURE3D        = 0x012E,
197     RM_SCENE_TEXTURE3D_UPDATE = 0x012F,
198 
199     /* 3D point & surface prims */
200     RM_LINES               = 0x0140,
201     RM_LINE_STRIP          = 0x0141,
202     RM_TRIANGLES           = 0x0142,
203     RM_TRIANGLE_STRIP      = 0x0143,
204     RM_TRIANGLE_FAN        = 0x0144,
205     RM_QUADMESH            = 0x0145,
206     RM_POINTS              = 0x0146,
207     RM_POLYS               = 0x0147,
208     RM_QUAD_STRIP          = 0x0148,
209 
210     /* semi-procedural prims */
211     RM_SPHERES             = 0x0150,
212     RM_BOX3D               = 0x0151,
213     RM_BOX3D_WIRE          = 0x0152,
214     RM_CONES               = 0x0153,
215     RM_CYLINDERS           = 0x0154,
216 
217     /* volume prims */
218     RM_OCTMESH             = 0x0158,
219 
220     /* 2D-specific prims */
221     RM_TEXT                = 0x0160,
222     RM_INDEXED_TEXT        = 0x0161,
223     RM_QUADS               = 0x0162, /* this one can be 2D or 3D */
224     RM_MARKERS2D           = 0x0163,
225 
226     RM_CIRCLE2D            = 0x0164,
227     RM_BOX2D               = 0x0165,
228     RM_ELLIPSE2D           = 0x0166,
229 
230     RM_SPRITE              = 0x0167,
231     RM_BITMAP              = 0x0168,
232     RM_INDEXED_BITMAP      = 0x0169,
233 
234     /* indexed prims */
235     RM_INDEXED_TFAN        = 0x0170,
236     RM_INDEXED_QUADS       = 0x0171,
237     RM_INDEXED_TRIANGLES   = 0x0172,
238     RM_INDEXED_TRIANGLE_STRIP = 0x0173,
239     RM_INDEXED_QUAD_STRIP  = 0x0174,
240 
241     /* prim that uses an app-defined display list */
242     RM_APP_DISPLAYLIST     = 0x0175,
243 
244 
245     RM_USERDEFINED_PRIM    = 0x0180,
246 
247 
248     /* misc texture parameters */
249     RM_TEXTURE_WRAP_CLAMP            = 0x0210,
250     RM_TEXTURE_WRAP_REPEAT           = 0x0211,
251     RM_TEXTURE_FILTER_NEAREST        = 0x0212,
252     RM_TEXTURE_FILTER_LINEAR         = 0x0213,
253     RM_TEXTURE_FILTER_MIPMAP_NEAREST = 0x0214,
254     RM_TEXTURE_FILTER_MIPMAP_LINEAR  = 0x0215,
255 
256     /* rendering parms */
257     RM_SHADER_SMOOTH  		= 0x0220,
258     RM_SHADER_FLAT    		= 0x0221,
259     RM_SHADER_NOLIGHT 		= 0x0222,
260 
261     /* polygon face defs and render modes, corresponds to glPolygonMode() */
262     RM_FRONT            = 0x0230,
263     RM_BACK             = 0x0231,
264     RM_FRONT_AND_BACK   = 0x0232,
265     RM_POINT            = 0x0233,
266     RM_LINE             = 0x0234,
267     RM_FILL             = 0x0235,
268 
269     /* face culling modes */
270     RM_CULL_NONE            = 0x0240,
271     RM_CULL_FRONT           = 0x0241,
272     RM_CULL_BACK            = 0x0242,
273     RM_CULL_FRONT_AND_BACK  = 0x0243,
274 
275     /* define face orientation for culling and lighting */
276     RM_CCW              = 0x0250,
277     RM_CW               = 0x0251,
278 
279     /* transformation enumerators */
280     RM_TRANSFORM_GEOMETRY = 0x0260,
281     RM_TRANSFORM_TEXTURE  = 0x0261,
282     RM_TRANSFORM_IGNORE   = 0x0262,
283 
284     /* display format definitions */
285     RM_ALL_CHANNELS           = 0x0270,
286     RM_LEFT_CHANNEL           = 0x0271,
287     RM_RIGHT_CHANNEL          = 0x0272,
288 
289     RM_MONO_CHANNEL           = 0x0273,
290     RM_REDBLUE_STEREO_CHANNEL = 0x0274,
291     RM_BLUERED_STEREO_CHANNEL = 0x0275,
292     RM_MBUF_STEREO_CHANNEL    = 0x0276,
293 
294     RM_OFFSCREEN_MONO_CHANNEL      = 0x0277,
295     RM_OFFSCREEN_REDBLUE_STEREO_CHANNEL = 0x0278,
296     RM_OFFSCREEN_BLUERED_STEREO_CHANNEL = 0x0279,
297 
298     /* camera projection */
299     RM_PROJECTION_ORTHOGRAPHIC = 0x0301,
300     RM_PROJECTION_PERSPECTIVE  = 0x0302,
301 
302     /* light types */
303     RM_LIGHT_POINT        = 0x0310,
304     RM_LIGHT_DIRECTIONAL  = 0x0311,
305     RM_LIGHT_SPOT         = 0x0312,
306 
307     RM_LIGHT0             = 0x0320,
308     RM_LIGHT1             = 0x0321,
309     RM_LIGHT2             = 0x0322,
310     RM_LIGHT3             = 0x0323,
311     RM_LIGHT4             = 0x0324,
312     RM_LIGHT5             = 0x0325,
313     RM_LIGHT6             = 0x0326,
314     RM_LIGHT7             = 0x0327,
315 
316     /* image format enumerators */
317     RM_IMAGE_ALPHA           = 0x0401,
318 #if 0
319     RM_IMAGE_INDEXED_RGB     = 0x0402,
320     RM_IMAGE_INDEXED_RGBA    = 0x0403,
321 #endif
322     RM_IMAGE_LUMINANCE       = 0x0404,
323     RM_IMAGE_LUMINANCE_ALPHA = 0x0405,
324     RM_IMAGE_RGB             = 0x0406,
325     RM_IMAGE_RGBA            = 0x0407,
326     RM_IMAGE_DEPTH           = 0x0408,
327 
328     /* image type enums */
329     RM_UNSIGNED_BYTE         = 0x0409,
330     RM_FLOAT                 = 0x040A,
331     RM_SHORT                 = 0x040B,
332     RM_UNSIGNED_SHORT        = 0x040C,
333 
334     /* image mirroring enumerators */
335     RM_IMAGE_MIRROR_WIDTH    = 0x0410,
336     RM_IMAGE_MIRROR_HEIGHT   = 0x0411,
337     RM_IMAGE_MIRROR_DEPTH    = 0x0412,
338 
339     /* data copy flags */
340     RM_COPY_DATA         = 0x0420,
341     RM_DONT_COPY_DATA    = 0x0421,
342     RM_COPY_UNDEFINED    = 0x0422, /* an initial condition, used internally */
343 
344     /* line style enumerators */
345     RM_LINES_SOLID         = 0x0501,
346     RM_LINES_DASHED        = 0x0502,
347     RM_LINES_DOTTED        = 0x0503,
348     RM_LINES_DOT_DASH      = 0x0504,
349     RM_LINES_DASH_DASH_DOT = 0x0505,
350 
351     /* line width enumerators */
352     RM_LINEWIDTH_NARROW  = 0x0510,
353     RM_LINEWIDTH_MEDIUM  = 0x0511,
354     RM_LINEWIDTH_HEAVY   = 0x0512,
355 
356     RM_LINEWIDTH_1       = 0x0513,
357     RM_LINEWIDTH_2       = 0x0514,
358     RM_LINEWIDTH_3       = 0x0515,
359     RM_LINEWIDTH_4       = 0x0516,
360     RM_LINEWIDTH_5       = 0x0517,
361     RM_LINEWIDTH_6       = 0x0518,
362     RM_LINEWIDTH_7       = 0x0519,
363     RM_LINEWIDTH_8       = 0x051A,
364 
365     /* text justification modes */
366     RM_LEFT              = 0x0520,
367     RM_CENTER            = 0x0521, /* used for either horiz or vert, or both */
368     RM_RIGHT             = 0x0522,
369     RM_TOP               = 0x0523,
370     RM_BOTTOM            = 0x0524,
371 
372     RM_PRINT_TERSE       = 0x0520, /* for rmPrintSceneGraph */
373     RM_PRINT_VERBOSE     = 0x0521,
374 
375     /* multi-pass tag definitions */
376     RM_RENDERPASS_OPAQUE      = 0x0600,
377     RM_RENDERPASS_TRANSPARENT = 0x0601,
378     RM_RENDERPASS_3D          = 0x0602,
379     RM_RENDERPASS_2D          = 0x0603,
380     RM_RENDERPASS_ALL         = 0x0604,
381 
382     /* notification controls */
383     RM_NOTIFY_SILENCE         = 0x0610,
384     RM_NOTIFY_FULL            = 0x0611,
385 
386     /* multistage identification tokens */
387     RM_VIEW                   = 0x0620,
388     RM_RENDER                 = 0x0621,
389 
390     /* RMpipe processing mode tokens */
391     RM_PIPE_SERIAL            = 0x0630,
392     RM_PIPE_MULTISTAGE        = 0x0631,
393     RM_PIPE_MULTISTAGE_PARALLEL = 0x0632,
394     RM_PIPE_MULTISTAGE_VIEW_PARALLEL = 0x0633,
395     /* the following NBLOCK modes are not yet implemented. */
396     RM_PIPE_SERIAL_NOBLOCK    = 0x0634,
397     RM_PIPE_MULTISTAGE_NOBLOCK = 0x0635,
398     RM_PIPE_MULTISTAGE_PARALLEL_NOBLOCK = 0x0636,
399 
400     RM_PIPE_GLX               = 0x0650,
401     RM_PIPE_WGL               = 0x0651,
402     RM_PIPE_CR                = 0x0652,
403     RM_PIPE_NOPLATFORM        = 0x0653,
404 
405     /* named default values that can be set/get by applications */
406     RM_DEFAULT_NODE_PICK_TRAVERSAL_MASK    = 0x0700,
407     RM_DEFAULT_NODE_TRAVERSAL_MASK         = 0x0701
408 
409 } RMenum;
410 
411 #ifdef __cplusplus
412 }
413 #endif
414 
415 
416 /* numerical constants */
417 #define RM_PI		3.1415926535897931
418 #define RM_TWO_PI	6.2831853071795862
419 
420 #define	RM_SQRT2	1.4142135623730951
421 #define	RM_SQRT1_2	0.7071067811865476
422 
423 #define RM_MAXFLOAT 	1.0e+20F
424 #define RM_MINFLOAT 	-1.0e+20F
425 
426 /* constants and limits */
427 #define RM_MAX_STRING_LENGTH 		64
428 
429 #define RM_SINGLEBUFFERED 		0
430 #define RM_DOUBLEBUFFERED 		1
431 
432 #define RM_MAX_MIPMAPS   		16
433 #define RM_MAX_LIGHTS  			8
434 #define RM_MAX_MULTITEXTURES            8 /* 8 multitextures, 1 regular */
435 
436 #define RM_FEEDBACK_MIN_BUFFER_SIZE	65536 /* for picking */
437 
438 /* macros */
439 #define RM_MIN(a,b) 		 ((a) < (b) ? (a) : (b))
440 #define RM_MAX(a,b) 		 ((a) > (b) ? (a) : (b))
441 
442 #define RM_DEGREES_TO_RADIANS(a) ((a)*0.017453292)
443 #define RM_RADIANS_TO_DEGREES(a) ((a) * 57.29577951)
444 
445 /* font definitions
446  *
447  * Serif font -> Adobe Times
448  * Sans Serif font -> Adobe Helvetica
449  * Mono Font -> Adobe Courier
450  * Symbol Font -> Adobe Symbol Roman
451  *
452  *
453  * in an integer, we use the following bits for the following things:
454  *
455  * bit number   6     5      4     3       2    1    0
456  *            font family   bold  italic   --size enum--
457  *
458  * the two bits of "font family" are used to create an index into a table
459  * of font family names. there is one such table used in X and another
460  * table used in Postscript.
461  *
462  * boolean values are used for "bold" and "italic". some font families,
463  * like "symbol", don't support these faces.
464  *
465  * three bits are used for sizing information. again, these are indices
466  * into a table of ints which are real live point sizes.  this table should
467  * eventually be built at run time from the list of available fonts
468  * on the server.  for now, it's hard coded.
469  */
470 
471 #define RM_NUM_FONT_FACES	5
472 
473 #define RM_FONT_SERIF		0
474 #define RM_FONT_SANS		1
475 #define RM_FONT_MONO		2
476 #define RM_FONT_SYMBOL		3
477 #define RM_FONT_DINGBATS	4
478 
479 #define RM_NUM_FONT_SIZES	7
480 
481 #define RM_FONT_XXS		0
482 #define RM_FONT_XS		1
483 #define RM_FONT_S		2
484 #define RM_FONT_M		3
485 #define RM_FONT_L		4
486 #define RM_FONT_XL		5
487 #define RM_FONT_XXL		6
488 
489 /* plain + bold + italic + bold&italic */
490 #define RM_NUM_FONT_STYLES	4
491 
492 /* stuff for line styles */
493 #define RM_MAX_LINESTYLES	5
494 #define RM_MAX_LINEWEIGHTS	8
495 
496 /*
497  * definitions for predefined procedural models. these include
498  * model selection flags for spheres, cones and cylinders.
499  *
500  * use a particular model flag enumerator with
501  * rmPrimitiveSetModelFlag() to control which of the prebuilt
502  * models is used when your primitive is rendered. the goal is
503  * to provide applications a mechanism to select from one of
504  * several different resolution models.
505  *
506  * Note to RMSG developers: changes to any of these groups will
507  * necessitate corresponding changes in $RMSG/rm/rmqdrix.c.
508  */
509 
510 /*
511  * sphere model flags
512  */
513 #define RM_SPHERES_8     1	/* an octahedron */
514 #define RM_SPHERES_32    2	/* 32 faces - this is the default  */
515 #define RM_SPHERES_128   3	/* 128 faces */
516 #define RM_SPHERES_512   4	/* 512 faces */
517 
518 /*
519  * cones - some definitions for cones of varying resolutions. these
520  * values indicate the number of subdivisions along the radial axis
521  * of the cone.
522  */
523 #define RM_CONES_4	4	/* 4-sided cone */
524 #define RM_CONES_8	8	/* 8 sides */
525 #define RM_CONES_12	12	/* etc. */
526 #define RM_CONES_16	16	/* 16 sides (the default) */
527 #define RM_CONES_32	32
528 #define RM_CONES_64	64
529 #define RM_CONES_128	128
530 
531 /*
532  * cylinders - same as cones.
533  */
534 #define RM_CYLINDERS_4		4	/* 4-sided cylinder */
535 #define RM_CYLINDERS_8		8	/* etc. */
536 #define RM_CYLINDERS_12		12
537 #define RM_CYLINDERS_16		16 /* 16 sides (the default) */
538 #define RM_CYLINDERS_32		32
539 #define RM_CYLINDERS_64		64
540 #define RM_CYLINDERS_128	128
541 
542 /*
543  * octmesh model flags. these are "divide by" constants. when the
544  * octmesh is rendered, RM figures out how many slices of volume
545  * should be rendered as a function of maximum grid resolution.
546  * then, this value is reduced through division by one of these
547  * constants. the tradeoff is speed vs. resolution.
548  */
549 #define RM_OCTMESH_1	0x0001	/* (the default) */
550 #define RM_OCTMESH_2	0x0002
551 #define RM_OCTMESH_4	0x0004
552 #define RM_OCTMESH_8	0x0008
553 #define RM_OCTMESH_16	0x0010
554 
555 #define RM_OCTMESH_DIVISOR_MASK 0x001F
556 
557 /* use 2d textures for rendering octmeshes */
558 #define RM_OCTMESH_2DTEXTURES_MIN_MEMORY              0x0040
559 #define RM_OCTMESH_2DTEXTURES_MAX_PERFORMANCE         0x0080
560 /* #define RM_OCTMESH_2DTEXTURES_IBRAVR       0x0100 */ /* 1/17/05, to do later */
561 #endif /* _rmdefs_h */
562 /* EOF */
563