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