1 /*****************************************************************************/
2 /*									     */
3 /*									     */
4 /*	X patience version 2 -- module X-markcard.c			     */
5 /*									     */
6 /*	Routines for marking selected cards				     */
7 /*	written by Heiko Eissfeldt and Michael Bischoff			     */
8 /*	see COPYRIGHT.xpat2 for Copyright details			     */
9 /*									     */
10 /*									     */
11 /*****************************************************************************/
12 #include "X-pat.h"
13 
14 #ifndef NO_ROUND_CARDS
15 #include	<X11/Xmu/Drawing.h>
16 #endif
17 
18 
19 #include "stipple.bm"
20 
21 /* game.for set-mark / clear-mark */
22 
23 static GC stipplegc;
24 static Pixmap mark_storage = 0;
25 static int mark_height = 0, mark_width = 0;
26 
27 static int rem_x, rem_y;
28 static XSize_t rem_w, rem_h;	   /* h = 0: only horizontal bars saved */
29 
init_mark(unsigned long pixel,int markwidth)30 void init_mark(unsigned long pixel, int markwidth) {
31     /* make GCs for dashed lines or colored lines (to mark cards) */
32     XGCValues gcv;
33     long gcflags;
34     Pixmap stipplemap;
35 
36     stipplemap = XCreateBitmapFromData(dpy,
37 				       RootWindow(dpy, screen),
38 				       stipple_bits,
39 				       stipple_width,
40 				       stipple_height);
41     gcflags = GCForeground | /* GCBackground | */ GCGraphicsExposures |
42 	GCFillStyle | GCStipple;
43     gcv.graphics_exposures = True;
44     gcv.foreground = BlackPixel(dpy, screen);
45     gcv.background = WhitePixel(dpy, screen);
46     gcv.stipple = stipplemap;
47     gcv.fill_style = FillStippled;
48     stipplegc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
49 }
50 
create_mark_storage(void)51 static void create_mark_storage(void) {
52     mark_storage = XCreatePixmap(dpy, table, mark_width, mark_height, /* geo.lsw, geo.lsh, */
53 				 DefaultDepth(dpy, screen));
54 
55 }
56 
free_mark(void)57 static void free_mark(void) {
58     if (mark_storage)
59 	XFreePixmap(dpy, mark_storage);
60     mark_storage = 0;
61 }
62 
set_mark(int x,int y,XSize_t W,XSize_t h)63 static void set_mark(int x, int y, XSize_t W, XSize_t h) {
64     if (h > mark_height) {	/* make sure there's enough space */
65 	free_mark();
66 	mark_height = h;
67     }
68     if (W > mark_width) {
69 	free_mark();
70 	mark_width = W;
71     }
72     if (!mark_storage)
73 	create_mark_storage();
74 
75     rem_h = h;
76     rem_w = W;
77     rem_x = x;
78     rem_y = y;
79     XCopyArea(dpy, table, mark_storage, whitegc, x, y,
80 	      rem_w, rem_h, 0, 0);
81 #ifndef NO_ROUND_CARDS
82     if (ROUND_W)
83 	XmuFillRoundedRectangle(dpy, table, stipplegc, x, y,
84 				rem_w, rem_h, ROUND_W, ROUND_H);
85     else
86 #endif
87 	XFillRectangle(dpy, table, stipplegc, x, y, rem_w, rem_h);
88     XFlush(dpy);
89 }
90 
clear_mark(void)91 static void clear_mark(void) {
92     XCopyArea(dpy, mark_storage, table, whitegc, 0, 0,
93 	      rem_w, rem_h, rem_x, rem_y);
94     XFlush(dpy);
95 }
96 
97 /* pile is completely drawn and unmarked. */
98 /* check, if pile has to be marked.       */
99 /* if so, do it                           */
100 
show_mark(boolean on)101 void show_mark(boolean on) {
102     if (!game.graphic)
103 	return;
104     if (on) {
105 	struct pilegeometry *p;
106 	int f, l;
107 	int pile, m_x, m_y, m_w, m_h;
108 
109  	if (game.srcind < 0)
110 	    return;
111 	if (!mark_storage) {
112 	    mark_height = geo.lsh;
113 	    mark_width = geo.lsw;
114 	    create_mark_storage();
115 	}
116 
117 	p = geo.pg + (pile = getpile(game.srcind));
118 	f = game.srcind - INDEX_OF_FIRST_CARD(pile);
119 	l = CARDS_ON_PILE(pile)-1;
120 	if (p->cdx >= 0) {
121 	    m_x = p->x + p->ox + f * p->cdx;
122 	    m_w = (l-f)*p->cdx + geo.cw;
123 	} else {
124 	    m_x = p->x + p->ox + l * p->cdx;
125 	    m_w = (f-l)*p->cdx + geo.cw;
126 	}
127 	if (p->cdy >= 0) {
128 	    m_y = p->y + p->oy + f * p->cdy;
129 	    m_h = (l-f)*p->cdy + geo.ch;
130 	} else {
131 	    m_y = p->y + p->oy + l * p->cdy;
132 	    m_h = (f-l)*p->cdy + geo.ch;
133 	}
134 	set_mark(m_x, m_y, m_w, m_h);
135     } else {
136 	clear_mark();
137     }
138 }
139