/*
 * 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