118 lines
3.0 KiB
Plaintext
118 lines
3.0 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
#ifndef toolx_X11_pixwin
|
|
#define toolx_X11_pixwin
|
|
|
|
#include "colors"
|
|
#include <tools/sg/zb_viewer>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h> //XPutPixel
|
|
|
|
namespace toolx {
|
|
namespace X11 {
|
|
|
|
class pixwin {
|
|
public:
|
|
pixwin(std::ostream& a_out,unsigned int a_monitor,Display* a_display)
|
|
:m_out(a_out)
|
|
,m_monitor(a_monitor)
|
|
,m_display(a_display)
|
|
,m_GC(0)
|
|
,m_image(0)
|
|
{
|
|
if(!m_display) return;
|
|
m_GC = ::XCreateGC(m_display,XRootWindow(m_display,m_monitor),0,0);
|
|
}
|
|
virtual ~pixwin() {
|
|
free_pixels();
|
|
m_colors.clear();
|
|
if(m_GC) ::XFreeGC(m_display,m_GC);
|
|
free_XImage();
|
|
}
|
|
protected:
|
|
pixwin(const pixwin& a_from)
|
|
:m_out(a_from.m_out)
|
|
,m_monitor(0)
|
|
,m_display(0)
|
|
,m_GC(0)
|
|
,m_image(0)
|
|
{}
|
|
pixwin& operator=(const pixwin&){
|
|
m_monitor = 0;
|
|
m_display = 0;
|
|
m_GC = 0;
|
|
m_image = 0;
|
|
return *this;
|
|
}
|
|
public:
|
|
void put_buffer(Window a_win,unsigned int a_ww,unsigned int a_wh,const unsigned char* a_rgbas) {
|
|
if(!m_display) return;
|
|
if(!m_GC) return;
|
|
if(!m_image) alloc_XImage(a_ww,a_wh);
|
|
if(!m_image) return;
|
|
const unsigned int* pos = (const unsigned int*)a_rgbas;
|
|
unsigned int row,col;
|
|
toolx::X11::Pixel pixel;
|
|
for(row=0;row<a_wh;row++) {
|
|
for(col=0;col<a_ww;col++) {
|
|
if(!get_pixel(m_display,m_monitor,m_pixels,m_colors,*pos,pixel)) {}
|
|
pos++;
|
|
XPutPixel(m_image,col,row,pixel);
|
|
}}
|
|
::XPutImage(m_display,a_win,m_GC,m_image,0,0,0,0,a_ww,a_wh);
|
|
}
|
|
void set_size(unsigned int a_ww,unsigned int a_wh) {
|
|
free_XImage();
|
|
alloc_XImage(a_ww,a_wh);
|
|
}
|
|
protected:
|
|
void alloc_XImage(unsigned int a_ww,unsigned int a_wh) {
|
|
if(m_image) return; //done.
|
|
if(!m_display) return;
|
|
Screen* screen = ::XScreenOfDisplay(m_display,m_monitor);
|
|
m_image = ::XCreateImage(m_display,::XDefaultVisualOfScreen(screen),::XDefaultDepthOfScreen(screen),ZPixmap,0,NULL,a_ww,a_wh,8,0);
|
|
if(!m_image) {
|
|
m_out << "toolx::X11::pixwin::alloc_XImage : can't create an XImage." << std::endl;
|
|
return;
|
|
}
|
|
//warning : a priori, a_ww*3 != m_image->bytes_per_line.
|
|
m_image->data = new char[a_wh*m_image->bytes_per_line];
|
|
if(!m_image->data) {
|
|
m_out << "toolx::X11::pixwin::alloc_XImage : can't alloc buffer." << std::endl;
|
|
::XFree((char*)m_image);
|
|
m_image = 0;
|
|
return;
|
|
}
|
|
}
|
|
void free_XImage() {
|
|
if(!m_image) return;
|
|
delete [] m_image->data;
|
|
::XFree((char*)m_image);
|
|
m_image = 0;
|
|
}
|
|
void free_pixels() {
|
|
if(!m_display) return;
|
|
Screen* screen = ::XScreenOfDisplay(m_display,m_monitor);
|
|
tools_vforit(toolx::X11::Pixel,m_pixels,it) {
|
|
::XFreeColors(m_display,XDefaultColormapOfScreen(screen),&(*it),1,0);
|
|
}
|
|
m_pixels.clear();
|
|
}
|
|
protected:
|
|
std::ostream& m_out;
|
|
unsigned int m_monitor;
|
|
Display* m_display;
|
|
GC m_GC;
|
|
std::vector<toolx::X11::Pixel> m_pixels;
|
|
colors_t m_colors;
|
|
XImage* m_image;
|
|
};
|
|
|
|
}}
|
|
|
|
|
|
#endif
|
|
|