Commit 325c55e2 authored by Daniel Vogel's avatar Daniel Vogel
Browse files

added X drawing demos

parent 76ac0bf1
/*
CS 349 Code Examples: X Windows and XLib
displaylist Demos Displayable class and display list
- - - - - - - - - - - - - - - - - - - - - -
See associated makefile for compiling instructions
*/
#include <iostream>
#include <list>
#include <cstdlib>
#include <vector>
/*
* Header files for X functions
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <unistd.h> // needed for sleep
using namespace std;
/*
* Information to draw on the window.
*/
struct XInfo {
Display* display;
Window window;
GC gc;
};
/*
* An abstract class representing displayable things.
*/
class Displayable {
public:
virtual void paint(XInfo& xinfo) = 0;
};
/*
* A text displayable
*/
class Text : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
XDrawImageString( xinfo.display, xinfo.window, xinfo.gc,
this->x, this->y, this->s.c_str(), this->s.length() );
}
// constructor
Text(int x, int y, string s): x(x), y(y), s(s) {}
private:
int x;
int y;
string s; // string to show
};
/*
* A displayable polyline
*/
class Polyline : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
// CLIPPING CODE HERE!
// =====================================
// create a clip window
XRectangle clip_rect;
clip_rect.x = 50;
clip_rect.y = 50;
clip_rect.width = 200;
clip_rect.height = 200;
// clips all drawings that use the same GC after this call ...
XSetClipRectangles(xinfo.display, xinfo.gc, 0, 0, &clip_rect, 1, Unsorted);
XDrawLines(xinfo.display, xinfo.window, xinfo.gc,
&points[0], points.size(), // vector of points
CoordModeOrigin ); // use absolute coordinates
// turn clipping off again
XSetClipMask(xinfo.display, xinfo.gc, None);
// =====================================
// to here
}
// constructor
Polyline(int x, int y) {
add_point(x, y);
}
// add another point to the line
void add_point(int x, int y) {
XPoint p; // XPoint is a built in struct
p.x = x;
p.y = y;
points.push_back(p);
}
private:
// need to use a vector to dynamically add points
vector < XPoint > points; // XPoint is a built in struct
};
/*
* A face displayable
*/
class Face : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
// create a simple graphics context
GC gc = XCreateGC(xinfo.display, xinfo.window, 0, 0);
int screen = DefaultScreen( xinfo.display );
XSetForeground(xinfo.display, gc, BlackPixel(xinfo.display, screen));
XSetBackground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
XSetFillStyle(xinfo.display, gc, FillSolid);
XSetLineAttributes(xinfo.display, gc,
3, // 3 is line width
LineSolid, CapButt, JoinRound); // other line options
// draw head
XFillArc(xinfo.display, xinfo.window, gc,
x - (d / 2), y - (d / 2), d, d, 0, 360 * 64);
XSetForeground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
// draw mouth either smiling or serious
if (smile) {
int dd = d / 2;
XDrawArc(xinfo.display, xinfo.window, gc,
x - (dd / 2), y - (dd / 2), dd, dd, 210 * 64, 120 * 64);
} else {
int dd = d / 3;
XDrawLine(xinfo.display, xinfo.window, gc,
x - dd, y + dd / 2, x + dd, y + dd / 2);
}
}
// constructor
Face(int x, int y, int d, bool smile): x(x), y(y), d(d), smile(smile) {}
private:
int x;
int y;
int d; // diameter
bool smile; // is smiling
};
/*
* Function to put out a message on error exits.
*/
void error( string str ) {
cerr << str << endl;
exit(0);
}
/*
* Create a window
*/
void initX(int argc, char* argv[], XInfo& xinfo) {
/*
* Display opening uses the DISPLAY environment variable.
* It can go wrong if DISPLAY isn't set, or you don't have permission.
*/
xinfo.display = XOpenDisplay( "" );
if ( !xinfo.display ) {
error( "Can't open display." );
}
/*
* Find out some things about the display you're using.
*/
// DefaultScreen is as macro to get default screen index
int screen = DefaultScreen( xinfo.display );
unsigned long white, black;
white = XWhitePixel( xinfo.display, screen );
black = XBlackPixel( xinfo.display, screen );
xinfo.window = XCreateSimpleWindow(
xinfo.display, // display where window appears
DefaultRootWindow( xinfo.display ), // window's parent in window tree
10, 10, // upper left corner location
300, 300, // size of the window
5, // width of window's border
black, // window border colour
white ); // window background colour
// extra window properties like a window title
XSetStandardProperties(
xinfo.display, // display containing the window
xinfo.window, // window whose properties are set
"clipping", // window's title
"CL", // icon's title
None, // pixmap for the icon
argv, argc, // applications command line args
None ); // size hints for the window
/*
* Put the window on the screen.
*/
XMapRaised( xinfo.display, xinfo.window );
XFlush(xinfo.display);
// give server time to setup
sleep(1);
}
/*
* Function to repaint a display list
*/
void repaint( list<Displayable*> dList, XInfo& xinfo) {
list<Displayable*>::const_iterator begin = dList.begin();
list<Displayable*>::const_iterator end = dList.end();
XClearWindow(xinfo.display, xinfo.window);
while ( begin != end ) {
Displayable* d = *begin;
d->paint(xinfo);
begin++;
}
XFlush(xinfo.display);
}
int main( int argc, char* argv[] ) {
XInfo xinfo;
initX(argc, argv, xinfo);
// create a simple graphics context
GC gc = XCreateGC(xinfo.display, xinfo.window, 0, 0);
int screen = DefaultScreen( xinfo.display );
XSetForeground(xinfo.display, gc, BlackPixel(xinfo.display, screen));
XSetBackground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
// load a larger font
XFontStruct * font;
font = XLoadQueryFont (xinfo.display, "12x24");
XSetFont (xinfo.display, gc, font->fid);
xinfo.gc = gc;
// list of Displayables
list<Displayable*> dList;
Polyline* polyline = new Polyline(0, 0);
for (int i = 0; i < 100; i++) {
polyline->add_point(rand() % 300, rand() % 300);
}
// try changing the order or commenting out these lines
dList.push_back(new Text(50, 50, "ABC"));
dList.push_back(new Text(130, 100, "DEF"));
dList.push_back(new Text(200, 200, "GHI"));
dList.push_back(new Face(200, 200, 50, false));
dList.push_back(polyline);
// paint everything in the display list
repaint(dList, xinfo);
XFlush(xinfo.display);
std::cout << "ENTER2exit"; std::cin.get(); // wait for input
XCloseDisplay(xinfo.display);
}
\ No newline at end of file
/*
CS 349 Code Examples: X Windows and XLib
displaylist Demos Displayable class and display list
- - - - - - - - - - - - - - - - - - - - - -
See associated makefile for compiling instructions
*/
#include <iostream>
#include <list>
#include <cstdlib>
#include <vector>
/*
* Header files for X functions
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <unistd.h> // needed for sleep
using namespace std;
/*
* Information to draw on the window.
*/
struct XInfo {
Display* display;
Window window;
GC gc;
};
/*
* An abstract class representing displayable things.
*/
class Displayable {
public:
virtual void paint(XInfo& xinfo) = 0;
};
/*
* A text displayable
*/
class Text : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
XDrawImageString( xinfo.display, xinfo.window, xinfo.gc,
this->x, this->y, this->s.c_str(), this->s.length() );
}
// constructor
Text(int x, int y, string s): x(x), y(y), s(s) {}
private:
int x;
int y;
string s; // string to show
};
/*
* A displayable polyline
*/
class Polyline : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
// note the trick to pass a stl vector as an C array
XDrawLines(xinfo.display, xinfo.window, xinfo.gc,
&points[0], points.size(), // vector of points
CoordModeOrigin ); // use absolute coordinates
}
// constructor
Polyline(int x, int y) {
add_point(x, y);
}
// add another point to the line
void add_point(int x, int y) {
XPoint p; // XPoint is a built in struct
p.x = x;
p.y = y;
points.push_back(p);
}
private:
// need to use a vector to dynamically add points
vector < XPoint > points; // XPoint is a built in struct
};
/*
* A face displayable
*/
class Face : public Displayable {
public:
virtual void paint(XInfo& xinfo) {
// create a simple graphics context
GC gc = XCreateGC(xinfo.display, xinfo.window, 0, 0);
int screen = DefaultScreen( xinfo.display );
XSetForeground(xinfo.display, gc, BlackPixel(xinfo.display, screen));
XSetBackground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
XSetFillStyle(xinfo.display, gc, FillSolid);
XSetLineAttributes(xinfo.display, gc,
3, // 3 is line width
LineSolid, CapButt, JoinRound); // other line options
// draw head
XFillArc(xinfo.display, xinfo.window, gc,
x - (d / 2), y - (d / 2), d, d, 0, 360 * 64);
XSetForeground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
// draw mouth either smiling or serious
if (smile) {
int dd = d / 2;
XDrawArc(xinfo.display, xinfo.window, gc,
x - (dd / 2), y - (dd / 2), dd, dd, 210 * 64, 120 * 64);
} else {
int dd = d / 3;
XDrawLine(xinfo.display, xinfo.window, gc,
x - dd, y + dd / 2, x + dd, y + dd / 2);
}
}
// constructor
Face(int x, int y, int d, bool smile): x(x), y(y), d(d), smile(smile) {}
private:
int x;
int y;
int d; // diameter
bool smile; // is smiling
};
/*
* Function to put out a message on error exits.
*/
void error( string str ) {
cerr << str << endl;
exit(0);
}
/*
* Create a window
*/
void initX(int argc, char* argv[], XInfo& xinfo) {
/*
* Display opening uses the DISPLAY environment variable.
* It can go wrong if DISPLAY isn't set, or you don't have permission.
*/
xinfo.display = XOpenDisplay( "" );
if ( !xinfo.display ) {
error( "Can't open display." );
}
/*
* Find out some things about the display you're using.
*/
// DefaultScreen is as macro to get default screen index
int screen = DefaultScreen( xinfo.display );
unsigned long white, black;
white = XWhitePixel( xinfo.display, screen );
black = XBlackPixel( xinfo.display, screen );
xinfo.window = XCreateSimpleWindow(
xinfo.display, // display where window appears
DefaultRootWindow( xinfo.display ), // window's parent in window tree
10, 10, // upper left corner location
300, 300, // size of the window
5, // width of window's border
black, // window border colour
white ); // window background colour
// extra window properties like a window title
XSetStandardProperties(
xinfo.display, // display containing the window
xinfo.window, // window whose properties are set
"displaylist", // window's title
"DL", // icon's title
None, // pixmap for the icon
argv, argc, // applications command line args
None ); // size hints for the window
/*
* Put the window on the screen.
*/
XMapRaised( xinfo.display, xinfo.window );
XFlush(xinfo.display);
// give server time to setup
sleep(1);
}
/*
* Function to repaint a display list
*/
void repaint( list<Displayable*> dList, XInfo& xinfo) {
list<Displayable*>::const_iterator begin = dList.begin();
list<Displayable*>::const_iterator end = dList.end();
XClearWindow(xinfo.display, xinfo.window);
while ( begin != end ) {
Displayable* d = *begin;
d->paint(xinfo);
begin++;
}
XFlush(xinfo.display);
}
int main( int argc, char* argv[] ) {
XInfo xinfo;
initX(argc, argv, xinfo);
// create a simple graphics context
GC gc = XCreateGC(xinfo.display, xinfo.window, 0, 0);
int screen = DefaultScreen( xinfo.display );
XSetForeground(xinfo.display, gc, BlackPixel(xinfo.display, screen));
XSetBackground(xinfo.display, gc, WhitePixel(xinfo.display, screen));
// load a larger font
XFontStruct * font;
font = XLoadQueryFont (xinfo.display, "12x24");
XSetFont (xinfo.display, gc, font->fid);
xinfo.gc = gc;
// list of Displayables
list<Displayable*> dList;
Polyline* polyline = new Polyline(0, 0);
for (int i = 0; i < 100; i++) {
polyline->add_point(rand() % 300, rand() % 300);
}
// try changing the order or commenting out these lines
dList.push_back(new Text(50, 50, "ABC"));
dList.push_back(new Text(130, 100, "DEF"));
dList.push_back(new Text(200, 200, "GHI"));
dList.push_back(new Face(200, 200, 50, false));
dList.push_back(polyline);
// paint everything in the display list
repaint(dList, xinfo);
XFlush(xinfo.display);
std::cout << "ENTER2exit"; std::cin.get(); // wait for input
XCloseDisplay(xinfo.display);
}
\ No newline at end of file
/*
CS 349 Code Examples: X Windows and XLib
drawing Demos drawing functions and graphics contexts
- - - - - - - - - - - - - - - - - - - - - -
See associated makefile for compiling instructions
*/
#include <iostream>
#include <list>
#include <cstdlib>
#include <unistd.h>
// Header files for X functions
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
// handy struct to save display, window, and screen
struct XInfo {
Display *display;
int screen;
Window window;
};
// Function to put out a message on error and exits
void error( string str ) {
cerr << str << endl;
exit(0);
}
void drawRectanglesInCorners(XInfo &xinfo, GC gc) {
Display *display = xinfo.display;
Window win = xinfo.window;
XWindowAttributes windowInfo;
XGetWindowAttributes(display, win, &windowInfo);
// max x and y coordinate
unsigned int maxHeight = windowInfo.height - 1;
unsigned int maxWidth = windowInfo.width - 1;
// draw rectangles in each corner of the window
int s = 32; // rectangle size
XDrawRectangle(display, win, gc, 0, 0, s, s); // top left
XDrawRectangle(display, win, gc, 0, maxHeight - s, s, s); // bottom left
XDrawRectangle(display, win, gc, maxWidth - s, 0, s, s); // top right
XDrawRectangle(display, win, gc, maxWidth - s, maxHeight - s, s, s); // bottom right
}
void drawStuff(XInfo &xinfo, GC gc, int x, int y) {
Display *display = xinfo.display;
Window win = xinfo.window;
// draw two intersecting lines, one horizontal and one vertical,
// which intersect at point "x,y".
XDrawLine(display, win, gc, x, y - 30, x, y + 200);
XDrawLine(display, win, gc, x - 30, y, x + 200, y);
// now use the XDrawArc() function to draw a circle whose diameter
// is 30 pixels, and whose center is at location 'x,y'.
XDrawArc(display, win, gc, x - (30 / 2), y - (30 / 2), 30, 30, 0, 360 * 64);
// draw a small triangle at the top-left corner of the window.
// the triangle is made of a set of consecutive lines, whose
// end-point pixels are specified in the 'points' array.
{
XPoint points[] = {
{x + 200, y + 50},
{x + 250, y + 80},
{x + 200, y + 80},
{x + 200, y + 50}