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

#define WINDOW_W   400      /* ウィンドウの幅 */
#define WINDOW_H   300      /* ウィンドウの高さ */
#define BORDER     2        /* ボーダの幅 */
#define MOVEB_W    70       /* 移動ボタンの幅 */
#define MOVEB_H    30       /* 移動ボタンの高さ */
#define RESIZEB_W  MOVEB_W  /* サイズ変更ボタンの幅 */
#define RESIZEB_H  MOVEB_H  /* サイズ変更ボタンの高さ */


static Display*       dpy;              /* ディスプレイ */
static int            screen;           /* スクリーン */
static Window         root;             /* ルートウィンドウ */
static unsigned long  black, white;     /* 黒、白のピクセル値 */
static GC             gc;               /* グラフィックスコンテキスト */
static Window         win;              /* 表示するウィンドウ */
static Window         move_b, resize_b; /* ボタン用ウィンドウ */
static int            x = 100, y = 100; /* win の位置座標 */


static void xctrl_init( void );
static void xctrl_create_window( void );
static void xctrl_event_loop( void );
static void xctrl_proc_moveb( void );
static void xctrl_proc_resizeb( void );


int 
main( void )
{
	/* 初期処理 */
	xctrl_init();

	/* ウィンドウ作成 */
	xctrl_create_window();

	/* 僕の環境では XCreateSimpleWindow() の座標指定では指定通りの位置
	   に表示されないので、マップした後に一度移動させている */
	XMapWindow( dpy, win );
	XMoveWindow( dpy, win, x, y );

	/* winを親ウィンドウとする全ての子ウィンドウをマップする */
	XMapSubwindows( dpy, win );

	/* イベントループ */
	xctrl_event_loop();

	return 0;
}


static void 
xctrl_init( void )
{
	dpy = XOpenDisplay( "" );

	root   = DefaultRootWindow( dpy );
	screen = DefaultScreen( dpy );

	white = WhitePixel( dpy, screen );
	black = BlackPixel( dpy, screen );
}


static void 
xctrl_create_window( void )
{
	win = XCreateSimpleWindow( dpy, root, 100, 100, 
		   WINDOW_W, WINDOW_H, BORDER, black, white );

	move_b = XCreateSimpleWindow( dpy, win, 10, 10, 
		      MOVEB_W, MOVEB_H, BORDER, black, white );

	resize_b = XCreateSimpleWindow( dpy, win, 10 + MOVEB_W + 5, 10, 
		RESIZEB_W, RESIZEB_H, BORDER, black, white );

	gc = XCreateGC( dpy, win, 0, NULL );
	XSetBackground( dpy, gc, white );
	XSetForeground( dpy, gc, black );

	XSelectInput( dpy, win,      ExposureMask    | KeyPressMask );
	XSelectInput( dpy, move_b,   ButtonPressMask | ExposureMask );
	XSelectInput( dpy, resize_b, ButtonPressMask | ExposureMask );
}


static void
xctrl_event_loop( void )
{
	XEvent event;

	while( 1 ) {
		XNextEvent( dpy, &event );
		switch( event.type ) {
			case Expose:
				if ( event.xexpose.count == 0 ) {
					/* ボタンのラベルを描画 */
					XDrawString( dpy, move_b, gc, 
					    15, MOVEB_H / 2, "MOVE", 
					    strlen( "MOVE" ) );

					XDrawString( dpy, resize_b, gc, 
					    15, RESIZEB_H / 2, "RESIZE", 
					    strlen( "RESIZE" ) );
				}
				break;

			case ButtonPress:
				/* 移動ボタン */
				if ( event.xbutton.window == move_b  ) {
					xctrl_proc_moveb();
				}

				/* サイズ変更ボタン */
				else if ( event.xbutton.window == resize_b ) {
					xctrl_proc_resizeb();
				}	    

				break;

			case KeyPress:
				XFreeGC( dpy, gc );
				XDestroyWindow( dpy, win );
				XCloseDisplay( dpy );
				return;
		}
	}
}


static void 
xctrl_proc_moveb()
{
	/* ウィンドウマネージャが間にいるためか、XGetGeometry() では正しく
	   位置を取得できなかったので現在座標は別に保存しておくことにして、
	   それを引数としてウィンドウを移動させています。 */

	x += 10;
	y += 10;
	
	XMoveWindow( dpy, win, x, y );
}


static void 
xctrl_proc_resizeb( void )
{
	static int stat = 0;

	unsigned int w, h;
	unsigned int dummy;


	/* 現在の幅と高さを取得 */
	XGetGeometry( dpy, win, (Window*)&dummy, (int*)&dummy, (int*)&dummy, 
		      &w, &h, &dummy, &dummy );

	if ( ! stat ) {
		/* 拡大 */
		w    *= 2;
		h    *= 2;
		stat  = 1;
	}
	else {
		/* 縮小 */
		w    /= 2;
		h    /= 2;
		stat  = 0;
	}

	XResizeWindow( dpy, win, w, h );
}

/* End of xctrl.c */
