Files
2025-12-05 08:54:02 +01:00

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