//
// PixmapHandler.cc for pekwm
// Copyright (C) 2003-2004 Claes Nasten <pekdon{@}pekdon{.}net>
//
// This program is licensed under the GNU GPL.
// See the LICENSE file for more information.
//
#include "../config.h"
#include "PixmapHandler.hh"
#include "PScreen.hh"
#ifdef DEBUG
#include <iostream>
using std::cerr;
using std::endl;
#endif // DEBUG
#include <list>
using std::list;
// PixmapHandler::Entry
//! @brief Constructor for Entry class
PixmapHandler::Entry::Entry(uint width, uint height, uint depth, Pixmap pixmap) :
_width(width), _height(height), _depth(depth), _pixmap(pixmap)
{
}
//! @brief Destructor for Entry class
PixmapHandler::Entry::~Entry(void)
{
XFreePixmap(PScreen::instance()->getDpy(), _pixmap);
}
// PixmapHandler
//! @brief Constructor for PixmapHandler class
PixmapHandler::PixmapHandler(uint cache_size, uint threshold) :
_cache_size(cache_size), _size_threshold(threshold)
{
}
//! @brief Destructor for PixmapHandler class
PixmapHandler::~PixmapHandler(void)
{
#ifdef DEBUG
if (_used_list.size() > 0) {
cerr << __FILE__ << "@" << __LINE__ << ": "
<< "Used pixmap list size > 0, size: " << _used_list.size() << endl;
}
#endif // DEBUG
list<Entry*>::iterator it;
for (it = _free_list.begin(); it != _free_list.end(); ++it) {
delete *it;
}
for (it = _used_list.begin(); it != _used_list.end(); ++it) {
delete *it;
}
}
//! @brief Sets the cache size and trims the cache if needed
void
PixmapHandler::setCacheSize(uint cache)
{
_cache_size = cache;
while (_free_list.size() > _cache_size) {
delete _free_list.front();
_free_list.pop_front();
}
}
//! @brief Sets size threshold
void
PixmapHandler::setThreshold(uint threshold)
{
_size_threshold = threshold;
}
//! @brief Searches the Pixmap cache for a sutiable Pixmap or creates a new
//! @param width Width of the pixmap
//! @param height Height of the pixmap
//! @param depth Depth of the pixmap
//! @param exact Wheter or not to match the exact size ignoring threshold
Pixmap
PixmapHandler::getPixmap(uint width, uint height, uint depth, bool exact)
{
Pixmap pixmap = None;
// search allready created pixmaps
list<Entry*>::iterator it(_free_list.begin());
for (; it != _free_list.end(); ++it) {
if ((*it)->isMatch(width, height, depth, exact ? 0 : _size_threshold)) {
pixmap = (*it)->getPixmap();
// move the entry to the used list
_used_list.push_back(*it);
_free_list.erase(it);
break;
}
}
// no entry, create one
if (pixmap == None) {
pixmap = XCreatePixmap(PScreen::instance()->getDpy(),
PScreen::instance()->getRoot(),
width, height, depth);
_used_list.push_back(new Entry(width, height, depth, pixmap));
}
return pixmap;
}
//! @brief Returns the pixmap to the Pixmap cache
void
PixmapHandler::returnPixmap(Pixmap pixmap)
{
list<Entry*>::iterator it(_used_list.begin());
for (; it != _used_list.end(); ++it) {
if ((*it)->getPixmap() == pixmap) {
Entry *entry = *it;
// move the pixmap to the back ( front ) of the cache
_used_list.erase(it);
_free_list.push_back(entry);
break;
}
}
// trim the cache
while (_free_list.size() > _cache_size) {
delete _free_list.front();
_free_list.pop_front();
}
}
syntax highlighted by Code2HTML, v. 0.9.1