|
@@ -1,105 +1,35 @@
|
1
|
1
|
#include <unistd.h>
|
2
|
2
|
#include <cstdio>
|
3
|
3
|
#include "x.hpp"
|
4
|
|
-
|
5
|
|
-int borderSize = 10;
|
6
|
|
-int padding = 0;
|
7
|
|
-std::string xserver = ":0";
|
8
|
|
-
|
9
|
|
-void printHelp() {
|
10
|
|
- printf( "Usage: slrn [options]\n" );
|
11
|
|
- printf( "Print user selected region to stdout.\n" );
|
12
|
|
- printf( "\n" );
|
13
|
|
- printf( "options\n" );
|
14
|
|
- printf( " -h, --help show this message.\n" );
|
15
|
|
- printf( " -b=INT, --bordersize=INT set selection rectangle border size.\n" );
|
16
|
|
- printf( " -p=INT, --padding=INT set padding size for selection.\n" );
|
17
|
|
- printf( " -x=STRING, --xdisplay=STRING set x display (STRING must be hostname:number.screen_number format)\n" );
|
18
|
|
- printf( "examples\n" );
|
19
|
|
- printf( " slrn -b=10 -x=:0 -p=-30\n" );
|
20
|
|
-}
|
21
|
|
-
|
22
|
|
-int parseOptions( int argc, char** argv ) {
|
23
|
|
- for ( int i=0; i<argc; i++ ) {
|
24
|
|
- std::string arg = argv[i];
|
25
|
|
- if ( arg.substr( 0, 3 ) == "-b=" || arg.substr( 0, 13 ) == "--bordersize=" ) {
|
26
|
|
- int find = arg.find( "=" );
|
27
|
|
- if ( find != arg.npos ) {
|
28
|
|
- arg.at( find ) = ' ';
|
29
|
|
- }
|
30
|
|
- int num = sscanf( arg.c_str(), "%*s %i", &borderSize );
|
31
|
|
- if ( borderSize < 0 ) {
|
32
|
|
- borderSize = 0;
|
33
|
|
- }
|
34
|
|
- if ( num != 1 ) {
|
35
|
|
- printf( "Error parsing command arguments near %s\n", argv[i] );
|
36
|
|
- printf( "Usage: -b=INT or --bordersize=INT\n" );
|
37
|
|
- printf( "Example: -b=10 or --bordersize=12\n" );
|
38
|
|
- return 1;
|
39
|
|
- }
|
40
|
|
- } else if ( arg.substr( 0, 3 ) == "-p=" || arg.substr( 0, 10 ) == "--padding=" ) {
|
41
|
|
- int find = arg.find( "=" );
|
42
|
|
- if ( find != arg.npos ) {
|
43
|
|
- arg.at( find ) = ' ';
|
44
|
|
- }
|
45
|
|
- int num = sscanf( arg.c_str(), "%*s %i", &padding );
|
46
|
|
- if ( num != 1 ) {
|
47
|
|
- printf( "Error parsing command arguments near %s\n", argv[i] );
|
48
|
|
- printf( "Usage: -p=INT or --padding=INT\n" );
|
49
|
|
- printf( "Example: -p=0 or --padding=-12\n" );
|
50
|
|
- return 1;
|
51
|
|
- }
|
52
|
|
- } else if ( arg.substr( 0, 3 ) == "-x=" || arg.substr( 0, 11 ) == "--xdisplay=" ) {
|
53
|
|
- int find = arg.find( "=" );
|
54
|
|
- if ( find != arg.npos ) {
|
55
|
|
- arg.at( find ) = ' ';
|
56
|
|
- }
|
57
|
|
- char* x = new char[ arg.size() ];
|
58
|
|
- int num = sscanf( arg.c_str(), "%*s %s", x );
|
59
|
|
- if ( num != 1 ) {
|
60
|
|
- printf( "Error parsing command arguments near %s\n", argv[i] );
|
61
|
|
- printf( "Usage: -x=STRING or --xserver=STRING.\n" );
|
62
|
|
- printf( "Example: -x=:0 or --xserver=winston:1.3\n" );
|
63
|
|
- delete[] x;
|
64
|
|
- return 1;
|
65
|
|
- }
|
66
|
|
- xserver = x;
|
67
|
|
- delete[] x;
|
68
|
|
- } else if ( arg == "-h" || arg == "--help" ) {
|
69
|
|
- printHelp();
|
70
|
|
- return 2;
|
71
|
|
- } else {
|
72
|
|
- if ( i == 0 ) {
|
73
|
|
- continue;
|
74
|
|
- }
|
75
|
|
- printf( "Error: Unknown argument %s\n", argv[i] );
|
76
|
|
- printf( "Try -h or --help for help.\n" );
|
77
|
|
- return 1;
|
78
|
|
- }
|
79
|
|
- }
|
80
|
|
- return 0;
|
81
|
|
-}
|
|
4
|
+#include "options.hpp"
|
82
|
5
|
|
83
|
6
|
int main( int argc, char** argv ) {
|
84
|
|
- int err = parseOptions( argc, argv );
|
|
7
|
+ int err = options->parseOptions( argc, argv );
|
85
|
8
|
if ( err ) {
|
86
|
9
|
return err;
|
87
|
10
|
}
|
88
|
11
|
int state = 0;
|
89
|
12
|
bool running = true;
|
90
|
|
- is::Rectangle* selection;
|
91
|
|
- is::Rectangle* windowselection = NULL;
|
|
13
|
+ slrn::Rectangle* selection;
|
|
14
|
+ slrn::Rectangle* windowselection = NULL;
|
92
|
15
|
Window window = None;
|
|
16
|
+ std::string xdisplay = options->m_xdisplay;
|
|
17
|
+ int padding = options->m_padding;
|
|
18
|
+ int borderSize = options->m_borderSize;
|
|
19
|
+ int tolerance = options->m_tolerance;
|
93
|
20
|
|
94
|
|
- err = xengine->init( xserver.c_str() );
|
|
21
|
+ // First we set up the x interface and grab the mouse,
|
|
22
|
+ // if we fail for either we exit immediately.
|
|
23
|
+ err = xengine->init( xdisplay.c_str() );
|
95
|
24
|
if ( err ) {
|
96
|
25
|
return err;
|
97
|
26
|
}
|
98
|
|
- err = xengine->grabCursor( is::Cross );
|
|
27
|
+ err = xengine->grabCursor( slrn::Cross );
|
99
|
28
|
if ( err ) {
|
100
|
29
|
return err;
|
101
|
30
|
}
|
102
|
31
|
while ( running ) {
|
|
32
|
+ // "ticking" the xengine makes it process all queued events.
|
103
|
33
|
xengine->tick();
|
104
|
34
|
if ( xengine->mouseDown( 3 ) ) {
|
105
|
35
|
printf( "X=0\n" );
|
|
@@ -110,17 +40,21 @@ int main( int argc, char** argv ) {
|
110
|
40
|
state = -1;
|
111
|
41
|
running = false;
|
112
|
42
|
}
|
|
43
|
+ // Our adorable little state manager will handle what state we're in.
|
113
|
44
|
switch ( state ) {
|
114
|
45
|
default: {
|
115
|
46
|
break;
|
116
|
47
|
}
|
117
|
48
|
case 0: {
|
|
49
|
+ // If xengine has found a window we're hovering over (or if it changed)
|
|
50
|
+ // create a rectangle around it so the user knows he/she can click on it.
|
118
|
51
|
if ( window != xengine->m_hoverXWindow ) {
|
|
52
|
+ // Make sure to delete the old selection rectangle.
|
119
|
53
|
if ( windowselection ) {
|
120
|
|
- xengine->removeRect( windowselection );
|
|
54
|
+ xengine->removeRect( windowselection ); // removeRect also dealloc's the rectangle for us.
|
121
|
55
|
}
|
122
|
|
- is::WindowRectangle t = xengine->m_hoverWindow;
|
123
|
|
- windowselection = new is::Rectangle( t.m_x - t.m_border,
|
|
56
|
+ slrn::WindowRectangle t = xengine->m_hoverWindow;
|
|
57
|
+ windowselection = new slrn::Rectangle( t.m_x - t.m_border,
|
124
|
58
|
t.m_y - t.m_border,
|
125
|
59
|
t.m_width + t.m_border,
|
126
|
60
|
t.m_height + t.m_border,
|
|
@@ -128,6 +62,8 @@ int main( int argc, char** argv ) {
|
128
|
62
|
xengine->addRect( windowselection );
|
129
|
63
|
window = xengine->m_hoverXWindow;
|
130
|
64
|
}
|
|
65
|
+ // If the user clicked, remove the old selection rectangle and then
|
|
66
|
+ // move on to the next state.
|
131
|
67
|
if ( xengine->mouseDown( 1 ) ) {
|
132
|
68
|
if ( windowselection ) {
|
133
|
69
|
xengine->removeRect( windowselection );
|
|
@@ -137,46 +73,63 @@ int main( int argc, char** argv ) {
|
137
|
73
|
break;
|
138
|
74
|
}
|
139
|
75
|
case 1: {
|
140
|
|
- selection = new is::Rectangle( xengine->m_mousex, xengine->m_mousey, 0, 0, borderSize, padding );
|
|
76
|
+ // Simply create a new rectangle at the mouse position and move on
|
|
77
|
+ // to the next state.
|
|
78
|
+ selection = new slrn::Rectangle( xengine->m_mousex, xengine->m_mousey, 0, 0, borderSize, padding );
|
141
|
79
|
xengine->addRect( selection );
|
142
|
80
|
state++;
|
143
|
81
|
break;
|
144
|
82
|
}
|
145
|
83
|
case 2: {
|
|
84
|
+ // If the user has let go of the mouse button, we'll just
|
|
85
|
+ // continue to the next state.
|
146
|
86
|
if ( !xengine->mouseDown( 1 ) ) {
|
147
|
87
|
state++;
|
148
|
88
|
break;
|
149
|
89
|
}
|
|
90
|
+ // Set the selection rectangle's dimensions to mouse movement.
|
|
91
|
+ // We use the function setDim since rectangles can't have negative widths,
|
|
92
|
+ // and because the rectangles have borders and padding to worry about.
|
150
|
93
|
selection->setDim( xengine->m_mousex - selection->m_x, xengine->m_mousey - selection->m_y );
|
|
94
|
+ // We also detect which way the user is pulling and set the mouse icon accordingly.
|
151
|
95
|
bool x = selection->m_flippedx;
|
152
|
96
|
bool y = selection->m_flippedy;
|
153
|
97
|
if ( !x && !y ) {
|
154
|
|
- xengine->setCursor( is::LowerRightCorner );
|
|
98
|
+ xengine->setCursor( slrn::LowerRightCorner );
|
155
|
99
|
} else if ( x && !y ) {
|
156
|
|
- xengine->setCursor( is::LowerLeftCorner );
|
|
100
|
+ xengine->setCursor( slrn::LowerLeftCorner );
|
157
|
101
|
} else if ( !x && y ) {
|
158
|
|
- xengine->setCursor( is::UpperRightCorner );
|
|
102
|
+ xengine->setCursor( slrn::UpperRightCorner );
|
159
|
103
|
} else {
|
160
|
|
- xengine->setCursor( is::UpperLeftCorner );
|
|
104
|
+ xengine->setCursor( slrn::UpperLeftCorner );
|
161
|
105
|
}
|
162
|
106
|
|
163
|
107
|
break;
|
164
|
108
|
}
|
165
|
109
|
case 3: {
|
|
110
|
+ // We pull the dimensions and positions from the selection rectangle.
|
|
111
|
+ // The selection rectangle automatically converts the positions and
|
|
112
|
+ // dimensions to absolute coordinates when we set them earilier.
|
166
|
113
|
int x = selection->m_x+selection->m_xoffset;
|
167
|
114
|
int y = selection->m_y+selection->m_yoffset;
|
168
|
115
|
int w = selection->m_width;
|
169
|
116
|
int h = selection->m_height;
|
|
117
|
+ // Delete the rectangle.
|
170
|
118
|
xengine->removeRect( selection );
|
|
119
|
+ // Exit the utility after this state runs once.
|
171
|
120
|
running = false;
|
172
|
|
- if ( w || h || xengine->m_hoverXWindow == None ) {
|
|
121
|
+ // If the user simply clicked (and thus made the width and height smaller than
|
|
122
|
+ // our tolerance) or if we're not hovering over a window, just print the selection
|
|
123
|
+ // rectangle's stuff.
|
|
124
|
+ if ( w > tolerance || h > tolerance || xengine->m_hoverXWindow == None ) {
|
173
|
125
|
printf( "X=%i\n", x );
|
174
|
126
|
printf( "Y=%i\n", y );
|
175
|
127
|
printf( "W=%i\n", w + 1 );
|
176
|
128
|
printf( "H=%i\n", h + 1 );
|
177
|
129
|
break;
|
178
|
130
|
}
|
179
|
|
- is::WindowRectangle t = xengine->m_hoverWindow;
|
|
131
|
+ // Otherwise lets grab the window's dimensions and use those (with padding).
|
|
132
|
+ slrn::WindowRectangle t = xengine->m_hoverWindow;
|
180
|
133
|
x = t.m_x - padding - t.m_border;
|
181
|
134
|
y = t.m_y - padding - t.m_border;
|
182
|
135
|
w = t.m_width + t.m_border + padding*2;
|
|
@@ -188,9 +141,14 @@ int main( int argc, char** argv ) {
|
188
|
141
|
break;
|
189
|
142
|
}
|
190
|
143
|
}
|
191
|
|
- // No need to max out CPU--
|
|
144
|
+ // No need to max out CPU
|
|
145
|
+ // FIXME: This could be adjusted to measure how much time has passed,
|
|
146
|
+ // we may very well need to max out the CPU if someone has a really- really
|
|
147
|
+ // bad computer.
|
192
|
148
|
usleep( 1000 );
|
193
|
149
|
}
|
|
150
|
+ // Clean up global classes.
|
194
|
151
|
delete xengine;
|
|
152
|
+ delete options;
|
195
|
153
|
return 0;
|
196
|
154
|
}
|