1 /*
2  *      This program is free software; you can redistribute it and/or modify
3  *      it under the terms of the GNU General Public License as published by
4  *      the Free Software Foundation; either version 2 of the License, or
5  *      (at your option) any later version.
6  *
7  *      This program is distributed in the hope that it will be useful,
8  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *      GNU General Public License for more details.
11  *
12  *      You should have received a copy of the GNU General Public License
13  *      along with this program; if not, write to the Free Software
14  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 #include <string.h>
17 #include <gtk/gtk.h>
18 #include <glib/gi18n.h>
19 #include <gdk/gdkkeysyms.h>
20 #include "load.h"
21 #include "free.h"
22 #include "alloc.h"
23 #include "draw.h"
24 #include "throw.h"
25 #include "game.h"
26 #include "position.h"
27 #include "select.h"
28 #include "set.h"
29 #include "get.h"
30 #include "callback.h"
31 #include "find.h"
32 #include "clear.h"
33 #include "list.h"
34 #include "def.h"
35 
36 #include "config.h"
37 
event_blink(gpointer data)38 gboolean event_blink(gpointer data)
39 {
40 	struct _prog *prog_data = (struct _prog*) data;
41 
42 	struct _card *tmp;
43 
44 	GList *lst;
45 
46 	struct _card *card = NULL;
47 
48 
49 	for(lst = prog_data->waiting; lst; lst = lst->next)
50 	{
51 		tmp = lst->data;
52 
53 		if(tmp->blink == TRUE)
54 		{
55 			tmp->draw = !tmp->draw;
56 			card = tmp;
57 		}
58 	}
59 
60 
61 	if(card && prog_data->copy)
62 	{
63 		GdkGC *gc = prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)];
64 
65 		if(card->draw == TRUE)
66 		{
67 			draw_card_pixmap(card->pixmap, card->pixmask,
68 				prog_data->target, card->dim.x, card->dim.y, gc);
69 			/*gdk_gc_set_clip_mask(gc,
70 				prog_data->cardmask);
71 
72 			gdk_gc_set_clip_origin(gc,
73 				card->dim.x,
74 				card->dim.y);
75 
76 			gdk_draw_pixbuf( prog_data->target,
77 				gc,
78 				card->img, 0, 0,
79 				card->dim.x, card->dim.y, card->dim.w, card->dim.h,
80 			GDK_RGB_DITHER_NONE, 0, 0);
81 
82 			gdk_gc_set_clip_mask(gc, NULL);*/
83 		}
84 		else
85 			gdk_draw_drawable(prog_data->target,
86 				gc,
87 				prog_data->copy,
88 				card->dim.x, card->dim.y, card->dim.x, card->dim.y,
89 				card->dim.w, card->dim.h);
90 
91 
92 		gdk_draw_drawable( prog_data->area->window,
93 			gc,	prog_data->target,
94 				card->dim.x, card->dim.y, card->dim.x, card->dim.y,
95 				card->dim.w, card->dim.h);
96 
97 	}
98 
99 	return(TRUE);
100 }
101 
key_down(GtkWidget * widget,GdkEventKey * event,gpointer user_data)102 gboolean key_down(GtkWidget *widget,
103 	GdkEventKey *event,
104 	gpointer user_data)
105 {
106 	struct _prog *prog_data = user_data;
107 
108 	if(event->type == GDK_KEY_PRESS)
109 	{
110 		/*int family = 0;
111 
112 		if(prog_data->waiting)
113 			family = ((struct _card*)prog_data->waiting->data)->family ;
114 		if(prog_data->state == EGS_SECOND)
115 		{
116 			int j = -1;
117 			switch(event->keyval)
118 			{
119 				case GDK_1:
120 				case GDK_KP_1:
121 					j = 0;
122 				case GDK_2:
123 				case GDK_KP_2:
124 					if(j==-1)
125 						j = 1;
126 				case GDK_3:
127 				case GDK_KP_3:
128 					if(j==-1)
129 						j = 2;
130 				case GDK_4:
131 				case GDK_KP_4:
132 					if(j==-1)
133 						j = 3;
134 				if( j != family )
135 				{
136 					int i;
137 					for(i = 0; i<4; i++)
138 					gtk_widget_set_sensitive(
139 					prog_data->allwidgets[10+i],
140 					FALSE);
141 				}
142 				break;
143 			}
144 			if(j != -1 && j != family )
145 				click_selectmaster(prog_data, prog_data->player, j);
146 		}
147 		else if(prog_data->state == READY_DISTRIB2
148 			&& is_player_next(prog_data, 2) )
149 		{
150 			int j= g_list_length(prog_data->players[2]);
151 			switch(event->keyval)
152 			{
153 				case GDK_1: j = j-1;
154 					break;
155 				case GDK_2: j = j-2;
156 					break;
157 				case GDK_3: j = j-3;
158 					break;
159 				case GDK_4: j = j-4;
160 					break;
161 				case GDK_5: j = j-5;
162 					break;
163 				case GDK_6: j = j-6;
164 					break;
165 				case GDK_7: j = j-7;
166 					break;
167 				case GDK_8: j = j-8;
168 					break;
169 
170 			}
171 
172 			if(j >= 0)
173 			{
174 				game_turn(prog_data, g_list_nth_data(prog_data->players[2], j) );
175 				game_play_ia(prog_data);
176 			}
177 		}*/
178 
179 		switch(event->keyval)
180 		{
181 			case GDK_Escape:
182 			if(prog_data->movecard)
183 			{
184 				if(prog_data->copy)
185 					g_object_unref(prog_data->copy);
186 
187 				prog_data->copy = NULL;
188 
189 				prog_data->movecard->card->draw = TRUE;
190 
191 				g_free(prog_data->movecard);
192 				prog_data->movecard = NULL;
193 
194 				draw_container(prog_data);
195 			}
196 			break;
197 			/*
198 			case GDK_space:
199 			if(prog_data->state == READY_DISTRIB1
200 				|| prog_data->state == EGS_SECOND)
201 				dowhatever_click(prog_data);
202 			else
203 				action_click(prog_data);
204 
205 			break;
206 
207 			case GDK_Return:
208 			if(prog_data->state == READY_DISTRIB1)
209 			{
210 			int i;
211 			for(i = 0; i<4; i++)
212 			gtk_widget_set_sensitive(
213 			prog_data->allwidgets[10+i],
214 			FALSE);
215 				click_selectmaster(prog_data,
216 					prog_data->player, family);
217 			}
218 			break;
219 
220 			*/
221 		}
222 	}
223 }
224 
225 
226 /* click_givecard : takes care of distributing
227  * the first batch of cards to the players
228  * (5 cards each) and show one more card. This
229  * final card will be proposed to each player
230  * one at a time. If anyone decide to take it,
231  * then the family of this card will become the
232  * master family of the round (trump).
233  *
234  * struct _prog *prog_data: see file def.h
235  *
236  * What is needed in struct _prog :
237  *
238  * prog_data->state : the status of the game
239  * right now. Are we playing yet ?
240  * This is an enum egstate (see file def.h
241  * for more details about it)
242  *
243  * prog_data->allwidgets[4] : allwidgets is
244  * an array composed by many GtkWidget* each.
245  * The Fifth ([4]) is a spinbutton; which will
246  * be suppressed in the future.
247  */
click_givecard(struct _prog * prog_data)248 void click_givecard(struct _prog *prog_data)
249 {
250 	gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]), NULL);
251 	gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]),
252 		_("Pass") );
253 
254 	prog_data->state = DISTRIBUTING;
255 
256 	game_distribute_phase1(prog_data);
257 
258 	game_finish_phase1(prog_data);
259 
260 	prog_data->player = prog_data->distributer;
261 
262 	select_player_next(&prog_data->player);
263 
264 	prog_data->menext = prog_data->player;
265 
266 	prog_data->state = READY_DISTRIB1;
267 
268 	if(prog_data->output != NULL)
269 	{
270 		fprintf(prog_data->output,
271 			_("Ready, distribution phase 1 done.\n") );
272 	}
273 
274 	game_choose_trump(prog_data);
275 }
276 
play_next_turn(struct _prog * prog_data)277 gboolean play_next_turn(struct _prog* prog_data)
278 {
279 	return (
280 		prog_data->player != 2
281 		&& prog_data->player == prog_data->menext
282 		&& prog_data->players[prog_data->player]
283 	);
284 }
285 
286 /* click_selectmaster : Start the first turn of this round.
287  * This means many things has to be done. First of all
288  * when calling this function it means a player decided
289  * which master family is the trump of this round.
290  * We need to set this, to send the remaining cards
291  * to each player (3 each, except the so called master
292  * of the game, he will get 2 from the pile and one
293  * which was the card proposed to the players as the
294  * trump). Then we needs to set new points for all
295  * cards from the trump family. They are now more
296  * powerful then they were initialised.
297  * Then the computer will play he has to.
298  *
299  * struct _prog *prog_data: see file def.h
300  *
301  * What is needed in struct _prog:
302  *
303  * prog_data->state : an enum egstate, see
304  * file def.h for more details
305  *
306  * prog_data->master : who takes the proposed
307  * card.
308  *
309  * prog_data->player : who has to drop a card
310  * right now. It's not exactly always this.
311  * When each players has dropped one card,
312  * the player is not the player who needs to
313  * drop a card next.
314  *
315  * prog_data->hashand : who is in charge
316  * of deciding the first of each four cards
317  * to be dropped on the table at each turn.
318  * This is the player who has the hand
319  * before anyone drops a more powerful card.
320  * Note: it's not chaning when someone do
321  * this (dropping a more powerful card).
322  * That is why it's called "hashand" and not
323  * "havehand". See menext for the player who
324  * have the hand right now.
325  *
326  * prog_data->menext : the player which
327  * win this turn at the moment. It can
328  * be changed at any card drop except the
329  * first. When you win a turn, you are
330  * the first to drop the first card next.
331  * This is exactly when menext should
332  * not be changed. You can't change menext
333  * at this time because you are the one
334  * to drop the card. You are then already
335  * the menext player.
336  *
337  * prog_data->distributer : which player
338  * takes care of distributing the cards.
339  * Note: you don't have to do it with
340  * the mouse or something like this. This
341  * is all virtual dude. Anyway it's needed
342  * to know who is the first to play on the
343  * first turn.
344  * Note: each round it's incremented by
345  * turning round the clock.
346  *
347  * prog_data->family : the trump color.
348  *
349  * prog_data->allwidgets[4] : allwidgets is an
350  * array composed by many GtkWidget*.
351  * The fifth is the spinbutton, which will
352  * be suppressed in the future.
353  *
354  * prog_data->waiting : a GList representing
355  * the table. This is where you drop your cards.
356  * Each element of this list is a struct _card,
357  * defined in the def.h file.
358  *
359  * prog_data->allwidgets[5] : a GtkImage
360  * containing nothing at first. This is where
361  * we put the icon of the trump family
362  * (diamond, spade, heart or club)
363  *
364  * prog_data->icons : an array of 4 GtkImage,
365  * each of the family icons.
366  *
367  * prog_data->output : the stream to print
368  * messages to. Default is stdout.
369  */
click_selectmaster(struct _prog * prog_data,int master,int trump)370 void click_selectmaster(struct _prog *prog_data, int master, int trump)
371 {
372 	char str[10];
373 
374 	prog_data->state = DISTRIBUTING;
375 
376 	prog_data->master = master;
377 
378 	switch(master)
379 	{
380 		case 0:
381 		g_stpcpy(str, _("Top") );
382 		break;
383 		case 1:
384 		g_stpcpy(str, _("Right") );
385 		break;
386 		case 2:
387 		g_stpcpy(str, _("You") );
388 		break;
389 		case 3:
390 		g_stpcpy(str, _("Left") );
391 		break;
392 	}
393 
394 	gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[7]), str);
395 
396 	prog_data->family = trump;
397 
398 	prog_data->player = prog_data->menext;
399 	prog_data->hashand = prog_data->menext;
400 
401 	gtk_image_set_from_pixbuf(GTK_IMAGE(prog_data->allwidgets[5]),
402 		prog_data->icons[prog_data->family]);
403 
404 	if(prog_data->output != NULL)
405 	{
406 		fprintf(prog_data->output, _("Trump: ") );
407 		game_print_family(prog_data->output, prog_data->family);
408 		fprintf(prog_data->output, "\n");
409 	}
410 
411 	game_distribute_phase2(prog_data);
412 
413 	set_points(prog_data);
414 
415 	prog_data->players[2] = g_list_sort(prog_data->players[2],
416 		list_sort);
417 
418 	if(prog_data->withdeclaration == TRUE)
419 	{
420 		game_check_declarations(prog_data);
421 	}
422 
423 	gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[8]),
424 		"1/8" );
425 
426 	gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]),
427 		_("Next") );
428 	gtk_widget_set_sensitive(prog_data->allwidgets[2], FALSE);
429 
430 	if(prog_data->player == 2)
431 	{
432 		set_moveable(prog_data->players[2], TRUE);
433 	}
434 	else
435 	{
436 		set_moveable(prog_data->players[2], FALSE);
437 	}
438 
439 	prog_data->state = READY_DISTRIB2;
440 
441 	game_hand_position(prog_data, -1);
442 
443 
444 	draw_container(prog_data);
445 
446 	if( play_next_turn(prog_data) )
447 	{
448 		game_turn(prog_data, NULL);
449 	}
450 	game_play_ia(prog_data);
451 
452 }
453 
454 /* click_play : a mouse click on the
455  * game area means something should be
456  * done. The action here can be a card
457  * drop, a distributing process, or
458  * an end of a round.
459  * In all case it should be related to
460  * the computer doing something.
461  */
click_play(struct _prog * prog_data)462 void click_play(struct _prog *prog_data)
463 {
464 
465 	game_turn(prog_data, NULL);
466 
467 	game_play_ia(prog_data);
468 }
469 
470 /* action_click : the user clicked
471  * on something. And we need to know
472  * what he means. This is depending
473  * on the game state.
474  *
475  * struct _prog *prog_data: see file def.h
476  *
477  * What is used in the struct _prog:
478  *
479  * prog_data->state : enum egstate,
480  * see file def.h for more details.
481  *
482  *
483  */
action_click(struct _prog * prog_data)484 void action_click(struct _prog *prog_data)
485 {
486 	if(prog_data->state == READY_PILE)
487 	{
488 		if(prog_data->output != NULL)
489 		{
490 			fprintf(prog_data->output,
491 				_("Distribute phase 1 please!\n") );
492 		}
493 
494 		if((prog_data->points[0] > 100 || prog_data->points[1] > 100 )
495 		&& (prog_data->points[0] != prog_data->points[1]) )
496 		{
497 
498 			free_cell_list(&prog_data->cells);
499 
500 
501 			prog_data->report = 0;
502 
503 			prog_data->points[0] = 0;
504 			prog_data->points[1] = 0;
505 
506 			prog_data->row = 0;
507 
508 			gtk_table_resize(GTK_TABLE(prog_data->allwidgets[9]),
509 				1, 2);
510 
511 		}
512 
513 
514 		click_givecard(prog_data);
515 	}
516 	else
517 	if(prog_data->state == READY_DISTRIB2)
518 	{
519 		/*if(prog_data->output != NULL)
520 			fprintf(prog_data->output,
521 				_("Play !\n") );*/
522 
523 		click_play(prog_data);
524 	}
525 
526 	draw_container(prog_data);
527 }
528 
529 /* event_start : user clicked on the Start
530  * labelled button. In the future this will
531  * be replaced by something else.
532  *
533  * struct _prog *prog_data: see file def.h
534  *
535  */
event_start(GtkButton * button,gpointer data)536 void event_start(GtkButton *button, gpointer data)
537 {
538 	struct _prog *prog_data = (struct _prog*)data;
539 
540 	dowhatever_click(prog_data);
541 
542 }
543 
dowhatever_click(struct _prog * prog_data)544 void dowhatever_click(struct _prog * prog_data)
545 {
546 
547 	if(prog_data->output != NULL)
548 	{
549 		fprintf(prog_data->output,
550 			_("Click on Button\n") );
551 	}
552 
553 	if(prog_data->state == READY_DISTRIB1)
554 	{
555 		gtk_widget_set_sensitive(prog_data->allwidgets[10+
556 			((struct _card*)prog_data->waiting->data)->family],
557 			FALSE);
558 
559 		if(prog_data->output != NULL)
560 		{
561 			fprintf(prog_data->output,
562 				_("You don't want this card. Ok!\n") );
563 		}
564 
565 		game_choose_trump_next(prog_data);
566 
567 	}
568 	else if(prog_data->state == EGS_SECOND)
569 	{
570 		int i;
571 		for(i=0; i<4; i++)
572 		{
573 			if(i != ((struct _card*)prog_data->waiting->data)->family )
574 			gtk_widget_set_sensitive(prog_data->allwidgets[10+i], FALSE);
575 		}
576 
577 		if(prog_data->output)
578 		{
579 			fprintf(prog_data->output,
580 				_("Player decided to pass a second time.\n") );
581 		}
582 
583 		game_choose_trump_next(prog_data);
584 	}
585 	else
586 		action_click(prog_data);
587 
588 }
589 
590 /* motion_notify_event : the user drag the mouse.
591  * This means a mouse button is pressed and the
592  * cursor is moving.
593  *
594  * struct _prog *prog_data: see fil def.h
595  *
596  * What is needed in struct _prog:
597  *
598  * prog_data->movecard : this is a pointer
599  * to a struct _movingcard defined in the
600  * def.h file. It will be NULL if there are
601  * no moving card at the moment. A moving
602  * card is a card which the user is dragging
603  * around on the game area.
604  * The struct contains informations about
605  * this card, like a pointer to the
606  * struct _card of this particular card.
607  * Also a separate struct _dim for the
608  * position of the dragged card exists
609  * because we need to recover the orginal
610  * position of the card if it can't be
611  * dropped. It's preferable to keep
612  * the original data in the struct _card,
613  * not in the newly allocated movecard _dim.
614  *
615  */
motion_notify_event(GtkWidget * widget,GdkEventMotion * event,gpointer data)616 gint motion_notify_event (GtkWidget *widget, GdkEventMotion *event,
617 	gpointer data)
618 {
619 	struct _prog *prog_data = (struct _prog*)data;
620 
621 	struct _target *zone = NULL;
622 
623 	GdkPixmap *source;
624 
625 	int x, y, w, h, toph, leftw,
626 	    ax, ay, aw, ah,
627 	    bx, by, bw, bh;
628 
629 	if(prog_data->movecard)
630 	{
631 		if(!prog_data->copy)
632 		{
633 			prog_data->movecard->card->draw = FALSE;
634 
635 			draw_copy(prog_data);
636 
637 			prog_data->movecard->card->draw = TRUE;
638 		}
639 
640 		if(prog_data->copy)
641 		{
642 			x = prog_data->movecard->dim.x;
643 			y = prog_data->movecard->dim.y;
644 
645 			w = prog_data->movecard->card->dim.w;
646 			h = prog_data->movecard->card->dim.h;
647 
648 			gdk_draw_drawable(prog_data->target,
649 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
650 				prog_data->copy,
651 				x-1, y-1, x-1, y-1, w+2, h+2);
652 
653 			if(prog_data->dropping)
654 			{
655 				zone = draw_dropping_zone(prog_data,
656 					prog_data->target);
657 
658 			}
659 
660 			prog_data->movecard->dim.x =
661 				(gint)event->x -prog_data->movecard->dim.w;
662 
663 			prog_data->movecard->dim.y =
664 				(gint)event->y -prog_data->movecard->dim.h;
665 			if(zone)
666 			{
667 				if(zone->active == FALSE)
668 					source = prog_data->copy;
669 				else
670 					source = prog_data->target;
671 
672 
673 				gdk_draw_drawable(prog_data->area->window,
674 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
675 				source,
676 				zone->dim.x, zone->dim.y,
677 				zone->dim.x, zone->dim.y,
678 				zone->dim.w, 1);
679 
680 
681 				gdk_draw_drawable(prog_data->area->window,
682 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
683 				source,
684 				zone->dim.x+zone->dim.w,
685 				zone->dim.y,
686 				zone->dim.x+zone->dim.w,
687 				zone->dim.y,
688 				1, zone->dim.h);
689 
690 				gdk_draw_drawable(prog_data->area->window,
691 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
692 				source,
693 				zone->dim.x,
694 				zone->dim.y+zone->dim.h,
695 				zone->dim.x,
696 				zone->dim.y+zone->dim.h,
697 				zone->dim.w+1, 1);
698 
699 				gdk_draw_drawable(prog_data->area->window,
700 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
701 				source,
702 				zone->dim.x,
703 				zone->dim.y,
704 				zone->dim.x,
705 				zone->dim.y,
706 				1, zone->dim.h);
707 
708 			}
709 
710 			draw_moving_card(prog_data, prog_data->target);
711 
712 			gdk_draw_drawable(prog_data->area->window,
713 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
714 				prog_data->target,
715 				prog_data->movecard->dim.x,
716 				prog_data->movecard->dim.y,
717 				prog_data->movecard->dim.x,
718 				prog_data->movecard->dim.y,
719 				w, h);
720 
721 
722 			/*----Refreshing area optimization----
723 			 * try this on an old XXX Mhz, and
724 			 * see how fast it is when you drag
725 			 * a card around. */
726 			if(x <= prog_data->movecard->dim.x)
727 			{
728 				leftw = prog_data->movecard->dim.x -x;
729 				bx = x-1;
730 
731 				bw = leftw+2;
732 			}
733 			else
734 			{
735 				leftw = w-x+prog_data->movecard->dim.x;
736 				bx = x+leftw-1;
737 
738 				bw = w-leftw+2;
739 			}
740 
741 			if(y <= prog_data->movecard->dim.y)
742 			{
743 				ax = x-1;
744 				ay = y-1;
745 				toph = prog_data->movecard->dim.y -y;
746 				ah = toph+1;
747 				aw = w+2;
748 
749 				by = y+toph;
750 				bh = h - toph +1;
751 			}
752 			else
753 			{
754 				toph = h-(y-prog_data->movecard->dim.y);
755 				ax = x -1;
756 				ay = y+toph;
757 				ah = h - toph +1;
758 				aw = w +2;
759 
760 				by = y-1;
761 				bh = toph+1;
762 			}
763 
764 
765 			gdk_draw_drawable(
766 				prog_data->area->window,
767 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
768 				prog_data->target,
769 				ax, ay, ax, ay,
770 				aw, ah);
771 
772 			gdk_draw_drawable(
773 				prog_data->area->window,
774 				prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
775 				prog_data->target,
776 				bx, by, bx, by,
777 				bw, bh);
778 
779 		}
780 
781 	}
782 
783 	return TRUE;
784 }
785 
786 
787 
788 /* button_press_event : user did press a mouse button.
789  *
790  * prog_data->waiting: GList containing cards dropped
791  * on the table.
792  *
793  * prog_data->players[2] : GList containing the user
794  * hand. The player corresponding to the human
795  * player is the third of the players array ([2])
796  * and is represented at the bottom of the screen.
797  *
798  */
button_press_event(GtkWidget * widget,GdkEventButton * event,gpointer data)799 void button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
800 {
801 	struct _prog *prog_data = (struct _prog*)data;
802 
803 	gboolean found = FALSE;
804 
805 	if(event->button == 1)
806 	{
807 		found = find_moveable_card(prog_data->waiting, event, prog_data);
808 
809 		if(found == FALSE)
810 			found = find_moveable_card(prog_data->players[2], event, prog_data);
811 
812 		if(found == TRUE)
813 			clear_blink(prog_data);
814 	}
815 }
816 
is_player_next(struct _prog * prog_data,int n)817 gboolean is_player_next(struct _prog *prog_data, int n)
818 {
819 	return (
820 		(
821 			(prog_data->player == n
822 				&& prog_data->player != prog_data->hashand )
823 			|| ( prog_data->player == prog_data->hashand
824 				&& prog_data->menext == n)
825 		)
826 		&& prog_data->players[n] != NULL
827 	);
828 }
829 
game_drop_enable(struct _prog * prog_data)830 gboolean game_drop_enable(struct _prog *prog_data)
831 {
832 	struct _target *zone = get_active_targetzone(prog_data->dropping);
833 
834 	return (
835 		prog_data->no_drag == TRUE
836 		|| ( zone
837 			&& zone->active == TRUE
838 			&& (prog_data->state == READY_DISTRIB2
839 				|| prog_data->state == READY_DISTRIB1)
840 		)
841 	);
842 }
843 
844 /* button_release_event : user released a pressed
845  * mouse button. This means we need to check if
846  * a card was selected. If true, then we want
847  * to check if it can be dropped here.
848  *
849  * See file def.h for more details about
850  * structs and their fields.
851  */
button_release_event(GtkWidget * widget,GdkEventButton * event,gpointer data)852 void button_release_event (GtkWidget *widget,
853 	GdkEventButton *event, gpointer data)
854 {
855 	struct _prog *prog_data = (struct _prog*)data;
856 
857 	struct _card *drop = NULL;
858 
859 	if(event->button == 1)
860 	{
861 		if(prog_data->movecard)
862 		{
863 			if(prog_data->copy)
864 				g_object_unref(prog_data->copy);
865 
866 			prog_data->copy = NULL;
867 
868 			prog_data->movecard->card->draw = TRUE;
869 
870 			if( is_player_next(prog_data, 2) )
871 			{
872 				if(prog_data->output != NULL)
873 					fprintf(prog_data->output,
874 						_("Click on a moveable card!\n") );
875 
876 				if( game_drop_enable(prog_data) )
877 					drop = prog_data->movecard->card;
878 			}
879 
880 			g_free(prog_data->movecard);
881 			prog_data->movecard = NULL;
882 
883 			if(drop != NULL)
884 			{
885 				if(prog_data->state == READY_DISTRIB1)
886 				{
887 					if(prog_data->output != NULL)
888 					{
889 						fprintf(prog_data->output,
890 							_("You selected the card!\n") );
891 					}
892 
893 					gtk_widget_set_sensitive(
894 						prog_data->allwidgets[10+((struct _card*)
895 						prog_data->waiting->data)->family], FALSE);
896 
897 					click_selectmaster(prog_data, 2,
898 					((struct _card*)prog_data->waiting->data)->family);
899 				}
900 				else if(prog_data->state != EGS_SECOND)
901 				{
902 					if(prog_data->hide == TRUE)
903 					{
904 						int i;
905 
906 						prog_data->hide = FALSE;
907 
908 						for(i = 0; i < 4; i++)
909 						{
910 							if(i != 2)
911 								set_draw_face(prog_data->players[i], FALSE);
912 						}
913 					}
914 
915 					gtk_label_set_text(
916 						GTK_LABEL(prog_data->allwidgets[6]),
917 						NULL);
918 
919 					game_turn(prog_data, drop);
920 
921 					game_play_ia(prog_data);
922 				}
923 			}
924 
925 			draw_container(prog_data);
926 		}
927 		else
928 		{
929 			/*if(prog_data->output != NULL)
930 				fprintf(prog_data->output,
931 					_("Click on game area occured\n") );*/
932 
933 			action_click(prog_data);
934 		}
935 	}
936 }
937 
938 /* realisation : the game area has been
939  * initilialised by Gtk, we now needs to
940  * draw it. This means allocating a
941  * GtkPixmap to draw to, then loading
942  * cards (because we need to know the window
943  * depth before loading any images).
944  *
945  * Then we can set the position of the
946  * dropping zone area, because we need
947  * to know the size of the area before
948  * positioning it. At least it's true
949  * for the middle area of the table.
950  * At the moment it's the only dropping
951  * area created.
952  *
953  * Then we can start the game, that means
954  * preparing everything for the game to
955  * be played. As an example there is the
956  * prog_data->pile GList that needs to be
957  * mixed.
958  *
959  * See game_start() function for more details
960  * about what needs to be done. (file game.c)
961  *
962  * return gboolean: see Gtk documentation
963  * about realize event of a gdk-drawing area.
964  */
realisation(GtkWidget * aire_de_dessin,gpointer data)965 gboolean realisation( GtkWidget *aire_de_dessin, gpointer data )
966 {
967 	struct _prog *prog_data = (struct _prog*) data;
968 
969 	alloc_prog(prog_data);
970 
971 	if(prog_data->target)
972 		draw_background(prog_data, prog_data->target);
973 
974 	if(	load_cards(DATA_DIR,
975 			prog_data,
976 			aire_de_dessin) == FALSE)
977 	{
978 		int i;
979 		for(i =0; i< 4; i++)
980 		{
981 			if(prog_data->icons[i])
982 				gtk_image_set_from_pixbuf(
983 				GTK_IMAGE(prog_data->allwidgets[14+i]),
984 				prog_data->icons[i]);
985 		}
986 
987 
988 		if(!prog_data->card_stretch)
989 			resize_cards(prog_data, 80, 108);
990 		else
991 		{
992 			int w, h;
993 			gdk_drawable_get_size(prog_data->target, &w, &h);
994 			resize_cards(prog_data,
995 				w/6,
996 				h/5);
997 		}
998 
999 		position_targetzone(prog_data);
1000 
1001 		game_start(prog_data);
1002 	}
1003 	else
1004 	{
1005 		GtkWidget *dialog;
1006 
1007 		dialog = gtk_message_dialog_new(
1008 			GTK_WINDOW(prog_data->allwidgets[0]),
1009 			GTK_DIALOG_MODAL,
1010 			GTK_MESSAGE_ERROR,
1011 			GTK_BUTTONS_CLOSE,
1012 			_("An error occured while loading cards pictures.\nPlease reinstall.") , NULL);
1013 
1014 		g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(error_event), prog_data);
1015 
1016 		gtk_widget_show_all(dialog);
1017 	}
1018 
1019 	return TRUE;
1020 }
1021 
1022 /* rafraichissement : refresh the game area.
1023  *
1024  * return gboolean: see Gtk documentation
1025  * about expose-event
1026  */
rafraichissement(GtkWidget * aire_de_dessin,GdkEventExpose * event,gpointer data)1027 gboolean rafraichissement( GtkWidget *aire_de_dessin, GdkEventExpose *event, gpointer data)
1028 {
1029 	draw_container((struct _prog*)data );
1030 
1031 	return FALSE;
1032 }
1033 
1034 /*
1035  * return gboolean: see Gtk documentation
1036  * about destroy event
1037  */
quit(GtkWidget * window,gpointer data)1038 gboolean quit(GtkWidget *window, gpointer data)
1039 {
1040 	gtk_main_quit();
1041 
1042 	return TRUE;
1043 }
1044 
resize_cards(struct _prog * prog_data,int w,int h)1045 void resize_cards(struct _prog* prog_data, int w, int h)
1046 {
1047 	GdkPixbuf *src, *scaled = NULL;
1048 	int original_w, original_h;
1049 
1050 	if(prog_data->back_original)
1051 	{
1052 		original_w = gdk_pixbuf_get_width(prog_data->back_original);
1053 		original_h = gdk_pixbuf_get_height(prog_data->back_original);
1054 
1055 		if(prog_data->card_ratio)
1056 		{
1057 			float ratio;
1058 
1059 			ratio = original_w/(float)original_h;
1060 
1061 			w = h*ratio;
1062 		}
1063 	}
1064 
1065 	GList *ptr;
1066 
1067 	struct _card * data_card;
1068 
1069 	for(ptr = prog_data->all; ptr; ptr = ptr->next)
1070 	{
1071 		data_card = ptr->data;
1072 
1073 		/*if(data_card->dim.w != w || data_card->dim.h != h)*/
1074 		{
1075 			scaled = gdk_pixbuf_scale_simple(data_card->original,
1076 				w, h, GDK_INTERP_BILINEAR);
1077 
1078 		}
1079 		/*else
1080 			scaled = NULL;*/
1081 
1082 		if(scaled)
1083 		{
1084 			src = scaled;
1085 		}
1086 		else
1087 			src = data_card->original;
1088 
1089 		if(data_card->pixmap)
1090 			g_object_unref(data_card->pixmap);
1091 
1092 		if(data_card->pixmask)
1093 			g_object_unref(data_card->pixmask);
1094 
1095 		gdk_pixbuf_render_pixmap_and_mask(src,
1096 			&data_card->pixmap,
1097 			&data_card->pixmask, 150);
1098 
1099 		gdk_drawable_get_size(data_card->pixmap,
1100 			&data_card->dim.w, &data_card->dim.h);
1101 		/*
1102 		data_card->dim.w = gdk_pixbuf_get_width(data_card->img);
1103 		data_card->dim.h = gdk_pixbuf_get_height(data_card->img);
1104 		*/
1105 
1106 		if(scaled)
1107 		{
1108 			g_object_unref(scaled);
1109 			scaled = NULL;
1110 		}
1111 
1112 	}
1113 
1114 	if(prog_data->back)
1115 	{
1116 		gdk_drawable_get_size(prog_data->back,
1117 			&original_w, &original_h);
1118 	}
1119 
1120 	/*if( original_w != w || original_h != h)*/
1121 	{
1122 		if(prog_data->output)
1123 			fprintf(prog_data->output,
1124 				"Resizing img to %d %d\n",
1125 					w, h);
1126 		scaled = gdk_pixbuf_scale_simple(prog_data->back_original,
1127 			w, h, GDK_INTERP_BILINEAR);
1128 	}
1129 	/*else
1130 	{
1131 		if(prog_data->output)
1132 			fprintf(prog_data->output,
1133 				"Copying the original %d %d\n",
1134 					w, h);
1135 		scaled = NULL;
1136 	}*/
1137 
1138 	if(scaled)
1139 		src = scaled;
1140 	else
1141 		src = prog_data->back_original;
1142 
1143 	if(prog_data->back)
1144 		g_object_unref(prog_data->back);
1145 
1146 	if(prog_data->backmask)
1147 		g_object_unref(prog_data->backmask);
1148 
1149 	gdk_pixbuf_render_pixmap_and_mask(src,
1150 		&prog_data->back,
1151 		&prog_data->backmask, 170);
1152 
1153 	gdk_draw_pixbuf(prog_data->back, NULL, src,
1154 		0, 0, 0, 0,
1155 		-1, -1, GDK_RGB_DITHER_NONE, 0, 0);
1156 
1157 	if(scaled)
1158 	{
1159 		gdk_drawable_get_size(prog_data->back, &w, &h);
1160 
1161 		if(prog_data->output)
1162 			fprintf(prog_data->output,
1163 				"Back img is %d %d\n",
1164 					w, h);
1165 		g_object_unref(scaled);
1166 	}
1167 }
1168 
1169 /* resize: the window size has changed.
1170  * We need to draw and position everything
1171  * again.
1172  *
1173  * see Gtk documentation about check-resize
1174  * event for more informations.
1175  */
resize(GtkContainer * container,gpointer data)1176 void resize(GtkContainer *container, gpointer data)
1177 {
1178 	struct _prog *prog_data = (struct _prog*) data;
1179 
1180 	gboolean animation;
1181 	int w,h;
1182 
1183 	if(prog_data->target
1184 	&& prog_data->area &&
1185 		prog_data->area->window )
1186 	{
1187 		gdk_drawable_get_size(prog_data->target, &w, &h);
1188 
1189 		if(prog_data->area->allocation.width != w
1190 			|| prog_data->area->allocation.height !=  h)
1191 		{
1192 			clear_blink(prog_data);
1193 
1194 			alloc_pixmap(prog_data);
1195 
1196 			if(prog_data->card_stretch)
1197 			{
1198 				gdk_drawable_get_size(prog_data->target, &w, &h);
1199 
1200 				if(prog_data->output)
1201 					fprintf(prog_data->output, "resize %d %d\n",
1202 					w, h);
1203 
1204 				resize_cards(prog_data,
1205 					w/6, h/5);
1206 			}
1207 
1208 			animation = prog_data->animation;
1209 			if(animation == TRUE)
1210 				prog_data->animation = FALSE;
1211 
1212 			game_middle_position(prog_data);
1213 
1214 			game_hand_position(prog_data, -1);
1215 
1216 			position_targetzone(prog_data);
1217 
1218 			draw_container(prog_data);
1219 
1220 			if(animation == TRUE)
1221 				prog_data->animation = TRUE;
1222 		}
1223 	}
1224 }
1225 
error_event(GtkDialog * dialog,gint rid,gpointer data)1226 void error_event(GtkDialog *dialog, gint rid, gpointer data)
1227 {
1228 	struct _prog *prog_data = (struct _prog *) data;
1229 
1230 	gtk_widget_destroy(GTK_WIDGET(dialog));
1231 
1232 	gtk_widget_destroy(GTK_WIDGET(prog_data->allwidgets[0]));
1233 }
1234 
1235 
dialog_response_event(GtkDialog * dialog,gint rid,gpointer data)1236 void dialog_response_event(GtkDialog *dialog, gint rid, gpointer data)
1237 {
1238 	/*if(rid == GTK_RESPONSE_CLOSE)*/
1239 		gtk_widget_destroy(GTK_WIDGET(dialog));
1240 }
1241 
click_diamond(GtkButton * button,gpointer data)1242 void click_diamond(GtkButton *button, gpointer data)
1243 {
1244 	struct _prog *prog_data = (struct _prog *) data;
1245 	int i=0;
1246 	for(i = 0; i<4; i++)
1247 		gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1248 			FALSE);
1249 
1250 	click_selectmaster(prog_data, prog_data->player, 0);
1251 }
1252 
click_heart(GtkButton * button,gpointer data)1253 void click_heart(GtkButton *button, gpointer data)
1254 {
1255 	struct _prog *prog_data = (struct _prog *) data;
1256 	int i=0;
1257 	for(i = 0; i<4; i++)
1258 		gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1259 			FALSE);
1260 
1261 	click_selectmaster(prog_data, prog_data->player, 2);
1262 }
1263 
click_club(GtkButton * button,gpointer data)1264 void click_club(GtkButton *button, gpointer data)
1265 {
1266 	struct _prog *prog_data = (struct _prog *) data;
1267 	int i=0;
1268 	for(i = 0; i<4; i++)
1269 		gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1270 			FALSE);
1271 
1272 	click_selectmaster(prog_data, prog_data->player, 3);
1273 }
1274 
click_spade(GtkButton * button,gpointer data)1275 void click_spade(GtkButton *button, gpointer data)
1276 {
1277 	struct _prog *prog_data = (struct _prog *) data;
1278 	int i=0;
1279 	for(i = 0; i<4; i++)
1280 		gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1281 			FALSE);
1282 
1283 	click_selectmaster(prog_data, prog_data->player, 1);
1284 }
1285