1 /*****************************************************************************/
2 /* */
3 /* */
4 /* X patience version 2 -- module X-cards.c */
5 /* */
6 /* Card drawing interface for X11 */
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 struct graphic graphic;
15 struct card card;
16 int table_clear = 1;
17
win_game(void)18 void win_game(void) {
19 #if 0
20 #ifdef useXlib
21 XMoveWindow(dpy, finished_win, (graphic.width - FINISHED_W) / 2,
22 (graphic.height - FINISHED_H) / 2);
23 XMapWindow(dpy, finished_win);
24 redraw_finwin((XExposeEvent *)0); /* must unmap it later! */
25 #endif
26 #endif
27 #ifdef useXview
28 xv_set(xv_default_server, SERVER_SYNC, FALSE, 0);
29 #else
30 XSync(dpy, 0); /* show all requests and let it be for now */
31 #endif
32 }
33
34
init_gfx(void)35 void init_gfx(void) {
36 XGCValues gcv;
37 long gcflags;
38
39 blackpixel = BlackPixel(dpy, screen);
40 whitepixel = WhitePixel(dpy, screen);
41
42
43 /* make gc for white */
44 gcv.foreground = WhitePixel(dpy, screen);
45 gcv.background = BlackPixel(dpy, screen);
46 gcv.graphics_exposures = False;
47 gcflags = GCForeground | GCBackground | GCGraphicsExposures;
48
49 whitegc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
50
51 /* make gc for black */
52 gcv.foreground = BlackPixel(dpy, screen);
53 gcv.background = WhitePixel(dpy, screen);
54 gcflags = GCForeground | GCBackground | GCGraphicsExposures;
55
56 blackgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
57 }
58
59
60 /* this is a helper routine only called by do_move(): */
61 /* it transfers card game.which is unknown to the generic part */
62 /* these transfers do not necessarily affect the appearance on the screen, */
63 /* they are needed due to the design of the game.structures as arrays */
64 /* instead of linked lists */
65
66
move_card_data(Cardindex dst,Cardindex src)67 void move_card_data(Cardindex dst, Cardindex src) {
68 game.cards[dst] = game.cards[src];
69 game.visible[dst] = game.visible[src];
70 /* graphic.cardy[dst] = graphic.cardy[src]; */
71 }
72
73
refresh_screen(void)74 void refresh_screen(void) {
75 #ifdef LABER
76 printf("refresh_screen called\n");
77 #endif
78 if (table_clear) {
79 #ifdef LABER
80 printf("(ignored)\n");
81 #endif
82 return;
83 }
84 table_clear = 1;
85 XClearArea(dpy, table, 0, 0, 0, 0, True); /* force redraw */
86 }
87
88 /* all card drawings go through this routine: */
89 /* inform the graphics interface that cards are added (delta > 0) */
90 /* or removed (delta < 0) from the specified pile. if delta = 0, */
91 /* then redrawing of the complete pile is necessary (possibly caused */
92 /* by "new game" commands) */
93 /* if cards on the pile are marked (selected), the mark is refreshed */
94
draw_pileupdate(int pile,int delta)95 void draw_pileupdate(int pile, int delta) {
96 struct pilegeometry *p = geo.pg + pile;
97 int cx, cy;
98
99 if (!game.graphic) { /* this is off when replaying saved games */
100 /* only log changes */
101 if (game.pile_changed[pile] == PILE_UNCHANGED)
102 game.pile_changed[pile] = delta;
103 else
104 if ((delta > 0 && game.pile_changed[pile] > 0) ||
105 (delta < 0 && game.pile_changed[pile] < 0))
106 game.pile_changed[pile] += delta;
107 else
108 game.pile_changed[pile] = 0;
109 return;
110 }
111 if (game.disable[pile]) /* don't draw THIS pile */
112 return;
113 if (NOT_DISPLAYED(geo.pg+pile))
114 return; /* draw nothing */
115
116 cx = p->x + p->ox; /* card position of lowest card */
117 cy = p->y + p->oy;
118 if (EMPTY(pile)) { /* draw empty pile */
119 int c;
120 XClearArea(dpy, table, p->x, p->y, p->w, p->h, False);
121 switch (game.piletype[pile]) {
122 case Stack:
123 c = SUITSYMBOL + SUIT(pile);
124 break;
125 default:
126 c = OUTLINE;
127 break;
128 }
129 PaintCard(cx, cy, c, 0, 0);
130 return;
131 }
132 if (!p->cdx && !p->cdy) { /* only topmost card is visible */
133 Cardindex c;
134 c = INDEX_OF_LAST_CARD(pile);
135 PaintCard(cx, cy, game.visible[c] ? game.cards[c] : CARDBACK, 0, 0);
136 } else {
137 if (pile_resize(pile)) /* delta changed => complete redraw */
138 delta = 0;
139
140 if ((p->cdx < 0 || p->cdy < 0) && delta < 0)
141 /* this does not work correctly yet. simply avoid the case */
142 delta = 0;
143
144 if (delta < 0) { /* cards were removed. Clear area and redraw top */
145 int x, y;
146 if (p->cdx) {
147 x = (CARDS_ON_PILE(pile)-1) * p->cdx + geo.cw - geo.rx;
148 y = (CARDS_ON_PILE(pile)-1) * p->cdy;
149 XClearArea(dpy, table, p->x+x, p->y+y, p->w-x, p->h-y, False);
150 }
151 if (p->cdy) {
152 x = (CARDS_ON_PILE(pile)-1) * p->cdx;
153 y = (CARDS_ON_PILE(pile)-1) * p->cdy + geo.cw - geo.rx;
154 XClearArea(dpy, table, p->x+x, p->y+y, p->w-x, p->h-y, False);
155 }
156 delta = 1; /* only last card is to be drawn new */
157 } else if (!delta) { /* draw complete pile */
158 XClearArea(dpy, table, p->x, p->y, p->w, p->h, False);
159 delta = CARDS_ON_PILE(pile);
160 }
161 /* (delta > 0) */
162 /* draw last cards */
163 { Cardindex c = INDEX_OF_LAST_CARD(pile) + 1 - delta;
164 int i = c - INDEX_OF_FIRST_CARD(pile);
165 /* printf("Drawing %d cards on slot %d: d=%d,%d\n",
166 delta, pile, p->cdx, p->cdy); */
167 while (--delta >= 0) {
168 int pw, ph; /* paint-width and height */
169 pw = geo.cw;
170 ph = geo.ch;
171 if (delta) {
172 /* Not the last card. May use card clipping optimisation */
173 if (p->cdx == 0 && p->cdy > 0)
174 ph = p->cdy + geo.ry;
175 if (p->cdy == 0 && p->cdx > 0)
176 pw = p->cdx + geo.rx;
177 }
178 PaintCard(cx + p->cdx*i,
179 cy + p->cdy*i,
180 (game.visible[c] ? game.cards[c] : CARDBACK),
181 pw, ph);
182 ++c;
183 ++i;
184 }
185 }
186 }
187 if (game.srcind >= 0 && getpile(game.srcind) == pile)
188 show_mark(True);
189 }
190