diff options
Diffstat (limited to 'src/Workspace.cc')
-rw-r--r-- | src/Workspace.cc | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/src/Workspace.cc b/src/Workspace.cc new file mode 100644 index 0000000..8c46b43 --- /dev/null +++ b/src/Workspace.cc | |||
@@ -0,0 +1,339 @@ | |||
1 | // Workspace.cc for FbPager | ||
2 | // Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) | ||
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$ | ||
23 | |||
24 | #include "Workspace.hh" | ||
25 | |||
26 | #include "FbTk/App.hh" | ||
27 | #include "FbTk/Color.hh" | ||
28 | #include "FbTk/EventManager.hh" | ||
29 | |||
30 | #include "ScaleWindowToWindow.hh" | ||
31 | #include "FbRootWindow.hh" | ||
32 | |||
33 | #include <X11/Xutil.h> | ||
34 | |||
35 | #include <iostream> | ||
36 | #include <algorithm> | ||
37 | #include <functional> | ||
38 | using namespace std; | ||
39 | |||
40 | namespace FbPager { | ||
41 | |||
42 | Window Workspace::s_focused_window = 0; | ||
43 | |||
44 | Workspace::Workspace(FbTk::EventHandler &evh, | ||
45 | FbTk::FbWindow &parent, unsigned int width, unsigned int height, | ||
46 | const FbTk::Color &focused_win_color, | ||
47 | const FbTk::Color &wincolor, const FbTk::Color &border_color, | ||
48 | const FbTk::Color &background_color, | ||
49 | const char *name, | ||
50 | const bool use_pixmap, | ||
51 | const int window_border_width): | ||
52 | m_name(name ? name : ""), | ||
53 | m_window(parent, | ||
54 | 0, 0, // position | ||
55 | width, height, // size | ||
56 | ButtonPressMask | ButtonReleaseMask | ExposureMask | ButtonMotionMask), | ||
57 | m_eventhandler(evh), | ||
58 | m_window_color(wincolor), | ||
59 | m_focused_window_color(focused_win_color), | ||
60 | m_window_bordercolor(border_color), | ||
61 | m_focused_window(0), | ||
62 | m_use_pixmap(use_pixmap), | ||
63 | m_window_border_width(window_border_width) { | ||
64 | |||
65 | m_window.setBackgroundColor(background_color); | ||
66 | FbTk::EventManager::instance()->add(evh, m_window); | ||
67 | } | ||
68 | |||
69 | Workspace::~Workspace() { | ||
70 | WindowList::iterator it = m_windowlist.begin(); | ||
71 | WindowList::iterator it_end = m_windowlist.end(); | ||
72 | for (; it != it_end; ++it) { | ||
73 | FbTk::EventManager::instance()->remove(*(*it).second); | ||
74 | FbTk::EventManager::instance()->remove((*it).first); | ||
75 | delete (*it).second; | ||
76 | } | ||
77 | |||
78 | FbTk::EventManager::instance()->remove(m_window); | ||
79 | } | ||
80 | |||
81 | void Workspace::add(Window win) { | ||
82 | FbTk::FbWindow *fbwin = find(win); | ||
83 | if (fbwin != 0) | ||
84 | delete fbwin; | ||
85 | |||
86 | |||
87 | fbwin = new FbTk::FbWindow(m_window, // parent | ||
88 | 0, 0, // pos | ||
89 | 10, 10, // size | ||
90 | // event mask | ||
91 | ExposureMask); | ||
92 | // fbwin->setAlpha(m_window.alpha()); | ||
93 | |||
94 | XSelectInput(FbTk::App::instance()->display(), win, | ||
95 | PropertyChangeMask | // for shade/iconic state | ||
96 | StructureNotifyMask // for pos and size | ||
97 | ); | ||
98 | // add to event manager | ||
99 | FbTk::EventManager::instance()->add(m_eventhandler, *fbwin); | ||
100 | FbTk::EventManager::instance()->add(m_eventhandler, win); | ||
101 | |||
102 | // add window to list | ||
103 | m_windowlist[win] = fbwin; | ||
104 | |||
105 | // update pos and size | ||
106 | updateGeometry(win); | ||
107 | |||
108 | fbwin->show(); | ||
109 | fbwin->setBorderWidth(m_window_border_width); | ||
110 | fbwin->setBorderColor(m_window_bordercolor); | ||
111 | |||
112 | updateBackground(win, m_window_color); | ||
113 | } | ||
114 | |||
115 | void Workspace::resize(unsigned int width, unsigned int height) { | ||
116 | m_window.resize(width, height); | ||
117 | WindowList::iterator it = m_windowlist.begin(); | ||
118 | WindowList::iterator it_end = m_windowlist.end(); | ||
119 | for (; it != it_end; ++it) { | ||
120 | updateGeometry((*it).first); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | |||
125 | void Workspace::shadeWindow(Window win) { | ||
126 | FbTk::FbWindow *fbwin = find(win); | ||
127 | if (fbwin == 0) | ||
128 | return; | ||
129 | |||
130 | fbwin->resize(fbwin->width(), m_window.height()/30); | ||
131 | } | ||
132 | |||
133 | void Workspace::unshadeWindow(Window win) { | ||
134 | updateGeometry(win); | ||
135 | } | ||
136 | |||
137 | void Workspace::iconifyWindow(Window win) { | ||
138 | FbTk::FbWindow *fbwin = find(win); | ||
139 | if (fbwin == 0) | ||
140 | return; | ||
141 | |||
142 | fbwin->hide(); | ||
143 | } | ||
144 | |||
145 | void Workspace::deiconifyWindow(Window win) { | ||
146 | FbTk::FbWindow *fbwin = find(win); | ||
147 | if (fbwin != 0) | ||
148 | return; | ||
149 | fbwin->show(); | ||
150 | } | ||
151 | |||
152 | void Workspace::lowerWindow(Window win) { | ||
153 | FbTk::FbWindow *fbwin = find(win); | ||
154 | if (fbwin == 0) | ||
155 | return; | ||
156 | fbwin->lower(); | ||
157 | } | ||
158 | |||
159 | void Workspace::raiseWindow(Window win) { | ||
160 | FbTk::FbWindow *fbwin = find(win); | ||
161 | if (fbwin == 0) | ||
162 | return; | ||
163 | fbwin->raise(); | ||
164 | } | ||
165 | |||
166 | void Workspace::setWindowColor(const std::string &focused, | ||
167 | const std::string &unfocused, | ||
168 | const std::string &bordercolor_str) { | ||
169 | m_window_color = FbTk::Color(unfocused.c_str(), m_window.screenNumber()); | ||
170 | m_focused_window_color = FbTk::Color(focused.c_str(), m_window.screenNumber()); | ||
171 | m_window_bordercolor = FbTk::Color(bordercolor_str.c_str(), m_window.screenNumber()); | ||
172 | |||
173 | WindowList::iterator it = m_windowlist.begin(); | ||
174 | WindowList::iterator it_end = m_windowlist.end(); | ||
175 | for (; it != it_end; ++it) { | ||
176 | (*it).second->setBorderColor(m_window_bordercolor); | ||
177 | updateBackground((*it).first, m_window_color); | ||
178 | } | ||
179 | updateFocusedWindow(); | ||
180 | } | ||
181 | |||
182 | |||
183 | void Workspace::setAlpha(unsigned char alpha) { | ||
184 | m_window.setAlpha(alpha); | ||
185 | WindowList::iterator it = m_windowlist.begin(); | ||
186 | WindowList::iterator it_end = m_windowlist.end(); | ||
187 | for (; it != it_end; ++it) { | ||
188 | (*it).second->setAlpha(alpha); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void Workspace::clearWindows() { | ||
193 | m_window.clear(); | ||
194 | WindowList::iterator it = m_windowlist.begin(); | ||
195 | WindowList::iterator it_end = m_windowlist.end(); | ||
196 | for (; it != it_end; ++it) { | ||
197 | if (m_use_pixmap) { | ||
198 | updateBackground((*it).first,m_window_color); | ||
199 | } | ||
200 | (*it).second->clear(); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | void Workspace::remove(Window win) { | ||
205 | FbTk::FbWindow *fbwin = find(win); | ||
206 | if (fbwin == 0) | ||
207 | return; | ||
208 | FbTk::EventManager::instance()->remove(*fbwin); | ||
209 | // FbTk::EventManager::instance()->remove(win); | ||
210 | |||
211 | delete fbwin; | ||
212 | |||
213 | if (fbwin == m_focused_window) | ||
214 | m_focused_window = 0; | ||
215 | |||
216 | m_windowlist.erase(win); | ||
217 | } | ||
218 | |||
219 | ClientWindow Workspace::findClient(const FbTk::FbWindow &win) const { | ||
220 | WindowList::const_iterator it = m_windowlist.begin(); | ||
221 | WindowList::const_iterator it_end = m_windowlist.end(); | ||
222 | for (; it != it_end; ++it) { | ||
223 | if (*(*it).second == win) | ||
224 | return ClientWindow((*it).first); | ||
225 | } | ||
226 | return ClientWindow(0); | ||
227 | } | ||
228 | |||
229 | FbTk::FbWindow *Workspace::find(Window win) { | ||
230 | WindowList::iterator it = m_windowlist.begin(); | ||
231 | WindowList::iterator it_end = m_windowlist.end(); | ||
232 | for (; it != it_end; ++it) { | ||
233 | if ((*it).second->window() == win || | ||
234 | (*it).first == win) | ||
235 | return it->second; | ||
236 | } | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | const FbTk::FbWindow *Workspace::find(Window win) const { | ||
241 | WindowList::const_iterator it = m_windowlist.begin(); | ||
242 | WindowList::const_iterator it_end = m_windowlist.end(); | ||
243 | for (; it != it_end; ++it) { | ||
244 | if ((*it).second->window() == win || | ||
245 | (*it).first == win) | ||
246 | return it->second; | ||
247 | } | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | void Workspace::updateFocusedWindow() { | ||
252 | if (s_focused_window == 0) | ||
253 | return; | ||
254 | |||
255 | FbTk::FbWindow *fbwin = find(s_focused_window); | ||
256 | if (fbwin == m_focused_window) | ||
257 | return; | ||
258 | |||
259 | if (m_focused_window != 0) { | ||
260 | |||
261 | updateBackground(m_focused_window->window(), m_window_color); | ||
262 | m_focused_window->clear(); | ||
263 | } | ||
264 | |||
265 | if (fbwin == 0) { | ||
266 | m_focused_window = 0; | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | WindowList::const_iterator it = m_windowlist.begin(); | ||
271 | WindowList::const_iterator it_end = m_windowlist.end(); | ||
272 | for (; it != it_end; ++it) { | ||
273 | if ((*it).second == fbwin ) | ||
274 | break; | ||
275 | } | ||
276 | |||
277 | if (it == it_end) | ||
278 | return; | ||
279 | |||
280 | updateBackground((*it).first, m_focused_window_color); | ||
281 | fbwin->clear(); | ||
282 | m_focused_window = fbwin; | ||
283 | } | ||
284 | |||
285 | void Workspace::updateGeometry(Window win) { | ||
286 | |||
287 | FbTk::FbWindow* fbwin= find(win); | ||
288 | if (!fbwin) | ||
289 | return; | ||
290 | |||
291 | int x = 0, y = 0; | ||
292 | Window child; | ||
293 | ClientWindow client(win); | ||
294 | FbRootWindow rootwin(m_window.screenNumber()); | ||
295 | rootwin.translateCoordinates(client, | ||
296 | client.x(), client.y(), | ||
297 | x, y, | ||
298 | child); | ||
299 | x = -x; | ||
300 | y = -y; | ||
301 | unsigned int w = client.width(), h = client.height(); | ||
302 | scaleFromWindowToWindow(rootwin, m_window, x, y); | ||
303 | scaleFromWindowToWindow(rootwin, m_window, w, h); | ||
304 | w -= fbwin->borderWidth(); | ||
305 | if (w == 0) | ||
306 | w = 1; | ||
307 | if (h == 0) | ||
308 | h = 1; | ||
309 | |||
310 | fbwin->moveResize(x, y, w, h); | ||
311 | updateBackground(win, m_window_color); | ||
312 | } | ||
313 | |||
314 | void Workspace::updateBackground(Window win, const FbTk::Color &bg_color) { | ||
315 | |||
316 | FbTk::FbWindow* fbwin= find(win); | ||
317 | if (!fbwin ) | ||
318 | return; | ||
319 | |||
320 | |||
321 | if (m_use_pixmap) { | ||
322 | XWMHints *hints = XGetWMHints(FbTk::App::instance()->display(), win); | ||
323 | if (hints && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) { | ||
324 | FbTk::FbPixmap fbpix; | ||
325 | fbpix.copy(hints->icon_pixmap); | ||
326 | fbpix.scale(fbwin->width(), fbwin->height()); | ||
327 | fbwin->setBackgroundPixmap(fbpix.drawable()); | ||
328 | } | ||
329 | else | ||
330 | fbwin->setBackgroundColor(bg_color); | ||
331 | |||
332 | XFree(hints); | ||
333 | } | ||
334 | else | ||
335 | fbwin->setBackgroundColor(bg_color); | ||
336 | } | ||
337 | |||
338 | }; // end namespace FbPager | ||
339 | |||