Merge "Redesigning render sync to handle reduced frequency" into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / common / command-line-options.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "command-line-options.h"
20
21 // EXTERNAL INCLUDES
22 #include <getopt.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <iostream>
26
27 #include <dali/public-api/common/vector-wrapper.h>
28
29 using namespace std;
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace Adaptor
38 {
39
40 namespace
41 {
42 struct Argument
43 {
44   const char * const opt;
45   const char * const optDescription;
46
47   void Print()
48   {
49     const ios_base::fmtflags flags = cout.flags();
50     cout << left << "  --";
51     cout.width( 18 );
52     cout << opt;
53     cout << optDescription;
54     cout << endl;
55     cout.flags( flags );
56   }
57 };
58
59 Argument EXPECTED_ARGS[] =
60 {
61   { "no-vsync",    "Disable VSync on Render" },
62   { "width",       "Stage Width"             },
63   { "height",      "Stage Height"            },
64   { "dpi",         "Emulated DPI"            },
65   { "view",        "Stereocopic 3D view mode ([0]=MONO, 1=STEREO_HORZ, 2=STEREO_VERT, 3=STEREO_INTERLACED)" },
66   { "stereo-base", "Distance in millimeters between left/right cameras [65.0]" },
67   { "help",        "Help"                    },
68   { NULL,          NULL                      }
69 };
70
71 enum Option
72 {
73   OPTION_NO_VSYNC = 0,
74   OPTION_STAGE_WIDTH,
75   OPTION_STAGE_HEIGHT,
76   OPTION_DPI,
77   OPTION_STEREO_MODE,
78   OPTION_STEREO_BASE,
79   OPTION_HELP
80 };
81
82 typedef vector< int > UnhandledContainer;
83
84 void ShowHelp()
85 {
86   cout << "Available options:" << endl;
87   Argument* arg = EXPECTED_ARGS;
88   while ( arg->opt )
89   {
90     arg->Print();
91     ++arg;
92   }
93 }
94
95 } // unnamed namespace
96
97 CommandLineOptions::CommandLineOptions(int *argc, char **argv[])
98 : noVSyncOnRender(0),
99   stageWidth(0), stageHeight(0),
100   viewMode(0),
101   stereoBase(65)
102 {
103   // Exit gracefully if no arguments provided
104   if ( !argc || !argv )
105   {
106     return;
107   }
108
109   if ( *argc > 1 )
110   {
111     // We do not want to print out errors.
112     int origOptErrValue( opterr );
113     opterr = 0;
114
115     int help( 0 );
116
117     const struct option options[]=
118     {
119       { EXPECTED_ARGS[OPTION_NO_VSYNC].opt,     no_argument,       &noVSyncOnRender, 1   },  // "--no-vsync"
120       { EXPECTED_ARGS[OPTION_STAGE_WIDTH].opt,  required_argument, NULL,             'w' },  // "--width"
121       { EXPECTED_ARGS[OPTION_STAGE_HEIGHT].opt, required_argument, NULL,             'h' },  // "--height"
122       { EXPECTED_ARGS[OPTION_DPI].opt,          required_argument, NULL,             'd' },  // "--dpi"
123       { EXPECTED_ARGS[OPTION_STEREO_MODE].opt,  required_argument, NULL,             'v' },  // "--view"
124       { EXPECTED_ARGS[OPTION_STEREO_BASE].opt,  required_argument, NULL,             's' },  // "--stereo-base"
125       { EXPECTED_ARGS[OPTION_HELP].opt,         no_argument,       &help,            '?' },  // "--help"
126       { 0, 0, 0, 0 } // end of options
127     };
128
129     int shortOption( 0 );
130     int optionIndex( 0 );
131
132     const char* optString = "-w:h:d:v:s:"; // The '-' ensures that argv is NOT permuted
133     bool optionProcessed( false );
134
135     UnhandledContainer unhandledOptions; // We store indices of options we do not handle here
136
137     do
138     {
139       shortOption = getopt_long( *argc, *argv, optString, options, &optionIndex );
140
141       switch ( shortOption )
142       {
143         case 0:
144         {
145           // Check if we want help
146           if ( help )
147           {
148             ShowHelp();
149             optionProcessed = true;
150           }
151           break;
152         }
153
154         case 'w':
155         {
156           if ( optarg )
157           {
158             stageWidth = atoi( optarg );
159             optionProcessed = true;
160           }
161           break;
162         }
163
164         case 'h':
165         {
166           if ( optarg )
167           {
168             stageHeight = atoi( optarg );
169             optionProcessed = true;
170           }
171           break;
172         }
173
174         case 'd':
175         {
176           if ( optarg )
177           {
178             stageDPI.assign( optarg );
179             optionProcessed = true;
180           }
181           break;
182         }
183
184         case 'v':
185         {
186           if ( optarg )
187           {
188             viewMode = atoi(optarg);
189             optionProcessed = true;
190           }
191           break;
192         }
193
194         case 's':
195         {
196           if ( optarg )
197           {
198             stereoBase = atoi(optarg);
199             optionProcessed = true;
200           }
201           break;
202         }
203
204         case -1:
205         {
206           // All command-line options have been parsed.
207           break;
208         }
209
210         default:
211         {
212           unhandledOptions.push_back( optind - 1 );
213           break;
214         }
215       }
216     } while ( shortOption != -1 );
217
218     // Take out the options we have processed
219     if ( optionProcessed )
220     {
221       if ( !unhandledOptions.empty() )
222       {
223         int index( 1 );
224
225         // Overwrite the argv with the values from the unhandled indices
226         const UnhandledContainer::const_iterator endIter = unhandledOptions.end();
227         for ( UnhandledContainer::iterator iter = unhandledOptions.begin(); iter != endIter; ++iter )
228         {
229           (*argv)[ index++ ] = (*argv)[ *iter ];
230         }
231         *argc = unhandledOptions.size() + 1; // +1 for the program name
232       }
233       else
234       {
235         // There are no unhandled options, so we should just have the program name
236         *argc = 1;
237       }
238
239       optind = 1; // Reset to start
240     }
241
242     opterr = origOptErrValue; // Reset opterr value.
243   }
244 }
245
246 CommandLineOptions::~CommandLineOptions()
247 {
248 }
249
250 } // namespace Adaptor
251
252 } // namespace Internal
253
254 } // namespace Dali