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.cc321
1 files changed, 141 insertions, 180 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc
index 1dc5ae7..0ce297a 100644
--- a/util/fbrun/FbRun.cc
+++ b/util/fbrun/FbRun.cc
@@ -19,12 +19,13 @@
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.8 2002/11/27 21:56:56 fluxgen Exp $ 22// $Id: FbRun.cc,v 1.9 2002/12/05 00:07:39 fluxgen Exp $
23 23
24#include "FbRun.hh" 24#include "FbRun.hh"
25 25
26#include "App.hh" 26#include "App.hh"
27#include "EventManager.hh" 27#include "EventManager.hh"
28#include "Color.hh"
28 29
29#include <X11/Xlib.h> 30#include <X11/Xlib.h>
30#include <X11/keysym.h> 31#include <X11/keysym.h>
@@ -37,248 +38,208 @@
37 38
38using namespace std; 39using namespace std;
39FbRun::FbRun(int x, int y, size_t width): 40FbRun::FbRun(int x, int y, size_t width):
40m_font("fixed"), 41 m_font("fixed"),
41m_win(None), 42 m_win((int)0, x, y, //screen num and position
42m_display(FbTk::App::instance()->display()), 43 width + m_bevel, m_font.height(), // size
43m_bevel(4), 44 KeyPressMask|ExposureMask), // eventmask
44m_gc(DefaultGC(m_display, DefaultScreen(m_display))), 45 m_display(FbTk::App::instance()->display()),
45m_end(false), 46 m_bevel(4),
46m_current_history_item(0) { 47 m_gc(DefaultGC(m_display, DefaultScreen(m_display))),
47 createWindow(x, y, width + m_bevel, m_font.height()); 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());
48} 53}
49 54
50FbRun::~FbRun() { 55FbRun::~FbRun() {
51 hide(); 56 hide();
52 FbTk::EventManager::instance()->unregisterEventHandler(m_win); 57 FbTk::EventManager::instance()->unregisterEventHandler(m_win.window());
53 XDestroyWindow(m_display, m_win);
54} 58}
55 59
56void FbRun::run(const std::string &command) { 60void FbRun::run(const std::string &command) {
57 //fork and execute program 61 //fork and execute program
58 if (!fork()) { 62 if (!fork()) {
59 setsid(); 63 setsid();
60 execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0); 64 execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0);
61 exit(0); //exit fork 65 exit(0); //exit child
62 } 66 }
63 67
64 hide(); // hide gui 68 hide(); // hide gui
65 69
66 // save command history to file 70 // save command history to file
67 if (m_runtext.size() != 0) { // no need to save empty command 71 if (m_runtext.size() != 0) { // no need to save empty command
68 // open file in append mode 72 // open file in append mode
69 ofstream outfile(m_history_file.c_str(), ios::app); 73 ofstream outfile(m_history_file.c_str(), ios::app);
70 if (outfile) 74 if (outfile)
71 outfile<<m_runtext<<endl; 75 outfile<<m_runtext<<endl;
72 else 76 else
73 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl; 77 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
74 } 78 }
75 FbTk::App::instance()->end(); // end application 79 FbTk::App::instance()->end(); // end application
76 m_end = true; // mark end of processing 80 m_end = true; // mark end of processing
77} 81}
78 82
79bool FbRun::loadHistory(const char *filename) { 83bool FbRun::loadHistory(const char *filename) {
80 if (filename == 0) 84 if (filename == 0)
81 return false; 85 return false;
82 ifstream infile(filename); 86 ifstream infile(filename);
83 if (!infile) { 87 if (!infile) {
84 //even though we fail to load file, we should try save to it 88 //even though we fail to load file, we should try save to it
85 m_history_file = filename; 89 m_history_file = filename;
86 return false; 90 return false;
87 } 91 }
88 // clear old history and load new one from file 92 // clear old history and load new one from file
89 m_history.clear(); 93 m_history.clear();
90 // each line is a command 94 // each line is a command
91 string line; 95 string line;
92 while (!infile.eof()) { 96 while (!infile.eof()) {
93 getline(infile, line); 97 getline(infile, line);
94 if (line.size()) // don't add empty lines 98 if (line.size()) // don't add empty lines
95 m_history.push_back(line); 99 m_history.push_back(line);
96 } 100 }
97 // set no current histor to display 101 // set no current histor to display
98 m_current_history_item = m_history.size(); 102 m_current_history_item = m_history.size();
99 // set history file 103 // set history file
100 m_history_file = filename; 104 m_history_file = filename;
101 return true; 105 return true;
102} 106}
103 107
104bool FbRun::loadFont(const string &fontname) { 108bool FbRun::loadFont(const string &fontname) {
105 if (!m_font.load(fontname.c_str())) 109 if (!m_font.load(fontname.c_str()))
106 return false; 110 return false;
107 111
108 // resize to fit new font height 112 // resize to fit new font height
109 resize(m_width, m_font.height() + m_bevel); 113 resize(m_win.width(), m_font.height() + m_bevel);
110 return true; 114 return true;
111} 115}
112 116
113void FbRun::setForeground(const XColor &color) { 117void FbRun::setForeground(const FbTk::Color &color) {
114 XSetForeground(m_display, m_gc, color.pixel); 118 XSetForeground(m_display, m_gc, color.pixel());
115 redrawLabel(); 119 redrawLabel();
116} 120}
117 121
118void FbRun::setBackground(const XColor &color) { 122void FbRun::setBackground(const FbTk::Color &color) {
119 XSetWindowBackground(m_display, m_win, color.pixel); 123 m_win.setBackgroundColor(color);
120 redrawLabel(); 124 redrawLabel();
121} 125}
122 126
123 127
124void FbRun::setText(const string &text) { 128void FbRun::setText(const string &text) {
125 m_runtext = text; 129 m_runtext = text;
126 redrawLabel(); 130 redrawLabel();
127} 131}
128 132
129void FbRun::setTitle(const string &title) { 133void FbRun::setTitle(const string &title) {
130 assert(m_win); 134 m_win.setName(title.c_str());
131 XStoreName(m_display, m_win, const_cast<char *>(title.c_str()));
132} 135}
133 136
134void FbRun::move(int x, int y) { 137void FbRun::move(int x, int y) {
135 XMoveWindow(m_display, m_win, x, y); 138 m_win.move(x, y);
136} 139}
137 140
138void FbRun::resize(size_t width, size_t height) { 141void FbRun::resize(size_t width, size_t height) {
139 assert(m_win); 142 m_win.resize(width, height);
140 XResizeWindow(m_display, m_win, width, height); 143 setNoMaximize();
141 m_width = width;
142 m_height = height;
143 setNoMaximize();
144} 144}
145 145
146void FbRun::show() { 146void FbRun::show() {
147 assert(m_win); 147 m_win.show();
148 XMapWindow(m_display, m_win);
149} 148}
150 149
151void FbRun::hide() { 150void FbRun::hide() {
152 assert(m_win); 151 m_win.hide();
153 XUnmapWindow(m_display, m_win);
154} 152}
155 153
156void FbRun::redrawLabel() { 154void FbRun::redrawLabel() {
157 assert(m_win); 155 m_win.clear();
158 156 drawString(m_bevel/2, m_font.ascent() + m_bevel/2,
159 XClearWindow(m_display, m_win); 157 m_runtext.c_str(), m_runtext.size());
160 drawString(m_bevel/2, m_font.ascent() + m_bevel/2,
161 m_runtext.c_str(), m_runtext.size());
162 158
163} 159}
164 160
165void FbRun::drawString(int x, int y, 161void FbRun::drawString(int x, int y,
166 const char *text, size_t len) { 162 const char *text, size_t len) {
167 assert(m_win); 163 assert(m_gc);
168 assert(m_gc);
169 // check right boundary
170 // and adjust text drawing
171 size_t text_width = m_font.textWidth(text, len);
172 size_t startpos = 0;
173 if (text_width > m_width) {
174 for (; startpos < len; ++startpos) {
175 if (m_font.textWidth(text+startpos, len-startpos) < m_width)
176 break;
177 }
178 }
179
180 m_font.drawText(m_win, DefaultScreen(m_display), m_gc, text + startpos, len-startpos, x, y);
181}
182
183
184void FbRun::createWindow(int x, int y, size_t width, size_t height) {
185 m_win = XCreateSimpleWindow(m_display, // display
186 DefaultRootWindow(m_display), // parent windows
187 x, y,
188 width, height,
189 1, // border_width
190 0, // border
191 WhitePixel(m_display, DefaultScreen(m_display))); // background
192
193 if (m_win == None)
194 throw string("Failed to create FbRun window!");
195
196 XSelectInput(m_display, m_win, KeyPressMask|ExposureMask);
197
198 FbTk::EventManager::instance()->registerEventHandler(*this, m_win);
199
200 setNoMaximize();
201 164
202 m_width = width; 165 // check right boundary and adjust text drawing
203 m_height = height; 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 }
204 174
175 m_font.drawText(m_win.window(), DefaultScreen(m_display), m_gc, text + startpos, len-startpos, x, y);
205} 176}
206 177
207void FbRun::keyPressEvent(XKeyEvent &ke) { 178void FbRun::keyPressEvent(XKeyEvent &ke) {
208 KeySym ks; 179 KeySym ks;
209 char keychar[1]; 180 char keychar[1];
210 XLookupString(&ke, keychar, 1, &ks, 0); 181 XLookupString(&ke, keychar, 1, &ks, 0);
211 if (ks == XK_Escape) { 182 if (ks == XK_Escape) {
212 m_end = true; 183 m_end = true;
213 hide(); 184 hide();
214 return; // no more processing 185 FbTk::App::instance()->end(); // end program
215 } else if (ks == XK_Return) { 186 return; // no more processing
216 run(m_runtext); 187 } else if (ks == XK_Return) {
217 m_runtext = ""; // clear text 188 run(m_runtext);
218 } else if (ks == XK_BackSpace) { 189 m_runtext = ""; // clear text
219 if (m_runtext.size() != 0) { // we can't erase what we don't have ;) 190 } else if (ks == XK_BackSpace) {
220 m_runtext.erase(m_runtext.size()-1); 191 if (m_runtext.size() != 0) { // we can't erase what we don't have ;)
221 redrawLabel(); 192 m_runtext.erase(m_runtext.size()-1);
222 } 193 redrawLabel();
223 } else if (! IsModifierKey(ks) && !IsCursorKey(ks)) { 194 }
224 m_runtext+=keychar[0]; // append character 195 } else if (! IsModifierKey(ks) && !IsCursorKey(ks)) {
225 redrawLabel(); 196 m_runtext+=keychar[0]; // append character
226 } else if (IsCursorKey(ks)) { 197 redrawLabel();
198 } else if (IsCursorKey(ks)) {
227 199
228 switch (ks) { 200 switch (ks) {
229 case XK_Up: 201 case XK_Up:
230 prevHistoryItem(); 202 prevHistoryItem();
231 break; 203 break;
232 case XK_Down: 204 case XK_Down:
233 nextHistoryItem(); 205 nextHistoryItem();
234 break; 206 break;
235 } 207 }
236 redrawLabel(); 208 redrawLabel();
237 } 209 }
238} 210}
239 211
240void FbRun::exposeEvent(XExposeEvent &ev) { 212void FbRun::exposeEvent(XExposeEvent &ev) {
241 redrawLabel(); 213 redrawLabel();
242} 214}
243 215
244void FbRun::getSize(size_t &width, size_t &height) {
245 XWindowAttributes attr;
246 XGetWindowAttributes(m_display, m_win, &attr);
247 width = attr.width;
248 height = attr.height;
249}
250 216
251void FbRun::setNoMaximize() { 217void FbRun::setNoMaximize() {
252 218 // we don't need to maximize this window
253 size_t width, height; 219 XSizeHints sh;
254 220 sh.flags = PMaxSize | PMinSize;
255 getSize(width, height); 221 sh.max_width = m_win.width();
256 222 sh.max_height = m_win.height();
257 // we don't need to maximize this window 223 sh.min_width = m_win.width();
258 XSizeHints sh; 224 sh.min_height = m_win.height();
259 sh.flags = PMaxSize | PMinSize; 225 XSetWMNormalHints(m_display, m_win.window(), &sh);
260 sh.max_width = width;
261 sh.max_height = height;
262 sh.min_width = width;
263 sh.min_height = height;
264 XSetWMNormalHints(m_display, m_win, &sh);
265} 226}
266 227
267void FbRun::prevHistoryItem() { 228void FbRun::prevHistoryItem() {
268 229
269 if (m_current_history_item > 0 && m_history.size() > 0) 230 if (m_current_history_item > 0 && m_history.size() > 0)
270 m_current_history_item--; 231 m_current_history_item--;
271 if (m_current_history_item < m_history.size()) 232 if (m_current_history_item < m_history.size())
272 m_runtext = m_history[m_current_history_item]; 233 m_runtext = m_history[m_current_history_item];
273} 234}
274 235
275void FbRun::nextHistoryItem() { 236void FbRun::nextHistoryItem() {
276 m_current_history_item++; 237 m_current_history_item++;
277 if (m_current_history_item >= m_history.size()) { 238 if (m_current_history_item >= m_history.size()) {
278 m_current_history_item = m_history.size(); 239 m_current_history_item = m_history.size();
279 m_runtext = ""; 240 m_runtext = "";
280 return; 241 return;
281 } else 242 } else
282 m_runtext = m_history[m_current_history_item]; 243 m_runtext = m_history[m_current_history_item];
283 244
284} 245}