added: CDebugWindow, accepts CTcpData and processes it the same way as the bitpanel, and shows it in a window

This commit is contained in:
Bob van Loosen 2013-02-19 16:06:29 +01:00
parent 821d2d9820
commit 7f27734b7a
3 changed files with 309 additions and 1 deletions

238
src/util/debugwindow.cpp Normal file
View file

@ -0,0 +1,238 @@
/*
* bitvis
* Copyright (C) Bob 2013
*
* bitvis 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 3 of the License, or
* (at your option) any later version.
*
* bitvis 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "debugwindow.h"
#include "lock.h"
#include "log.h"
#include "timeutils.h"
#include "inclstdint.h"
#include <cstring>
#include <cstdlib>
CDebugWindow::CDebugWindow()
{
m_scale = 0;
m_dpy = NULL;
m_width = 0;
m_height = 0;
m_pixmap = None;
m_srcformat = NULL;
m_dstformat = NULL;
m_srcpicture = None;
m_dstpicture = None;
memset(&m_pictattr, 0, sizeof(m_pictattr));
memset(&m_transform, 0, sizeof(m_transform));
memset(&m_rootattr, 0, sizeof(m_rootattr));
m_xim = NULL;
m_window = None;
m_rootwin = None;
m_gc = None;
}
CDebugWindow::~CDebugWindow()
{
}
void CDebugWindow::Enable(int width, int height, int scale)
{
Disable();
m_width = width;
m_height = height;
m_scale = scale;
StartThread();
}
void CDebugWindow::Disable()
{
AsyncStopThread();
m_condition.Signal();
StopThread();
}
void CDebugWindow::DisplayFrame(CTcpData& data)
{
if (m_running)
{
CLock lock(m_condition);
m_data = data;
m_condition.Signal();
}
}
void CDebugWindow::Process()
{
if (!Setup())
{
Cleanup();
return;
}
ProcessInternal();
Cleanup();
}
bool CDebugWindow::Setup()
{
m_dpy = XOpenDisplay(NULL);
if (m_dpy == NULL)
{
LogError("Unable to open display");
return false;
}
m_window = XCreateSimpleWindow(m_dpy, RootWindow(m_dpy, DefaultScreen(m_dpy)),
0, 0, m_width * m_scale, m_height * m_scale, 0, 0, 0);
XMapWindow(m_dpy, m_window);
XFlush(m_dpy);
m_rootwin = RootWindow(m_dpy, DefaultScreen(m_dpy));
XGetWindowAttributes(m_dpy, m_rootwin, &m_rootattr);
m_gc = XCreateGC(m_dpy, m_window, 0, NULL);
m_pixmap = XCreatePixmap(m_dpy, m_rootwin, m_width, m_height, m_rootattr.depth);
m_srcformat = XRenderFindVisualFormat(m_dpy, m_rootattr.visual);
m_dstformat = XRenderFindVisualFormat(m_dpy, m_rootattr.visual);
m_srcpicture = XRenderCreatePicture(m_dpy, m_pixmap, m_srcformat, CPRepeat, &m_pictattr);
m_dstpicture = XRenderCreatePicture(m_dpy, m_window, m_dstformat, CPRepeat, &m_pictattr);
XRenderSetPictureFilter(m_dpy, m_srcpicture, "nearest", NULL, 0);
m_xim = XCreateImage(m_dpy, m_rootattr.visual, m_rootattr.depth, ZPixmap, 0, NULL, m_width, m_height, 8, m_width * 4);
m_xim->data = (char*)malloc(m_width * m_height * 4);
memset(m_xim->data, 0, m_width * m_height * 4);
m_transform.matrix[0][0] = m_width;
m_transform.matrix[1][1] = m_width;
m_transform.matrix[2][2] = m_width * m_scale;
return true;
}
void CDebugWindow::Cleanup()
{
if (m_xim)
{
XDestroyImage(m_xim);
m_xim = NULL;
}
if (m_dstpicture != None)
{
XRenderFreePicture(m_dpy, m_dstpicture);
m_dstpicture = None;
}
if (m_srcpicture != None)
{
XRenderFreePicture(m_dpy, m_srcpicture);
m_srcpicture = None;
}
if (m_pixmap != None)
{
XFreePixmap(m_dpy, m_pixmap);
m_pixmap = None;
}
if (m_gc != None)
{
XFreeGC(m_dpy, m_gc);
m_gc = None;
}
if (m_window != None)
{
XDestroyWindow(m_dpy, m_window);
m_window = None;
}
if (m_dpy)
{
XCloseDisplay(m_dpy);
m_dpy = NULL;
}
}
void CDebugWindow::ProcessInternal()
{
bool render = true;
int count = -3;
int xcount = 0;
int ycount = 0;
while (!m_stop)
{
if (render)
{
XPutImage(m_dpy, m_pixmap, m_gc, m_xim, 0, 0, 0, 0, m_width, m_height);
XRenderSetPictureTransform (m_dpy, m_srcpicture, &m_transform);
XRenderComposite(m_dpy, PictOpSrc, m_srcpicture, None, m_dstpicture,
0, 0, 0, 0, 0, 0, m_width * m_scale, m_height * m_scale);
XFlush(m_dpy);
render = false;
}
CLock lock(m_condition);
m_condition.Wait();
CTcpData data = m_data;
lock.Leave();
int size = m_data.GetSize();
uint8_t* dataptr = (uint8_t*)m_data.GetData();
for (int i = 0; i < size; i++)
{
if (count == -3)
{
if (dataptr[i] == ':')
count++;
}
else if (count == -2 || count == -1)
{
if (dataptr[i] == '0')
count++;
else
count = -3;
}
else
{
uint8_t* pixelptr = (uint8_t*)m_xim->data + ycount * m_xim->bytes_per_line + xcount * 4;
for (int j = 0; j < 4; j++)
{
pixelptr++;
*(pixelptr++) = ((dataptr[i] >> (j * 2)) & 1) ? 0xFF : 0;
*(pixelptr++) = ((dataptr[i] >> (j * 2 + 1)) & 1) ? 0xFF : 0;
pixelptr++;
xcount++;
if (xcount == m_width)
{
xcount = 0;
ycount++;
if (ycount == m_height)
{
render = true;
count = -3;
ycount = 0;
}
}
}
}
}
}
}

67
src/util/debugwindow.h Normal file
View file

@ -0,0 +1,67 @@
/*
* bitvis
* Copyright (C) Bob 2013
*
* bitvis 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 3 of the License, or
* (at your option) any later version.
*
* bitvis 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEBUGWINDOW_H
#define DEBUGWINDOW_H
#include "thread.h"
#include "condition.h"
#include "tcpsocket.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
class CDebugWindow : public CThread
{
public:
CDebugWindow();
~CDebugWindow();
void Enable(int width, int height, int scale);
void Disable();
void DisplayFrame(CTcpData& data);
void Process();
private:
bool Setup();
void ProcessInternal();
void Cleanup();
int m_scale;
CCondition m_condition;
CTcpData m_data;
Display* m_dpy;
int m_width;
int m_height;
Window m_rootwin;
XWindowAttributes m_rootattr;
Pixmap m_pixmap;
XRenderPictFormat* m_srcformat;
XRenderPictFormat* m_dstformat;
Picture m_srcpicture;
Picture m_dstpicture;
XRenderPictureAttributes m_pictattr;
XTransform m_transform;
XImage* m_xim;
Window m_window;
GC m_gc;
};
#endif //DEBUGWINDOW_H

View file

@ -61,11 +61,14 @@ def build(bld):
bld.program(source='src/bitx11/main.cpp\
src/bitx11/bitx11.cpp\
src/util/debugwindow.cpp\
src/util/log.cpp\
src/util/misc.cpp\
src/util/mutex.cpp\
src/util/timeutils.cpp\
src/util/tcpsocket.cpp',
src/util/condition.cpp\
src/util/tcpsocket.cpp\
src/util/thread.cpp',
use=['m', 'rt', 'X11', 'Xrender', 'Xext'],
includes='./src',
cxxflags='-Wall -g -DUTILNAMESPACE=BitX11Util',