static int get_audiosup( void )
{
  uint8_t sample_rates[] = {32, 44, 48, 88, 96, 176, 192};
  uint8_t sample_sizes[] = {16, 20, 24};
  const char *formats[] = {"Reserved", "PCM", "AC3", "MPEG1", "MP3", "MPEG2", "AAC", "DTS", "ATRAC", "DSD", "EAC3", "DTS_HD", "MLP", "DST", "WMAPRO", "Extended"};
  int i, j, k;
  for (k=EDID_AudioFormat_ePCM; k<EDID_AudioFormat_eMaxCount; k++) {
    int num_channels = 0, max_sample_rate = 0, max_sample_size = 0;
    for (i=1; i<=8; i++) {
      if (vc_tv_hdmi_audio_supported(k, i, EDID_AudioSampleRate_e44KHz, EDID_AudioSampleSize_16bit ) == 0)
        num_channels = i;
    }
    for (i=0, j=EDID_AudioSampleRate_e32KHz; j<=EDID_AudioSampleRate_e192KHz; i++, j<<=1) {
      if (vc_tv_hdmi_audio_supported(k, 1, j, EDID_AudioSampleSize_16bit ) == 0)
        max_sample_rate = i;
    }
    if (k==EDID_AudioFormat_ePCM) {
      for (i=0, j=EDID_AudioSampleSize_16bit; j<=EDID_AudioSampleSize_24bit; i++, j<<=1) {
        if (vc_tv_hdmi_audio_supported(k, 1, EDID_AudioSampleRate_e44KHz, j ) == 0)
          max_sample_size = i;
      }
      if (num_channels>0)
        LOG_STD("%8s supported: Max channels: %d, Max samplerate:%4dkHz, Max samplesize %2d bits.", formats[k], num_channels, sample_rates[max_sample_rate], sample_sizes[max_sample_size]);
    } else {
      for (i=0; i<256; i++) {
        if (vc_tv_hdmi_audio_supported(k, 1, EDID_AudioSampleRate_e44KHz, i ) == 0)
          max_sample_size = i;
      }
      if (num_channels>0)
        LOG_STD("%8s supported: Max channels: %d, Max samplerate:%4dkHz, Max rate %4d kb/s.", formats[k], num_channels, sample_rates[max_sample_rate], 8*max_sample_size);
    }
  }
  return 0;
}
static int dump_edid( const char *filename )
{
   uint8_t buffer[128];
   size_t written = 0, offset = 0;
   int i, extensions = 0;
   FILE *fp = NULL;
   int siz = vc_tv_hdmi_ddc_read(offset, sizeof (buffer), buffer);
   offset += sizeof( buffer);
   /* First block always exist */
   if (siz == sizeof(buffer) && (fp = fopen(filename, "wb")) != NULL) {
      written += fwrite(buffer, 1, sizeof buffer, fp);
      extensions = buffer[0x7e]; /* This tells you how many more blocks to read */
      for(i = 0; i < extensions; i++, offset += sizeof( buffer)) {
         siz = vc_tv_hdmi_ddc_read(offset, sizeof( buffer), buffer);
         if(siz == sizeof(buffer)) {
            written += fwrite(buffer, 1, sizeof (buffer), fp);
         } else {
            break;
         }
      }
   } 
   if (fp)
      fclose(fp);
   if(written) {
      LOG_STD( "Written %d bytes to %s", written, filename);
   } else {
      LOG_STD( "Nothing written!");
   }
   return written < sizeof(buffer);
}
예제 #3
0
static int get_status( void )
{
   TV_DISPLAY_STATE_T tvstate;
   if( vc_tv_get_display_state( &tvstate ) == 0) {
      //The width/height parameters are in the same position in the union
      //for HDMI and SDTV
      HDMI_PROPERTY_PARAM_T property;
      property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
      vc_tv_hdmi_get_property(&property);
      float frame_rate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tvstate.display.hdmi.frame_rate * (1000.0f/1001.0f) : tvstate.display.hdmi.frame_rate;

      if(tvstate.display.hdmi.width && tvstate.display.hdmi.height) {
         LOG_STD( "state 0x%x [%s], %ux%u @ %.2fHz, %s", tvstate.state,
                  status_mode(&tvstate),
                  tvstate.display.hdmi.width, tvstate.display.hdmi.height,
                  frame_rate,
                  tvstate.display.hdmi.scan_mode ? "interlaced" : "progressive" );
      } else {
         LOG_STD( "state 0x%x [%s]", tvstate.state, status_mode(&tvstate));
      }
   } else {
      LOG_STD( "Error getting current display state");
   }
  return 0;
}
static void control_c( int signum )
{
    (void)signum;

    LOG_STD( "Shutting down..." );

    vcos_event_signal( &quit_event );
}
예제 #5
0
static int get_modes( HDMI_RES_GROUP_T group)
{
   static TV_SUPPORTED_MODE_T supported_modes[MAX_MODE_ID] = {{0}};
   HDMI_RES_GROUP_T preferred_group;
   uint32_t preferred_mode;
   int num_modes;
   int i;

   vcos_assert(( group == HDMI_RES_GROUP_CEA ) ||
               ( group == HDMI_RES_GROUP_DMT ));

   num_modes = vc_tv_hdmi_get_supported_modes( group, supported_modes,
                                               vcos_countof(supported_modes),
                                               &preferred_group,
                                               &preferred_mode );
   if ( num_modes < 0 )
   {
      LOG_ERR( "Failed to get modes" );
      return -1;
   }

   LOG_STD( "Group %s has %u modes:",
            HDMI_RES_GROUP_NAME(group), num_modes );
   for ( i = 0; i < num_modes; i++ )
   {
      char p[8] = {0};
      if( supported_modes[i].pixel_rep )
         snprintf(p, sizeof(p)-1, "x%d ", supported_modes[i].pixel_rep);
      else
         snprintf(p, sizeof(p)-1, " ");

      LOG_STD( "%s mode %u: %ux%u @ %uHz %s, clock:%luMHz %s%s %s",
               supported_modes[i].native ? "  (native)" : "          ",
               supported_modes[i].code, supported_modes[i].width,
               supported_modes[i].height, supported_modes[i].frame_rate,
               aspect_ratio_str(supported_modes[i].aspect_ratio),
               supported_modes[i].pixel_freq / 1000000UL, p,
               supported_modes[i].scan_mode ? "interlaced" : "progressive",
               supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask) : "");
   }

   return 0;
}
static int get_status( void )
{
   TV_DISPLAY_STATE_T tvstate;
   if( vc_tv_get_display_state( &tvstate ) == 0) {
      //The width/height parameters are in the same position in the union
      //for HDMI and SDTV
      if(tvstate.display.hdmi.width && tvstate.display.hdmi.height) {
         LOG_STD( "state 0x%x [%s], %ux%u @ %uHz, %s", tvstate.state,
                  status_mode(&tvstate),
                  tvstate.display.hdmi.width, tvstate.display.hdmi.height,
                  tvstate.display.hdmi.frame_rate,
                  tvstate.display.hdmi.scan_mode ? "interlaced" : "progressive" );
      } else {
         LOG_STD( "state 0x%x [%s]", tvstate.state, status_mode(&tvstate));
      }
   } else {
      LOG_STD( "Error getting current display state");
   }
  return 0;
}
static int power_off( void )
{
   int ret;

   LOG_STD( "Powering off HDMI");

   ret = vc_tv_power_off();
   if ( ret != 0 )
   {
      LOG_ERR( "Failed to power off HDMI" );
   }

   return ret;
}
static int power_on_preferred( void )
{
   int ret;

   LOG_STD( "Powering on HDMI with preferred settings" );

   ret = vc_tv_hdmi_power_on_preferred();
   if ( ret != 0 )
   {
      LOG_ERR( "Failed to power on HDMI with preferred settings" );
   }

   return ret;
}
static int set_property(HDMI_PROPERTY_T prop, uint32_t param1, uint32_t param2)
{
   int ret;
   HDMI_PROPERTY_PARAM_T property;
   property.property = prop;
   property.param1 = param1;
   property.param2 = param2;
   LOG_STD( "Setting property %d with params %d, %d", prop, param1, param2);
   ret = vc_tv_hdmi_set_property(&property);
   if(ret != 0)
   {
      LOG_ERR( "Failed to set property %d", prop);
   }
   return ret;
}
static int power_on_explicit( HDMI_RES_GROUP_T group,
                              uint32_t mode, uint32_t drive )
{
   int ret;

   LOG_STD( "Powering on HDMI with explicit settings (%s mode %u)",
            group == HDMI_RES_GROUP_CEA ? "CEA" : group == HDMI_RES_GROUP_DMT ? "DMT" : "CUSTOM", mode );

   ret = vc_tv_hdmi_power_on_explicit( drive, group, mode );
   if ( ret != 0 )
   {
      LOG_ERR( "Failed to power on HDMI with explicit settings (%s mode %u)",
               group == HDMI_RES_GROUP_CEA ? "CEA" : group == HDMI_RES_GROUP_DMT ? "DMT" : "CUSTOM", mode );
   }

   return ret;
}
static int power_on_sdtv( SDTV_MODE_T mode,
                              SDTV_ASPECT_T aspect )
{
   int ret;
   SDTV_OPTIONS_T options;
   memset(&options, 0, sizeof options);
   options.aspect = aspect;
   LOG_STD( "Powering on SDTV with explicit settings (mode:%d aspect:%d)",
            mode, aspect );

   ret = vc_tv_sdtv_power_on(mode, &options);
   if ( ret != 0 )
   {
      LOG_ERR( "Failed to power on SDTV with explicit settings (mode:%d aspect:%d)",
               mode, aspect );
   }

   return ret;
}
int main( int argc, char **argv )
{
   int32_t ret;
   char optstring[OPTSTRING_LEN];
   int  opt;
   int  opt_preferred = 0;
   int  opt_explicit = 0;
   int  opt_sdtvon = 0;
   int  opt_off = 0;
   int  opt_modes = 0;
   int  opt_monitor = 0;
   int  opt_status = 0;
   int  opt_audiosup = 0;
   int  opt_dumpedid = 0;
   int  opt_showinfo = 0;
   int  opt_3d = 0;
   int  opt_json = 0;
   int  opt_name = 0;

   char *dumpedid_filename = NULL;
   VCHI_INSTANCE_T    vchi_instance;
   VCHI_CONNECTION_T *vchi_connection;
   HDMI_RES_GROUP_T power_on_explicit_group = HDMI_RES_GROUP_INVALID;
   uint32_t         power_on_explicit_mode;
   uint32_t         power_on_explicit_drive = HDMI_MODE_HDMI;
   HDMI_RES_GROUP_T get_modes_group = HDMI_RES_GROUP_INVALID;
   SDTV_MODE_T sdtvon_mode;
   SDTV_ASPECT_T sdtvon_aspect;

   // Initialize VCOS
   vcos_init();

   // Create the option string that we will be using to parse the arguments
   create_optstring( optstring );

   // Parse the command line arguments
   while (( opt = getopt_long_only( argc, argv, optstring, long_opts,
                                    NULL )) != -1 )
   {
      switch ( opt )
      {
         case 0:
         {
            // getopt_long returns 0 for entries where flag is non-NULL
            break;
         }
         case OPT_PREFERRED:
         {
            opt_preferred = 1;
            break;
         }
         case OPT_EXPLICIT:
         {
            char group_str[32], drive_str[32];

            /* coverity[secure_coding] String length specified, so can't overflow */
            int s = sscanf( optarg, "%31s %u %31s", group_str, &power_on_explicit_mode, drive_str );
            if ( s != 2 && s != 3 )
            {
               LOG_ERR( "Invalid arguments '%s'", optarg );
               goto err_out;
            }

            // Check the group first
            if ( vcos_strcasecmp( "CEA", group_str ) == 0 )
            {
               power_on_explicit_group = HDMI_RES_GROUP_CEA;
            }
            else if ( vcos_strcasecmp( "DMT", group_str ) == 0 )
            {
               power_on_explicit_group = HDMI_RES_GROUP_DMT;
            }
            else if ( vcos_strcasecmp( "CEA_3D", group_str ) == 0  ||
                      vcos_strcasecmp( "CEA_3D_SBS", group_str ) == 0)
            {
               power_on_explicit_group = HDMI_RES_GROUP_CEA;
               opt_3d = 1;
            }
            else if ( vcos_strcasecmp( "CEA_3D_TB", group_str ) == 0 )
            {
               power_on_explicit_group = HDMI_RES_GROUP_CEA;
               opt_3d = 2;
            }
            else
            {
               LOG_ERR( "Invalid group '%s'", group_str );
               goto err_out;
            }
            if (s==3)
            {
               if (vcos_strcasecmp( "HDMI", drive_str ) == 0 )
               {
                  power_on_explicit_drive = HDMI_MODE_HDMI;
               }
               else if (vcos_strcasecmp( "DVI", drive_str ) == 0 )
               {
                  power_on_explicit_drive = HDMI_MODE_DVI;
               }
               else
               {
                  LOG_ERR( "Invalid drive '%s'", drive_str );
                  goto err_out;
               }
            }
            // Then check if mode is a sane number
            if ( power_on_explicit_mode > MAX_MODE_ID )
            {
               LOG_ERR( "Invalid mode '%u'", power_on_explicit_mode );
               goto err_out;
            }

            opt_explicit = 1;
            break;
         }
         case OPT_SDTVON:
         {
            char mode_str[32], aspect_str[32];

            if ( sscanf( optarg, "%s %s", mode_str,
                         aspect_str ) != 2 )
            {
               LOG_ERR( "Invalid arguments '%s'", optarg );
               goto err_out;
            }

            // Check the group first
            if ( vcos_strcasecmp( "NTSC", mode_str ) == 0 )
            {
               sdtvon_mode = SDTV_MODE_NTSC;
            }
            else if ( vcos_strcasecmp( "NTSC_J", mode_str ) == 0 )
            {
               sdtvon_mode = SDTV_MODE_NTSC_J;
            }
            else if ( vcos_strcasecmp( "PAL", mode_str ) == 0 )
            {
               sdtvon_mode = SDTV_MODE_PAL;
            }
            else if ( vcos_strcasecmp( "PAL_M", mode_str ) == 0 )
            {
               sdtvon_mode = SDTV_MODE_PAL_M;
            }
            else
            {
               LOG_ERR( "Invalid mode '%s'", mode_str );
               goto err_out;
            }

            if ( vcos_strcasecmp( "4:3", aspect_str ) == 0 )
            {
               sdtvon_aspect = SDTV_ASPECT_4_3;
            }
            else if ( vcos_strcasecmp( "14:9", aspect_str ) == 0 )
            {
               sdtvon_aspect = SDTV_ASPECT_14_9;
            }
            else if ( vcos_strcasecmp( "16:9", aspect_str ) == 0 )
            {
               sdtvon_aspect = SDTV_ASPECT_16_9;
            }

            opt_sdtvon = 1;
            break;
         }
         case OPT_OFF:
         {
            opt_off = 1;
            break;
         }
         case OPT_MODES:
         {
            if ( vcos_strcasecmp( "CEA", optarg ) == 0 )
            {
               get_modes_group = HDMI_RES_GROUP_CEA;
            }
            else if ( vcos_strcasecmp( "DMT", optarg ) == 0 )
            {
               get_modes_group = HDMI_RES_GROUP_DMT;
            }
            else
            {
               LOG_ERR( "Invalid group '%s'", optarg );
               goto err_out;
            }

            opt_modes = 1;
            break;
         }
         case OPT_MONITOR:
         {
            opt_monitor = 1;
            break;
         }
         case OPT_STATUS:
         {
            opt_status = 1;
            break;
         }
         case OPT_AUDIOSUP:
         {
            opt_audiosup = 1;
            break;
         }
         case OPT_DUMPEDID:
         {
            opt_dumpedid = 1;
            dumpedid_filename = optarg;
            break;
         }
         case OPT_SHOWINFO:
         {
            opt_showinfo = atoi(optarg)+1;
            break;
         }
         case OPT_JSON:
         {
            opt_json = 1;
            break;
         }
         case OPT_NAME:
         {
            opt_name = 1;
            break;
         }
         default:
         {
            LOG_ERR( "Unrecognized option '%d'\n", opt );
            goto err_usage;
         }
         case '?':
         case OPT_HELP:
         {
            goto err_usage;
         }
      } // end switch
   } // end while

   argc -= optind;
   argv += optind;

   if (( optind == 1 ) || ( argc > 0 ))
   {
      if ( argc > 0 )
      {
         LOG_ERR( "Unrecognized argument -- '%s'", *argv );
      }

      goto err_usage;
   }

   if (( opt_preferred + opt_explicit + opt_sdtvon > 1 ))
   {
      LOG_ERR( "Conflicting power on options" );
      goto err_usage;
   }

   if ((( opt_preferred == 1 ) || ( opt_explicit == 1 ) || ( opt_sdtvon == 1)) && ( opt_off == 1 ))
   {
      LOG_ERR( "Cannot power on and power off simultaneously" );
      goto err_out;
   }

   // Initialize the VCHI connection
   ret = vchi_initialise( &vchi_instance );
   if ( ret != 0 )
   {
      LOG_ERR( "Failed to initialize VCHI (ret=%d)", ret );
      goto err_out;
   }

   ret = vchi_connect( NULL, 0, vchi_instance );
   if ( ret != 0)
   {
      LOG_ERR( "Failed to create VCHI connection (ret=%d)", ret );
      goto err_out;
   }

//   LOG_INFO( "Starting tvservice" );

   // Initialize the tvservice
   vc_vchi_tv_init( vchi_instance, &vchi_connection, 1 );

   if ( opt_monitor == 1 )
   {
      LOG_STD( "Starting to monitor for HDMI events" );

      if ( start_monitor() != 0 )
      {
         goto err_stop_service;
      }
   }

   if ( opt_modes == 1 )
   {
      if ( get_modes( get_modes_group, opt_json ) != 0 )
      {
         goto err_stop_service;
      }
   }

   if ( opt_preferred == 1 )
   {
      if ( power_on_preferred() != 0 )
      {
         goto err_stop_service;
      }
   }
   else if ( opt_explicit == 1 )
   {
      //Distinguish between turning on 3D side by side and 3D top/bottom
      if(opt_3d == 1 && set_property( HDMI_PROPERTY_3D_STRUCTURE, HDMI_3D_FORMAT_SBS_HALF, 0) != 0)
      {
         goto err_stop_service;
      }
      else if(opt_3d == 2 && set_property( HDMI_PROPERTY_3D_STRUCTURE, HDMI_3D_FORMAT_TB_HALF, 0) != 0)
      {
         goto err_stop_service;
      }

      if ( power_on_explicit( power_on_explicit_group,
                              power_on_explicit_mode, power_on_explicit_drive ) != 0 )
      {
         goto err_stop_service;
      }
   }
   else if ( opt_sdtvon == 1 )
   {
      if ( power_on_sdtv( sdtvon_mode,
                              sdtvon_aspect ) != 0 )
      {
         goto err_stop_service;
      }
   }
   else if (opt_off == 1 )
   {
      if ( power_off() != 0 )
      {
         goto err_stop_service;
      }
   }

   if ( opt_status == 1 )
   {
      if ( get_status() != 0 )
      {
         goto err_stop_service;
      }
   }
   
   if ( opt_audiosup == 1 )
   {
      if ( get_audiosup() != 0 )
      {
         goto err_stop_service;
      }
   }
   
   if ( opt_dumpedid == 1 )
   {
      if ( dump_edid(dumpedid_filename) != 0 )
      {
         goto err_stop_service;
      }
   }

   if ( opt_showinfo )
   {
      if ( show_info(opt_showinfo-1) != 0 )
      {
         goto err_stop_service;
      }
   }

   if ( opt_name == 1 )
   {
      TV_DEVICE_ID_T id;
      memset(&id, 0, sizeof(id));
      if(vc_tv_get_device_id(&id) == 0) {
         if(id.vendor[0] == '\0' || id.monitor_name[0] == '\0') {
            LOG_ERR( "No device present" );
         } else {
            LOG_STD( "device_name=%s-%s", id.vendor, id.monitor_name);
         }
      } else {
         LOG_ERR( "Failed to obtain device name" );
      }
   }

   if ( opt_monitor == 1 )
   {
      // Wait until we get the signal to exit
      vcos_event_wait( &quit_event );

      vcos_event_delete( &quit_event );
   }

err_stop_service:
//   LOG_INFO( "Stopping tvservice" );

   // Stop the tvservice
   vc_vchi_tv_stop();

   // Disconnect the VCHI connection
   vchi_disconnect( vchi_instance );

   exit( 0 );

err_usage:
   show_usage();

err_out:
   exit( 1 );
}
static int get_modes( HDMI_RES_GROUP_T group, int json_output)
{
   static TV_SUPPORTED_MODE_T supported_modes[MAX_MODE_ID];
   HDMI_RES_GROUP_T preferred_group;
   uint32_t preferred_mode;
   int num_modes;
   int i;

   vcos_assert(( group == HDMI_RES_GROUP_CEA ) ||
               ( group == HDMI_RES_GROUP_DMT ));

   memset(supported_modes, 0, sizeof(supported_modes));

   num_modes = vc_tv_hdmi_get_supported_modes( group, supported_modes,
                                               vcos_countof(supported_modes),
                                               &preferred_group,
                                               &preferred_mode );
   if ( num_modes < 0 )
   {
      LOG_ERR( "Failed to get modes" );
      return -1;
   }

   if (json_output)
   {
      LOG_STD( "[" );
   }
   else
   {
      LOG_STD( "Group %s has %u modes:",
               HDMI_RES_GROUP_NAME(group), num_modes );
   }

   for ( i = 0; i < num_modes; i++ )
   {
      char p[8] = {0};
      if( supported_modes[i].pixel_rep )
         vcos_safe_sprintf(p, sizeof(p)-1, 0, "x%d ", supported_modes[i].pixel_rep);

      if (json_output)
      {
         LOG_STD( "{ \"code\":%u, \"width\":%u, \"height\":%u, \"rate\":%u, \"aspect_ratio\":\"%s\", \"scan\":\"%s\", \"3d_modes\":[%s] }%s",
                  supported_modes[i].code, supported_modes[i].width,
                  supported_modes[i].height, supported_modes[i].frame_rate,
                  aspect_ratio_str(supported_modes[i].aspect_ratio),
                  supported_modes[i].scan_mode ? "i" : "p",
                  supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask, 1) : "",
                  (i+1 < num_modes) ? "," : "");
      }
      else
      {
         int preferred = supported_modes[i].group == preferred_group && supported_modes[i].code == preferred_mode;
         LOG_STD( "%s mode %u: %ux%u @ %uHz %s, clock:%uMHz %s%s %s",
                  preferred ? "  (prefer)" : supported_modes[i].native ? "  (native)" : "          ",
                  supported_modes[i].code, supported_modes[i].width,
                  supported_modes[i].height, supported_modes[i].frame_rate,
                  aspect_ratio_str(supported_modes[i].aspect_ratio),
                  supported_modes[i].pixel_freq / 1000000U, p,
                  supported_modes[i].scan_mode ? "interlaced" : "progressive",
                  supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask, 0) : "");
      }
   }

   if (json_output)
   {
      LOG_STD( "]" );
   }
   return 0;
}
static void show_usage( void )
{
   LOG_STD( "Usage: tvservice [OPTION]..." );
   LOG_STD( "  -p, --preferred                   Power on HDMI with preferred settings" );
   LOG_STD( "  -e, --explicit=\"GROUP MODE DRIVE\" Power on HDMI with explicit GROUP (CEA, DMT, CEA_3D_SBS, CEA_3D_TB)\n"
            "                                      MODE (see --modes) and DRIVE (HDMI, DVI)" );
   LOG_STD( "  -c, --sdtvon=\"MODE ASPECT\"        Power on SDTV with MODE (PAL or NTSC) and ASPECT (4:3 14:9 or 16:9)" );
   LOG_STD( "  -o, --off                         Power off the display" );
   LOG_STD( "  -m, --modes=GROUP                 Get supported modes for GROUP (CEA, DMT)" );
   LOG_STD( "  -M, --monitor                     Monitor HDMI events" );
   LOG_STD( "  -s, --status                      Get HDMI status" );
   LOG_STD( "  -a, --audio                       Get supported audio information" );
   LOG_STD( "  -d, --dumpedid <filename>         Dump EDID information to file" );
   LOG_STD( "  -j, --json                        Use JSON format for --modes output" );
   LOG_STD( "  -n, --name                        Print the device ID from EDID" );
   LOG_STD( "  -h, --help                        Print this information" );
}