added: CDebugWindow, accepts CTcpData and processes it the same way as the bitpanel, and shows it in a window
This commit is contained in:
parent
821d2d9820
commit
7f27734b7a
3 changed files with 309 additions and 1 deletions
238
src/util/debugwindow.cpp
Normal file
238
src/util/debugwindow.cpp
Normal 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
67
src/util/debugwindow.h
Normal 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
|
5
wscript
5
wscript
|
@ -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',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue