/*
* image.cc
*
* Copyright (C) 1995, 1996, 1997, 1997, 1998, 1999, 2000, 2001, 2002 Kenichi Kourai
* Copyright (C) 1999, 2000, 2001, 2002 Luiz Blanes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blwm; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "main.h"
#include "image.h"
#include "callback.h"
BlImage::BlImage()
{
Init();
}
BlImage::BlImage(Pixmap pix, GC gc, const Dim& size)
{
Init();
m_pix = pix;
m_gc = gc;
m_size = size;
}
void BlImage::Init()
{
m_pix = None;
m_mask = None;
m_gc = NULL;
m_refcnt = 1;
m_error = 0;
m_cbPre = NULL;
m_cbDisp = NULL;
m_cbPost = NULL;
m_import = False;
}
BlImage::~BlImage()
{
ASSERT(m_refcnt == 0);
if (m_import)
return;
if (m_pix)
XFreePixmap(display, m_pix);
if (m_mask)
XFreePixmap(display, m_mask);
if (m_gc)
XFreeGC(display, m_gc);
delete m_cbPre;
delete m_cbDisp;
delete m_cbPost;
}
BlImage* BlImage::Duplicate()
{
m_refcnt++;
return this;
}
void BlImage::Destroy(BlImage* img)
{
if (img == NULL)
return;
if (--img->m_refcnt == 0)
delete img;
}
void BlImage::Display(Window win, const Point& pt)
{
if (win == None)
return;
ASSERT(m_refcnt > 0)
XSetClipOrigin(display, m_gc, pt.x, pt.y);
XCopyArea(display, m_pix, win, m_gc,
0, 0, m_size.width, m_size.height, pt.x, pt.y);
}
void BlImage::SetBackground(Window win)
{
XSetWindowBackgroundPixmap(display, win, m_pix);
}
/*
* Adjust pixmap according to a start point(pt).
*
* size.width
* +-------+---+ +---+-------+
* |4 |2 | |1 |3 |
* size. | off| | => +---+-------+
* height +-------+---+ |2 |4 |
* |3 |1 | | | |
* +-------+---+ +---+-------+
* pix fpix
*/
BlImage* BlImage::GetOffsetImage(const Point& pt)
{
Pixmap fpix;
Point offset;
fpix = XCreatePixmap(display, root, m_size.width, m_size.height, depth);
offset.x = pt.x % m_size.width;
offset.y = pt.y % m_size.height;
// copy original bottom-right to top-left
XCopyArea(display, m_pix, fpix, gc,
offset.x, offset.y,
m_size.width - offset.x, m_size.height - offset.y,
0, 0);
// copy original top-right to bottom-left
XCopyArea(display, m_pix, fpix, gc,
offset.x, 0, m_size.width - offset.x, offset.y,
0, m_size.height - offset.y);
// copy original bottom-left to top-right
XCopyArea(display, m_pix, fpix, gc,
0, offset.y, offset.x, m_size.height - offset.y,
m_size.width - offset.x, 0);
// copy original top-left to bottom-right
XCopyArea(display, m_pix, fpix, gc,
0, 0, offset.x, offset.y,
m_size.width - offset.x, m_size.height - offset.y);
GC gcNew = XCreateGC(display, root, 0, 0);
BlImage* img = new BlImage(fpix, gcNew, m_size);
return img;
}
void BlImage::OutputError(char* filename)
{
switch (m_error) {
case IMG_DATA_ERROR:
BlwmError("data error: '%s'", filename);
break;
case IMG_COLOR_ERROR:
BlwmError("color error: '%s'", filename);
break;
case IMG_MEMORY_ERROR:
BlwmError("not enough memory: '%s'", filename);
break;
case IMG_OPEN_ERROR:
BlwmError("cannot open file: '%s'", filename);
break;
case IMG_FILE_ERROR:
BlwmError("cannot read file: '%s'", filename);
break;
case IMG_UNKNOWN_ERROR:
BlwmError("unknown error: '%s'", filename);
break;
}
}
syntax highlighted by Code2HTML, v. 0.9.1