1 /*
2  * (c) Copyright 1997, Qun Zhang.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without fee,
6  * provided that the above copyright notice appear in all copies and
7  * that both that copyright notice and this permission notice appear in
8  * supporting documentation, and that the name of Qun Zhang not be used
9  * in advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  Qun Zhang make no
11  * representations about the suitability of this software for any purpose.
12  * It is provided "as is" without express or implied warranty.
13  *
14  * THE ABOVE-NAMED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE ABOVE-NAMED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  */
23 #include <stdlib.h>
24 #include <iostream>
25 #include <X11/Intrinsic.h>
26 #include <X11/StringDefs.h>
27 #include <X11/Xlib.h>
28 #include <X11/Xmu/Drawing.h>
29 #include <X11/Xutil.h>
30 #include <Xm/Xm.h>
31 #include "Hands.h"
32 #include "Seat.h"
33 #include "Table.h"
34 
35 #include <assert.h>
36 #include <strings.h>
37 #include "Bitmaps.h"
38 
39 int Seat::_firstTime = 1;
40 GC  Seat::_redgc;
41 GC  Seat::_blackgc;
42 GC  Seat::_whitegc;
43 GC  Seat::_backgc;
44 GC  Seat::_cardgc;
45 
46 Pixmap  Seat::s_map[13];
47 Pixmap  Seat::c_map[13];
48 Pixmap  Seat::d_map[13];
49 Pixmap  Seat::h_map[13];
50 Pixmap  Seat::back_map;
51 
Seat(Table * table)52 Seat::Seat(Table* table) : _isAvailable(1), _table(table)
53 {
54 }
55 
Reset()56 void Seat::Reset() {}
57 
Initialize(Display * d,int scr,Widget drawArea)58 void Seat::Initialize( Display*d, int scr, Widget  drawArea)
59 {
60 
61 	XGCValues   gcv;
62 	long     gcflags;
63 	XColor   color;
64 	Colormap cmap;
65 	GC       logogc;
66 	int      i;
67 	Arg      args[10];
68 
69 
70 	Pixmap   logomap;
71 
72 	Pixel blackpixel;
73 	Pixel whitepixel;
74 	Pixel borderpixel;
75 	Pixel greenpixel;
76 	Pixel redpixel;
77 
78 	_drawingArea = drawArea;
79 	_dpy = d;
80 	_screen = scr;
81 	Window w = XtWindow(_drawingArea);
82 
83 	blackpixel = BlackPixel(_dpy, _screen);
84 	whitepixel = WhitePixel(_dpy, _screen);
85 
86 
87 	if(_firstTime){
88 	   _firstTime = 0;
89 
90       // make card maps
91 		MakeCardMaps();
92 
93 		// make gc for white
94 		gcv.foreground = WhitePixel(_dpy, _screen);
95 		gcv.background = BlackPixel(_dpy, _screen);
96 		gcv.graphics_exposures = False;
97 		gcflags = GCForeground | GCBackground | GCGraphicsExposures;
98 		_whitegc = XCreateGC(_dpy, RootWindow(_dpy, _screen), gcflags, &gcv);
99 
100 		// make gc for black
101 		gcv.foreground = BlackPixel(_dpy, _screen);
102 		gcv.background = WhitePixel(_dpy, _screen);
103 		gcflags = GCForeground | GCBackground | GCGraphicsExposures;
104 
105 		_blackgc = XCreateGC(_dpy, RootWindow(_dpy, _screen), gcflags, &gcv);
106 
107 		logomap = XCreatePixmap(_dpy, RootWindow(_dpy, _screen), CARD_MAP_WIDTH,
108 			CARD_MAP_HEIGHT, DefaultDepth(_dpy, _screen));
109 
110 		cmap = DefaultColormap(_dpy, _screen);
111 		XAllocNamedColor(_dpy, cmap, "Yellow", &color, &color);
112 		gcv.foreground = color.pixel;
113 		XAllocNamedColor(_dpy, cmap, "Tan", &color, &color);
114 		gcv.background = color.pixel;
115 		gcflags = GCForeground | GCBackground;
116 		logogc = XCreateGC(_dpy, RootWindow(_dpy, _screen), gcflags, &gcv);
117 		XCopyPlane(_dpy, back_map, logomap, logogc, 0, 0,
118 					  CARD_MAP_WIDTH, CARD_MAP_HEIGHT, 0, 0, 1);
119 		XFreeGC(_dpy, logogc);
120 
121 		gcv.tile = logomap;
122 		gcv.fill_style = FillTiled;
123 		gcflags |= GCTile | GCFillStyle | GCGraphicsExposures;
124 
125 		_backgc = XCreateGC(_dpy, RootWindow(_dpy, _screen), gcflags, &gcv);
126 
127 		borderpixel = blackpixel;
128 
129 		cmap = DefaultColormap(_dpy, _screen);
130 
131 		color.flags = DoRed | DoGreen | DoBlue;
132 
133 
134 		// color levels are the NeWS RGB values
135 
136 		color.red = 13107;
137 		color.green = 52428;
138 		color.blue = 39321;
139 
140 		XAllocColor(_dpy, cmap, &color);
141 		greenpixel = color.pixel;
142 
143 		color.red = 52428;
144 		color.green = color.blue = 0;
145 		XAllocColor(_dpy, cmap, &color);
146 		redpixel = color.pixel;
147 
148 		gcv.foreground = redpixel;
149 		gcv.background = WhitePixel(_dpy, _screen);
150 //	   gcv.font = XLoadFont(_dpy, "9x15bold");
151 	   gcv.font = XLoadFont(_dpy, "10x20");
152 		gcflags = GCForeground | GCBackground | GCGraphicsExposures;
153 		_redgc = XCreateGC(_dpy, RootWindow(_dpy, _screen), gcflags, &gcv);
154 		// allocate drawing area background color, set areas
155 		XAllocNamedColor(_dpy, cmap, "Forest Green", &color, &color);
156 
157 	}
158 	i = 0;
159 	XtSetArg(args[i], XmNbackground, color.pixel);   i++;
160 	XtSetArg(args[i], XmNforeground, whitepixel);   i++;
161 	XtSetValues(_drawingArea, args, i);
162 
163 }
164 
~Seat()165 Seat::~Seat()
166 {
167 }
168 
ShowCards(Hands * hands)169 void Seat::ShowCards(Hands * hands)
170 {
171 	Card ** cards = hands->Cards();
172    for(int i=0; i< hands->NumOfCards(); i++)
173 		DrawCard(GetWindow(), cards[i], PositionCardX(cards[i],i),
174 												  PositionCardY(cards[i],i));
175 
176    ShowMessage(GetWindow(), hands->HandName(), PositionCardX(cards[0],2),
177 					PositionCardY(cards[0],0) + 20 + CARD_HEIGHT);
178 }
179 
DrawCardBack(Window win,Card *,int x,int y)180 void Seat::DrawCardBack(Window win, Card*, int x, int y)
181 {
182    int   delta = CARD_HEIGHT;
183 
184    /* change the origin so cards will have the same back anywhere
185     * on the Window
186     *
187     * there should be a tile centered in the card, with the
188     * surrounding tiles being partial
189     */
190    XmuFillRoundedRectangle(_dpy, win, _blackgc, x, y, CARD_WIDTH,
191       delta , ROUND_W, ROUND_H);
192    XSetTSOrigin(_dpy, _blackgc, x , y);
193 
194    XmuFillRoundedRectangle(_dpy, win, _backgc, x , y ,
195       CARD_WIDTH , CARD_HEIGHT, ROUND_W, ROUND_H);
196 }
197 
DrawCard(Window win,Card * card,int x,int y)198 void Seat::DrawCard(Window win, Card* card, int x, int y)
199 {
200 
201    if (card->Suit() == 'S' || card->Suit() == 'C')  {
202       _cardgc = _blackgc;
203    } else   {
204       _cardgc = _redgc;
205    }
206 
207    // fill the background
208    XmuFillRoundedRectangle(_dpy, win, _whitegc, x, y,
209       CARD_WIDTH, CARD_HEIGHT,
210       ROUND_W, ROUND_H);
211 
212    // draw border on card
213    XmuDrawRoundedRectangle(_dpy, win, _blackgc, x, y,
214       CARD_WIDTH, CARD_HEIGHT,
215       ROUND_W, ROUND_H);
216       _cardIsClipped = False;
217 
218    XCopyPlane(_dpy, GetCardMap(card) , win, _cardgc,
219       0, 0, CARD_MAP_WIDTH, CARD_MAP_HEIGHT, x+MARGIN_W , y+MARGIN_H , 1);
220 
221    // clear the clip mask
222    XSetClipMask(_dpy, _cardgc, None);
223    XSetClipMask(_dpy, _whitegc, None);
224    if (_cardgc != _blackgc)
225    XSetClipMask(_dpy, _blackgc, None);
226 
227 }
228 
GetCardMap(Card * card)229 Pixmap Seat::GetCardMap(Card* card)
230 {
231    assert(card);
232 
233    if(card->Rank() < 1 || card->Rank() > 14 )
234       throw(" Card Rank out of range. " );
235 
236     int index = (card->Rank() == 14) ? 1 : card->Rank();
237     switch(card->Suit()){
238     case 'S':
239       return s_map[index-1];
240     case 'C':
241       return c_map[index-1];
242     case 'H':
243       return h_map[index-1];
244     case 'D':
245       return d_map[index-1];
246     case 'W':
247     defaults:
248       throw(" Card not used in this game. ");
249     }
250 }
251 
MakeCardMaps()252 void Seat::MakeCardMaps()
253 {
254 
255    for (int i = 0; i< 13; i++) {
256       s_map[i] = XCreateBitmapFromData(_dpy,
257          RootWindow(_dpy, _screen),
258          reinterpret_cast<const char *>(s_bits[i]), CARD_MAP_WIDTH, CARD_MAP_HEIGHT);
259 
260       h_map[i] = XCreateBitmapFromData(_dpy,
261          RootWindow(_dpy, _screen),
262          reinterpret_cast<const char *>(h_bits[i]), CARD_MAP_WIDTH, CARD_MAP_HEIGHT);
263 
264       c_map[i] = XCreateBitmapFromData(_dpy,
265          RootWindow(_dpy, _screen),
266          reinterpret_cast<const char *>(c_bits[i]), CARD_MAP_WIDTH, CARD_MAP_HEIGHT);
267 
268       d_map[i] = XCreateBitmapFromData(_dpy,
269          RootWindow(_dpy, _screen),
270          reinterpret_cast<const char *>(d_bits[i]), CARD_MAP_WIDTH, CARD_MAP_HEIGHT);
271 
272    }
273 
274    back_map = XCreateBitmapFromData(_dpy,
275       RootWindow(_dpy, _screen),
276       reinterpret_cast<const char *>(back_bits), CARD_MAP_WIDTH, CARD_MAP_HEIGHT);
277 
278 }
279 
280 
PlayerSeat(Table * table,int from,int to)281 PlayerSeat::PlayerSeat(Table* table, int from, int to) : Seat(table),
282                                                     _from(from),
283                                                     _to(to)
284 {
285 	Initialize(GetTable()->GetDisplay(), DefaultScreen(GetTable()->GetDisplay()),
286 				  GetTable()->PlayerDrawingArea());
287 }
288 
289 
~PlayerSeat()290 PlayerSeat::~PlayerSeat()
291 {
292 }
293 
PositionCardX(Card * card,int n)294 int  PlayerSeat::PositionCardX(Card* card, int n)
295 {
296 
297 	Dimension width;
298 	int i;
299 	Arg args[5];
300 
301 	i = 0;
302 	XtSetArg(args[i], XmNwidth, &width);	i++;
303 	XtGetValues(GetTable()->PlayerDrawingArea(), args, i);
304 #ifdef DEBUG
305 	cout << "Player Drawing Area width: " << width << endl;
306 #endif
307 
308 	// spread them out if 6 will fit
309 	if (width*(_to-_from)/100 >= (10 + 6*(10+CARD_WIDTH))) {
310 		return(width*_from/100+10 + n*(10+CARD_WIDTH));
311 	}
312 	else {	// otherwise overlap, accomodating 6
313 		return(width*_from/100+10+ n*(width*(_to-_from)/100-20-CARD_WIDTH)/5);
314 	}
315 }
316 
PositionCardY(Card *,int)317 int  PlayerSeat::PositionCardY(Card*, int)
318 {
319 	Dimension height;
320 	int i;
321 	Arg args[5];
322 
323 	i = 0;
324 	XtSetArg(args[i], XmNheight, &height);	i++;
325 	XtGetValues(GetTable()->PlayerDrawingArea(), args, i);
326 	return ((height -30- CARD_HEIGHT)/2);
327 }
328 
DealerSeat(Table * table)329 DealerSeat::DealerSeat(Table* table) : Seat(table)
330 {
331 	Initialize(GetTable()->GetDisplay(), DefaultScreen(GetTable()->GetDisplay()),
332 				  GetTable()->DealerDrawingArea());
333 }
334 
~DealerSeat()335 DealerSeat::~DealerSeat()
336 {
337    XFreeGC(_dpy,_msggc);
338 }
339 
ShowCardsBeforeBet(Hands * hands)340 void DealerSeat::ShowCardsBeforeBet(Hands * hands)
341 {
342    Card ** cards = hands->Cards();
343    if( hands->NumOfCards() )
344    {
345       int i;
346       for(i=0; i< hands->NumOfCards() -1; i++)
347         DrawCardBack(GetWindow(), cards[i], PositionCardX(cards[i],i),
348                                           PositionCardY(cards[i],i));
349       DrawCard(GetWindow(), cards[i], PositionCardX(cards[i],i),
350                                           PositionCardY(cards[i],i));
351    }
352 }
353 
ShowCards(Hands * hands)354 void DealerSeat::ShowCards(Hands * hands)
355 {
356    Card ** cards = hands->Cards();
357    for(int i=0; i< hands->NumOfCards(); i++)
358       DrawCard(GetWindow(), cards[i],
359                PositionCardX(cards[i], hands->NumOfCards()-1-i),
360                PositionCardY(cards[i],  hands->NumOfCards()-1-i));
361 
362    ShowMessage(GetWindow(), hands->HandName(),
363                  PositionCardX(cards[0], hands->NumOfCards()-2),
364                  20);
365 }
366 
PositionCardX(Card * card,int n)367 int  DealerSeat::PositionCardX(Card* card, int n)
368 {
369    Dimension width;
370    int i;
371    Arg args[5];
372 
373    i = 0;
374    XtSetArg(args[i], XmNwidth, &width); i++;
375    XtGetValues(GetTable()->DealerDrawingArea(), args, i);
376 
377 #ifdef DEBUG
378 	cout << "Dealer Drawing Area width: " << width << endl;
379 #endif
380 
381    /* spread them out if 6 will fit */
382    if (width >= (10 + 6*(10+CARD_WIDTH))) {
383       int marg = (width - (10 + 6*(10+CARD_WIDTH)))/2;
384       return width - ( marg + 10 + (n+1)*(10+CARD_WIDTH));
385    }
386    else {   /* otherwise overlap, accomodating 6 */
387       return width - (10+ CARD_WIDTH + n*(width-20-CARD_WIDTH)/5);
388    }
389 }
390 
PositionCardY(Card * card,int n)391 int  DealerSeat::PositionCardY(Card* card , int n)
392 {
393    Dimension height;
394    int i;
395    Arg args[5];
396 
397    i = 0;
398    XtSetArg(args[i], XmNheight, &height); i++;
399    XtGetValues(GetTable()->DealerDrawingArea(), args, i);
400    return 30+(height -  30 -CARD_HEIGHT)/2;
401 }
402 
403