j^RP^Pd^Nh8
_j
^F^[Ftl^O@hN&DELxN&^At&^Hhj^WFlgUDELDELbk^B@^Os^_8j
DELDELbd^Z^HC!^LWy'PDELDEL`T(^Z^Y^W~^D|^_@|
^C^F'PDELDEL`T
^By'PDELDELpPPDELDELb`Z^U^OWDELDELb`^WPDELDELb`N^\Flj:^O^WDELDEL`$^_^PDELDEL`$z^SWVDELDEL`$^B@^F^P^W^Fhj^U^O^PDELDEL`$^D^W^PDELDEL`$^DN^XFDELh^WFhl^WFlDELDELq^X&
DELDELq^X^Z^Q^OPDELDELb\^WVDELDELq^Xdj	^WVDELDELq^Xd^_Gd^Z_@`j	^WVDELDELq^X`^O@p^W@p^WF`x^TBxDEL^W.t'PDELDEL`T(z
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDELj^AN^O2N^\h^AN# ^L'`PDELDELaNW^A^W^C|j^A/j^Ab'PDELDEL`T(Z^AW'PDELDEL`T#(N? ^B'hPDELDEL`T^W^FtW^A^W@x'h(^C(W^A.DELDELbHJ
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDELj^A^L^O2N^\h^AN# ^L'`PDELDELaNW^A^W^C|j
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDELj
^PWy'PDELDEL`T(^Z=f^OGp^W@pN^\FDELDELq^X&
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDELj^Ej<ij^A^N^OGp^W@p\@^A^_p



DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDELNc^VDELDELtH^WpWE^H^B^A"^_8^_
^M'PDELDELq 0J?+N^\^FpDELDELbd^W6DELDELt@^W@pgPDELDELp^D#^H'F^ADELDELp^WPDELDELp\`PDELDELp^D^ORDELDELtH^WPDELDELtH^W@|j^AKN^\^FpDELDELq^X&
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDEL^O6'p^DgPDELDELq GJ>h^\PDELDELp^D^Z^Q'VDELDELpPDELDELb`_j
DELDELq^X^Z^Q^OPDELDELb\^WVDELDELq^Xdj	^WVDELDELq^Xd^_Gd^Z\@^j	^TVDELDELq^X^^TF^DELDELp^DN^\VDELDELp^DDELDELbd^_PDELDELbdZ>^O^WDELDEL`(^_^PDELDEL`(z^YWVDELDEL`(NXUDELDELbd^B@^Cs^_8j^W^O^PDELDEL`(^D^W^PDELDEL`(^D^TRDELDELbdDEL'VDELDELp^Dpj:^]^_8^R^R^B_8^_@^H^Z^F_j^\j^R^OB^H^W@^HF|^L^Z^F_j
^_
DELDELq^X^Z^Q^OPDELDELb\^WVDELDELq^Xtj	^WVDELDELq^Xt^_Gt^Z^F_j^H^WPDELDELq^X^_8^R^R^B_8^O^WDELDEL`(^_^PDELDEL`(z^VWVDELDEL`(NXE^H^B@^B[^_8j^T^O^PDELDEL`(^D^W^PDELDEL`(^D^TB^HDEL^_8^R^R^B_8^WF^HDELDELq^X&
DELDELq^X^Z^H^OWDELDELb\^OPDELDELb`^WPDELDELb`^TRDELDELq^XDEL^_8^R^R^B_8^BDELDELx#_H^B@'^_8^R^R^B_8_^_8^R^R^B_8^_8^R^R^B_8^B@^[^B@nWF^H^B@	i^_8^R^R^B_8^_8^R^R^B@^D_8WA^H^_x^H^Z
W>^B@^C8t#^L
&'QDELDELc^Xj^V4#^F^L^Z
W6^B@^A^R^C!^N6DELDELf^X*fW{^H^Dt#^B^L^Z_@|j^SN^\x^M^WpPDELDELf^\#x^H^W^F|WF|W}^HN\}^M^B@yG=W^C^ODEL^_xj^N^Ox^D^Wx^DN^X@DELj#^_DEL
	NX#^E^Lj^RNX#^D^Lt#^L^ZNH#^L_x_^_8^R^C^R^B
)t#^B^L^Z^F_0j	W>^B>^W^AN\~^M^B@	L^_z
_7_QDELDELg@t#^C^L^Z^NW~^H^B@^F^A_x^H\x^L_xW{^H^D^W0^_8^R^C^R^B
^HG{^D^HJet#^E^L^Z^F_j^D_^_8^R^A^R^B
DEL
	N^X@^Hj
^XG{^D^H^Z^]^_x^Z^X'(
_j
_xj^SN^\x^M^WpPDELDELf^\#x^HW^C^_xz_@|j^F^W~|N^\x^M^WpPDELDELf^\#x^D^F|Z^HW>^B^Ad^_(Z^_W.W5N\}^M^B@^FsG=(
^KNX#^E^L_j^D_^_8^R^R^B
^_'(
^YNX#^C^LN^\x^MWx^H'OP^DDELDELf^\j^X'xVDELDEL|\W^C^HN\x^M'GQ^HDELDELf^\W{^H^DW6^B@^]^_
^Mt#^B^L
G3Z^EW3^_8^R^C^R^B
N^X$^A^H^Lj^F_j"WF^HWE|WE^L^B@^FOG=W^A4$^E^H^L^Z^F_j^D^W8^_8^R^A^R^B^R_8gFnW%@^RT^AWE^H^B@^]6G=^_z^F_j^D_^_8^R^R^Bx^D_8_ ^_PDELDELg ^Z
_j^Aa^O^X^_^X*^Ej?^^WQDELDELg4_H^B@^BP^W^Ag^PDELDELg,^DG0
.gh
W^HNL0^A^\^H
^Q_"NX^H#	W0C ^W	C j+W(^WPDELDELg,#PDELDELg4N? ^Dc'X^AN^W xW^W^XN^W 
W^W0^C^X^A:_j
^R_^[^PDELDELg,^W^DDELDELg,^WvDELDELg,'PDELDELg ^[ ^A^W^DDELDELg,^W9j>^N'p-^C8^W^FDELDELg(6DELDELg(Z^U^W^VDELDELg(DELDELg0^W|DELDELg(_^[PDELDELg(W^CGQDELDELg4^Z^L^WVDELDELg(DELDELg4'x^D^_8^R^_^R^B@_8WA^H^W9^O6^W6DELDELg(_+p^W^CvDELDELg,^Z^H^W6DELDELg4^_8^R^C^R^Bh^D_8^WA^H4#|^Z	WF^H^B??^Wp|#0N? ^D^W^F|WF^L^B=W^A^_8
>^H^Z^W8j
^O8^O0TsDELDEL^O/^_(zt^W^X^_8^R^W^R^B
^F^W0j
^W>DELDELg@_^_8^R^C^R^B^D_8^WVDELDELg<|^_@^H
^[^WPDELDELg<^C@^HW^F^B@^AU^_z^F_j^E^W@|^_8^R^R^B^D_8'F^L|WF|WE^HgUDELDELc^X^B@^NFG=^_8^R^R^B^D_8'F^P|WF|WE^LWE^H^B@^N&G=^_8^R^R^B
^F^W0j
^W>DELDELg@_^_8^R^C^R^BW@^HN^X ^Ab^R^R^B@|^R^P^R^B^HW@^H^W@^LW@^PN^X ^Eb
.^WX#h^Dc^CW[^DW.^BDELDELy^CW.W5_8W=^B@^V8|%tWj^Dj^VW6W=W]^BDELDEL|rG=^C0W^B^_8^R^W^R^Bx^Ad_8WA^H^WA^P_@tN^\v^M>(^Wv^D|&@>(^Z^P^W DELDELDELDEL^[@|^W^Fxj^N^W@>(^WvPDELDELf^\xN^\xW^_



G %^Zn^W8#(^W^F>(^C^Ft^W@|^C@>(^W^F>$^FxZ^VgF|W5WE>(W-^B?^U|%tj^XWF>(W-WE|^BDELDEL|@G=^WF>$|^_^X^Z

W6^BDELDELxu'(
*4#^B^L
^W@|#@tW^E^B@^W#G=^_

W6^BDELDELv^F4#^E^L^Z^F_j^E^W@tj^K	_ _@>P_@>X_@l^O8j^TN^X!^AjyN^X!^BjsN^X!^CjmN^X!^DjgN^X!^F_@hj^4!^F
N#@>$^C^X'FP>$^O8N^\xW4'P^BDELDELhA
^KN#F>L>Lj^OgF>L^B=6^O/T^Cj&4!^A^Z^P'VDELDELgp>h_@>Xj^S4!^C^Z^N'VDELDELgr>h_@>X^WF>L>$&	>$J^[^_@>$^Z4!^F
>$^T@>(g(
N`@>$ ^H 0^O/T^C&	>$JS^O/'(0@>$T^C4!^F^Z$^W@hW@pc(#^H^W^F>$^_@>$Z^P^WF>$d^WFd>PN^X!	j^F,4!^Z^O^OB^L^W@^L^WF|>Lj^M^OB^L^W@^L^WF|>L'@>wW^A^W^Fp4&^_>L^Z^OgF>L^B<H^O/T^Cj?8_C>,_A>0j^K'.^O>,_A>04!^Z^O^OB^L^W@^L^WF|>Lj^M^OB^L^W@^L^WF|>LG X^Z^L'VDELDELgt>8j
'VDELDELh^E>8'@>wW^A^W^Fp^WF>L>$^_@>$^Z^T4!^F

'^Fh^A>^\j'.^Q>^\gF><gE>@WE>^\>DE>D^B@^O^Y|%pW^A^_@><
^P'VDELDELh^\>h_@>Xj&4!^A^Z^P'VDELDELh^^>h_@>Xj^S4!^C^Z^N'VDELDELh >h_@>X'F>lp^\h
^P^O@p^W@p^O(^TjDELDELj^L^O@p^W@p^T"0DEL^_@h^Z4!^D^Z^L^O@p^W@p^T".DEL^WFh>$j^R^O@p^W@p^O(^TjDELDEL^OG>$^_@>$Z^\h^Zg^_@>$Z^P^WF>$`^WF`>PN^X!^HgA>l'@>c^W^F>d\@>^HE>D

@ 0^T
N?&
>$&	>$JV^OG>d^W@>dg(0@@>$^T
j^N^OG>d^W@>d^T"0'@>a@>dJl^_@>@J^Q>^HE>D^Z^P^OG>d^W@>d^T"+j^N^OG>d^W@>d^T"-4'SDELDELhA^Z^P^OG>d^W@>d^T"Ej^N^OG>d^W@>d^T"e'@>c#@>d^W^F>T^C^F>PN^X!j^C\4!^F
 N#@h@>@z^VD#0
^P'VDELDELh">h_@>Xj&4!^A^Z^P'VDELDELh$>h_@>Xj^S4!^C^Z^N'VDELDELh&>h_@>X'F>lp^WF>@>$_@>4^_@>$Z^Q^\h
^L&^Q>4j^N^O@p^W@p^T"0DELj^R^O@>4^O@p^W@p^O(^TjDELDEL^OG>$^_@>$JG4!^D
^L&^Q>4j^N^O@p^W@p^T"0DELj^R^O@>4^O@p^W@p^O(^TjDELDEL^OG>$^_@>$zCgA>lj^Aw4!^F
^_@h^Z^E_@h^C&^H^L^W@^L>^DFx>D&^Qhz	^WFh>^\j'.^Q>^\gF><gE>@WE>^\>DE>D^B@^KH|%pW^A>^HE>D^Z^F_@>@^WFh>$4!^D
l^_F>@j	F>@hz^K'^F>$DELhj<M^W@>$#@>@^W^Fhj>!^T^^>lj^M^OB^L^W@^L^TF|>l'@>lW^A'F^Apj^A^S^OB^L^W@^LWA|4!^F

^OGh^_@hzm'^F>$DELpj

^CF>4tj

^AA4!^H^Z
^A^RW>WE>t^B@
DEL^_8^_
	^W@>|j^A
N#@>x^C('FP>x^O0NXqDEL4'U^BDELDELhA
^W&DELDELDELDEL>x^W.>l&l>l
^L&h>l^Z^H^O0NXqDEL^_(
^\G![^Z^YgF?W5^B^Dp^_8^W^A^_^Z_j



^RG!s

G![^Z"gF^PW=gE?WE>xW-WE>p^B^C\|%l^W^F>hj gF^PW=WE>lWE>xW-WE>p^B
^H^CF>p>|^_@^P
^Q^_@>l^Z^H^W@>|j^Sj=?^_@>|
^H^W@>|j^D_^_8^R^R^Bh
j

^W^_@?0^Z^Q^W@?(N#^X^C@?$^W^F?(^O@?<j


^KG!E^Z

W^Aj^L^Ox^D^Wx^DNXADEL4'U^BDELDELhA

G!-^Z^Dj^Dj.^O0^T+DEL^ODEL^_xz^NW>^BDELDELcIW^Aj^L^Ox^D^Wx^DNXADEL^OG^P^_@^Pz>Q^_@^H



	>^TF? ? &l^T^Z^U^O^B^\^W
^S&
	N#F?(?(&l^T^Z^T^O^B^\^W
^P^O^B^\^W
^TD|x^O@x^O/^_(Z
+!s^Z^O^W@|4'P^CDELDELhA
?^^^_G|
^W^_(Z^WW&WE|^B@^E/^_8^_^Z^F_
^N!c
^F\

G -^Z^L^W0^C^X^TB|^O8j
(N^Xx~W^A^AZ^^^W #(gF^AWE|^W0^C(W^E^B@^DMG=^O8j
^W0^C^X^TB|^O8N^XxDELW ]^Z?%^W8^_8^R^_^R^B_8_HWE^XWE^TWE^P>DE^H^B+|%l^_8^R^R^B_8_HWE^XWE^TWE^P>DE^H^B^K|%l^_8^R^R^Bx^P_8WA^T'QDELDELhp^W@^PgaPDELDELhpN^M@^N
^T^]^Z"^_@^H^Z^KN^O@^L^S^_
^Tg.^H^B@^CeW^E^B@^C^H^_8>^HE^H?^F^W^D^X^_
>^TF^H^H\PDELDELhp_x>^HE^H

^ECy'PDELDELhp(*
^L'PDELDELh^B0*^H^T#0j*>^D@^H>+W 0^T^C>^D@^H>^C^X>^P^P>0 @$>^D^F^HG1*^F^W)j^O0j?0^D#5j.'PDELDELhp0^Z^U^T&1DELDELhp^Ox^_@^\
^D^O(j^Q^T#0^O7^Lp^D#9JV\h'PDELDELhp^_8^R^_^R^Bx^D_8WA^T^_@^LZ
^XG{^D^H^Z^_^_x^Z^Z'(
_j^A^VN^\x^M^WqPDELDELf^\^WA^PN#A^LG{^H^D*?t#^B^L
!^DJ1W6WE^HN\}^M^BDELDELgWG=W^A^A
^QNX#^E^L^_(j^FW)j^D_(^W(N?@^Lj
W>^BDELDELb^_#)^_0^Z;'(
+t#^B^L
W}^H^B@FG=^_

W>^BDELDEL`)^W@^Pj^H^C.^Hj?E^_8^R^_^R^BDELDELg8^R^R^BN^X ^Qb
^O/^_(zo_^_8^R^R^Bh_8WA^H^TA^LWA^PW8j^O8T3DEL^O/^_(zw^W^X^_8^R^W^R^B



j^]!^LLLLz^RN#!
Nc 
j^E^O@|^OGh^_@hJK^OG|G!^LLLLz^PNc!
'pPC^Aj"!^LLLLz^WN#!
Nc 
'pPCj^E^O@|^O8N^\xDEL^W^A4'P^BDELDELhA
?K^_(^Z^P>^D j^At>^C.p^_ Z^S>^C >0@p>^C^X>^P>^D^Fp!E
^K!e^Z
N#(^C0gAPj5'."DELDELg@^_^X
^O>^D j^Z^_@x
^N>^[PDELDELiH>^Tj	>^[PDELDELiHj
#.|j^E^C.|j^W'."DELDELg@>^D j


C!^Hjh_PDELDELg@^_@|z^P>^D@p> @h>^D^F`j>^DFh`_^AN#@|W^F>DE`^B@!G=>^D^Fp^_@x
^H>^T@pj^F>^D@p^_8^R^_^R^B@^H_8WA^P^_8
^P>^HE^H^Z	>^D@^Hj
^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A0000000000^A^A^A^A^A^A^A000000^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A000000^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^A^AP`
%x0x%02x%s%sbad switch yylook %dLdTh^A^B^Allll^F^B^XVtldndn                    00000000000000000000-+ 0123456789ABCDEF0123456789abcdef0x0X-+ -+ ^Wn^E558^SF 
^P^Al^X[^H^A^D^Y@
^Cf^P^K'^B^DT^E^AT^F^AT^A^[^W^A^P^A^L^Y[^H^A^Q^Y
^Z^[^B^]^Z^[^C2^Z^[^D9^Z[^UO^Z^[^OO^Z^[^Ea^Z^[V^Am^Z^[#^A^P^As^Z[^F^H^Z^[^H
'^B^D^D^Z+^A^P@W[6^A^P^At#@1^Cf0^A^['^B^D^D^[8^A
^B^)[^K^Bi)[^M^B})[^N^B0)[^P^B2)[^Q^BT)[^S^Bp)[^T^Br)[^V^B~)[^W^B^]*[^Y^B+*[^Z^B7*[^\^BO*[^]^B[*[^_^Br*[ ^Bz*["^B^Z*[#^B^_*[%^B;*[&^B_*[(^Br*[)^B^C+[+^B^C+[,^B^C+[.^B^R+[/^B'+[1^B3+[2^BC+[4^BW+[5^Ba+[7^Bq+[8^Bv+[:^B^O+[;^B^Q+[=^B*+[>^B6+[@^BF+[A^BF+[C^BW+[D^BW+[F^Ba+[G^Bi+[I^Bi+[J^B	,[L^B^N,[M^B=,[O^Ba,[P^Bc,[R^Bg,[S^By,[U^By,[V^B^F,[X^B^O,[Y^B^],[[^B#,[\^B.,[^^B;,[_^BX,[a^B\,[b^B\,[d^Bq,[e^Bw,[g^Bz,^[^]DEL,[h^B^M-^[j^B^Q-[l^B^Y-^[TK-^[n^Bo-^[o^B^M.^[q^B^W.^[r^B^_.^[t^B2.^[u^BO.^[w^B^A.^[x^B^[.^[z^B^[.^[{^B^[.^[}^B^[.^[~^BH.^[
/^[^F^B</^[^BV/^[	^BV/^[
^B^P7[^M^B^Z7[^S^B*7^[9^B,7[:^B^A27[^N^BK7[^Q^Bt7[^P^B~7[^T^B^A7[^Y^B
:^['^P:^[4+:^[/-:[2<:[&<:^[C?:^[Q^BE:
echo extracting sunBMconv.l 1>&2
cat >sunBMconv.l << 'EnD of sunBMconv.l'
%{

%}

HEXDIGIT	[0-9a-fA-F]
HEX             0x{HEXDIGIT}{HEXDIGIT}

%%

{HEX}   {
	    int oldBit, newBit;
	    int oldVal, newVal;
	    int n;

	    sscanf(yytext+2, "%x", &oldVal);
	    for (n=0, newVal=0, oldBit=0x80, newBit=0x01;
			    n<8;
			    n++, oldBit>>=1, newBit<<=1)
		if (oldVal & oldBit) newVal |= newBit;
	    printf("0x%02x", newVal);
	}

.       ECHO;

\n      ECHO;

%%
EnD of sunBMconv.l
echo extracting xpuzzle.c 1>&2
cat >xpuzzle.c << 'EnD of xpuzzle.c'
/*
 * 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 (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) ;
}
EnD of xpuzzle.c
echo extracting xpuzzle.man 1>&2
cat >xpuzzle.man << 'EnD of xpuzzle.man'
.TH XPUZZLE 6 "February 1987"
.UC 4
.SH NAME
xpuzzle \- another X-window V11 puzzle game
.SH SYNOPSIS
.B xpuzzle
[
.B options
]
.SH DESCRIPTION
The goal of this game is to move down the largest piece to the bottom in 
minimal number of movements.  It is known that the puzzle can be solved in 
86 movements.  To move a piece, point it by the mouse and press a button,
hold the button until you move the mouse to an adjacent empty
square.  
.br
If you want to quit, press 'q' or 'Q' on the keyboard, while the cursor is
in the puzzle window.

The following options are valid:
.PP
.TP 8
.B -fg color
as usual - change foreground color
.TP 8
.B -bg color
as usual - change background color
.TP 8
.B -bd color
as usual - change border color
.TP 8
.B -bw number
as usual - change border width
.TP 8 
.B host:display
Name of the display you want the puzzle to run on.
.SH AUTHORS
.PP
Jiang-Hsing Chu (jchu@mimsy.umd.edu) original game for suntools
.PP
Claus Gittinger (..!decvax!unido!sinix!claus) X11 version
EnD of xpuzzle.man

