ad5a8f9fbdb1f4af932b1387be8ab9621a89f9ac
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / internal / 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 #include <vector>
27
28 using namespace std;
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36 namespace Adaptor
37 {
38
39 namespace
40 {
41 struct Argument
42 {
43   const char * const opt;
44   const char * const optDescription;
45
46   void Print()
47   {
48     const ios_base::fmtflags flags = cout.flags();
49     cout << left << "  --";
50     cout.width( 18 );
51     cout << opt;
52     cout << optDescription;
53     cout << endl;
54     cout.flags( flags );
55   }
56 };
57
58 Argument EXPECTED_ARGS[] =
59 {
60   { "no-vsync",    "Disable VSync on Render" },
61   { "width",       "Stage Width"             },
62   { "height",      "Stage Height"            },
63   { "dpi",         "Emulated DPI"            },
64   { "view",        "Stereocopic 3D view mode ([0]=MONO, 1=STEREO_HORZ, 2=STEREO_VERT, 3=STEREO_INTERLACED)" },
65   { "stereo-base", "Distance in millimeters between left/right cameras [65.0]" },
66   { "help",        "Help"                    },
67   { NULL,          NULL                      }
68 };
69
70 enum Option
71 {
72   OPTION_NO_VSYNC = 0,
73   OPTION_STAGE_WIDTH,
74   OPTION_STAGE_HEIGHT,
75   OPTION_DPI,
76   OPTION_STEREO_MODE,
77   OPTION_STEREO_BASE,
78   OPTION_HELP
79 };
80
81 typedef vector< int > UnhandledContainer;
82
83 void ShowHelp()
84 {
85   cout << "Available options:" << endl;
86   Argument* arg = EXPECTED_ARGS;
87   while ( arg->opt )
88   {
89     arg->Print();
90     ++arg;
91   }
92 }
93
94 } // unnamed namespace
95
96 CommandLineOptions::CommandLineOptions(int *argc, char **argv[])
97 : noVSyncOnRender(0),
98   stageWidth(0), stageHeight(0),
99   viewMode(0),
100   stereoBase(65)
101 {
102   if ( *argc > 1 )
103   {
104     // We do not want to print out errors.
105     int origOptErrValue( opterr );
106     opterr = 0;
107
108     int help( 0 );
109
110     const struct option options[]=
111     {
112       { EXPECTED_ARGS[OPTION_NO_VSYNC].opt,     no_argument,       &noVSyncOnRender, 1   },  // "--no-vsync"
113       { EXPECTED_ARGS[OPTION_STAGE_WIDTH].opt,  required_argument, NULL,             'w' },  // "--width"
114       { EXPECTED_ARGS[OPTION_STAGE_HEIGHT].opt, required_argument, NULL,             'h' },  // "--height"
115       { EXPECTED_ARGS[OPTION_DPI].opt,          required_argument, NULL,             'd' },  // "--dpi"
116       { EXPECTED_ARGS[OPTION_STEREO_MODE].opt,  required_argument, NULL,             'v' },  // "--view"
117       { EXPECTED_ARGS[OPTION_STEREO_BASE].opt,  required_argument, NULL,             's' },  // "--stereo-base"
118       { EXPECTED_ARGS[OPTION_HELP].opt,         no_argument,       &help,            '?' },  // "--help"
119       { 0, 0, 0, 0 } // end of options
120     };
121
122     int shortOption( 0 );
123     int optionIndex( 0 );
124
125     const char* optString = "-w:h:d:v:s:"; // The '-' ensures that argv is NOT permuted
126     bool optionProcessed( false );
127
128     UnhandledContainer unhandledOptions; // We store indices of options we do not handle here
129
130     do
131     {
132       shortOption = getopt_long( *argc, *argv, optString, options, &optionIndex );
133
134       switch ( shortOption )
135       {
136         case 0:
137         {
138           // Check if we want help
139           if ( help )
140           {
141             ShowHelp();
142             optionProcessed = true;
143           }
144           break;
145         }
146
147         case 'w':
148         {
149           if ( optarg )
150           {
151             stageWidth = atoi( optarg );
152             optionProcessed = true;
153           }
154           break;
155         }
156
157         case 'h':
158         {
159           if ( optarg )
160           {
161             stageHeight = atoi( optarg );
162             optionProcessed = true;
163           }
164           break;
165         }
166
167         case 'd':
168         {
169           if ( optarg )
170           {
171             stageDPI.assign( optarg );
172             optionProcessed = true;
173           }
174           break;
175         }
176
177         case 'v':
178         {
179           if ( optarg )
180           {
181             viewMode = atoi(optarg);
182             optionProcessed = true;
183           }
184           break;
185         }
186
187         case 's':
188         {
189           if ( optarg )
190           {
191             stereoBase = atoi(optarg);
192             optionProcessed = true;
193           }
194           break;
195         }
196
197         case -1:
198         {
199           // All command-line options have been parsed.
200           break;
201         }
202
203         default:
204         {
205           unhandledOptions.push_back( optind - 1 );
206           break;
207         }
208       }
209     } while ( shortOption != -1 );
210
211     // Take out the options we have processed
212     if ( optionProcessed )
213     {
214       if ( !unhandledOptions.empty() )
215       {
216         int index( 1 );
217
218         // Overwrite the argv with the values from the unhandled indices
219         const UnhandledContainer::const_iterator endIter = unhandledOptions.end();
220         for ( UnhandledContainer::iterator iter = unhandledOptions.begin(); iter != endIter; ++iter )
221         {
222           (*argv)[ index++ ] = (*argv)[ *iter ];
223         }
224         *argc = unhandledOptions.size() + 1; // +1 for the program name
225       }
226       else
227       {
228         // There are no unhandled options, so we should just have the program name
229         *argc = 1;
230       }
231
232       optind = 1; // Reset to start
233     }
234
235     opterr = origOptErrValue; // Reset opterr value.
236   }
237 }
238
239 CommandLineOptions::~CommandLineOptions()
240 {
241 }
242
243 } // namespace Adaptor
244
245 } // namespace Internal
246
247 } // namespace Dali