DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T x

⟦5dde3c8a6⟧ TextFile

    Length: 12861 (0x323d)
    Types: TextFile
    Names: »xpuzzle.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Xpuzzle/xpuzzle.c« 

TextFile

static char SCCSID[] = "@(#)xpuzzle.c	1.1 88/05/31";
/*
 * Copyright 1988 by Siemens
 *		All Rights Reserved
 *
 * Permission to use, copy, modify and distribute this software is
 * hereby granted, provided that this copyright notice appear in all
 * copies and that the copyright notice appear in supporting 
 * documentation.
 *
 * written Feb 1988 by claus gittinger
 * based on puzzletool by Jiang-Hsing Chu (jchu@mimsy.umd.edu)
 *
 * Email: ...!decvax!unido!athen!claus
 *
 */

#include "X11/Xlib.h"
#include <stdio.h>

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

/*
 * you may have to modify this for your system
 */
#ifndef ATT
# define strchr index
#endif

#define  PIECE_COLS    4                /* No of columns of pieces. */
#define  PIECE_H       32               /* Number of pixels for height. */
#define  PIECE_ROWS    5                /* No of rows of pieces. */
#define  PIECE_W       32               /* No of pixels for width. */
#define  DISPLAY       30               /* Calculators numerical display. */

#define  MAXLINE        80               /* Length of character strings. */
#define  TOTAL_HEIGHT   (PIECE_ROWS * PIECE_H)
#define  TOTAL_WIDTH    (PIECE_COLS * PIECE_W)

Display     *dpy;
int         screen;
GC          gc;

Window      rootWindow, puzzleWindow;
long        FgPixel, BgPixel, BdPixel;

#include "piece0.bit"
#include "piece1.bit"
#include "piece2.bit"
#include "piece3.bit"
#include "icon.bit"

int ncolumn,column ;    /* Column number of key pressed. */
int m,n ;               /* mouse and index */
int nrow,row ;          /* Row number of key pressed. */
int step=0;

#define NPIECES 10

#define EMPTY           -1
#define BORDER          -2
#define SMALLPIECE      0
#define  SMALLPIECE1    (SMALLPIECE+0)
#define  SMALLPIECE2    (SMALLPIECE+1)
#define  SMALLPIECE3    (SMALLPIECE+2)
#define  SMALLPIECE4    (SMALLPIECE+3)
#define VLONGPIECE      4
#define  VLONGPIECE1    (VLONGPIECE+0)
#define  VLONGPIECE2    (VLONGPIECE+1)
#define  VLONGPIECE3    (VLONGPIECE+2)
#define  VLONGPIECE4    (VLONGPIECE+3)
#define HLONGPIECE      8
#define BIGPIECE        9

int board[PIECE_ROWS+2][PIECE_COLS+2]= {
	{BORDER, BORDER,      BORDER,      BORDER,      BORDER,      BORDER},
	{BORDER, VLONGPIECE1, BIGPIECE,    BIGPIECE,    VLONGPIECE2, BORDER},
	{BORDER, VLONGPIECE1, BIGPIECE,    BIGPIECE,    VLONGPIECE2, BORDER},
	{BORDER, VLONGPIECE3, HLONGPIECE,  HLONGPIECE,  VLONGPIECE4, BORDER},
	{BORDER, VLONGPIECE3, SMALLPIECE1, SMALLPIECE2, VLONGPIECE4, BORDER},
	{BORDER, EMPTY,       SMALLPIECE3, SMALLPIECE4, EMPTY,       BORDER},
	{BORDER, BORDER,      BORDER,      BORDER,      BORDER,      BORDER}
};

#define empty(row, col) (board[row][col]==EMPTY)

Pixmap      piece0_bitmap = NULL,
	    piece1_bitmap = NULL,
	    piece2_bitmap = NULL,
	    piece3_bitmap = NULL;

struct pieceStruct {
	int     pType;
	int     pX, pY;
	int     pWidth, pHeight;
	Pixmap  pPixmap;
} pieces[NPIECES] = {
	{SMALLPIECE, 2, 4, 1, 1, NULL},
	{SMALLPIECE, 3, 4, 1, 1, NULL},
	{SMALLPIECE, 2, 5, 1, 1, NULL},
	{SMALLPIECE, 3, 5, 1, 1, NULL},
	{VLONGPIECE, 1, 1, 1, 2, NULL},
	{VLONGPIECE, 4, 1, 1, 2, NULL},
	{VLONGPIECE, 1, 3, 1, 2, NULL},
	{VLONGPIECE, 4, 3, 1, 2, NULL},
	{HLONGPIECE, 2, 3, 2, 1, NULL},
	{BIGPIECE,   2, 1, 2, 2, NULL}
};

#define pieceType(p)    (pieces[p].pType)
#define pieceX(p)       ((pieces[p].pX-1)*PIECE_W)
#define pieceY(p)       ((pieces[p].pY-1)*PIECE_H)
#define pieceWidth(p)   (pieces[p].pWidth*PIECE_W)
#define pieceHeight(p)  (pieces[p].pHeight*PIECE_H)
#define piecePixmap(p)  (pieces[p].pPixmap)

main(argc,argv)
int argc ;
char *argv[] ;
{
	int i;
	Visual visual;
	XGCValues xgcv;
	XSetWindowAttributes xswa;
	XSizeHints sizehints;
	char *ProgName, *server, *geom, *borderColor;
	char *foreGround, *backGround;
	int borderWidth = 1;

	server = "";
	geom   = "";
	borderColor = "black";
	foreGround = "black";
	backGround = "white";

	ProgName = argv[0];

	/********************************/
	/** parse command line options **/
	/********************************/

	for (i=1; i<argc; i++) {
	    if (argv[i][0] == '=')
		geom = argv[i];
	    else if (strchr(argv[i],':') != NULL)
		server = argv[i];
	    else if (strcmp(argv[i], "-fg") == 0)
		foreGround = argv[++i];
	    else if (strcmp(argv[i], "-bg") == 0)
		backGround = argv[++i];
	    else if (strcmp(argv[i], "-bd") == 0)
		borderColor = argv[++i];
	    else if (strcmp(argv[i], "-bw") == 0)
		sscanf(argv[++i], "%d", &borderWidth);
	    else
		usage(ProgName);
	}

	dpy = XOpenDisplay(server);
	if (dpy == NULL) {
	    fprintf(stderr, "can't open display \"%s\"\n",server);
	    exit(1);
	}
	screen = DefaultScreen(dpy);

	FgPixel = requestColor(foreGround);
	BgPixel = requestColor(backGround);
	BdPixel = requestColor(borderColor);

	/*************************************/
	/** configure the window size hints **/
	/*************************************/

	sizehints.flags = PMinSize | PMaxSize | PPosition | PSize;
	sizehints.min_width = TOTAL_WIDTH;
	sizehints.min_height = TOTAL_HEIGHT;
	sizehints.max_width = TOTAL_WIDTH;
	sizehints.max_height = TOTAL_HEIGHT;
	sizehints.width = TOTAL_WIDTH;
	sizehints.height = TOTAL_HEIGHT;
	sizehints.x = 100;
	sizehints.y = 300;

	if (geom && strlen(geom)) {
	    int width, height, flags;

	    flags = XParseGeometry(geom, &sizehints.x, &sizehints.y,
					 &width, &height);
	    if (flags & (XValue | YValue))
		sizehints.flags |= USPosition;
	}

	/*******************************************************************/
	/** create the puzzle main window and set its standard properties **/
	/*******************************************************************/

	xswa.event_mask = ExposureMask | ButtonPressMask |
			  ButtonReleaseMask | KeyPressMask;
	xswa.background_pixel = BgPixel;
	xswa.border_pixel = BdPixel;
	xswa.cursor = XCreateFontCursor(dpy, XC_hand1);

	visual.visualid = CopyFromParent;

	rootWindow = RootWindow(dpy, screen);

	puzzleWindow = XCreateWindow(dpy, rootWindow,
			       sizehints.x, sizehints.y,
			       sizehints.width, sizehints.height,
			       borderWidth,
			       DefaultDepth(dpy,screen),
			       InputOutput,
			       &visual,
			       CWCursor | CWEventMask | CWBackPixel | CWBorderPixel,
			       &xswa);

	/*******************************************************************/
	/** define its name and icon-bitmap                               **/
	/*******************************************************************/

	XSetStandardProperties(dpy, puzzleWindow, "puzzle","Puzzle",
			       XCreateBitmapFromData(dpy, rootWindow,
						     icon_bits,
						     icon_width, icon_height),
			       argv, argc, &sizehints);

	XMapWindow(dpy, puzzleWindow);

	xgcv.foreground = FgPixel;
	xgcv.background = BgPixel;
	xgcv.line_width = 0;
	gc = XCreateGC(dpy, puzzleWindow,
		       GCForeground|GCBackground|GCLineWidth,
		       &xgcv);

	make_bitmaps();
	eventloop();
	exit(0) ;
}

make_bitmaps() {
	int p;

	piece0_bitmap = XCreateBitmapFromData(dpy, rootWindow,
				   piece0_bits, piece0_width, piece0_height);
	piece1_bitmap = XCreateBitmapFromData(dpy, rootWindow,
				   piece1_bits, piece1_width, piece1_height);
	piece2_bitmap = XCreateBitmapFromData(dpy, rootWindow,
				   piece2_bits, piece2_width, piece2_height);
	piece3_bitmap = XCreateBitmapFromData(dpy, rootWindow,
				   piece3_bits, piece3_width, piece3_height);

	if (piece0_bitmap==NULL || piece1_bitmap==NULL ||
				   piece2_bitmap==NULL ||
				   piece3_bitmap==NULL) {
	    fprintf(stderr, "cannot allocated bitmaps\n");
	    finish();
	}

	for (p=SMALLPIECE1; p <= SMALLPIECE4; p++)
	    pieces[p].pPixmap = piece0_bitmap;

	for (p=VLONGPIECE1; p <= VLONGPIECE4; p++)
	    pieces[p].pPixmap = piece1_bitmap;

	pieces[HLONGPIECE].pPixmap = piece2_bitmap;
	pieces[BIGPIECE].pPixmap = piece3_bitmap;
}

finish() {
	if (piece0_bitmap != NULL)
	    XFreePixmap(dpy, piece0_bitmap);
	if (piece1_bitmap != NULL)
	    XFreePixmap(dpy, piece1_bitmap);
	if (piece2_bitmap != NULL)
	    XFreePixmap(dpy, piece2_bitmap);
	if (piece3_bitmap != NULL)
	    XFreePixmap(dpy, piece3_bitmap);
	exit(1);
}

usage(name)
char *name;
{
	fprintf(stderr, "usage: %s [geometry] [display]\n", name);
	fprintf(stderr, "          [-fg color] [-bg color]\n");
	fprintf(stderr, "          [-bd color] [-bw number]\n");
	exit(1);
}

requestColor(name)
char *name;
{
	XColor truecolor, availcolor;

	if (XAllocNamedColor(dpy,
			     DefaultColormap(dpy, DefaultScreen(dpy)),
			     name, &availcolor, &truecolor) == 0) {
	    fprintf(stderr, "Color '%s' unknown\n", name);
	    exit(1);
	}
	if (truecolor.red != availcolor.red ||
		truecolor.green != availcolor.green ||
		truecolor.blue != availcolor.blue) {
	    fprintf(stderr, "Warning: %s color bay be wrong\n", name);
	}

	return availcolor.pixel;
}

eventloop() {
	XEvent event;
	XExposeEvent *ee = (XExposeEvent *)&event;
	XKeyPressedEvent *ke = (XKeyPressedEvent *)&event;
	XButtonPressedEvent *be = (XButtonPressedEvent *)&event;
	char keybuff[10];
	int nchar;

	while(1) {
	    XNextEvent(dpy, &event);
	    switch(event.type) {
		case KeyPress:
		    nchar = XLookupString(ke, keybuff, 1, NULL, NULL);

		    if (nchar > 0) {
			switch (keybuff[0]) {
			    case 'q':
			    case 'Q':
				finish();
			}
		    }
		    break;

		case ButtonPress:
		    column = be->x / PIECE_W ;
		    row = be->y / PIECE_H ;
		    n = board[row+1][column+1] ;
		    m=0;
		    break;

		case ButtonRelease:
		    if (n>=0) {
			ncolumn = be->x / PIECE_W;
			nrow = be->y / PIECE_H ;
			if (! empty(nrow+1, ncolumn+1)) break;
			if (ncolumn > column) m=0;
			if (nrow<row) m=1;
			if (ncolumn<column) m=2;
			if (nrow>row) m=3;
			do_move();
		    }
		    break;

		case Expose:
		    if (! ee->count)
			repaint();
		    break;

		default:
		    break;
	    }
	}
}

repaint() {
	int p;

	XClearWindow(dpy, puzzleWindow);
	for(p=0; p < NPIECES; p++)
	    XCopyPlane(dpy, piecePixmap(p), puzzleWindow, gc,
				0, 0, pieceWidth(p), pieceHeight(p),
				pieceX(p), pieceY(p), 1) ;
}

do_move() {
	int ox,oy,nx,ny;

	ox=pieces[n].pX;
	oy=pieces[n].pY;
	switch(pieceType(n)){
	    case SMALLPIECE:
		switch(m){
		    case 0:
			if (empty(ny=oy, nx=ox+1)) break;
			return;
		    case 1:
			if (empty(ny=oy-1, nx=ox)) break;
			return;
		    case 2:
			if (empty(ny=oy, nx=ox-1)) break;
			return;
		    case 3:
			if (empty(ny=oy+1, nx=ox)) break;
			return;
		}
		break;

	    case VLONGPIECE:
		switch(m){
		    case 0:
			if (empty(oy, ox+1) && empty(oy+1, ox+1)) {
			    nx=ox+1; ny=oy;
			    break;
			}
			return;
		    case 1:
			if (empty(oy-1, ox)) {
			    nx=ox; ny=oy-1;
			    break;
			}
			return;
		    case 2:
			if (empty(oy, ox-1) && empty(oy+1, ox-1)) {
			    nx=ox-1; ny=oy;
			    break;
			}
			return;
		    case 3:
			if (empty(oy+2, ox)) {
			    nx=ox; ny=oy+1;
			    break;
			}
			return;
		}
		break;

	    case HLONGPIECE:
		switch(m){
		    case 0:
			if (empty(oy, ox+2)) {
			    nx=ox+1; ny=oy;
			    break;
			}
			return;
		    case 1:
			if (empty(oy-1, ox) && empty(oy-1, ox+1)) {
			    nx=ox; ny=oy-1;
			    break;
			}
			return;
		    case 2:
			if (empty(oy, ox-1)) {
			    nx=ox-1; ny=oy;
			    break;
			}
			return;
		    case 3:
			if (empty(oy+1, ox) && empty(oy+1, ox+1)) {
			    nx=ox; ny=oy+1;
			    break;
			}
			return;
		}
		break;

	    case BIGPIECE:
		switch(m){
		    case 0:
			if (empty(oy, ox+2) && empty(oy+1, ox+2)) {
			    nx=ox+1; ny=oy;
			    break;
			}
			return;
		    case 1:
			if (empty(oy-1, ox) && empty(oy-1, ox+1)) {
			    nx=ox; ny=oy-1;
			    break;
			}
			return;
		    case 2:
			if (empty(oy, ox-1) && empty(oy+1, ox-1)) {
			    nx=ox-1; ny=oy;
			    break;
			}
			return;
		    case 3:
			if (empty(oy+2, ox) && empty(oy+2, ox+1)) {
			    nx=ox; ny=oy+1;
			    break;
			}
			return;
		}
		break;
	}

#ifdef LATER
	{
	    char display[MAXLINE];  /* Current number of moves display. */

	    sprintf(display, "%d", ++step);
	    XDrawImageString(dpy, displayWindow, gc,
				  0, 0, display, strlen(display));
	}
#endif LATER

	pieces[n].pX=nx;   /* move the piece */
	pieces[n].pY=ny;

	XClearArea(dpy, puzzleWindow,
			(ox-1)*PIECE_W, (oy-1)*PIECE_H,
			pieceWidth(n), pieceHeight(n), 0);

	switch(pieceType(n)){
	    case SMALLPIECE:
		board[oy][ox]= EMPTY;
		board[ny][nx]= n;
		break;

	    case VLONGPIECE:
		board[oy][ox]=board[oy+1][ox]= EMPTY;
		board[ny][nx]=board[ny+1][nx]=n;
		break;

	    case HLONGPIECE:
		board[oy][ox]=board[oy][ox+1]= EMPTY;
		board[ny][nx]=board[ny][nx+1]=n;
		break;

	    case BIGPIECE:
		board[oy][ox]=board[oy][ox+1]=board[oy+1][ox]=board[oy+1][ox+1]= EMPTY;
		board[ny][nx]=board[ny][nx+1]=board[ny+1][nx]=board[ny+1][nx+1]=n;
		break;
	}
	XCopyPlane(dpy, piecePixmap(n), puzzleWindow, gc,
			0, 0, pieceWidth(n), pieceHeight(n),
			pieceX(n), pieceY(n), 1) ;
}