// Workspace.cc for FbPager // Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // $Id$ #include "Workspace.hh" #include "FbTk/App.hh" #include "FbTk/Color.hh" #include "FbTk/EventManager.hh" #include "ScaleWindowToWindow.hh" #include "FbRootWindow.hh" #include #include #include #include using namespace std; namespace FbPager { Window Workspace::s_focused_window = 0; Workspace::Workspace(FbTk::EventHandler &evh, FbTk::FbWindow &parent, unsigned int width, unsigned int height, const FbTk::Color &focused_win_color, const FbTk::Color &wincolor, const FbTk::Color &border_color, const FbTk::Color &background_color, const char *name, const bool use_pixmap, const int window_border_width): m_name(name ? name : ""), m_window(parent, 0, 0, // position width, height, // size ButtonPressMask | ButtonReleaseMask | ExposureMask | ButtonMotionMask), m_eventhandler(evh), m_window_color(wincolor), m_focused_window_color(focused_win_color), m_window_bordercolor(border_color), m_focused_window(0), m_use_pixmap(use_pixmap), m_window_border_width(window_border_width) { m_window.setBackgroundColor(background_color); FbTk::EventManager::instance()->add(evh, m_window); } Workspace::~Workspace() { WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { FbTk::EventManager::instance()->remove(*(*it).second); FbTk::EventManager::instance()->remove((*it).first); delete (*it).second; } FbTk::EventManager::instance()->remove(m_window); } void Workspace::add(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin != 0) delete fbwin; fbwin = new FbTk::FbWindow(m_window, // parent 0, 0, // pos 10, 10, // size // event mask ExposureMask); // fbwin->setAlpha(m_window.alpha()); XSelectInput(FbTk::App::instance()->display(), win, PropertyChangeMask | // for shade/iconic state StructureNotifyMask // for pos and size ); // add to event manager FbTk::EventManager::instance()->add(m_eventhandler, *fbwin); FbTk::EventManager::instance()->add(m_eventhandler, win); // add window to list m_windowlist[win] = fbwin; // update pos and size updateGeometry(win); fbwin->show(); fbwin->setBorderWidth(m_window_border_width); fbwin->setBorderColor(m_window_bordercolor); updateBackground(win, m_window_color); } void Workspace::resize(unsigned int width, unsigned int height) { m_window.resize(width, height); WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { updateGeometry((*it).first); } } void Workspace::shadeWindow(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin == 0) return; fbwin->resize(fbwin->width(), m_window.height()/30); } void Workspace::unshadeWindow(Window win) { updateGeometry(win); } void Workspace::iconifyWindow(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin == 0) return; fbwin->hide(); } void Workspace::deiconifyWindow(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin != 0) return; fbwin->show(); } void Workspace::lowerWindow(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin == 0) return; fbwin->lower(); } void Workspace::raiseWindow(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin == 0) return; fbwin->raise(); } void Workspace::setWindowColor(const std::string &focused, const std::string &unfocused, const std::string &bordercolor_str) { m_window_color = FbTk::Color(unfocused.c_str(), m_window.screenNumber()); m_focused_window_color = FbTk::Color(focused.c_str(), m_window.screenNumber()); m_window_bordercolor = FbTk::Color(bordercolor_str.c_str(), m_window.screenNumber()); WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { (*it).second->setBorderColor(m_window_bordercolor); updateBackground((*it).first, m_window_color); } updateFocusedWindow(); } void Workspace::setAlpha(unsigned char alpha) { m_window.setAlpha(alpha); WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { (*it).second->setAlpha(alpha); } } void Workspace::clearWindows() { m_window.clear(); WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { if (m_use_pixmap) { updateBackground((*it).first,m_window_color); } (*it).second->clear(); } } void Workspace::remove(Window win) { FbTk::FbWindow *fbwin = find(win); if (fbwin == 0) return; FbTk::EventManager::instance()->remove(*fbwin); // FbTk::EventManager::instance()->remove(win); delete fbwin; if (fbwin == m_focused_window) m_focused_window = 0; m_windowlist.erase(win); } void Workspace::removeAll() { WindowList::iterator it = m_windowlist.begin(); for (; it != m_windowlist.end(); ++it) { FbTk::EventManager::instance()->remove(*(it->second)); delete it->second; } m_windowlist.clear(); s_focused_window = 0; } ClientWindow Workspace::findClient(const FbTk::FbWindow &win) const { WindowList::const_iterator it = m_windowlist.begin(); WindowList::const_iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { if (*(*it).second == win) return ClientWindow((*it).first); } return ClientWindow(0); } FbTk::FbWindow *Workspace::find(Window win) { WindowList::iterator it = m_windowlist.begin(); WindowList::iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { if ((*it).second->window() == win || (*it).first == win) return it->second; } return 0; } const FbTk::FbWindow *Workspace::find(Window win) const { WindowList::const_iterator it = m_windowlist.begin(); WindowList::const_iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { if ((*it).second->window() == win || (*it).first == win) return it->second; } return 0; } void Workspace::updateFocusedWindow() { if (s_focused_window == 0) return; FbTk::FbWindow *fbwin = find(s_focused_window); if (fbwin == m_focused_window) return; if (m_focused_window != 0) { updateBackground(m_focused_window->window(), m_window_color); m_focused_window->clear(); } if (fbwin == 0) { m_focused_window = 0; return; } WindowList::const_iterator it = m_windowlist.begin(); WindowList::const_iterator it_end = m_windowlist.end(); for (; it != it_end; ++it) { if ((*it).second == fbwin ) break; } if (it == it_end) return; updateBackground((*it).first, m_focused_window_color); fbwin->clear(); m_focused_window = fbwin; } void Workspace::updateGeometry(Window win) { FbTk::FbWindow* fbwin= find(win); if (!fbwin) return; int x = 0, y = 0; Window child; ClientWindow client(win); FbRootWindow rootwin(m_window.screenNumber()); rootwin.translateCoordinates(client, client.x(), client.y(), x, y, child); x = -x; y = -y; unsigned int w = client.width(), h = client.height(); scaleFromWindowToWindow(rootwin, m_window, x, y); scaleFromWindowToWindow(rootwin, m_window, w, h); w -= fbwin->borderWidth(); if (w == 0) w = 1; if (h == 0) h = 1; fbwin->moveResize(x, y, w, h); updateBackground(win, m_window_color); } void Workspace::updateBackground(Window win, const FbTk::Color &bg_color) { FbTk::FbWindow* fbwin= find(win); if (!fbwin ) return; if (m_use_pixmap) { XWMHints *hints = XGetWMHints(FbTk::App::instance()->display(), win); if (hints && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) { FbTk::FbPixmap fbpix; fbpix.copy(hints->icon_pixmap); fbpix.scale(fbwin->width(), fbwin->height()); fbwin->setBackgroundPixmap(fbpix.drawable()); } else fbwin->setBackgroundColor(bg_color); XFree(hints); } else fbwin->setBackgroundColor(bg_color); } }; // end namespace FbPager