moved to FbTk
This commit is contained in:
parent
7dd4823340
commit
c9299fff8f
6 changed files with 0 additions and 2911 deletions
|
@ -1,636 +0,0 @@
|
|||
// ImageControl.cc for Fluxbox Window Manager
|
||||
// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxbox at linuxmail.org)
|
||||
//
|
||||
// Image.cc for Blackbox - an X11 Window manager
|
||||
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.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: ImageControl.cc,v 1.2 2002/12/01 13:41:57 rathnor Exp $
|
||||
|
||||
#include "ImageControl.hh"
|
||||
|
||||
#include "TextureRender.hh"
|
||||
#include "App.hh"
|
||||
|
||||
//use GNU extensions
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif // _GNU_SOURCE
|
||||
|
||||
#include "i18n.hh"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif // HAVE_SYS_TYPES_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif // HAVE_CTYPE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// lookup table for texture
|
||||
unsigned long *BImageControl::sqrt_table = 0;
|
||||
|
||||
namespace { // anonymous
|
||||
|
||||
unsigned long bsqrt(unsigned long x) {
|
||||
if (x <= 0) return 0;
|
||||
if (x == 1) return 1;
|
||||
|
||||
unsigned long r = x >> 1;
|
||||
unsigned long q;
|
||||
|
||||
while (1) {
|
||||
q = x / r;
|
||||
if (q >= r) return r;
|
||||
r = (r + q) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
BImageControl::BImageControl(int screen_num, bool dither,
|
||||
int cpc, unsigned long cache_timeout, unsigned long cmax):
|
||||
m_dither(dither),
|
||||
m_timer(this),
|
||||
m_colors(0),
|
||||
m_num_colors(0),
|
||||
m_colors_per_channel(cpc) {
|
||||
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
|
||||
m_screen_depth = DefaultDepth(disp, screen_num);
|
||||
m_screen_num = screen_num;
|
||||
m_root_window = RootWindow(disp, screen_num);
|
||||
m_visual = DefaultVisual(disp, screen_num);
|
||||
m_colormap = DefaultColormap(disp, screen_num);
|
||||
|
||||
cache_max = cmax;
|
||||
#ifdef TIMEDCACHE
|
||||
if (cache_timeout) {
|
||||
m_timer.setTimeout(cache_timeout);
|
||||
m_timer.start();
|
||||
}
|
||||
#endif // TIMEDCACHE
|
||||
|
||||
createColorTable();
|
||||
}
|
||||
|
||||
|
||||
BImageControl::~BImageControl() {
|
||||
if (sqrt_table) {
|
||||
delete [] sqrt_table;
|
||||
}
|
||||
|
||||
if (grad_xbuffer) {
|
||||
delete [] grad_xbuffer;
|
||||
}
|
||||
|
||||
if (grad_ybuffer) {
|
||||
delete [] grad_ybuffer;
|
||||
}
|
||||
|
||||
if (m_colors) {
|
||||
unsigned long *pixels = new unsigned long [m_num_colors];
|
||||
|
||||
for (unsigned int color = 0; color < m_num_colors; color++)
|
||||
*(pixels + color) = (*(m_colors + color)).pixel;
|
||||
|
||||
XFreeColors(FbTk::App::instance()->display(), m_colormap, pixels, m_num_colors, 0);
|
||||
|
||||
delete [] m_colors;
|
||||
}
|
||||
|
||||
if (cache.size() > 0) {
|
||||
fprintf(stderr,
|
||||
I18n::instance()->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImagePixmapRelease,
|
||||
"BImageContol::~BImageControl: pixmap cache - "
|
||||
"releasing %d pixmaps\n"), cache.size());
|
||||
|
||||
CacheList::iterator it = cache.begin();
|
||||
CacheList::iterator it_end = cache.end();
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
for (; it != it_end; ++it) {
|
||||
XFreePixmap(disp, (*it)->pixmap);
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Pixmap BImageControl::searchCache(unsigned int width, unsigned int height,
|
||||
unsigned long texture_type,
|
||||
const FbTk::Color &color, const FbTk::Color &color_to) const {
|
||||
CacheList::iterator it = cache.begin();
|
||||
CacheList::iterator it_end = cache.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (((*it)->width == width) &&
|
||||
((*it)->height == height) &&
|
||||
((*it)->texture == texture_type) &&
|
||||
((*it)->pixel1 == color.pixel())) {
|
||||
if (texture_type & FbTk::Texture::GRADIENT) {
|
||||
if ((*it)->pixel2 == color_to.pixel()) {
|
||||
(*it)->count++;
|
||||
return (*it)->pixmap;
|
||||
}
|
||||
} else {
|
||||
(*it)->count++;
|
||||
return (*it)->pixmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
Pixmap BImageControl::renderImage(unsigned int width, unsigned int height,
|
||||
const FbTk::Texture &texture) {
|
||||
|
||||
if (texture.type() & FbTk::Texture::PARENTRELATIVE)
|
||||
return ParentRelative;
|
||||
|
||||
// search cache first
|
||||
Pixmap pixmap = searchCache(width, height, texture.type(),
|
||||
texture.color(), texture.colorTo());
|
||||
if (pixmap)
|
||||
return pixmap; // return cache item
|
||||
|
||||
// render new image
|
||||
TextureRender image(*this, width, height);
|
||||
pixmap = image.render(texture);
|
||||
|
||||
if (pixmap) {
|
||||
// create new cache item and add it to cache list
|
||||
|
||||
Cache *tmp = new Cache;
|
||||
|
||||
tmp->pixmap = pixmap;
|
||||
tmp->width = width;
|
||||
tmp->height = height;
|
||||
tmp->count = 1;
|
||||
tmp->texture = texture.type();
|
||||
tmp->pixel1 = texture.color().pixel();
|
||||
|
||||
if (texture.type() & FbTk::Texture::GRADIENT)
|
||||
tmp->pixel2 = texture.colorTo().pixel();
|
||||
else
|
||||
tmp->pixel2 = 0l;
|
||||
|
||||
cache.push_back(tmp);
|
||||
|
||||
if ((unsigned) cache.size() > cache_max) {
|
||||
#ifdef DEBUG
|
||||
cerr<<I18n::instance()->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImagePixmapCacheLarge,
|
||||
"BImageControl::renderImage: cache is large, "
|
||||
"forcing cleanout\n")<<endl;
|
||||
#endif // DEBUG
|
||||
timeout();
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::removeImage(Pixmap pixmap) {
|
||||
if (!pixmap)
|
||||
return;
|
||||
|
||||
CacheList::iterator it = cache.begin();
|
||||
CacheList::iterator it_end = cache.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if ((*it)->pixmap == pixmap) {
|
||||
if ((*it)->count) {
|
||||
(*it)->count--;
|
||||
|
||||
#ifdef TIMEDCACHE
|
||||
timeout();
|
||||
#else // !TIMEDCACHE
|
||||
if (! (*it)->count) timeout();
|
||||
#endif // TIMEDCACHE
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::colorTables(const unsigned char **rmt, const unsigned char **gmt,
|
||||
const unsigned char **bmt,
|
||||
int *roff, int *goff, int *boff,
|
||||
int *rbit, int *gbit, int *bbit) const {
|
||||
|
||||
if (rmt) *rmt = red_color_table;
|
||||
if (gmt) *gmt = green_color_table;
|
||||
if (bmt) *bmt = blue_color_table;
|
||||
|
||||
if (roff) *roff = red_offset;
|
||||
if (goff) *goff = green_offset;
|
||||
if (boff) *boff = blue_offset;
|
||||
|
||||
if (rbit) *rbit = red_bits;
|
||||
if (gbit) *gbit = green_bits;
|
||||
if (bbit) *bbit = blue_bits;
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::getXColorTable(XColor **c, int *n) {
|
||||
if (c) *c = m_colors;
|
||||
if (n) *n = m_num_colors;
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::getGradientBuffers(unsigned int w,
|
||||
unsigned int h,
|
||||
unsigned int **xbuf,
|
||||
unsigned int **ybuf) {
|
||||
|
||||
if (w > grad_buffer_width) {
|
||||
if (grad_xbuffer) {
|
||||
delete [] grad_xbuffer;
|
||||
}
|
||||
|
||||
grad_buffer_width = w;
|
||||
|
||||
grad_xbuffer = new unsigned int[grad_buffer_width * 3];
|
||||
}
|
||||
|
||||
if (h > grad_buffer_height) {
|
||||
if (grad_ybuffer) {
|
||||
delete [] grad_ybuffer;
|
||||
}
|
||||
|
||||
grad_buffer_height = h;
|
||||
|
||||
grad_ybuffer = new unsigned int[grad_buffer_height * 3];
|
||||
}
|
||||
|
||||
*xbuf = grad_xbuffer;
|
||||
*ybuf = grad_ybuffer;
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::installRootColormap() {
|
||||
XGrabServer(FbTk::App::instance()->display());
|
||||
|
||||
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
bool install = true;
|
||||
int i = 0, ncmap = 0;
|
||||
Colormap *cmaps =
|
||||
XListInstalledColormaps(disp, m_root_window, &ncmap);
|
||||
|
||||
if (cmaps) {
|
||||
for (i = 0; i < ncmap; i++) {
|
||||
if (*(cmaps + i) == m_colormap)
|
||||
install = false;
|
||||
}
|
||||
|
||||
if (install)
|
||||
XInstallColormap(disp, m_colormap);
|
||||
|
||||
XFree(cmaps);
|
||||
}
|
||||
|
||||
XUngrabServer(FbTk::App::instance()->display());
|
||||
}
|
||||
|
||||
|
||||
void BImageControl::setColorsPerChannel(int cpc) {
|
||||
if (cpc < 2) cpc = 2;
|
||||
if (cpc > 6) cpc = 6;
|
||||
|
||||
m_colors_per_channel = cpc;
|
||||
}
|
||||
|
||||
|
||||
unsigned long BImageControl::getSqrt(unsigned int x) const {
|
||||
if (! sqrt_table) {
|
||||
// build sqrt table for use with elliptic gradient
|
||||
|
||||
sqrt_table = new unsigned long[(256 * 256 * 2) + 1];
|
||||
int i = 0;
|
||||
|
||||
for (; i < (256 * 256 * 2); i++)
|
||||
*(sqrt_table + i) = bsqrt(i);
|
||||
}
|
||||
|
||||
return (*(sqrt_table + x));
|
||||
}
|
||||
|
||||
void BImageControl::timeout() {
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
CacheList::iterator it = cache.begin();
|
||||
CacheList::iterator it_end = cache.end();
|
||||
for (; it != it_end; ++it) {
|
||||
Cache *tmp = (*it);
|
||||
|
||||
if (tmp->count <= 0) {
|
||||
XFreePixmap(disp, tmp->pixmap);
|
||||
it = cache.erase(it);
|
||||
delete tmp;
|
||||
if (it == it_end) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BImageControl::createColorTable() {
|
||||
Display *disp = FbTk::App::instance()->display();
|
||||
|
||||
grad_xbuffer = grad_ybuffer = (unsigned int *) 0;
|
||||
grad_buffer_width = grad_buffer_height = 0;
|
||||
|
||||
int count;
|
||||
XPixmapFormatValues *pmv = XListPixmapFormats(disp, &count);
|
||||
|
||||
if (pmv) {
|
||||
bits_per_pixel = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (pmv[i].depth == m_screen_depth) {
|
||||
bits_per_pixel = pmv[i].bits_per_pixel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XFree(pmv);
|
||||
}
|
||||
|
||||
if (bits_per_pixel == 0)
|
||||
bits_per_pixel = m_screen_depth;
|
||||
if (bits_per_pixel >= 24)
|
||||
setDither(false);
|
||||
|
||||
red_offset = green_offset = blue_offset = 0;
|
||||
I18n *i18n = I18n::instance();
|
||||
switch (visual()->c_class) {
|
||||
case TrueColor: {
|
||||
int i;
|
||||
|
||||
// compute color tables
|
||||
unsigned long red_mask = visual()->red_mask,
|
||||
green_mask = visual()->green_mask,
|
||||
blue_mask = visual()->blue_mask;
|
||||
|
||||
while (! (red_mask & 1)) { red_offset++; red_mask >>= 1; }
|
||||
while (! (green_mask & 1)) { green_offset++; green_mask >>= 1; }
|
||||
while (! (blue_mask & 1)) { blue_offset++; blue_mask >>= 1; }
|
||||
|
||||
red_bits = 255 / red_mask;
|
||||
green_bits = 255 / green_mask;
|
||||
blue_bits = 255 / blue_mask;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
red_color_table[i] = i / red_bits;
|
||||
green_color_table[i] = i / green_bits;
|
||||
blue_color_table[i] = i / blue_bits;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PseudoColor:
|
||||
case StaticColor: {
|
||||
|
||||
m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel;
|
||||
|
||||
if (m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) {
|
||||
m_colors_per_channel = (1 << m_screen_depth) / 3;
|
||||
m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel;
|
||||
}
|
||||
|
||||
if (m_colors_per_channel < 2 || m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) {
|
||||
fprintf(stderr,
|
||||
i18n->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImageInvalidColormapSize,
|
||||
"BImageControl::BImageControl: invalid colormap size %d "
|
||||
"(%d/%d/%d) - reducing"),
|
||||
m_num_colors, m_colors_per_channel, m_colors_per_channel,
|
||||
m_colors_per_channel);
|
||||
|
||||
m_colors_per_channel = (1 << m_screen_depth) / 3;
|
||||
}
|
||||
|
||||
m_colors = new XColor[m_num_colors];
|
||||
|
||||
int bits = 256 / m_colors_per_channel;
|
||||
|
||||
#ifndef ORDEREDPSEUDO
|
||||
bits = 255 / (m_colors_per_channel - 1);
|
||||
#endif // ORDEREDPSEUDO
|
||||
|
||||
red_bits = green_bits = blue_bits = bits;
|
||||
|
||||
for (unsigned int i = 0; i < 256; i++) {
|
||||
red_color_table[i] = green_color_table[i] = blue_color_table[i] =
|
||||
i / bits;
|
||||
}
|
||||
|
||||
for (int r = 0, i = 0; r < m_colors_per_channel; r++) {
|
||||
for (int g = 0; g < m_colors_per_channel; g++) {
|
||||
for (int b = 0; b < m_colors_per_channel; b++, i++) {
|
||||
m_colors[i].red = (r * 0xffff) / (m_colors_per_channel - 1);
|
||||
m_colors[i].green = (g * 0xffff) / (m_colors_per_channel - 1);
|
||||
m_colors[i].blue = (b * 0xffff) / (m_colors_per_channel - 1);;
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < m_num_colors; i++) {
|
||||
if (! XAllocColor(disp, m_colormap, &m_colors[i])) {
|
||||
fprintf(stderr,
|
||||
i18n->getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImageColorAllocFail,
|
||||
"couldn't alloc color %i %i %i\n"),
|
||||
m_colors[i].red, m_colors[i].green, m_colors[i].blue);
|
||||
m_colors[i].flags = 0;
|
||||
} else
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
|
||||
XColor icolors[256];
|
||||
unsigned int incolors = (((1 << m_screen_depth) > 256) ? 256 : (1 << m_screen_depth));
|
||||
|
||||
for (unsigned int i = 0; i < incolors; i++)
|
||||
icolors[i].pixel = i;
|
||||
|
||||
XQueryColors(disp, m_colormap, icolors, incolors);
|
||||
for (unsigned int i = 0; i < m_num_colors; i++) {
|
||||
if (! m_colors[i].flags) {
|
||||
unsigned long chk = 0xffffffff, pixel, close = 0;
|
||||
char p = 2;
|
||||
|
||||
while (p--) {
|
||||
for (unsigned int ii = 0; ii < incolors; ii++) {
|
||||
int r = (m_colors[i].red - icolors[i].red) >> 8;
|
||||
int g = (m_colors[i].green - icolors[i].green) >> 8;
|
||||
int b = (m_colors[i].blue - icolors[i].blue) >> 8;
|
||||
pixel = (r * r) + (g * g) + (b * b);
|
||||
|
||||
if (pixel < chk) {
|
||||
chk = pixel;
|
||||
close = ii;
|
||||
}
|
||||
|
||||
m_colors[i].red = icolors[close].red;
|
||||
m_colors[i].green = icolors[close].green;
|
||||
m_colors[i].blue = icolors[close].blue;
|
||||
|
||||
if (XAllocColor(disp, m_colormap,
|
||||
&m_colors[i])) {
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GrayScale:
|
||||
case StaticGray:
|
||||
{
|
||||
|
||||
if (visual()->c_class == StaticGray) {
|
||||
m_num_colors = 1 << m_screen_depth;
|
||||
} else {
|
||||
m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel;
|
||||
|
||||
if (m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) {
|
||||
m_colors_per_channel = (1 << m_screen_depth) / 3;
|
||||
m_num_colors = m_colors_per_channel * m_colors_per_channel * m_colors_per_channel;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_colors_per_channel < 2 || m_num_colors > static_cast<unsigned int>(1 << m_screen_depth)) {
|
||||
fprintf(stderr,
|
||||
i18n->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImageInvalidColormapSize,
|
||||
"BImageControl::BImageControl: invalid colormap size %d "
|
||||
"(%d/%d/%d) - reducing"),
|
||||
m_num_colors, m_colors_per_channel, m_colors_per_channel,
|
||||
m_colors_per_channel);
|
||||
|
||||
m_colors_per_channel = (1 << m_screen_depth) / 3;
|
||||
}
|
||||
|
||||
m_colors = new XColor[m_num_colors];
|
||||
|
||||
int p, bits = 255 / (m_colors_per_channel - 1);
|
||||
red_bits = green_bits = blue_bits = bits;
|
||||
|
||||
for (unsigned int i = 0; i < 256; i++)
|
||||
red_color_table[i] = green_color_table[i] = blue_color_table[i] =
|
||||
i / bits;
|
||||
|
||||
for (unsigned int i = 0; i < m_num_colors; i++) {
|
||||
m_colors[i].red = (i * 0xffff) / (m_colors_per_channel - 1);
|
||||
m_colors[i].green = (i * 0xffff) / (m_colors_per_channel - 1);
|
||||
m_colors[i].blue = (i * 0xffff) / (m_colors_per_channel - 1);;
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
|
||||
if (! XAllocColor(disp, m_colormap,
|
||||
&m_colors[i])) {
|
||||
fprintf(stderr,
|
||||
i18n->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImageColorAllocFail,
|
||||
"couldn't alloc color %i %i %i\n"),
|
||||
m_colors[i].red, m_colors[i].green, m_colors[i].blue);
|
||||
m_colors[i].flags = 0;
|
||||
} else
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
|
||||
|
||||
XColor icolors[256];
|
||||
unsigned int incolors = (((1 << m_screen_depth) > 256) ? 256 :
|
||||
(1 << m_screen_depth));
|
||||
|
||||
for (unsigned int i = 0; i < incolors; i++)
|
||||
icolors[i].pixel = i;
|
||||
|
||||
XQueryColors(disp, m_colormap, icolors, incolors);
|
||||
for (unsigned int i = 0; i < m_num_colors; i++) {
|
||||
if (! m_colors[i].flags) {
|
||||
unsigned long chk = 0xffffffff, pixel, close = 0;
|
||||
|
||||
p = 2;
|
||||
while (p--) {
|
||||
for (unsigned int ii = 0; ii < incolors; ii++) {
|
||||
int r = (m_colors[i].red - icolors[i].red) >> 8;
|
||||
int g = (m_colors[i].green - icolors[i].green) >> 8;
|
||||
int b = (m_colors[i].blue - icolors[i].blue) >> 8;
|
||||
pixel = (r * r) + (g * g) + (b * b);
|
||||
|
||||
if (pixel < chk) {
|
||||
chk = pixel;
|
||||
close = ii;
|
||||
}
|
||||
|
||||
m_colors[i].red = icolors[close].red;
|
||||
m_colors[i].green = icolors[close].green;
|
||||
m_colors[i].blue = icolors[close].blue;
|
||||
|
||||
if (XAllocColor(disp, m_colormap, &m_colors[i])) {
|
||||
m_colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw string(i18n->
|
||||
getMessage(
|
||||
FBNLS::ImageSet, FBNLS::ImageUnsupVisual,
|
||||
"BImageControl::BImageControl: unsupported visual"));
|
||||
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
// ImageControl.hh for Fluxbox Window Manager
|
||||
// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxbox at linuxmail.org)
|
||||
//
|
||||
// from Image.hh for Blackbox - an X11 Window manager
|
||||
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.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: ImageControl.hh,v 1.3 2002/12/01 13:41:57 rathnor Exp $
|
||||
|
||||
#ifndef IMAGECONTROL_HH
|
||||
#define IMAGECONTROL_HH
|
||||
|
||||
#include "Texture.hh"
|
||||
#include "Timer.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
Holds screen info and color tables
|
||||
*/
|
||||
class BImageControl : public TimeoutHandler {
|
||||
public:
|
||||
BImageControl(int screen_num, bool dither = false, int colors_per_channel = 4,
|
||||
unsigned long cache_timeout = 300000l, unsigned long cache_max = 200l);
|
||||
virtual ~BImageControl();
|
||||
|
||||
inline bool doDither() const { return m_dither; }
|
||||
inline int bitsPerPixel() const { return bits_per_pixel; }
|
||||
inline int depth() const { return m_screen_depth; }
|
||||
inline int colorsPerChannel() const { return m_colors_per_channel; }
|
||||
int screenNum() const { return m_screen_num; }
|
||||
Visual *visual() const { return m_visual; }
|
||||
unsigned long getSqrt(unsigned int val) const;
|
||||
|
||||
/**
|
||||
Render to pixmap
|
||||
@param width width of pixmap
|
||||
@param height height of pixmap
|
||||
@param src_texture texture type to render
|
||||
@return pixmap of the rendered image, on failure None
|
||||
*/
|
||||
Pixmap renderImage(unsigned int width, unsigned int height,
|
||||
const FbTk::Texture &src_texture);
|
||||
|
||||
void installRootColormap();
|
||||
void removeImage(Pixmap thepix);
|
||||
void colorTables(const unsigned char **, const unsigned char **, const unsigned char **,
|
||||
int *, int *, int *, int *, int *, int *) const;
|
||||
void getXColorTable(XColor **, int *);
|
||||
void getGradientBuffers(unsigned int, unsigned int,
|
||||
unsigned int **, unsigned int **);
|
||||
void setDither(bool d) { m_dither = d; }
|
||||
void setColorsPerChannel(int cpc);
|
||||
|
||||
virtual void timeout();
|
||||
|
||||
private:
|
||||
/**
|
||||
Search cache for a specific pixmap
|
||||
@return None if no cache was found
|
||||
*/
|
||||
Pixmap searchCache(unsigned int width, unsigned int height, unsigned long texture_type,
|
||||
const FbTk::Color &color, const FbTk::Color &color_to) const;
|
||||
|
||||
void createColorTable();
|
||||
bool m_dither;
|
||||
|
||||
BTimer m_timer;
|
||||
|
||||
Colormap m_colormap;
|
||||
|
||||
Window m_root_window;
|
||||
|
||||
XColor *m_colors; ///< color table
|
||||
unsigned int m_num_colors; ///< number of colors in color table
|
||||
|
||||
Visual *m_visual;
|
||||
|
||||
int bits_per_pixel, red_offset, green_offset, blue_offset,
|
||||
red_bits, green_bits, blue_bits;
|
||||
int m_colors_per_channel; ///< number of colors per channel
|
||||
int m_screen_depth; ///< bit depth of screen
|
||||
int m_screen_num; ///< screen number
|
||||
unsigned char red_color_table[256], green_color_table[256],
|
||||
blue_color_table[256];
|
||||
unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
|
||||
grad_buffer_height;
|
||||
|
||||
static unsigned long *sqrt_table; /// sqrt lookup table
|
||||
|
||||
typedef struct Cache {
|
||||
Pixmap pixmap;
|
||||
|
||||
unsigned int count, width, height;
|
||||
unsigned long pixel1, pixel2, texture;
|
||||
} Cache;
|
||||
|
||||
unsigned long cache_max;
|
||||
typedef std::list<Cache *> CacheList;
|
||||
|
||||
mutable CacheList cache;
|
||||
};
|
||||
|
||||
|
||||
#endif // IMAGECONTROL_HH
|
||||
|
1788
src/TextureRender.cc
1788
src/TextureRender.cc
File diff suppressed because it is too large
Load diff
|
@ -1,94 +0,0 @@
|
|||
// TextureRender.hh for fluxbox
|
||||
// Copyright (c) 2002 Henrik Kinnunen (fluxgen at fluxbox.org)
|
||||
//
|
||||
// Image.hh for Blackbox - an X11 Window manager
|
||||
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.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: TextureRender.hh,v 1.3 2002/12/01 13:42:00 rathnor Exp $
|
||||
|
||||
#ifndef TEXTURRENDER_HH
|
||||
#define TEXTURRENDER_HH
|
||||
|
||||
#include "Texture.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
class BImageControl;
|
||||
|
||||
/**
|
||||
Renders texture to pixmap
|
||||
*/
|
||||
class TextureRender {
|
||||
public:
|
||||
TextureRender(BImageControl &ic, unsigned int width, unsigned int height,
|
||||
XColor *_colors=0, size_t num_colors=0);
|
||||
~TextureRender();
|
||||
/// render to pixmap
|
||||
Pixmap render(const FbTk::Texture &src_texture);
|
||||
/// render solid texture to pixmap
|
||||
Pixmap renderSolid(const FbTk::Texture &src_texture);
|
||||
/// render gradient texture to pixmap
|
||||
Pixmap renderGradient(const FbTk::Texture &src_texture);
|
||||
|
||||
private:
|
||||
/**
|
||||
Render to pixmap
|
||||
@return rendered pixmap
|
||||
*/
|
||||
Pixmap renderPixmap();
|
||||
/**
|
||||
Render to XImage
|
||||
@returns allocated and rendered XImage, user is responsible to deallocate
|
||||
*/
|
||||
XImage *renderXImage();
|
||||
/**
|
||||
@name render functions
|
||||
*/
|
||||
//@{
|
||||
void invert();
|
||||
void bevel1();
|
||||
void bevel2();
|
||||
void dgradient();
|
||||
void egradient();
|
||||
void hgradient();
|
||||
void pgradient();
|
||||
void rgradient();
|
||||
void vgradient();
|
||||
void cdgradient();
|
||||
void pcgradient();
|
||||
//@}
|
||||
void makeGradientBuffers();
|
||||
|
||||
BImageControl &control;
|
||||
bool interlaced;
|
||||
|
||||
XColor *colors; // color table
|
||||
|
||||
const FbTk::Color *from, *to;
|
||||
int red_offset, green_offset, blue_offset, red_bits, green_bits, blue_bits,
|
||||
ncolors, cpc, cpccpc;
|
||||
unsigned char *red, *green, *blue;
|
||||
const unsigned char *red_table, *green_table, *blue_table;
|
||||
unsigned int width, height;
|
||||
unsigned int *xtable, *ytable;
|
||||
};
|
||||
|
||||
#endif // TEXTURERENDER_HH
|
177
src/Timer.cc
177
src/Timer.cc
|
@ -1,177 +0,0 @@
|
|||
// Timer.cc for Blackbox - An X11 Window Manager
|
||||
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.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.
|
||||
|
||||
#include "Timer.hh"
|
||||
|
||||
//use GNU extensions
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif // _GNU_SOURCE
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
|
||||
//static var
|
||||
BTimer::TimerList BTimer::m_timerlist;
|
||||
|
||||
BTimer::BTimer(TimeoutHandler *h):
|
||||
m_handler(h),
|
||||
m_timing(false),
|
||||
m_once(false) {
|
||||
}
|
||||
|
||||
|
||||
BTimer::~BTimer() {
|
||||
if (isTiming()) stop();
|
||||
}
|
||||
|
||||
|
||||
void BTimer::setTimeout(long t) {
|
||||
m_timeout.tv_sec = t / 1000;
|
||||
m_timeout.tv_usec = t;
|
||||
m_timeout.tv_usec -= (m_timeout.tv_sec * 1000);
|
||||
m_timeout.tv_usec *= 1000;
|
||||
}
|
||||
|
||||
|
||||
void BTimer::setTimeout(timeval t) {
|
||||
m_timeout.tv_sec = t.tv_sec;
|
||||
m_timeout.tv_usec = t.tv_usec;
|
||||
}
|
||||
|
||||
|
||||
void BTimer::start() {
|
||||
gettimeofday(&m_start, 0);
|
||||
|
||||
if (! m_timing) {
|
||||
m_timing = true;
|
||||
addTimer(this); //add us to the list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BTimer::stop() {
|
||||
m_timing = false;
|
||||
removeTimer(this); //remove us from the list
|
||||
}
|
||||
|
||||
|
||||
void BTimer::fireTimeout() {
|
||||
if (m_handler) m_handler->timeout();
|
||||
}
|
||||
|
||||
void BTimer::updateTimers(int fd) {
|
||||
fd_set rfds;
|
||||
timeval now, tm, *timeout = 0;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
if (m_timerlist.size() > 0) {
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
tm.tv_sec = tm.tv_usec = 0l;
|
||||
|
||||
BTimer *timer = m_timerlist.front();
|
||||
|
||||
tm.tv_sec = timer->getStartTime().tv_sec +
|
||||
timer->getTimeout().tv_sec - now.tv_sec;
|
||||
tm.tv_usec = timer->getStartTime().tv_usec +
|
||||
timer->getTimeout().tv_usec - now.tv_usec;
|
||||
|
||||
while (tm.tv_usec >= 1000000) {
|
||||
tm.tv_sec++;
|
||||
tm.tv_usec -= 1000000;
|
||||
}
|
||||
|
||||
while (tm.tv_usec < 0) {
|
||||
if (tm.tv_sec > 0) {
|
||||
tm.tv_sec--;
|
||||
tm.tv_usec += 1000000;
|
||||
} else {
|
||||
tm.tv_usec = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeout = &tm;
|
||||
}
|
||||
|
||||
select(fd + 1, &rfds, 0, 0, timeout);
|
||||
|
||||
// check for timer timeout
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
TimerList::iterator it = m_timerlist.begin();
|
||||
//must check end ...the timer might remove
|
||||
//it self from the list (should be fixed in the future)
|
||||
for(; it != m_timerlist.end(); ++it) {
|
||||
//This is to make sure we don't get an invalid iterator
|
||||
//when we do fireTimeout
|
||||
BTimer &t = *(*it);
|
||||
tm.tv_sec = t.getStartTime().tv_sec +
|
||||
t.getTimeout().tv_sec;
|
||||
tm.tv_usec = t.getStartTime().tv_usec +
|
||||
t.getTimeout().tv_usec;
|
||||
|
||||
if ((now.tv_sec < tm.tv_sec) ||
|
||||
(now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
|
||||
break;
|
||||
|
||||
t.fireTimeout();
|
||||
// restart the current timer so that the start time is updated
|
||||
if (! t.doOnce())
|
||||
t.start();
|
||||
else {
|
||||
t.stop();
|
||||
it--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BTimer::addTimer(BTimer *timer) {
|
||||
assert(timer);
|
||||
|
||||
TimerList::iterator it = m_timerlist.begin();
|
||||
TimerList::iterator it_end = m_timerlist.end();
|
||||
int index = 0;
|
||||
for (; it != it_end; ++it, ++index) {
|
||||
if (((*it)->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
|
||||
(((*it)->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
|
||||
((*it)->getTimeout().tv_usec >= timer->getTimeout().tv_usec))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_timerlist.insert(it, timer);
|
||||
|
||||
}
|
||||
|
||||
void BTimer::removeTimer(BTimer *timer) {
|
||||
assert(timer);
|
||||
m_timerlist.remove(timer);
|
||||
}
|
||||
|
91
src/Timer.hh
91
src/Timer.hh
|
@ -1,91 +0,0 @@
|
|||
// Timer.hh for fluxbox
|
||||
// Copyright (c) 2002 Henrik Kinnunen (fluxgen at linuxmail.org)
|
||||
//
|
||||
// Timer.hh for Blackbox - An X11 Window Manager
|
||||
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.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.
|
||||
|
||||
#ifndef TIMER_HH
|
||||
#define TIMER_HH
|
||||
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
Inherit this to have a timed object, that calls
|
||||
timeout function when the time is out
|
||||
*/
|
||||
class TimeoutHandler {
|
||||
public:
|
||||
/// called when the time is out
|
||||
virtual void timeout() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Handles TimeoutHandles
|
||||
*/
|
||||
class BTimer {
|
||||
public:
|
||||
explicit BTimer(TimeoutHandler *handler);
|
||||
virtual ~BTimer();
|
||||
|
||||
inline int isTiming() const { return m_timing; }
|
||||
inline int doOnce() const { return m_once; }
|
||||
|
||||
inline const timeval &getTimeout() const { return m_timeout; }
|
||||
inline const timeval &getStartTime() const { return m_start; }
|
||||
|
||||
inline void fireOnce(bool once) { m_once = once; }
|
||||
/// set timeout
|
||||
void setTimeout(long val);
|
||||
/// set timeout
|
||||
void setTimeout(timeval val);
|
||||
/// start timing
|
||||
void start();
|
||||
/// stop timing
|
||||
void stop();
|
||||
/// update all timers
|
||||
static void updateTimers(int file_descriptor);
|
||||
|
||||
protected:
|
||||
/// force a timeout
|
||||
void fireTimeout();
|
||||
|
||||
private:
|
||||
/// add a timer to the static list
|
||||
static void addTimer(BTimer *timer);
|
||||
/// remove a timer from the static list
|
||||
static void removeTimer(BTimer *timer);
|
||||
|
||||
typedef std::list<BTimer *> TimerList;
|
||||
static TimerList m_timerlist; ///< list of all timers
|
||||
|
||||
TimeoutHandler *m_handler; ///< handler
|
||||
|
||||
bool m_timing; ///< clock running?
|
||||
bool m_once; ///< do timeout only once?
|
||||
|
||||
timeval m_start; ///< start time
|
||||
timeval m_timeout; ///< time length
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMER_HH
|
||||
|
Loading…
Reference in a new issue