Files
test/cpp/testX11.cpp

221 lines
4.3 KiB
C++

//
// To compile use:
// g++ -L/usr/X11R6/lib64 -pthread -lX11 testX11.cpp
//
/* first include the standard headers that we're likely to need */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#include <pthread.h>
class threadDrawing
{
public:
Display* d;
Drawable w;
Pixmap p;
GC gc;
pthread_t t;
threadDrawing()
:
d( 0 ),
w( 0 ),
p( 0 ),
gc( 0 )
{
}
~threadDrawing()
{
deinit();
}
void init( const char * dname )
{
d = XOpenDisplay( dname );
int screen_num = XDefaultScreen(d);
unsigned long bg = XBlackPixel(d, screen_num);
unsigned long fg = XWhitePixel(d, screen_num);
w = XCreateSimpleWindow(d, XDefaultRootWindow(d),
0, 0, 1, 1,
0, fg, bg );
p = XCreatePixmap( d, w, 50, 50,
XDefaultDepth( d, XDefaultScreen( d ) ) );
gc = XCreateGC( d, w, 0, 0 );
XSetForeground( d, gc, fg );
XSetBackground( d, gc, bg );
}
void deinit()
{
if ( gc )
{
XFreeGC( d, gc );
gc = 0;
}
if ( p )
{
XFreePixmap( d, p );
p = 0;
}
if ( w )
{
XDestroyWindow( d, w );
w = 0;
}
if ( d )
{
XCloseDisplay( d );
d = 0;
}
}
static void* entry_point( void * pData)
{
threadDrawing* pThis = reinterpret_cast<threadDrawing*>(pData);
pThis->run();
return 0;
}
void start()
{
int rc = pthread_create( &t, 0, &entry_point, (void*)this );
std::cout << "Thread " << t << " created." << std::endl ;
}
void join()
{
void * s;
pthread_join( t, &s );
std::cout << "Thread " << t << " joined." << std::endl ;
}
void run()
{
// p = XCreatePixmap( d, w, 50, 50,
// XDefaultDepth( d, XDefaultScreen( d ) ) );
// GC gc = XCreateGC( d, w, 0, 0 );
XFillRectangle( d, p, gc, 0, 0, 50, 50 );
for (; true ; )
{
XDrawLine( d, p, gc, 0, 0, 50, 50 );
XDrawLine( d, p, gc, 0, 50, 50, 0 );
}
XFlush( d );
XSync( d, True );
}
};
void createThreads( Display* d, Drawable w )
{
const int tsize = 16;
typedef std::vector<threadDrawing> threads_type;
threads_type threads( tsize );
const char * dname = XDisplayString( d );
threads_type::iterator it = threads.begin();
threads_type::iterator itEnd = threads.end();
for ( ; it != itEnd; ++it )
{
it->init( dname );
it->start();
}
for ( it = threads.begin(); it != itEnd; ++it )
{
it->join();
}
}
int error_handler( Display* d, XErrorEvent* err )
{
puts( "error." );
}
int io_error_handler( Display* d )
{
puts( "io error." );
}
int main(int argc, char ** argv)
{
int screen_num, width, height;
unsigned long background, border;
Window win;
XEvent ev;
Display *dpy;
XSetErrorHandler( error_handler );
XSetIOErrorHandler( io_error_handler );
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
dpy = XOpenDisplay(NULL);
if (!dpy)
{
fprintf(stderr, "unable to connect to display");
return 7;
}
/* these are macros that pull useful data out of the display object */
/* we use these bits of info enough to want them in their own variables */
screen_num = DefaultScreen(dpy);
background = BlackPixel(dpy, screen_num);
border = WhitePixel(dpy, screen_num);
width = 400; /* start with a small window */
height = 400;
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */
0,0, /* x, y: the window manager will place the window elsewhere */
width, height, /* width, height */
2, border, /* border width & colour, unless you have a window manager */
background); /* background colour */
/* tell the display server what kind of events we would like to see */
XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask );
/* okay, put the window on the screen, please */
XMapWindow(dpy, win);
//
//
//
createThreads( dpy, win );
/* as each event that we asked about occurs, we respond. In this
* case we note if the window's shape changed, and exit if a button
* is pressed inside the window */
while(1)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case ConfigureNotify:
if (width != ev.xconfigure.width
|| height != ev.xconfigure.height)
{
width = ev.xconfigure.width;
height = ev.xconfigure.height;
printf("Size changed to: %d by %d\n", width, height);
}
break;
case ButtonPress:
XCloseDisplay(dpy);
return 0;
}
}
}