// 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 <X11/Xutil.h>
#include <iostream>
#include <algorithm>
#include <functional>
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
64, 64, // 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);
}
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
syntax highlighted by Code2HTML, v. 0.9.1