123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "options.hpp"
  2. slop::Options* options = new slop::Options();
  3. slop::Options::Options() {
  4. m_borderSize = 10;
  5. m_padding = 0;
  6. m_xdisplay = ":0";
  7. m_tolerance = 4;
  8. m_red = 0;
  9. m_green = 0;
  10. m_blue = 0;
  11. }
  12. void slop::Options::printHelp() {
  13. printf( "Usage: slop [options]\n" );
  14. printf( "Print user selected region to stdout.\n" );
  15. printf( "\n" );
  16. printf( "options\n" );
  17. printf( " -h, --help show this message.\n" );
  18. printf( " -b=INT, --bordersize=INT set selection rectangle border size.\n" );
  19. printf( " -p=INT, --m_padding=INT set m_padding size for selection.\n" );
  20. printf( " -t=INT, --tolerance=INT if you have a shaky mouse, increasing this value will make slop detect single clicks better. Rather than interpreting your shaky clicks as region selections.\n" );
  21. printf( " -x=STRING, --xdisplay=STRING set x display (STRING must be hostname:number.screen_number format)\n" );
  22. printf( " -c=COLOR, --color=COLOR set selection rectangle color, COLOR is in format FLOAT,FLOAT,FLOAT\n" );
  23. printf( "examples\n" );
  24. printf( " slop -b=10 -x=:0 -p=-30 -t=4 -c=0.5,0.5,0.5\n" );
  25. }
  26. int slop::Options::parseOptions( int argc, char** argv ) {
  27. // Simple command parsing. Just uses sscanf to read each argument.
  28. // It looks complicated because you have to have spaces for delimiters for sscanf.
  29. for ( int i=0; i<argc; i++ ) {
  30. std::string arg = argv[i];
  31. if ( matches( arg, "--b=", "--bordersize=" ) ) {
  32. int err = parseInt( arg, &m_borderSize );
  33. if ( err ) {
  34. return 1;
  35. }
  36. if ( m_borderSize < 0 ) {
  37. m_borderSize = 0;
  38. }
  39. } else if ( matches( arg, "-p=", "--padding=" ) ) {
  40. int err = parseInt( arg, &m_padding );
  41. if ( err ) {
  42. return 1;
  43. }
  44. } else if ( matches( arg, "-c=", "--color=" ) ) {
  45. int err = parseColor( arg, &m_red, &m_green, &m_blue );
  46. if ( err ) {
  47. return 1;
  48. }
  49. } else if ( matches( arg, "-t=", "--tolerance=" ) ) {
  50. int err = parseInt( arg, &m_tolerance );
  51. if ( err ) {
  52. return 1;
  53. }
  54. if ( m_tolerance < 0 ) {
  55. m_tolerance = 0;
  56. }
  57. } else if ( matches( arg, "-x=", "--xdisplay=" ) ) {
  58. int err = parseString( arg, &m_xdisplay );
  59. if ( err ) {
  60. return 1;
  61. }
  62. } else if ( arg == "-h" || arg == "--help" ) {
  63. printHelp();
  64. return 2;
  65. } else {
  66. if ( i == 0 ) {
  67. continue;
  68. }
  69. fprintf( stderr, "Error: Unknown argument %s\n", argv[i] );
  70. fprintf( stderr, "Try -h or --help for help.\n" );
  71. return 1;
  72. }
  73. }
  74. return 0;
  75. }
  76. int slop::Options::parseInt( std::string arg, int* returnInt ) {
  77. std::string copy = arg;
  78. int find = copy.find( "=" );
  79. if ( find != copy.npos ) {
  80. copy.at( find ) = ' ';
  81. }
  82. // Just in case we error out, grab the actual argument name into x.
  83. char* x = new char[ arg.size() ];
  84. int num = sscanf( copy.c_str(), "%s %i", x, returnInt );
  85. if ( num != 2 ) {
  86. fprintf( stderr, "Error parsing command arguments near %s\n", arg.c_str() );
  87. fprintf( stderr, "Usage: %s=INT\n", x );
  88. fprintf( stderr, "Example: %s=10 or %s=-12\n", x, x );
  89. fprintf( stderr, "Try -h or --help for help.\n" );
  90. delete[] x;
  91. return 1;
  92. }
  93. delete[] x;
  94. return 0;
  95. }
  96. bool slop::Options::matches( std::string arg, std::string shorthand, std::string longhand ) {
  97. if ( arg.substr( 0, shorthand.size() ) == shorthand ||
  98. arg.substr( 0, longhand.size() ) == longhand ) {
  99. return true;
  100. }
  101. return false;
  102. }
  103. int slop::Options::parseString( std::string arg, std::string* returnString ) {
  104. std::string copy = arg;
  105. int find = copy.find( "=" );
  106. if ( find != copy.npos ) {
  107. copy.at( find ) = ' ';
  108. }
  109. // Just in case we error out, grab the actual argument name into x.
  110. char* x = new char[ arg.size() ];
  111. char* y = new char[ arg.size() ];
  112. int num = sscanf( copy.c_str(), "%s %s", x, y );
  113. if ( num != 2 ) {
  114. fprintf( stderr, "Error parsing command arguments near %s\n", arg.c_str() );
  115. fprintf( stderr, "Usage: %s=STRING\n", x );
  116. fprintf( stderr, "Example: %s=:0 or %s=hostname:0.1\n", x, x );
  117. fprintf( stderr, "Try -h or --help for help.\n" );
  118. delete[] x;
  119. delete[] y;
  120. return 1;
  121. }
  122. *returnString = y;
  123. delete[] x;
  124. delete[] y;
  125. return 0;
  126. }
  127. int slop::Options::parseColor( std::string arg, float* r, float* g, float* b ) {
  128. std::string copy = arg;
  129. int find = copy.find( "=" );
  130. while( find != copy.npos ) {
  131. copy.at( find ) = ' ';
  132. find = copy.find( "," );
  133. }
  134. // Just in case we error out, grab the actual argument name into x.
  135. char* x = new char[ arg.size() ];
  136. int num = sscanf( copy.c_str(), "%s %f %f %f", x, r, g, b );
  137. if ( num != 4 ) {
  138. fprintf( stderr, "Error parsing command arguments near %s\n", arg.c_str() );
  139. fprintf( stderr, "Usage: %s=COLOR\n", x );
  140. fprintf( stderr, "Example: %s=0,0,0 or %s=0.7,0.2,1\n", x, x );
  141. fprintf( stderr, "Try -h or --help for help.\n" );
  142. delete[] x;
  143. return 1;
  144. }
  145. delete[] x;
  146. return 0;
  147. }