aboutsummaryrefslogtreecommitdiff
path: root/util/fbrun/FbRun.cc
diff options
context:
space:
mode:
Diffstat (limited to 'util/fbrun/FbRun.cc')
-rw-r--r--util/fbrun/FbRun.cc227
1 files changed, 32 insertions, 195 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc
index caf51ce..701f985 100644
--- a/util/fbrun/FbRun.cc
+++ b/util/fbrun/FbRun.cc
@@ -19,7 +19,7 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: FbRun.cc,v 1.17 2003/08/25 01:18:00 fluxgen Exp $ 22// $Id: FbRun.cc,v 1.18 2003/08/27 00:20:19 fluxgen Exp $
23 23
24#include "FbRun.hh" 24#include "FbRun.hh"
25 25
@@ -50,10 +50,8 @@
50 50
51using namespace std; 51using namespace std;
52FbRun::FbRun(int x, int y, size_t width): 52FbRun::FbRun(int x, int y, size_t width):
53 FbTk::FbWindow((int)DefaultScreen(FbTk::App::instance()->display()), 53 FbTk::TextBox(DefaultScreen(FbTk::App::instance()->display()),
54 x, y, 54 m_font, ""),
55 width, 10,
56 KeyPressMask | ExposureMask),
57 m_font("fixed"), 55 m_font("fixed"),
58 m_display(FbTk::App::instance()->display()), 56 m_display(FbTk::App::instance()->display()),
59 m_bevel(4), 57 m_bevel(4),
@@ -61,15 +59,13 @@ FbRun::FbRun(int x, int y, size_t width):
61 m_end(false), 59 m_end(false),
62 m_current_history_item(0), 60 m_current_history_item(0),
63 m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)), 61 m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)),
64 m_start_pos(0),
65 m_end_pos(0),
66 m_cursor_pos(0),
67 m_pixmap(0) { 62 m_pixmap(0) {
68 63
64 setGC(m_gc);
69 setCursor(m_cursor); 65 setCursor(m_cursor);
70 // setting nomaximize in local resize 66 // setting nomaximize in local resize
71 resize(width, m_font.height()); 67 resize(width, font().height() + m_bevel);
72 FbTk::EventManager::instance()->add(*this, *this); 68
73 // setup class name 69 // setup class name
74 XClassHint *class_hint = XAllocClassHint(); 70 XClassHint *class_hint = XAllocClassHint();
75 if (class_hint == 0) 71 if (class_hint == 0)
@@ -91,10 +87,12 @@ FbRun::FbRun(int x, int y, size_t width):
91 XFreePixmap(m_display, mask); 87 XFreePixmap(m_display, mask);
92#endif // HAVE_XPM 88#endif // HAVE_XPM
93 89
94 XWMHints wmhints; 90 if (m_pixmap) {
95 wmhints.flags = IconPixmapHint; 91 XWMHints wmhints;
96 wmhints.icon_pixmap = m_pixmap; 92 wmhints.flags = IconPixmapHint;
97 XSetWMHints(m_display, window(), &wmhints); 93 wmhints.icon_pixmap = m_pixmap;
94 XSetWMHints(m_display, window(), &wmhints);
95 }
98} 96}
99 97
100 98
@@ -118,18 +116,18 @@ void FbRun::run(const std::string &command) {
118 hide(); // hide gui 116 hide(); // hide gui
119 117
120 // save command history to file 118 // save command history to file
121 if (m_runtext.size() != 0) { // no need to save empty command 119 if (text().size() != 0) { // no need to save empty command
122 120
123 // don't allow duplicates into the history file, first 121 // don't allow duplicates into the history file, first
124 // look for a duplicate 122 // look for a duplicate
125 if (m_current_history_item < m_history.size() 123 if (m_current_history_item < m_history.size()
126 && m_runtext == m_history[m_current_history_item]) { 124 && text() == m_history[m_current_history_item]) {
127 // m_current_history_item is the duplicate 125 // m_current_history_item is the duplicate
128 } else { 126 } else {
129 m_current_history_item = 0; 127 m_current_history_item = 0;
130 for (; m_current_history_item < m_history.size(); 128 for (; m_current_history_item < m_history.size();
131 ++m_current_history_item) { 129 ++m_current_history_item) {
132 if (m_history[m_current_history_item] == m_runtext) 130 if (m_history[m_current_history_item] == text())
133 break; 131 break;
134 } 132 }
135 } 133 }
@@ -147,7 +145,7 @@ void FbRun::run(const std::string &command) {
147 inoutfile<<m_history[i]<<endl; 145 inoutfile<<m_history[i]<<endl;
148 146
149 // and append the current one back to the end 147 // and append the current one back to the end
150 inoutfile<<m_runtext<<endl; 148 inoutfile<<text()<<endl;
151 } else 149 } else
152 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl; 150 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
153 } 151 }
@@ -184,23 +182,12 @@ bool FbRun::loadFont(const string &fontname) {
184 return false; 182 return false;
185 183
186 // resize to fit new font height 184 // resize to fit new font height
187 resize(width(), m_font.height() + m_bevel); 185 resize(width(), font().height() + m_bevel);
188 return true; 186 return true;
189} 187}
190 188
191void FbRun::setForegroundColor(const FbTk::Color &color) { 189void FbRun::setForegroundColor(const FbTk::Color &color) {
192 XSetForeground(m_display, m_gc, color.pixel()); 190 XSetForeground(m_display, m_gc, color.pixel());
193 redrawLabel();
194}
195
196void FbRun::setBackgroundColor(const FbTk::Color &color) {
197 FbTk::FbWindow::setBackgroundColor(color);
198 redrawLabel();
199}
200
201void FbRun::setText(const string &text) {
202 m_runtext = text;
203 redrawLabel();
204} 191}
205 192
206void FbRun::setTitle(const string &title) { 193void FbRun::setTitle(const string &title) {
@@ -208,30 +195,16 @@ void FbRun::setTitle(const string &title) {
208} 195}
209 196
210void FbRun::resize(size_t width, size_t height) { 197void FbRun::resize(size_t width, size_t height) {
211 FbTk::FbWindow::resize(width, height); 198 FbTk::TextBox::resize(width, height);
212 setNoMaximize(); 199 setNoMaximize();
213} 200}
214 201
215void FbRun::redrawLabel() { 202void FbRun::redrawLabel() {
216 clear(); 203 clear();
217 drawString(m_bevel/2, m_font.ascent() + m_bevel/2,
218 m_runtext.c_str(), m_runtext.size());
219
220}
221
222void FbRun::drawString(int x, int y,
223 const char *text, size_t len) {
224 assert(m_gc);
225
226 m_font.drawText(window(), screenNumber(),
227 m_gc, text + m_start_pos,
228 m_end_pos - m_start_pos, x, y - 2);
229 // draw cursor position
230 int cursor_pos = m_font.textWidth(text + m_start_pos, m_cursor_pos) + 1;
231 drawLine(m_gc, cursor_pos, 0, cursor_pos, m_font.height());
232} 204}
233 205
234void FbRun::keyPressEvent(XKeyEvent &ke) { 206void FbRun::keyPressEvent(XKeyEvent &ke) {
207 FbTk::TextBox::keyPressEvent(ke);
235 KeySym ks; 208 KeySym ks;
236 char keychar[1]; 209 char keychar[1];
237 XLookupString(&ke, keychar, 1, &ks, 0); 210 XLookupString(&ke, keychar, 1, &ks, 0);
@@ -241,30 +214,12 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
241 if (ke.state) { // a modifier key is down 214 if (ke.state) { // a modifier key is down
242 if (ke.state == ControlMask) { 215 if (ke.state == ControlMask) {
243 switch (ks) { 216 switch (ks) {
244 case XK_b:
245 cursorLeft();
246 break;
247 case XK_f:
248 cursorRight();
249 break;
250 case XK_p: 217 case XK_p:
251 prevHistoryItem(); 218 prevHistoryItem();
252 break; 219 break;
253 case XK_n: 220 case XK_n:
254 nextHistoryItem(); 221 nextHistoryItem();
255 break; 222 break;
256 case XK_a:
257 cursorHome();
258 break;
259 case XK_e:
260 cursorEnd();
261 break;
262 case XK_d:
263 deleteForward();
264 break;
265 case XK_k:
266 killToEnd();
267 break;
268 } 223 }
269 } else if (ke.state == (Mod1Mask | ShiftMask)) { 224 } else if (ke.state == (Mod1Mask | ShiftMask)) {
270 switch (ks) { 225 switch (ks) {
@@ -275,8 +230,6 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
275 lastHistoryItem(); 230 lastHistoryItem();
276 break; 231 break;
277 } 232 }
278 } else if (ke.state == ShiftMask) {
279 if (isprint(keychar[0]))insertCharacter(ks, keychar);
280 } 233 }
281 } else { // no modifier key 234 } else { // no modifier key
282 switch (ks) { 235 switch (ks) {
@@ -286,17 +239,7 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
286 FbTk::App::instance()->end(); // end program 239 FbTk::App::instance()->end(); // end program
287 break; 240 break;
288 case XK_Return: 241 case XK_Return:
289 run(m_runtext); 242 run(text());
290 m_runtext = ""; // clear text
291 break;
292 case XK_BackSpace:
293 backspace();
294 break;
295 case XK_Home:
296 cursorHome();
297 break;
298 case XK_End:
299 cursorEnd();
300 break; 243 break;
301 case XK_Up: 244 case XK_Up:
302 prevHistoryItem(); 245 prevHistoryItem();
@@ -304,24 +247,12 @@ void FbRun::keyPressEvent(XKeyEvent &ke) {
304 case XK_Down: 247 case XK_Down:
305 nextHistoryItem(); 248 nextHistoryItem();
306 break; 249 break;
307 case XK_Left:
308 cursorLeft();
309 break;
310 case XK_Right:
311 cursorRight();
312 break;
313 case XK_Tab: 250 case XK_Tab:
314 tabCompleteHistory(); 251 tabCompleteHistory();
315 break; 252 break;
316 default:
317 if (isprint(keychar[0])) insertCharacter(ks, keychar);
318 } 253 }
319 } 254 }
320 redrawLabel(); 255 clear();
321}
322
323void FbRun::exposeEvent(XExposeEvent &ev) {
324 redrawLabel();
325} 256}
326 257
327void FbRun::setNoMaximize() { 258void FbRun::setNoMaximize() {
@@ -340,9 +271,7 @@ void FbRun::prevHistoryItem() {
340 XBell(m_display, 0); 271 XBell(m_display, 0);
341 } else { 272 } else {
342 m_current_history_item--; 273 m_current_history_item--;
343 m_runtext = m_history[m_current_history_item]; 274 setText(m_history[m_current_history_item]);
344 m_cursor_pos = m_end_pos = m_runtext.size();
345 adjustStartPos();
346 } 275 }
347} 276}
348 277
@@ -353,13 +282,9 @@ void FbRun::nextHistoryItem() {
353 m_current_history_item++; 282 m_current_history_item++;
354 if (m_current_history_item == m_history.size()) { 283 if (m_current_history_item == m_history.size()) {
355 m_current_history_item = m_history.size(); 284 m_current_history_item = m_history.size();
356 m_runtext = ""; 285 setText("");
357 m_start_pos = m_cursor_pos = m_end_pos = 0; 286 } else
358 } else { 287 setText(m_history[m_current_history_item]);
359 m_runtext = m_history[m_current_history_item];
360 m_cursor_pos = m_end_pos = m_runtext.size();
361 adjustStartPos();
362 }
363 } 288 }
364} 289}
365 290
@@ -368,9 +293,7 @@ void FbRun::firstHistoryItem() {
368 XBell(m_display, 0); 293 XBell(m_display, 0);
369 } else { 294 } else {
370 m_current_history_item = 0; 295 m_current_history_item = 0;
371 m_runtext = m_history[m_current_history_item]; 296 setText(m_history[m_current_history_item]);
372 m_cursor_pos = m_end_pos = m_runtext.size();
373 adjustStartPos();
374 } 297 }
375} 298}
376 299
@@ -380,8 +303,7 @@ void FbRun::lastHistoryItem() {
380 XBell(m_display, 0); 303 XBell(m_display, 0);
381 } else { 304 } else {
382 m_current_history_item = m_history.size(); 305 m_current_history_item = m_history.size();
383 m_runtext = ""; 306 setText("");
384 m_start_pos = m_cursor_pos = m_end_pos = 0;
385 } 307 }
386} 308}
387 309
@@ -390,12 +312,11 @@ void FbRun::tabCompleteHistory() {
390 XBell(m_display, 0); 312 XBell(m_display, 0);
391 } else { 313 } else {
392 int history_item = m_current_history_item - 1; 314 int history_item = m_current_history_item - 1;
393 string prefix = m_runtext.substr(0, m_cursor_pos); 315 string prefix = text().substr(0, cursorPosition());
394 while (history_item > - 1) { 316 while (history_item > - 1) {
395 if (m_history[history_item].find(prefix) == 0) { 317 if (m_history[history_item].find(prefix) == 0) {
396 m_current_history_item = history_item; 318 m_current_history_item = history_item;
397 m_runtext = m_history[m_current_history_item]; 319 setText(m_history[m_current_history_item]);
398 adjustEndPos();
399 break; 320 break;
400 } 321 }
401 history_item--; 322 history_item--;
@@ -404,92 +325,8 @@ void FbRun::tabCompleteHistory() {
404 } 325 }
405} 326}
406 327
407void FbRun::cursorLeft() { 328void FbRun::insertCharacter(char keychar) {
408 if (m_cursor_pos) 329 char val[2] = {keychar, 0};
409 m_cursor_pos--; 330 insertText(val);
410 else if (m_start_pos) {
411 m_start_pos--;
412 adjustEndPos();
413 }
414}
415
416void FbRun::cursorRight() {
417 if (m_start_pos + m_cursor_pos < m_end_pos)
418 m_cursor_pos++;
419 else if (m_end_pos < m_runtext.size()) {
420 m_cursor_pos++;
421 m_end_pos++;
422 adjustStartPos();
423 }
424}
425
426void FbRun::cursorHome() {
427 m_start_pos = m_cursor_pos = 0;
428 adjustEndPos();
429} 331}
430 332
431void FbRun::cursorEnd() {
432 m_cursor_pos = m_end_pos = m_runtext.size();
433 adjustStartPos();
434}
435
436void FbRun::backspace() {
437 if (m_start_pos || m_cursor_pos) {
438 m_runtext.erase(m_start_pos + m_cursor_pos - 1, 1);
439 if (m_cursor_pos)
440 m_cursor_pos--;
441 else
442 m_start_pos--;
443 adjustEndPos();
444 }
445}
446
447void FbRun::deleteForward() {
448 if (m_start_pos + m_cursor_pos < m_end_pos) {
449 m_runtext.erase(m_start_pos + m_cursor_pos, 1);
450 adjustEndPos();
451 }
452}
453
454void FbRun::killToEnd() {
455 if (m_start_pos + m_cursor_pos < m_end_pos) {
456 m_runtext.erase(m_start_pos + m_cursor_pos);
457 adjustEndPos();
458 }
459}
460
461void FbRun::insertCharacter(KeySym ks, char *keychar) {
462 char in_char[2] = {keychar[0], 0};
463 m_runtext.insert(m_start_pos + m_cursor_pos, in_char);
464 m_cursor_pos++;
465 m_end_pos++;
466 if (m_start_pos + m_cursor_pos < m_end_pos)
467 adjustEndPos();
468 else
469 adjustStartPos();
470}
471
472void FbRun::adjustEndPos() {
473 m_end_pos = m_runtext.size();
474 const char *text = m_runtext.c_str();
475 int text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos);
476 while (text_width > width()) {
477 m_end_pos--;
478 text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos);
479 }
480}
481
482void FbRun::adjustStartPos() {
483 const char *text = m_runtext.c_str();
484 int text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos);
485 if (text_width < width()) return;
486 int start_pos = 0;
487 text_width = m_font.textWidth(text + start_pos, m_end_pos - start_pos);
488 while (text_width > width()) {
489 start_pos++;
490 text_width = m_font.textWidth(text + start_pos, m_end_pos - start_pos);
491 }
492 // adjust m_cursor_pos according relative to change to m_start_pos
493 m_cursor_pos -= start_pos - m_start_pos;
494 m_start_pos = start_pos;
495}