/******************************************************************************!
* \file window.cpp
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright CeCILL 2.1 Free Software license
******************************************************************************/
#include <string.h>
#include "display.h"
#include "window.h"
#include "pixmap.h"
namespace X11 {
/******************************************************************************!
* \fn Window
******************************************************************************/
Window::Window(Display* display, int w, int h)
: Drawable(display, w, h)
{
this->init(NULL);
}
/******************************************************************************!
* \fn Window
******************************************************************************/
Window::Window(Display* display)
: Drawable(display)
{
this->init(NULL);
}
/******************************************************************************!
* \fn Window
******************************************************************************/
Window::Window(Window* parent, int x, int y, int w, int h)
: Drawable(parent->getDisplay(), x, y, w, h)
{
this->init(parent);
}
/******************************************************************************!
* \fn Window
******************************************************************************/
Window::Window(Window* parent)
: Drawable(parent->getDisplay())
{
this->init(parent);
}
/******************************************************************************!
* \fn init
* \brief Initialise certains attributs et complete la hierarchie des fenetres
* entree : la fenetre parente pour une sous-fenetre, 0 sinon
******************************************************************************/
void Window::init(Window* parent)
{
mWindow = 0;
if ((mParent = parent)) {
mParent->addChild(this);
}
mChilds = new std::list<Window*>;
setTitle("");
}
/******************************************************************************!
* \fn create
* \brief Demande de creation de la fenetre et de sa pixmap associee aupres du
* serveur X
******************************************************************************/
void Window::create(ULong color)
{
if (mWindow != 0) {
return;
}
mWindow =
XCreateSimpleWindow(mX11Display,
(mParent) ? mParent->id() : mDisplay->root(),
mIndic.x, mIndic.y,
mIndic.width, mIndic.height,
0, color, color);
// Selection d'evenements pour la fenetre
mEventMask = 0;
// Creation de la mPixmap associee a la fenetre
mPixmap = new Pixmap(mDisplay, mIndic.width, mIndic.height);
mX11Pixmap = mPixmap->id();
// Enlever les evenements provenant des copies de zones de mPixmap
XSetGraphicsExposures(mX11Display, mGC, False);
//addInput(0);
setTitle(mTitle);
this->clear(color);
}
/******************************************************************************!
* \fn ~Window
******************************************************************************/
Window::~Window()
{
delete mChilds;
delete mPixmap;
if (mWindow) {
XDestroyWindow(mX11Display, mWindow);
}
}
/******************************************************************************!
* \fn clear
******************************************************************************/
void Window::clear(ULong color)
{
mPixmap->clear(color);
}
/******************************************************************************!
* \fn setPosition
* \brief Positionne la fenetre dans sa fenetre parente
* entree : les coordonnees x et y du point superieur gauche de la fenetre
******************************************************************************/
void Window::setPosition(int x, int y)
{
Drawable::setPosition(x, y);
if (mWindow) {
XMoveWindow(mX11Display, mWindow, x, y);
}
}
/******************************************************************************!
* \fn setSize
* \brief Positionne ou change la taille de la fenetre
* entree : la largeur et la hauteur en pixels
******************************************************************************/
void Window::setSize(int w, int h)
{
Drawable::setSize(w, h);
if (mWindow) {
XResizeWindow(mX11Display, mWindow, w, h);
mPixmap->setSize(w, h);
mX11Pixmap = mPixmap->id();
}
}
/******************************************************************************!
* \fn addInput
* \brief Ajoute un evenement a la liste des evenements interceptes par la
* fenetre
* entree : un masque d'evenement(s)
******************************************************************************/
void Window::addInput(ULong mask)
{
mEventMask |= mask;
if (mWindow) {
XSelectInput(mX11Display, mWindow, mEventMask);
}
}
/******************************************************************************!
* \fn delInput
* \brief Enleve un ou tous les evenements a la liste des evenements
* interceptes par la fenetre
* entree : un masque d'evenement(s) ou rien
******************************************************************************/
void Window::delInput(ULong mask)
{
mEventMask &= ~mask;
if (mWindow) {
XSelectInput(mX11Display, mWindow, mEventMask);
}
}
/******************************************************************************!
* \fn delInput
******************************************************************************/
void Window::delInput()
{
mEventMask = 0;
if (mWindow) {
XSelectInput(mX11Display, mWindow, mEventMask);
}
}
/******************************************************************************!
* \fn delInput
* \brief Positionne le titre de la fenetre (visible dans la barre de titre)
* entree : une chaine de caracteres
******************************************************************************/
void Window::setTitle(const char* title)
{
if (const_cast<char*>(title) != mTitle) {
strcpy(mTitle, title);
}
if (mWindow) {
XSetStandardProperties(mX11Display, mWindow, mTitle, mTitle,
None, NULL, 0, &mIndic);
}
}
/******************************************************************************!
* \fn refresh
******************************************************************************/
void Window::refresh()
{
XCopyArea(mX11Display, mX11Pixmap, mWindow, mGC,
0, 0, mIndic.width, mIndic.height, 0, 0);
}
/******************************************************************************!
* \fn refresh
******************************************************************************/
void Window::refresh(int x1, int y1, int x2, int y2)
{
XCopyArea(mX11Display, mX11Pixmap, mWindow, mGC,
(x1 < x2) ? x1 : x2,
(y1 < y2) ? y1 : y2,
(x2 > x1) ? x2 - x1 + 1 : x1 - x2 + 1,
(y2 > y1) ? y2 - y1 + 1 : y1 - y2 + 1,
(x1 < x2) ? x1 : x2,
(y1 < y2) ? y1 : y2);
}
/******************************************************************************!
* \fn refreshAll
******************************************************************************/
void Window::refreshAll()
{
flush();
std::list<Window*>::const_iterator it;
for (it = mChilds->begin();
it != mChilds->end(); ++it) {
(*it)->refreshAll();
}
if (parentIsRoot()) {
XFlush(mX11Display);
}
}
/******************************************************************************!
* \fn flush
******************************************************************************/
void Window::flush()
{
XFlush(mX11Display);
}
/******************************************************************************!
* \fn raise
******************************************************************************/
void Window::raise(ULong color)
{
this->create(color);
XMapRaised(mX11Display, mWindow);
std::list<Window*>::const_iterator it;
for (it = mChilds->begin();
it != mChilds->end(); ++it) {
(*it)->raise(color);
}
refresh();
}
/******************************************************************************!
* \fn destroy
******************************************************************************/
void Window::destroy()
{
mWindow = 0;
delete this;
}
/******************************************************************************!
* \fn operator==
******************************************************************************/
int operator==(const Window& w1, const Window& w2)
{
return w1.mWindow == w2.mWindow;
}
/******************************************************************************!
* \fn operator!=
******************************************************************************/
int operator!=(const Window& w1, const Window& w2)
{
return w1.mWindow != w2.mWindow;
}
} // namespace X11