/******************************************************************************!
* \file display.cpp
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright CeCILL 2.1 Free Software license
******************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include "display.h"
namespace X11 {
/******************************************************************************!
* \fn Display
******************************************************************************/
Display::Display(int colormapSize) :
mDisplay(NULL),
mColormapSize(colormapSize),
mNbColor(0)
{
this->open(::getenv("DISPLAY"));
}
/******************************************************************************!
* \fn Display
******************************************************************************/
Display::Display(int argc, char** argv, char**, int colormapSize) :
mDisplay(NULL),
mColormapSize(colormapSize),
mNbColor(0)
{
char* display = NULL;
if (argc > 1 && argv != NULL) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0 && (i + 1) < argc) {
display = argv[i + 1];
break;
}
}
}
this->open(display);
}
/******************************************************************************!
* \fn open
******************************************************************************/
void Display::open(char* display)
{
if (mDisplay != NULL) {
return;
}
if ((mDisplay = XOpenDisplay(display)) == NULL) {
std::cerr << "error: XOpenDisplay" << std::endl;
if (display != NULL) {
std::cerr << "DISPLAY=" << display << std::endl;
}
throw Exception();
}
mScreen = DefaultScreen(mDisplay);
mRoot = DefaultRootWindow(mDisplay);
mDepth = XDefaultDepth(mDisplay, mScreen);
mBlack = BlackPixel(mDisplay, mScreen);
mWhite = WhitePixel(mDisplay, mScreen);
// Interception des evenements ResizeRequest par la fenetre racine
// pour que les fenetres top-niveau ne les recoivent pas
// std::cout << "root_input_mask = " << std::hex
// << XEventMaskOfScreen(XDefaultScreenOfDisplay(display))
// << std::endl;
XDefaultScreenOfDisplay(mDisplay)->root_input_mask |= ResizeRedirectMask;
// Creation du contexte graphique par defaut
mGC = XCreateGC(mDisplay, mRoot, 0, NULL);
// Informations sur la police de caracteres par defaut
if ((mFontStruct = XLoadQueryFont(mDisplay, "fixed"))) {
XCharStruct charStruct;
int direction;
XSetFont(mDisplay, mGC, mFontStruct->fid);
XTextExtents(mFontStruct, "", 0, &direction, &mFontAscent,
&mFontDescent, &charStruct);
} else {
std::cerr << "error: XLoadQueryFont" << std::endl;
}
// Creation de la palette de couleurs
mColormapDef = DefaultColormap(mDisplay, mScreen);
if (mColormapSize == 0) {
mColormapSize = 1 << mDepth;
}
mColormap = new XColor[mColormapSize];
}
/******************************************************************************!
* \fn ~Display
******************************************************************************/
Display::~Display()
{
if (mDisplay != NULL) {
this->close();
}
}
/******************************************************************************!
* \fn close
******************************************************************************/
void Display::close()
{
delete[] mColormap;
mColormap = NULL;
if (mFontStruct) {
XFreeFont(mDisplay, mFontStruct);
mFontStruct = NULL;
}
XFreeGC(mDisplay, mGC);
mGC = NULL;
XCloseDisplay(mDisplay);
mDisplay = NULL;
}
/******************************************************************************!
* \fn addColor
******************************************************************************/
void Display::addColor(int n, int r, int g, int b)
{
if (n < 0 || n >= mColormapSize) {
std::cerr << "error: X11::Display::addColor" << std::endl;
return;
}
mColormap[n].red = r << 8;
mColormap[n].green = g << 8;
mColormap[n].blue = b << 8;
if (XAllocColor(mDisplay, mColormapDef, mColormap + n)) {
mNbColor++;
}
}
/******************************************************************************!
* \fn textWidth
******************************************************************************/
int Display::textWidth(const char* s)
{
if (mFontStruct) {
return XTextWidth(mFontStruct, s, strlen(s));
} else {
std::cerr << "error: X11::Display::textWidth" << std::endl;
return 0;
}
}
} // namespace X11