1 /***********************************************************************
2  * ����ե��å����� (�����ƥ��¸)
3  *
4  *	�ܺ٤ϡ� graph.h ����
5  ************************************************************************/
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <gtk/gtk.h>
10 
11 #include "quasi88.h"
12 #include "graph.h"
13 #include "device.h"
14 
15 
16 int	use_gdk_image = TRUE;			/* ���ǡ�GdkImage����� */
17 
18 static	T_GRAPH_SPEC	graph_spec;		/* ���ܾ���		*/
19 
20 static	int		graph_exist;		/* ���ǡ����������Ѥ�	*/
21 static	T_GRAPH_INFO	graph_info;		/* ���λ��Ρ����̾���	*/
22 
23 
24 /************************************************************************
25  *	����ե��å������ν����
26  *	����ե��å�������ư��
27  *	����ե��å������ν�λ
28  ************************************************************************/
29 
30 static	GdkVisual 	*visual;
31 static	GdkColormap	*colormap;
32 
graph_init(void)33 const T_GRAPH_SPEC	*graph_init(void)
34 {
35     if (verbose_proc) {
36 	printf("Initializing Graphic System ... ");
37     }
38 
39     /* ??? �褯�狼��� */
40     {
41 	GtkStyle *style = gtk_widget_get_default_style();
42 	if (style != NULL) {
43 	    GdkFont* font = NULL;
44 #if 0
45 #ifdef ������ɥ�����
46 	    font = gdk_font_load("-*-*-*-*-*--*-*-*-*-*-*-windows-shiftjis");
47 #else
48 #ifdef __CYGWIN__
49 	    font = gdk_fontset_load("-*-*-*-*-*--*-*-*-*-*-*-iso8859-1,"
50 				    "-*-*-*-*-*--*-*-*-*-*-*-jisx0208.*-*");
51 #endif
52 #endif
53 #endif
54 	    if (font != NULL) {
55 		if (style->font != NULL) {
56 		    gdk_font_unref(style->font);
57 		}
58 		style->font = font;
59 		gdk_font_ref(style->font);
60 		gtk_widget_set_default_style(style);
61 	    }
62 	}
63     }
64 
65     /* ��Ϥ�狼��� */
66     {
67 	int found = FALSE;
68 	GdkVisual *v = gdk_visual_get_system();
69 
70 	if (use_gdk_image) {
71 	    if (v->type == GDK_VISUAL_TRUE_COLOR ||
72 		v->type == GDK_VISUAL_PSEUDO_COLOR) {
73 		if (v->depth == 32) {
74 #ifdef	SUPPORT_32BPP
75 		    found = TRUE;
76 #endif
77 		} else if (v->depth == 16 ||
78 			   v->depth == 15) {
79 #ifdef	SUPPORT_16BPP
80 		    found = TRUE;
81 #endif
82 		} else if (v->depth == 8) {
83 #ifdef	SUPPORT_8BPP
84 		    found = TRUE;
85 #endif
86 		}
87 	    }
88 
89 	    if (found) {
90 #ifdef	LSB_FIRST
91 		if (v->byte_order != GDK_LSB_FIRST) found = FALSE;
92 #else
93 		if (v->byte_order != GDK_MSB_FIRST) found = FALSE;
94 #endif
95 	    }
96 	}
97 
98 	if (found) {
99 	    use_gdk_image = TRUE;
100 
101 	    visual   = v;
102 	    colormap = gdk_colormap_get_system();
103 	} else {
104 	    use_gdk_image = FALSE;
105 
106 #ifdef	SUPPORT_8BPP
107 
108 	    gdk_rgb_init();
109 	    gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
110 	    gtk_widget_set_default_visual(gdk_rgb_get_visual());
111 
112 	    visual   = gdk_rgb_get_visual();	/* ̤���Ѥ����� */
113 	    colormap = gdk_rgb_get_cmap();
114 
115 #else
116 	    visual = NULL;
117 	    colormap = NULL;
118 #endif
119 	}
120     }
121 
122     if (visual && colormap) {
123 
124 	graph_spec.window_max_width      = 10000;
125 	graph_spec.window_max_height     = 10000;
126 	graph_spec.fullscreen_max_width  = 0;
127 	graph_spec.fullscreen_max_height = 0;
128 	graph_spec.forbid_status         = FALSE;
129 	graph_spec.forbid_half           = FALSE;
130 
131 	if (verbose_proc)
132 	    printf("OK (%s)\n", (use_gdk_image) ? "GdkImage" : "GdkRGB");
133 
134 	return &graph_spec;
135 
136     } else {
137 	if (verbose_proc) printf("FAILED\n");
138 	return NULL;
139     }
140 }
141 
142 /************************************************************************/
143 static	GtkWidget	*main_window;
144 static	GtkWidget	*menu_bar;
145 static	GtkWidget	*drawing_area;
146 
147 static	GdkGC		*graphic_context;
148 
149 static int create_image(int width, int height);
150 
graph_setup(int width,int height,int fullscreen,double aspect)151 const T_GRAPH_INFO	*graph_setup(int width, int height,
152 				     int fullscreen, double aspect)
153 {
154     GtkWidget *vbox;
155 
156     /* fullscreen, aspect ��̤���� */
157 
158     if (graph_exist == FALSE) {
159 
160 	/* ������ɥ����������� */
161 	main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
162 	{
163 	    gtk_window_set_policy(GTK_WINDOW(main_window), FALSE, FALSE, TRUE);
164 	    gtksys_set_signal_frame(main_window);
165 	}
166 
167 	/* ��˥塼�С����������� */
168 	{
169 	    create_menubar(main_window, &menu_bar);
170 	    gtk_widget_show(menu_bar);
171 	}
172 
173 
174 	/* �����ΰ���������� */
175 	drawing_area = gtk_drawing_area_new();
176 	{
177 	    gtk_drawing_area_size(GTK_DRAWING_AREA(drawing_area),
178 				  width, height);
179 	    gtksys_set_signal_view(drawing_area);
180 	}
181 	gtk_widget_show(drawing_area);
182 
183 
184 	/* ��������졼���� */
185 
186 
187 	/* ��˥塼�С��������ΰ��ѥå�����ɽ�� */
188 	vbox = gtk_vbox_new(FALSE, 0);
189 	gtk_widget_show(vbox);
190 	gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, TRUE, 0);
191 	gtk_box_pack_start(GTK_BOX(vbox), drawing_area, FALSE, FALSE, 0);
192 
193 	gtk_container_add(GTK_CONTAINER(main_window), vbox);
194 	gtk_widget_show(main_window);
195 
196 
197 	/* ����ե��å�����ƥ����Ȥ����� (ɽ����Ǥʤ��Ȥ���) ? */
198 	graphic_context = gdk_gc_new(drawing_area->window);
199     }
200 
201     if (create_image(width, height)) {
202 
203 	gtk_drawing_area_size(GTK_DRAWING_AREA(drawing_area),
204 			      width, height);
205 
206 	graph_exist = TRUE;
207 
208 	return &graph_info;
209     }
210 
211     return NULL;
212 }
213 
214 /*----------------------------------------------------------------------*/
215 
216 static	GdkImage	*image;
217 static	guchar		*indexbuf;
218 static	GdkRgbCmap	indexrgb;
219 
220 static void color_trash(void);
221 
create_image(int width,int height)222 static int create_image(int width, int height)
223 {
224     if (use_gdk_image) {
225 
226 	if (image) {
227 	    color_trash();
228 
229 	    gdk_image_destroy(image);
230 	    image = NULL;
231 	}
232 
233 	image = gdk_image_new(GDK_IMAGE_FASTEST,
234 			      visual,
235 			      width, height);
236 
237 	if (image == NULL) return FALSE;
238 
239 	graph_info.byte_per_pixel	= image->bpp;
240 	graph_info.byte_per_line	= image->bpl;
241 	graph_info.buffer		= image->mem;
242 
243     } else {
244 
245 	if (indexbuf) {
246 	    color_trash();
247 
248 	    free(indexbuf);
249 	    indexbuf = NULL;
250 	}
251 
252 	indexbuf = malloc(width * height * sizeof(guchar));
253 
254 	if (indexbuf == NULL) return FALSE;
255 
256 	memset(indexbuf, 0, width * height * sizeof(guchar));
257 
258 	graph_info.byte_per_pixel	= sizeof(guchar);
259 	graph_info.byte_per_line	= width;
260 	graph_info.buffer		= indexbuf;
261     }
262 
263     graph_info.fullscreen	= FALSE;
264     graph_info.width		= width;
265     graph_info.height		= height;
266     graph_info.nr_color		= 255;
267     graph_info.write_only	= FALSE;
268     graph_info.broken_mouse	= FALSE;
269     graph_info.draw_start	= NULL;
270     graph_info.draw_finish	= NULL;
271     graph_info.dont_frameskip	= FALSE;
272 
273     return TRUE;
274 }
275 
276 
277 
278 /************************************************************************/
279 
graph_exit(void)280 void	graph_exit(void)
281 {
282 }
283 
284 /************************************************************************
285  *	���γ���
286  *	���β���
287  ************************************************************************/
288 static	GdkColor	color_cell[256];	/* ���ݤ����������� */
289 static	int		nr_color_cell;		/* ���ݤ������θĿ� */
290 
graph_add_color(const PC88_PALETTE_T color[],int nr_color,unsigned long pixel[])291 void	graph_add_color(const PC88_PALETTE_T color[],
292 			int nr_color, unsigned long pixel[])
293 {
294     int i;
295     gboolean success[256];
296 
297     for (i = 0; i < nr_color; i++) {
298 	color_cell[nr_color_cell + i].red   = (gushort)color[i].red   << 8;
299 	color_cell[nr_color_cell + i].green = (gushort)color[i].green << 8;
300 	color_cell[nr_color_cell + i].blue  = (gushort)color[i].blue  << 8;
301     }
302 
303     i = gdk_colormap_alloc_colors(colormap,
304 				  &color_cell[ nr_color_cell ],
305 				  nr_color,
306 				  FALSE,
307 				  FALSE,
308 				  success);
309 
310     /* debug */
311     if (i != 0) printf("Color Alloc Failed %d/%d\n", i, nr_color);
312 
313 
314     if (use_gdk_image) {
315 
316 	for (i = 0; i < nr_color; i++) {
317 	    pixel[i] = color_cell[nr_color_cell + i].pixel;
318 	}
319 
320     } else {
321 
322 	for (i = 0; i < nr_color; i++) {
323 	    indexrgb.colors[nr_color_cell + i] =
324 		(((guint32)color_cell[nr_color_cell + i].red   & 0xff00) << 8)|
325 		 ((guint32)color_cell[nr_color_cell + i].green & 0xff00)      |
326 		 ((guint32)color_cell[nr_color_cell + i].blue            >> 8);
327 	    indexrgb.lut[nr_color_cell + i] =
328 		(guchar)color_cell[nr_color_cell + i].pixel;
329 
330 	    pixel[i] = nr_color_cell + i;
331 	}
332 
333     }
334 
335     nr_color_cell += nr_color;
336 }
337 
338 /************************************************************************/
339 
graph_remove_color(int nr_pixel,unsigned long pixel[])340 void	graph_remove_color(int nr_pixel, unsigned long pixel[])
341 {
342     nr_color_cell -= nr_pixel;
343 
344     gdk_colormap_free_colors(colormap,
345 			     &color_cell[ nr_color_cell ],
346 			     nr_pixel);
347 }
348 
349 /*----------------------------------------------------------------------*/
350 
color_trash(void)351 static void color_trash(void)
352 {
353     if (nr_color_cell) {
354 	gdk_colormap_free_colors(colormap,
355 				 &color_cell[ 0 ],
356 				 nr_color_cell);
357     }
358 
359     nr_color_cell = 0;
360 }
361 
362 
363 /************************************************************************
364  *	����ե��å��ι���
365  ************************************************************************/
366 
graph_update(int nr_rect,T_GRAPH_RECT rect[])367 void	graph_update(int nr_rect, T_GRAPH_RECT rect[])
368 {
369     int i;
370 
371     if (use_gdk_image) {
372 	for (i=0; i<nr_rect; i++) {
373 	    gdk_draw_image(drawing_area->window, graphic_context,
374 			   image,
375 			   rect[i].x, rect[i].y,
376 			   rect[i].x, rect[i].y,
377 			   rect[i].width, rect[i].height);
378 	}
379 
380     } else {
381 
382 	gdk_draw_indexed_image(drawing_area->window, graphic_context,
383 			       0, 0,
384 			       graph_info.width, graph_info.height,
385 			       GDK_RGB_DITHER_NONE,
386 			       indexbuf,
387 			       graph_info.width,
388 			       &indexrgb);
389     }
390 }
391 
392 
393 
394 /************************************************************************
395  *	�����ȥ������
396  *	°��������
397  ************************************************************************/
398 
graph_set_window_title(const char * title)399 void	graph_set_window_title(const char *title)
400 {
401     if (main_window) {
402 	gtk_window_set_title(GTK_WINDOW(main_window), title);
403     }
404 }
405 
406 /************************************************************************/
407 
408 static	int	gtksys_keyrepeat_on = TRUE;
409 
gtksys_set_attribute_focus_out(void)410 void	gtksys_set_attribute_focus_out(void)
411 {
412     gdk_key_repeat_restore();
413 }
414 
gtksys_set_attribute_focus_in(void)415 void	gtksys_set_attribute_focus_in(void)
416 {
417     if (gtksys_keyrepeat_on == FALSE) {
418 	gdk_key_repeat_disable();
419     } else {
420 	gdk_key_repeat_restore();
421     }
422 }
423 
graph_set_attribute(int mouse_show,int grab,int keyrepeat_on)424 void	graph_set_attribute(int mouse_show, int grab, int keyrepeat_on)
425 {
426     /* �ޥ�����̤�б� */
427     /* ����֤�̤�б� */
428     gtksys_keyrepeat_on = keyrepeat_on;
429 
430     if (gtksys_get_focus) {
431 	gtksys_set_attribute_focus_in();
432     }
433 }
434