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.cc245
1 files changed, 245 insertions, 0 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc
new file mode 100644
index 0000000..0ce297a
--- /dev/null
+++ b/util/fbrun/FbRun.cc
@@ -0,0 +1,245 @@
1// FbRun.hh
2// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: FbRun.cc,v 1.9 2002/12/05 00:07:39 fluxgen Exp $
23
24#include "FbRun.hh"
25
26#include "App.hh"
27#include "EventManager.hh"
28#include "Color.hh"
29
30#include <X11/Xlib.h>
31#include <X11/keysym.h>
32#include <X11/Xutil.h>
33
34#include <unistd.h>
35
36#include <iostream>
37#include <fstream>
38
39using namespace std;
40FbRun::FbRun(int x, int y, size_t width):
41 m_font("fixed"),
42 m_win((int)0, x, y, //screen num and position
43 width + m_bevel, m_font.height(), // size
44 KeyPressMask|ExposureMask), // eventmask
45 m_display(FbTk::App::instance()->display()),
46 m_bevel(4),
47 m_gc(DefaultGC(m_display, DefaultScreen(m_display))),
48 m_end(false),
49 m_current_history_item(0) {
50 // setting nomaximize in local resize
51 resize(width, m_font.height());
52 FbTk::EventManager::instance()->registerEventHandler(*this, m_win.window());
53}
54
55FbRun::~FbRun() {
56 hide();
57 FbTk::EventManager::instance()->unregisterEventHandler(m_win.window());
58}
59
60void FbRun::run(const std::string &command) {
61 //fork and execute program
62 if (!fork()) {
63 setsid();
64 execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0);
65 exit(0); //exit child
66 }
67
68 hide(); // hide gui
69
70 // save command history to file
71 if (m_runtext.size() != 0) { // no need to save empty command
72 // open file in append mode
73 ofstream outfile(m_history_file.c_str(), ios::app);
74 if (outfile)
75 outfile<<m_runtext<<endl;
76 else
77 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
78 }
79 FbTk::App::instance()->end(); // end application
80 m_end = true; // mark end of processing
81}
82
83bool FbRun::loadHistory(const char *filename) {
84 if (filename == 0)
85 return false;
86 ifstream infile(filename);
87 if (!infile) {
88 //even though we fail to load file, we should try save to it
89 m_history_file = filename;
90 return false;
91 }
92 // clear old history and load new one from file
93 m_history.clear();
94 // each line is a command
95 string line;
96 while (!infile.eof()) {
97 getline(infile, line);
98 if (line.size()) // don't add empty lines
99 m_history.push_back(line);
100 }
101 // set no current histor to display
102 m_current_history_item = m_history.size();
103 // set history file
104 m_history_file = filename;
105 return true;
106}
107
108bool FbRun::loadFont(const string &fontname) {
109 if (!m_font.load(fontname.c_str()))
110 return false;
111
112 // resize to fit new font height
113 resize(m_win.width(), m_font.height() + m_bevel);
114 return true;
115}
116
117void FbRun::setForeground(const FbTk::Color &color) {
118 XSetForeground(m_display, m_gc, color.pixel());
119 redrawLabel();
120}
121
122void FbRun::setBackground(const FbTk::Color &color) {
123 m_win.setBackgroundColor(color);
124 redrawLabel();
125}
126
127
128void FbRun::setText(const string &text) {
129 m_runtext = text;
130 redrawLabel();
131}
132
133void FbRun::setTitle(const string &title) {
134 m_win.setName(title.c_str());
135}
136
137void FbRun::move(int x, int y) {
138 m_win.move(x, y);
139}
140
141void FbRun::resize(size_t width, size_t height) {
142 m_win.resize(width, height);
143 setNoMaximize();
144}
145
146void FbRun::show() {
147 m_win.show();
148}
149
150void FbRun::hide() {
151 m_win.hide();
152}
153
154void FbRun::redrawLabel() {
155 m_win.clear();
156 drawString(m_bevel/2, m_font.ascent() + m_bevel/2,
157 m_runtext.c_str(), m_runtext.size());
158
159}
160
161void FbRun::drawString(int x, int y,
162 const char *text, size_t len) {
163 assert(m_gc);
164
165 // check right boundary and adjust text drawing
166 size_t text_width = m_font.textWidth(text, len);
167 size_t startpos = 0;
168 if (text_width > m_win.width()) {
169 for (; startpos < len; ++startpos) {
170 if (m_font.textWidth(text+startpos, len-startpos) < m_win.width())
171 break;
172 }
173 }
174
175 m_font.drawText(m_win.window(), DefaultScreen(m_display), m_gc, text + startpos, len-startpos, x, y);
176}
177
178void FbRun::keyPressEvent(XKeyEvent &ke) {
179 KeySym ks;
180 char keychar[1];
181 XLookupString(&ke, keychar, 1, &ks, 0);
182 if (ks == XK_Escape) {
183 m_end = true;
184 hide();
185 FbTk::App::instance()->end(); // end program
186 return; // no more processing
187 } else if (ks == XK_Return) {
188 run(m_runtext);
189 m_runtext = ""; // clear text
190 } else if (ks == XK_BackSpace) {
191 if (m_runtext.size() != 0) { // we can't erase what we don't have ;)
192 m_runtext.erase(m_runtext.size()-1);
193 redrawLabel();
194 }
195 } else if (! IsModifierKey(ks) && !IsCursorKey(ks)) {
196 m_runtext+=keychar[0]; // append character
197 redrawLabel();
198 } else if (IsCursorKey(ks)) {
199
200 switch (ks) {
201 case XK_Up:
202 prevHistoryItem();
203 break;
204 case XK_Down:
205 nextHistoryItem();
206 break;
207 }
208 redrawLabel();
209 }
210}
211
212void FbRun::exposeEvent(XExposeEvent &ev) {
213 redrawLabel();
214}
215
216
217void FbRun::setNoMaximize() {
218 // we don't need to maximize this window
219 XSizeHints sh;
220 sh.flags = PMaxSize | PMinSize;
221 sh.max_width = m_win.width();
222 sh.max_height = m_win.height();
223 sh.min_width = m_win.width();
224 sh.min_height = m_win.height();
225 XSetWMNormalHints(m_display, m_win.window(), &sh);
226}
227
228void FbRun::prevHistoryItem() {
229
230 if (m_current_history_item > 0 && m_history.size() > 0)
231 m_current_history_item--;
232 if (m_current_history_item < m_history.size())
233 m_runtext = m_history[m_current_history_item];
234}
235
236void FbRun::nextHistoryItem() {
237 m_current_history_item++;
238 if (m_current_history_item >= m_history.size()) {
239 m_current_history_item = m_history.size();
240 m_runtext = "";
241 return;
242 } else
243 m_runtext = m_history[m_current_history_item];
244
245}