initial check in
This commit is contained in:
215
testX11.cpp
Normal file
215
testX11.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user