1 /* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12 */
13
14
15 %{
16
17 #ifndef WIN32
18 #include <unistd.h>
19 #include <sys/wait.h>
20 #include <stdlib.h>
21 #include <fcntl.h>
22 #endif
23
24 #ifndef WIN32
25 #define SUPPORT_CPP 1
26 #endif
27
28 #include <stdio.h>
29 #include <fstream>
30 #include <string>
31
32 #include "FlexLexer.h"
33
34 #include <Producer/CameraConfig>
35
36
37 using namespace std;
38 using namespace Producer;
39
40 static void ConfigParser_error( const char * );
41 static CameraConfig *cfg = 0L;
42 static std::string fileName = "(stdin)";
43
44 static yyFlexLexer *flexer = 0L;
45
yylex()46 static int yylex()
47 {
48 if( flexer == 0L )
49 fprintf( stderr, "Internal error!\n" );
50 return flexer->yylex();
51 }
52
53 %}
54
55 %token PRTOKEN_VISUAL
56 %token PRTOKEN_SET_SIMPLE
57 %token PRTOKEN_VISUAL_ID
58 %token PRTOKEN_BUFFER_SIZE
59 %token PRTOKEN_LEVEL
60 %token PRTOKEN_RGBA
61 %token PRTOKEN_DOUBLEBUFFER
62 %token PRTOKEN_STEREO
63 %token PRTOKEN_AUX_BUFFERS
64 %token PRTOKEN_RED_SIZE
65 %token PRTOKEN_GREEN_SIZE
66 %token PRTOKEN_BLUE_SIZE
67 %token PRTOKEN_ALPHA_SIZE
68 %token PRTOKEN_DEPTH_SIZE
69 %token PRTOKEN_STENCIL_SIZE
70 %token PRTOKEN_ACCUM_RED_SIZE
71 %token PRTOKEN_ACCUM_GREEN_SIZE
72 %token PRTOKEN_ACCUM_BLUE_SIZE
73 %token PRTOKEN_ACCUM_ALPHA_SIZE
74 %token PRTOKEN_ACCUM_ALPHA_SIZE
75 %token PRTOKEN_SAMPLES
76 %token PRTOKEN_SAMPLE_BUFFERS
77 %token PRTOKEN_RENDER_SURFACE
78 %token PRTOKEN_WINDOW_RECT
79 %token PRTOKEN_INPUT_RECT
80 %token PRTOKEN_HOSTNAME
81 %token PRTOKEN_DISPLAY
82 %token PRTOKEN_SCREEN
83 %token PRTOKEN_BORDER
84 %token PRTOKEN_DRAWABLE_TYPE
85 %token PRTOKEN_WINDOW_TYPE
86 %token PRTOKEN_PBUFFER_TYPE
87 %token PRTOKEN_CAMERA_GROUP
88 %token PRTOKEN_CAMERA
89 %token PRTOKEN_PROJECTION_RECT
90 %token PRTOKEN_LENS
91 %token PRTOKEN_FRUSTUM
92 %token PRTOKEN_PERSPECTIVE
93 %token PRTOKEN_ORTHO
94 %token PRTOKEN_OFFSET
95 %token PRTOKEN_ROTATE
96 %token PRTOKEN_TRANSLATE
97 %token PRTOKEN_SCALE
98 %token PRTOKEN_SHEAR
99 %token PRTOKEN_CLEAR_COLOR
100 %token PRTOKEN_INPUT_AREA
101 %token PRTOKEN_ERROR
102 %token PRTOKEN_INTEGER
103 %token PRTOKEN_HEX_INTEGER
104 %token PRTOKEN_FLOAT
105 %token PRTOKEN_TRUE
106 %token PRTOKEN_FALSE
107 %token PRTOKEN_QUOTED_STRING
108 %token PRTOKEN_STEREO_SYSTEM_COMMANDS
109 %token PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE
110 %token PRTOKEN_METHOD
111 %token PRTOKEN_PREMULTIPLY
112 %token PRTOKEN_POSTMULTIPLY
113 %token PRTOKEN_OVERRIDE_REDIRECT
114 %token PRTOKEN_SHARELENS
115 %token PRTOKEN_SHAREVIEW
116 %token PRTOKEN_READ_DRAWABLE
117 %token PRTOKEN_SET_RTT_MODE
118 %token PRTOKEN_RTT_MODE_NONE
119 %token PRTOKEN_RTT_MODE_RGB
120 %token PRTOKEN_RTT_MODE_RGBA
121 %token PRTOKEN_THREAD_MODEL
122 %token PRTOKEN_SINGLE_THREADED
123 %token PRTOKEN_THREAD_PER_CAMERA
124 %token PRTOKEN_THREAD_PER_RENDER_SURFACE
125
126 %union {
127 char * string;
128 int integer;
129 float real;
130 bool boolean;
131 };
132
133 %type <string> name string;
134 %type <integer> intparam offset_multiply_method;
135 %type <integer> hex_integer;
136 %type <integer> drawableType rtt_mode;
137 %type <integer> threadModelDirective;
138 %type <real> floatparam;
139 %type <real> real;
140 %type <boolean> bool;
141
142 %%
143
144 config : entries
145 ;
146
147 entries : entry | entries entry
148 ;
149
150 entry : visual | render_surface | camera | input_area | camera_group | stereo_param | system_params
151 ;
152
153 system_params : system_param | system_params system_param
154 ;
155
156 system_param :
157 PRTOKEN_THREAD_MODEL threadModelDirective ';'
158 {
159 Producer::CameraGroup::ThreadModel tm = (Producer::CameraGroup::ThreadModel)$2;
160 cfg->setThreadModelDirective( tm );
161 }
162 ;
163
164 threadModelDirective:
165 PRTOKEN_SINGLE_THREADED { $$ = CameraGroup::SingleThreaded; }
166 | PRTOKEN_THREAD_PER_CAMERA { $$ = CameraGroup::ThreadPerCamera; }
167 | PRTOKEN_THREAD_PER_RENDER_SURFACE { $$ = CameraGroup::ThreadPerRenderSurface; }
168 ;
169
170 stereo_param : PRTOKEN_STEREO_SYSTEM_COMMANDS intparam string string ';'
171 {
172 cfg->addStereoSystemCommand( $2, $3, $4 );
173 };
174
175
176 camera_group: PRTOKEN_CAMERA_GROUP '{' camera_group_attributes '}'
177 ;
178
179 camera_group_attributes: cameras
180 ;
181
182 cameras : /* null */ | camera | cameras camera
183 ;
184
185 camera : PRTOKEN_CAMERA name
186 {
187 cfg->beginCamera( $2 );
188 }
189 '{' camera_attributes '}'
190 {
191 cfg->endCamera();
192 };
193
194 camera_attributes : camera_attribute | camera_attributes camera_attribute
195 ;
196
197 camera_attribute :
198 /* EMPTY */
199 | PRTOKEN_RENDER_SURFACE name ';'
200 {
201 cfg->setCameraRenderSurface( $2 );
202 }
203 | render_surface
204 {
205 cfg->setCameraRenderSurface();
206 }
207 | PRTOKEN_PROJECTION_RECT real real real real ';'
208 {
209 cfg->setCameraProjectionRectangle( $2, $3, $4, $5 );
210 }
211 | PRTOKEN_SHARELENS bool ';'
212 {
213 cfg->setCameraShareLens( $2 );
214 }
215 | PRTOKEN_SHAREVIEW bool ';'
216 {
217 cfg->setCameraShareView( $2 );
218 }
219 | PRTOKEN_CLEAR_COLOR real real real real ';'
220 {
221 cfg->setCameraClearColor( $2, $3, $4, $5 );
222 }
223 | lens
224 | camera_offset
225 ;
226
227 camera_offset : PRTOKEN_OFFSET '{'
228 {
229 cfg->beginCameraOffset();
230 }
231 camera_offset_attributes '}'
232 {
233 cfg->endCameraOffset();
234 }
235 ;
236
237 camera_offset_attributes : camera_offset_attribute | camera_offset_attributes camera_offset_attribute
238 ;
239
240 camera_offset_attribute :
241 PRTOKEN_SHEAR real real ';'
242 {
243 cfg->shearCameraOffset( $2, $3 );
244 }
245 | PRTOKEN_ROTATE real real real real ';'
246 {
247 cfg->rotateCameraOffset( $2, $3, $4, $5 );
248 }
249 | PRTOKEN_TRANSLATE real real real ';'
250 {
251 cfg->translateCameraOffset( $2, $3, $4 );
252 }
253 | PRTOKEN_SCALE real real real ';'
254 {
255 cfg->scaleCameraOffset( $2, $3, $4 );
256 }
257 | PRTOKEN_METHOD offset_multiply_method ';'
258 {
259 cfg->setCameraOffsetMultiplyMethod( (Producer::Camera::Offset::MultiplyMethod)$2 );
260 }
261 ;
262
263 offset_multiply_method:
264 PRTOKEN_PREMULTIPLY { $$ = Producer::Camera::Offset::PreMultiply; }
265 | PRTOKEN_POSTMULTIPLY { $$ = Producer::Camera::Offset::PostMultiply; }
266 ;
267
268 lens : PRTOKEN_LENS '{' lens_attributes '}'
269 ;
270
271 lens_attributes : lens_attribute | lens_attributes lens_attribute
272 ;
273
274 lens_attribute :
275 /* Empty */
276 | PRTOKEN_ORTHO real real real real real real ';'
277 {
278 cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7 );
279 }
280 | PRTOKEN_ORTHO real real real real real real real real ';'
281 {
282 cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7, $8, $9 );
283 }
284 | PRTOKEN_PERSPECTIVE real real real real ';'
285 {
286 cfg->setCameraPerspective( $2, $3, $4, $5 );
287 }
288 | PRTOKEN_PERSPECTIVE real real real real real real ';'
289 {
290 cfg->setCameraPerspective( $2, $3, $4, $5, $6, $7 );
291 }
292 | PRTOKEN_FRUSTUM real real real real real real ';'
293 {
294 cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7 );
295 }
296 | PRTOKEN_FRUSTUM real real real real real real real real ';'
297 {
298 cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7, $8, $9 );
299 }
300 | PRTOKEN_SHEAR real real ';'
301 {
302 cfg->setCameraLensShear( $2, $3 );
303 }
304 ;
305
306 render_surface : PRTOKEN_RENDER_SURFACE name
307 {
308 cfg->beginRenderSurface( $2 );
309 }
310 '{' render_surface_attributes '}'
311 {
312 cfg->endRenderSurface();
313 }
314 ;
315
316 render_surface_attributes :
317 render_surface_attribute
318 | render_surface_attributes render_surface_attribute
319 ;
320
321 render_surface_attribute :
322 /* Empty */
323 | PRTOKEN_VISUAL name ';'
324 {
325 cfg->setRenderSurfaceVisualChooser( $2 );
326 }
327 | visual
328 {
329 cfg->setRenderSurfaceVisualChooser();
330 }
331 | PRTOKEN_WINDOW_RECT intparam intparam intparam intparam ';'
332 {
333 cfg->setRenderSurfaceWindowRectangle( $2, $3, $4, $5 );
334 }
335 | PRTOKEN_INPUT_RECT floatparam floatparam floatparam floatparam ';'
336 {
337 cfg->setRenderSurfaceInputRectangle( $2, $3, $4, $5 );
338 }
339 | PRTOKEN_HOSTNAME name ';'
340 {
341 cfg->setRenderSurfaceHostName( std::string($2) );
342 }
343 | PRTOKEN_DISPLAY intparam ';'
344 {
345 cfg->setRenderSurfaceDisplayNum( $2 );
346 }
347 | PRTOKEN_SCREEN intparam ';'
348 {
349 cfg->setRenderSurfaceScreen( $2 );
350 }
351 | PRTOKEN_BORDER bool ';'
352 {
353 cfg->setRenderSurfaceBorder( $2 );
354 }
355 | PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE intparam intparam intparam intparam ';'
356 {
357 cfg->setRenderSurfaceCustomFullScreenRectangle( $2, $3, $4, $5 );
358 }
359 | PRTOKEN_OVERRIDE_REDIRECT bool ';'
360 {
361 cfg->setRenderSurfaceOverrideRedirect( $2 );
362 }
363 | PRTOKEN_DRAWABLE_TYPE drawableType ';'
364 {
365 Producer::RenderSurface::DrawableType drawableType = (RenderSurface::DrawableType)$2;
366 cfg->setRenderSurfaceDrawableType( drawableType );
367 }
368 | PRTOKEN_READ_DRAWABLE name ';'
369 {
370 cfg->setRenderSurfaceReadDrawable( $2 );
371 }
372 | PRTOKEN_SET_RTT_MODE rtt_mode ';'
373 {
374 cfg->setRenderSurfaceRenderToTextureMode( (Producer::RenderSurface::RenderToTextureMode)$2 );
375 }
376 ;
377
378 drawableType:
379 PRTOKEN_WINDOW_TYPE { $$ = RenderSurface::DrawableType_Window; }
380 | PRTOKEN_PBUFFER_TYPE { $$ = RenderSurface::DrawableType_PBuffer; }
381 ;
382
383 rtt_mode :
384 PRTOKEN_RTT_MODE_NONE { $$ = RenderSurface::RenderToTextureMode_None; }
385 | PRTOKEN_RTT_MODE_RGB { $$ = RenderSurface::RenderToRGBTexture; }
386 | PRTOKEN_RTT_MODE_RGBA { $$ = RenderSurface::RenderToRGBATexture; }
387 ;
388
389
390 visual : PRTOKEN_VISUAL name
391 {
392 cfg->beginVisual( $2 );
393 }
394 '{' visual_attributes '}'
395 {
396 cfg->endVisual();
397 }
398
399 | PRTOKEN_VISUAL
400 {
401 cfg->beginVisual();
402 }
403 '{' visual_attributes '}'
404 {
405 cfg->endVisual();
406 }
407 ;
408
409
410 visual_attributes : visual_attribute | visual_attributes ',' visual_attribute
411 ;
412 visual_attribute :
413 PRTOKEN_SET_SIMPLE
414 {
415 cfg->setVisualSimpleConfiguration();
416 }
417 | PRTOKEN_VISUAL_ID hex_integer
418 {
419 cfg->setVisualByID( $2 );
420 }
421
422 | PRTOKEN_BUFFER_SIZE intparam
423 {
424 cfg->addVisualAttribute( VisualChooser::BufferSize, $2 );
425 }
426 | PRTOKEN_LEVEL intparam
427 {
428 cfg->addVisualAttribute( VisualChooser::Level, $2 );
429 }
430
431 | PRTOKEN_RGBA
432 {
433 cfg->addVisualAttribute( VisualChooser::RGBA );
434 }
435 | PRTOKEN_DOUBLEBUFFER
436 {
437 cfg->addVisualAttribute( VisualChooser::DoubleBuffer );
438 }
439 | PRTOKEN_STEREO
440 {
441 cfg->addVisualAttribute( VisualChooser::Stereo );
442 }
443 | PRTOKEN_AUX_BUFFERS intparam
444 {
445 cfg->addVisualAttribute( VisualChooser::AuxBuffers, $2 );
446 }
447 | PRTOKEN_RED_SIZE intparam
448 {
449 cfg->addVisualAttribute( VisualChooser::RedSize, $2 );
450 }
451
452 | PRTOKEN_GREEN_SIZE intparam
453 {
454 cfg->addVisualAttribute( VisualChooser::GreenSize, $2 );
455 }
456
457 | PRTOKEN_BLUE_SIZE intparam
458 {
459 cfg->addVisualAttribute( VisualChooser::BlueSize, $2 );
460 }
461 | PRTOKEN_ALPHA_SIZE intparam
462 {
463 cfg->addVisualAttribute( VisualChooser::AlphaSize, $2 );
464 }
465 | PRTOKEN_DEPTH_SIZE intparam
466 {
467 cfg->addVisualAttribute( VisualChooser::DepthSize, $2 );
468 }
469 | PRTOKEN_STENCIL_SIZE intparam
470 {
471 cfg->addVisualAttribute( VisualChooser::StencilSize, $2 );
472 }
473 | PRTOKEN_ACCUM_RED_SIZE intparam
474 {
475 cfg->addVisualAttribute( VisualChooser::AccumRedSize, $2 );
476 }
477 | PRTOKEN_ACCUM_GREEN_SIZE intparam
478 {
479 cfg->addVisualAttribute( VisualChooser::AccumGreenSize, $2 );
480 }
481 | PRTOKEN_ACCUM_BLUE_SIZE intparam
482 {
483 cfg->addVisualAttribute( VisualChooser::AccumBlueSize, $2 );
484 }
485 | PRTOKEN_ACCUM_ALPHA_SIZE intparam
486 {
487 cfg->addVisualAttribute( VisualChooser::AccumAlphaSize, $2 );
488 }
489 | PRTOKEN_SAMPLES intparam
490 {
491 cfg->addVisualAttribute( VisualChooser::Samples, $2 );
492 }
493 | PRTOKEN_SAMPLE_BUFFERS
494 {
495 cfg->addVisualAttribute( VisualChooser::SampleBuffers );
496 }
497 | intparam intparam
498 {
499 cfg->addVisualExtendedAttribute( $1, $2 );
500 }
501 ;
502
503 input_area : PRTOKEN_INPUT_AREA
504 { cfg->beginInputArea(); }
505 '{' input_area_entries '}'
506 { cfg->endInputArea(); }
507 ;
508
509 input_area_entries : input_area_entry | input_area_entries input_area_entry
510 ;
511
512 input_area_entry :
513 PRTOKEN_RENDER_SURFACE name ';'
514 {
515 cfg->addInputAreaEntry( $2 );
516 }
517 ;
518
519 real : PRTOKEN_FLOAT
520 {
521 $$ = osg::asciiToFloat(flexer->YYText());
522 }
523 | PRTOKEN_INTEGER
524 {
525 $$ = osg::asciiToFloat(flexer->YYText());
526 }
527 ;
528
529
530 floatparam : PRTOKEN_FLOAT
531 {
532 $$ = osg::asciiToFloat(flexer->YYText());
533 }
534 ;
535
536 intparam : PRTOKEN_INTEGER
537 {
538 $$ = atoi( flexer->YYText() );
539 }
540 ;
541
542 name : PRTOKEN_QUOTED_STRING
543 {
544 $$ = strdup( flexer->YYText() );
545 }
546 ;
547
548 string : PRTOKEN_QUOTED_STRING
549 {
550 $$ = strdup( flexer->YYText() );
551 }
552 ;
553
554
555 hex_integer : PRTOKEN_HEX_INTEGER
556 {
557 int n;
558 sscanf( flexer->YYText(), "0x%x", &n );
559 $$ = n;
560 }
561 ;
562
563 bool : PRTOKEN_TRUE { $$ = true;} | PRTOKEN_FALSE { $$ = false; }
564 ;
565
566 %%
567
568 static void yyerror( const char *errmsg )
569 {
570 fprintf( stderr,
571 "CameraConfig::parseFile(\"%s\") : %s - Line %d at or before \"%s\"\n",
572 fileName.c_str(),
573 errmsg,
574 flexer->lineno(),
575 flexer->YYText() );
576 }
577
parseFile(const std::string & file)578 bool CameraConfig::parseFile( const std::string &file )
579 {
580 fileName.clear();
581
582 fileName = findFile(file);
583
584 if( fileName.empty() )
585 {
586 fprintf( stderr, "CameraConfig::parseFile() - Can't find file \"%s\".\n", file.c_str() );
587 return false;
588 }
589
590 bool retval = true;
591
592 #if defined (SUPPORT_CPP)
593
594 char *cpp_path =
595 #if defined(__APPLE__)
596 "/usr/bin/cpp";
597 #else
598 "/lib/cpp";
599 #endif
600
601 if( access( cpp_path, X_OK ) == 0 )
602 {
603
604 int pd[2];
605 pipe( pd );
606
607 flexer = new yyFlexLexer;
608 if( fork() == 0 )
609 {
610 // we don't want to read from the pipe in the child, so close it.
611 close( pd[0] );
612 close( 1 );
613 dup( pd[1] );
614
615
616 /* This was here to allow reading a config file from stdin.
617 * This has never been directly supported, so commenting out.
618 if( fileName.empty() )
619 execlp( cpp_path, "cpp", "-P", 0L );
620 else
621 */
622 execlp( cpp_path, "cpp", "-P", fileName.c_str(), 0L );
623
624 // This should not execute unless an error happens
625 perror( "execlp" );
626 }
627 else
628 {
629 close( pd[1]);
630 close( 0 );
631 dup( pd[0] );
632
633 cfg = this;
634
635 retval = ConfigParser_parse() == 0 ? true : false;
636
637 // Wait on child process to finish
638 int stat;
639 wait( &stat );
640 }
641 }
642 else
643 #endif
644 {
645 std::ifstream ifs(fileName.c_str());
646 flexer = new yyFlexLexer(&ifs);
647 cfg = this;
648 retval = ConfigParser_parse() == 0 ? true : false;
649 ifs.close();
650 delete flexer;
651 }
652 return retval;
653 }
654
655