X Windowのプログラムサンプル

X Windowのプログラムサンプル

/*
 * X Window sample program
 *
 * To create make file using X lib,
 * Create Imakefile and enter below.
 * $ xmkmf
 * Then automatically Makefile is created.
 *
 * To build target with debug information,
 * enter below as build command.
 * $ make "CDEBUGFLAGS=-Wall -g"
 *
 * To get core dump information, after core dump
 * enter below.
 * $ gdb rei core
 *
 * For Linux implementation, 
 * Actual header file is in /usr/X11R6/include/X11 .
 *
 */

#include <X11/Xlib.h>
#include <X11/Xutil.h>

static	Display	*display;
static	int	screen;
static	Window	window;
static	GC	gc;

#define	CANVAS_WIDTH	320
#define	CANVAS_HEIGHT	240

static	char	canvas[CANVAS_HEIGHT][CANVAS_WIDTH];

static	void redraw(int x0, int y0, int width, int height)
{
int	x, y;

	if(x0<0)	x0	= 0;
	if(y0<0)	y0	= 0;
	if(x0+width > CANVAS_WIDTH)	width	= CANVAS_WIDTH - x0;
	if(y0+height > CANVAS_HEIGHT)	height	= CANVAS_HEIGHT - y0;

	for(y=y0;y<y0+height;y++){
		for(x=x0;x<x0+width;x++){
			if(canvas[y][x]){
				XDrawPoint(display, window, gc, x, y);
			}
		}
	}
}


static	void plot(int x, int y, int n)
{
	if((x>=0) && (x<CANVAS_WIDTH) && (y>=0) && (y<CANVAS_HEIGHT)){
		canvas[y][x]	= n;
		XClearArea(display, window, x, y, 1, 1, True);
	}
}

static	void pattern(int n)
{
int	x, y;
int	c;

	switch(n){
	case 1:	/* All black */
		for(y=0;y<CANVAS_HEIGHT;y++){
			for(x=0;x<CANVAS_WIDTH;x++){
				plot(x, y, 1);
			}
		}
		break;
	case 2:	/* All white */
		for(y=0;y<CANVAS_HEIGHT;y++){
			for(x=0;x<CANVAS_WIDTH;x++){
				plot(x, y, 0);
			}
		}
		break;
	case 3:	/* vartical lines */
		c = 0;
		for(y=0;y<CANVAS_HEIGHT;y++){
			for(x=0;x<CANVAS_WIDTH;x++){
				plot(x, y, (c++)%2);
			}
		}
		break;
	case 4:	/* checker */
		c = 0;
		for(y=0;y<CANVAS_HEIGHT;y++){
			for(x=0;x<CANVAS_WIDTH;x++){
				plot(x, y, (c++)%2);
			}
			c++;
		}
		break;
	}
}

static	void line(void)
{
	XDrawLine(display, window, gc, 0, 0, 100, 100);
}

static	void string(void)
{
	XDrawString(display, window, gc, 100, 100, "Apple", 5);
}


int	main(int argc, char **argv)
{
char	*display_name	= ":0";
int	quit		= 0;
int	plot_mode	= 0;	/* 0:white 1:black */
XEvent	event;
char	buf[10];
int	i;

	if((argc == 3) && (strcmp(argv[1], "-display") == 0)){
		display_name	= argv[2];
	}
	display	= XOpenDisplay(display_name);
	screen	= DefaultScreen(display);
	window	= XCreateSimpleWindow(display, DefaultRootWindow(display),
				30, 20, CANVAS_WIDTH, CANVAS_HEIGHT, 2,
				BlackPixel(display, screen),
				WhitePixel(display, screen));
	XSelectInput(display, window,
			ExposureMask |
			ButtonPressMask |
			ButtonMotionMask |
			KeyPressMask);
	XStoreName(display, window, "Rei");
	XMapRaised(display, window);
	gc	= XCreateGC(display, window, 0, NULL);
	XSetForeground(display, gc, BlackPixel(display, screen));

	while(!quit){
		XNextEvent(display, &event);
		switch(event.type){
		case Expose:
			redraw(event.xexpose.x,     event.xexpose.y, 
		               event.xexpose.width, event.xexpose.height);
			break;
		case ButtonPress:
			plot_mode	= (event.xbutton.button == Button1);
			plot(event.xbutton.x, event.xbutton.y, plot_mode);
			break;
		case MotionNotify:
			plot(event.xmotion.x, event.xmotion.y, plot_mode);
			break;
		case MappingNotify:
			XRefreshKeyboardMapping(&event.xmapping);
			break;
		case KeyPress:
			if(XLookupString(&event.xkey, buf, sizeof(buf),
					NULL,NULL)){
				quit	= (buf[0] == 'q');

				switch(buf[0]){
				case 'q':
					quit	= 1;
					break;

				case 'a':
					pattern(1);
					break;
				case 's':
					pattern(2);
					break;
				case 'd':
					pattern(3);
					break;
				case 'f':
					pattern(4);
					break;
				case 'g':
					for(i=0;i<10;i++)
						pattern(i%4+1);
					break;

				case 'p':
					line();
					break;

				case 'o':
					string();
					break;
				}
			}
			break;
		}
	}

	XFreeGC(display, gc);
	XDestroyWindow(display, window);
	XCloseDisplay(display);
	return 0;
}