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