Move dump of C code for Huffman tables to stderr to avoid conflict with
[xiph/unicode.git] / planarity / gameboard.c
blob3ca4e836b1225fcdb702e0b755c4b0eb44ef090b
1 /*
3 * gPlanarity:
4 * The geeky little puzzle game with a big noodly crunch!
5 *
6 * gPlanarity copyright (C) 2005 Monty <monty@xiph.org>
7 * Original Flash game by John Tantalo <john.tantalo@case.edu>
8 * Original game concept by Mary Radcliffe
10 * gPlanarity is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
15 * gPlanarity is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Postfish; see the file COPYING. If not, write to the
22 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define _GNU_SOURCE
28 #include <gtk/gtk.h>
29 #include <gtk/gtkmain.h>
30 #include <gdk/gdk.h>
31 #include <gdk/gdkx.h>
32 #include <stdlib.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <time.h>
36 #include <string.h>
38 #include "gettext.h"
39 #include "graph.h"
40 #include "gameboard.h"
41 #include "levelstate.h"
44 static GtkWidgetClass *parent_class = NULL;
46 static void gameboard_init (Gameboard *g){
47 // instance initialization
48 g->g.width=g->g.orig_width=800;
49 g->g.height=g->g.orig_height=600;
50 g->resize_w = g->g.width;
51 g->resize_h = g->g.height;
52 g->resize_timeout = 0;
55 static void gameboard_destroy (GtkObject *object){
56 if (GTK_OBJECT_CLASS (parent_class)->destroy)
57 (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
59 // free local resources
63 static gint gameboard_expose (GtkWidget *widget,
64 GdkEventExpose *event){
65 if (GTK_WIDGET_REALIZED (widget)){
66 Gameboard *g = GAMEBOARD (widget);
67 gameboard_draw(g,event->area.x,event->area.y,
68 event->area.width,event->area.height);
71 if(g->resize_h>0 && g->resize_w>0){
72 if(widget->allocation.width != g->resize_w ||
73 widget->allocation.height != g->resize_h){
74 if(time(NULL) > g->resize_timeout){
75 fprintf(stderr,_("\n\nERROR: The windowmanager appears to be ignoring resize requests.\n"
76 "This stands a pretty good chance of scrambling any saved board larger\n"
77 "than the default window size.\n\n"));
78 fprintf(stderr,_("Clipping and/or expanding this board to the current window size...\n\n"));
79 g->resize_w = 0;
80 g->resize_h = 0;
81 resize_buttons(g,g->g.width, g->g.height, widget->allocation.width, widget->allocation.height);
82 graph_resize(&g->g, widget->allocation.width, widget->allocation.height);
83 update_score(g);
84 draw_buttonbar_box(g);
85 update_full(g);
87 }else{
88 g->resize_h=0;
89 g->resize_w=0;
93 return FALSE;
96 static void gameboard_size_request (GtkWidget *widget,
97 GtkRequisition *requisition){
98 Gameboard *g = GAMEBOARD (widget);
99 requisition->width = g->g.orig_width;
100 requisition->height = g->g.orig_height;
103 static void gameboard_realize (GtkWidget *widget){
104 Gameboard *g = GAMEBOARD (widget);
105 GdkWindowAttr attributes;
106 gint attributes_mask;
108 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
110 attributes.x = widget->allocation.x;
111 attributes.y = widget->allocation.y;
112 attributes.width = widget->allocation.width;
113 attributes.height = widget->allocation.height;
114 attributes.wclass = GDK_INPUT_OUTPUT;
115 attributes.window_type = GDK_WINDOW_CHILD;
116 attributes.event_mask =
117 gtk_widget_get_events (widget) |
118 GDK_EXPOSURE_MASK|
119 GDK_POINTER_MOTION_MASK|
120 GDK_BUTTON_PRESS_MASK |
121 GDK_BUTTON_RELEASE_MASK|
122 GDK_KEY_PRESS_MASK |
123 GDK_KEY_RELEASE_MASK |
124 GDK_STRUCTURE_MASK;
125 attributes.visual = gtk_widget_get_visual (widget);
126 attributes.colormap = gtk_widget_get_colormap (widget);
127 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
128 widget->window = gdk_window_new (widget->parent->window,
129 &attributes, attributes_mask);
130 gtk_style_attach (widget->style, widget->window);
131 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
132 gdk_window_set_user_data (widget->window, widget);
133 gtk_widget_set_double_buffered (widget, FALSE);
135 g->wc = gdk_cairo_create(widget->window);
137 g->forescore =
138 cairo_surface_create_similar (cairo_get_target (g->wc),
139 CAIRO_CONTENT_COLOR_ALPHA,
140 widget->allocation.width,
141 SCOREHEIGHT);
143 g->forebutton =
144 cairo_surface_create_similar (cairo_get_target (g->wc),
145 CAIRO_CONTENT_COLOR_ALPHA,
146 widget->allocation.width,
147 SCOREHEIGHT);
149 g->background =
150 cairo_surface_create_similar (cairo_get_target (g->wc),
151 CAIRO_CONTENT_COLOR,
152 widget->allocation.width,
153 widget->allocation.height);
154 g->foreground =
155 cairo_surface_create_similar (cairo_get_target (g->wc),
156 CAIRO_CONTENT_COLOR,
157 widget->allocation.width,
158 widget->allocation.height);
160 g->vertex = cache_vertex(g);
161 g->vertex_lit = cache_vertex_lit(g);
162 g->vertex_attached = cache_vertex_attached(g);
163 g->vertex_grabbed = cache_vertex_grabbed(g);
164 g->vertex_sel = cache_vertex_sel(g);
165 g->vertex_ghost = cache_vertex_ghost(g);
167 update_full(g);
168 update_score(g);
169 draw_buttonbar_box(g);
170 init_buttons(g);
171 cache_curtain(g);
174 void gameboard_size_allocate (GtkWidget *widget,
175 GtkAllocation *allocation){
176 Gameboard *g = GAMEBOARD (widget);
178 if (GTK_WIDGET_REALIZED (widget)){
180 if(allocation->width != g->resize_w &&
181 allocation->height != g->resize_h &&
182 g->resize_timeout == 0 ){
184 fprintf(stderr,_("\n\nERROR: The window size granted by the windowmanager is not the\n"
185 "window size gPlanarity requested. If the windowmanager is\n"
186 "configured to ignore application sizing requests, this stands\n"
187 "a pretty good chance of scrambling saved boards later (and\n"
188 "making everything look funny now).\n\n"));
189 fprintf(stderr,_("Clipping and/or expanding this board to the current window size...\n\n"));
191 g->resize_h=0;
192 g->resize_w=0;
195 g->resize_timeout=1;
197 if(widget->allocation.width == allocation->width &&
198 widget->allocation.height == allocation->height) return;
200 if(g->wc)
201 cairo_destroy(g->wc);
202 if (g->forescore)
203 cairo_surface_destroy(g->forescore);
204 if (g->forebutton)
205 cairo_surface_destroy(g->forebutton);
206 if (g->background)
207 cairo_surface_destroy(g->background);
208 if (g->foreground)
209 cairo_surface_destroy(g->foreground);
210 if (g->curtainp)
211 cairo_pattern_destroy(g->curtainp);
212 if (g->curtains)
213 cairo_surface_destroy(g->curtains);
216 gdk_window_move_resize (widget->window, allocation->x, allocation->y,
217 allocation->width, allocation->height);
219 g->wc = gdk_cairo_create(widget->window);
221 g->background =
222 cairo_surface_create_similar (cairo_get_target (g->wc),
223 CAIRO_CONTENT_COLOR, // don't need alpha
224 allocation->width,
225 allocation->height);
226 g->forescore =
227 cairo_surface_create_similar (cairo_get_target (g->wc),
228 CAIRO_CONTENT_COLOR_ALPHA,
229 allocation->width,
230 SCOREHEIGHT);
231 g->forebutton =
232 cairo_surface_create_similar (cairo_get_target (g->wc),
233 CAIRO_CONTENT_COLOR_ALPHA,
234 allocation->width,
235 SCOREHEIGHT);
237 g->foreground =
238 cairo_surface_create_similar (cairo_get_target (g->wc),
239 CAIRO_CONTENT_COLOR, // don't need alpha
240 allocation->width,
241 allocation->height);
243 cache_curtain(g);
245 resize_buttons(g,g->g.width, g->g.height, allocation->width, allocation->height);
246 graph_resize(&g->g, allocation->width, allocation->height);
248 draw_buttonbar_box(g);
249 update_score(g);
250 update_full(g);
253 widget->allocation = *allocation;
256 static void gameboard_class_init (GameboardClass * class) {
258 GtkObjectClass *object_class;
259 GtkWidgetClass *widget_class;
261 object_class = (GtkObjectClass *) class;
262 widget_class = (GtkWidgetClass *) class;
264 parent_class = gtk_type_class (GTK_TYPE_WIDGET);
266 object_class->destroy = gameboard_destroy;
268 widget_class->realize = gameboard_realize;
269 widget_class->expose_event = gameboard_expose;
270 widget_class->size_request = gameboard_size_request;
271 widget_class->size_allocate = gameboard_size_allocate;
272 widget_class->button_press_event = mouse_press;
273 widget_class->button_release_event = mouse_release;
274 widget_class->motion_notify_event = mouse_motion;
278 GType gameboard_get_type (void){
280 static GType gameboard_type = 0;
282 if (!gameboard_type)
284 static const GTypeInfo gameboard_info = {
285 sizeof (GameboardClass),
286 NULL,
287 NULL,
288 (GClassInitFunc) gameboard_class_init,
289 NULL,
290 NULL,
291 sizeof (Gameboard),
293 (GInstanceInitFunc) gameboard_init,
297 gameboard_type = g_type_register_static (GTK_TYPE_WIDGET, "Gameboard",
298 &gameboard_info, 0);
301 return gameboard_type;
304 Gameboard *gameboard_new (void) {
305 GtkWidget *g = GTK_WIDGET (g_object_new (GAMEBOARD_TYPE, NULL));
306 Gameboard *gb = GAMEBOARD (g);
307 return gb;