blob: 28d897fa39bfb03aa3560811714f4f8b6dbceaf7 [file] [log] [blame]
adamdunkels1103ef92003-04-02 09:17:18 +00001/*
2 * Copyright (c) 2002, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
adamdunkelsee08cc92004-07-04 21:04:13 +000014 * 3. The name of the author may not be used to endorse or promote
adamdunkels1103ef92003-04-02 09:17:18 +000015 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * This file is part of the "ctk" console GUI toolkit for cc65
31 *
adamdunkels77b45152004-08-11 21:21:26 +000032 * $Id: ctk-gtksim.c,v 1.5 2004/08/11 21:21:26 adamdunkels Exp $
adamdunkels1103ef92003-04-02 09:17:18 +000033 *
34 */
35
36/* This file provides a very simple implementation of CTK using the
37 GTK (Gimp toolkit) under FreeBSD/Linux. */
38
adamdunkels1103ef92003-04-02 09:17:18 +000039
adamdunkelsf6959692003-04-15 21:19:47 +000040#include "libconio.h"
41
adamdunkels1103ef92003-04-02 09:17:18 +000042#include "ctk.h"
43#include "ctk-draw.h"
adamdunkelsee08cc92004-07-04 21:04:13 +000044#include "ctk-mouse.h"
adamdunkels1103ef92003-04-02 09:17:18 +000045
46#include <string.h>
adamdunkelsee08cc92004-07-04 21:04:13 +000047#include <stdio.h>
48#include <stdlib.h>
adamdunkels1103ef92003-04-02 09:17:18 +000049
adamdunkelsee08cc92004-07-04 21:04:13 +000050#define FONT_HEIGHT 14
51#define FONT_WIDTH 8
52#define FONT_HEIGHT_BASELINE 11
adamdunkels1103ef92003-04-02 09:17:18 +000053
adamdunkelsee08cc92004-07-04 21:04:13 +000054GdkPixmap *ctk_gtksim_pixmap = NULL;
55GtkWidget *ctk_gtksim_drawing_area;
adamdunkels1103ef92003-04-02 09:17:18 +000056static GdkFont *font;
57
adamdunkelsf6959692003-04-15 21:19:47 +000058static int mouse_x, mouse_y, mouse_button;
adamdunkels1103ef92003-04-02 09:17:18 +000059
adamdunkelsee08cc92004-07-04 21:04:13 +000060static int redrawflag;
61
62void
63ctk_gtksim_redraw(void)
64{
65 if(redrawflag) {
66 gdk_draw_pixmap(ctk_gtksim_drawing_area->window,
67 ctk_gtksim_drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_gtksim_drawing_area)],
68 ctk_gtksim_pixmap,
69 0,0,0,0,
70 CTK_GTKSIM_SCREEN_WIDTH, CTK_GTKSIM_SCREEN_HEIGHT);
71 redrawflag = 0;
72 }
73
74}
75/*-----------------------------------------------------------------------------------*/
76void
77ctk_gtksim_set_redrawflag(void)
78{
79 redrawflag = 1;
80}
adamdunkels1103ef92003-04-02 09:17:18 +000081/*-----------------------------------------------------------------------------------*/
adamdunkelsf6959692003-04-15 21:19:47 +000082void
83ctk_arch_draw_char(char c,
84 unsigned char x, unsigned char y,
adamdunkels12d70cb2003-08-11 22:20:56 +000085 unsigned char reversed,
86 unsigned char color)
adamdunkels1103ef92003-04-02 09:17:18 +000087{
adamdunkelsf6959692003-04-15 21:19:47 +000088 char str[2];
89
90 str[0] = c;
91 str[1] = 0;
92
adamdunkels1103ef92003-04-02 09:17:18 +000093 if(reversed) {
adamdunkelsee08cc92004-07-04 21:04:13 +000094 gdk_draw_rectangle(ctk_gtksim_pixmap,
95 ctk_gtksim_drawing_area->style->black_gc,
adamdunkelsf6959692003-04-15 21:19:47 +000096 TRUE,
97 x * FONT_WIDTH,
98 y * FONT_HEIGHT,
99 FONT_WIDTH, FONT_HEIGHT);
100
adamdunkelsee08cc92004-07-04 21:04:13 +0000101 gdk_draw_string(ctk_gtksim_pixmap,
adamdunkelsf6959692003-04-15 21:19:47 +0000102 font,
adamdunkelsee08cc92004-07-04 21:04:13 +0000103 ctk_gtksim_drawing_area->style->white_gc,
104 x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT,
adamdunkelsf6959692003-04-15 21:19:47 +0000105 str);
adamdunkels1103ef92003-04-02 09:17:18 +0000106 } else {
adamdunkelsee08cc92004-07-04 21:04:13 +0000107 gdk_draw_rectangle(ctk_gtksim_pixmap,
108 ctk_gtksim_drawing_area->style->white_gc,
adamdunkelsf6959692003-04-15 21:19:47 +0000109 TRUE,
110 x * FONT_WIDTH,
111 y * FONT_HEIGHT,
112 FONT_WIDTH, FONT_HEIGHT);
113
adamdunkelsee08cc92004-07-04 21:04:13 +0000114 gdk_draw_string(ctk_gtksim_pixmap,
adamdunkelsf6959692003-04-15 21:19:47 +0000115 font,
adamdunkelsee08cc92004-07-04 21:04:13 +0000116 ctk_gtksim_drawing_area->style->black_gc,
117 x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT,
adamdunkelsf6959692003-04-15 21:19:47 +0000118 str);
adamdunkels1103ef92003-04-02 09:17:18 +0000119 }
adamdunkelsf6959692003-04-15 21:19:47 +0000120
adamdunkelsee08cc92004-07-04 21:04:13 +0000121 gdk_draw_pixmap(ctk_gtksim_drawing_area->window,
122 ctk_gtksim_drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_gtksim_drawing_area)],
123 ctk_gtksim_pixmap,
adamdunkelsf6959692003-04-15 21:19:47 +0000124 x * FONT_WIDTH,
125 y * FONT_HEIGHT,
126 x * FONT_WIDTH,
127 y * FONT_HEIGHT,
128 FONT_WIDTH, FONT_HEIGHT);
129
adamdunkels1103ef92003-04-02 09:17:18 +0000130}
131/*-----------------------------------------------------------------------------------*/
adamdunkels1103ef92003-04-02 09:17:18 +0000132#define NUMKEYS 100
133static ctk_arch_key_t keys[NUMKEYS];
134static int firstkey, lastkey;
135
adamdunkelsee08cc92004-07-04 21:04:13 +0000136unsigned char
adamdunkels1103ef92003-04-02 09:17:18 +0000137ctk_arch_keyavail(void)
138{
139 return firstkey != lastkey;
140}
141/*-----------------------------------------------------------------------------------*/
142ctk_arch_key_t
143ctk_arch_getkey(void)
144{
145 ctk_arch_key_t key;
146 key = keys[firstkey];
147
148 if(firstkey != lastkey) {
149 ++firstkey;
150 if(firstkey >= NUMKEYS) {
151 firstkey = 0;
152 }
153 }
154
155 return key;
156}
157/*-----------------------------------------------------------------------------------*/
adamdunkels1103ef92003-04-02 09:17:18 +0000158static gint
159configure_event(GtkWidget *widget, GdkEventConfigure *event)
160{
adamdunkelsee08cc92004-07-04 21:04:13 +0000161 if(ctk_gtksim_pixmap != NULL) {
162 gdk_pixmap_unref(ctk_gtksim_pixmap);
adamdunkels1103ef92003-04-02 09:17:18 +0000163 }
adamdunkelsf6959692003-04-15 21:19:47 +0000164
adamdunkelsee08cc92004-07-04 21:04:13 +0000165 ctk_gtksim_pixmap = gdk_pixmap_new(widget->window,
adamdunkels1103ef92003-04-02 09:17:18 +0000166 widget->allocation.width,
167 widget->allocation.height,
adamdunkelsf6959692003-04-15 21:19:47 +0000168 -1);
adamdunkels1103ef92003-04-02 09:17:18 +0000169
adamdunkelsee08cc92004-07-04 21:04:13 +0000170 if(ctk_gtksim_pixmap == NULL) {
adamdunkels1103ef92003-04-02 09:17:18 +0000171 printf("gdk_pixmap_new == NULL\n");
172 exit(1);
173 }
adamdunkelsee08cc92004-07-04 21:04:13 +0000174 gdk_draw_rectangle(ctk_gtksim_pixmap,
adamdunkels1103ef92003-04-02 09:17:18 +0000175 widget->style->white_gc,
176 TRUE,
177 0, 0,
178 widget->allocation.width,
179 widget->allocation.height);
adamdunkelsf6959692003-04-15 21:19:47 +0000180
adamdunkels1103ef92003-04-02 09:17:18 +0000181 return TRUE;
182}
183
184/* Redraw the screen from the backing pixmap */
185static gint
186expose_event (GtkWidget * widget, GdkEventExpose * event)
187{
adamdunkelsf6959692003-04-15 21:19:47 +0000188 /* draw_screen();*/
adamdunkels1103ef92003-04-02 09:17:18 +0000189 gdk_draw_pixmap(widget->window,
190 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
adamdunkelsee08cc92004-07-04 21:04:13 +0000191 ctk_gtksim_pixmap,
adamdunkels1103ef92003-04-02 09:17:18 +0000192 event->area.x, event->area.y,
193 event->area.x, event->area.y,
194 event->area.width, event->area.height);
195 return FALSE;
196}
197
198static gint
199key_press_event (GtkWidget * widget, GdkEventKey * event)
200{
201 if(event->keyval == GDK_Shift_L ||
202 event->keyval == GDK_Shift_R) {
203 return TRUE;
204 }
205 keys[lastkey] = event->keyval;
206 ++lastkey;
207 if(lastkey >= NUMKEYS) {
208 lastkey = 0;
209 }
adamdunkelsf6959692003-04-15 21:19:47 +0000210
adamdunkels1103ef92003-04-02 09:17:18 +0000211 return TRUE;
212}
213
214static gint
215key_release_event (GtkWidget * widget, GdkEventKey * event)
216{
217 return TRUE;
218}
219
adamdunkelsf6959692003-04-15 21:19:47 +0000220static gint
221motion_notify_event (GtkWidget * widget, GdkEventMotion * event)
222{
adamdunkelsee08cc92004-07-04 21:04:13 +0000223 int x, y;
224 GdkModifierType state;
225
226 if (event->is_hint) {
227 gdk_window_get_pointer (event->window, &x, &y, &state);
228 } else {
229 x = event->x;
230 y = event->y;
231 }
232
233 mouse_x = x;
234 mouse_y = y;
adamdunkelsf6959692003-04-15 21:19:47 +0000235 return TRUE;
236}
237
238static gint
239button_press_event (GtkWidget * widget, GdkEventButton * event)
240{
241 mouse_button = event->button;
242 return TRUE;
243}
244
245static gint
246button_release_event (GtkWidget * widget, GdkEventButton * event)
247{
248 mouse_button = 0;
249 return TRUE;
250}
251
adamdunkels1103ef92003-04-02 09:17:18 +0000252static void
253quit(void)
254{
255 gtk_exit(0);
256}
257/*-----------------------------------------------------------------------------------*/
adamdunkels1103ef92003-04-02 09:17:18 +0000258void
adamdunkels77b45152004-08-11 21:21:26 +0000259ctk_gtksim_init(void)
adamdunkels1103ef92003-04-02 09:17:18 +0000260{
261 GtkWidget *window;
adamdunkelsee08cc92004-07-04 21:04:13 +0000262#if 0
adamdunkels1103ef92003-04-02 09:17:18 +0000263 GtkWidget *vbox;
adamdunkelsee08cc92004-07-04 21:04:13 +0000264#endif
265
adamdunkels1103ef92003-04-02 09:17:18 +0000266 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
adamdunkelsee08cc92004-07-04 21:04:13 +0000267 gtk_window_set_title(window, "Contiki GTKsim");
adamdunkels1103ef92003-04-02 09:17:18 +0000268
adamdunkelsee08cc92004-07-04 21:04:13 +0000269#if 0
adamdunkels1103ef92003-04-02 09:17:18 +0000270 vbox = gtk_vbox_new(FALSE, 0);
271 gtk_container_add(GTK_CONTAINER (window), vbox);
272 gtk_widget_show(vbox);
adamdunkelsee08cc92004-07-04 21:04:13 +0000273#endif
adamdunkels1103ef92003-04-02 09:17:18 +0000274 gtk_signal_connect(GTK_OBJECT (window), "destroy",
275 GTK_SIGNAL_FUNC (quit), NULL);
276
277 /* Create the drawing area */
278
adamdunkelsee08cc92004-07-04 21:04:13 +0000279 ctk_gtksim_drawing_area = gtk_drawing_area_new();
280 gtk_drawing_area_size(GTK_DRAWING_AREA (ctk_gtksim_drawing_area),
281 CTK_GTKSIM_SCREEN_WIDTH,
282 CTK_GTKSIM_SCREEN_HEIGHT);
283#if 0
284 gtk_box_pack_start(GTK_BOX(vbox), ctk_gtksim_drawing_area, TRUE, TRUE, 0);
285#else
286 gtk_container_add(GTK_CONTAINER(window), ctk_gtksim_drawing_area);
287#endif
adamdunkels1103ef92003-04-02 09:17:18 +0000288
adamdunkelsee08cc92004-07-04 21:04:13 +0000289 gtk_widget_show(ctk_gtksim_drawing_area);
adamdunkels1103ef92003-04-02 09:17:18 +0000290
adamdunkelsee08cc92004-07-04 21:04:13 +0000291 /* Load a fixed width font. */
292 /* font = gdk_font_load("-*-gamow-medium-r-*-*-*-90-*-*-*-*-*-*");*/
293 /* font = gdk_font_load("-*-courier-*-r-normal-*-14-*-*-*-m-*-iso8859-1");*/
294 font = gdk_font_load("-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1");
adamdunkels1103ef92003-04-02 09:17:18 +0000295 if(font != NULL) {
296 printf("Font loaded OK\n");
297 } else {
298 printf("Font loading failed\n");
adamdunkelsee08cc92004-07-04 21:04:13 +0000299 exit(1);
adamdunkels1103ef92003-04-02 09:17:18 +0000300 }
301
302
303 /* Signals used to handle backing pixmap */
304
adamdunkelsee08cc92004-07-04 21:04:13 +0000305 gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "expose_event",
adamdunkels1103ef92003-04-02 09:17:18 +0000306 (GtkSignalFunc) expose_event, NULL);
adamdunkelsee08cc92004-07-04 21:04:13 +0000307 gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "configure_event",
adamdunkels1103ef92003-04-02 09:17:18 +0000308 (GtkSignalFunc) configure_event, NULL);
309
310 /* Event signals */
311
312 gtk_signal_connect(GTK_OBJECT (window), "key_press_event",
313 (GtkSignalFunc) key_press_event, NULL);
314 gtk_signal_connect(GTK_OBJECT (window), "key_release_event",
315 (GtkSignalFunc) key_release_event, NULL);
316
adamdunkelsee08cc92004-07-04 21:04:13 +0000317 gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "motion_notify_event",
adamdunkelsf6959692003-04-15 21:19:47 +0000318 (GtkSignalFunc) motion_notify_event, NULL);
319
adamdunkelsee08cc92004-07-04 21:04:13 +0000320 gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "button_press_event",
adamdunkelsf6959692003-04-15 21:19:47 +0000321 (GtkSignalFunc) button_press_event, NULL);
322
adamdunkelsee08cc92004-07-04 21:04:13 +0000323 gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "button_release_event",
adamdunkelsf6959692003-04-15 21:19:47 +0000324 (GtkSignalFunc) button_release_event, NULL);
325
adamdunkelsee08cc92004-07-04 21:04:13 +0000326 gtk_widget_set_events(ctk_gtksim_drawing_area, gtk_widget_get_events (ctk_gtksim_drawing_area)
adamdunkelsf6959692003-04-15 21:19:47 +0000327 | GDK_KEY_PRESS_MASK
328 | GDK_KEY_RELEASE_MASK
329 | GDK_POINTER_MOTION_MASK
adamdunkelsee08cc92004-07-04 21:04:13 +0000330 | GDK_POINTER_MOTION_HINT_MASK
adamdunkelsf6959692003-04-15 21:19:47 +0000331 | GDK_BUTTON_PRESS_MASK
332 | GDK_BUTTON_RELEASE_MASK);
adamdunkels1103ef92003-04-02 09:17:18 +0000333
334 gtk_widget_show(window);
335
336}
337/*-----------------------------------------------------------------------------------*/
adamdunkels1103ef92003-04-02 09:17:18 +0000338void
adamdunkelsf6959692003-04-15 21:19:47 +0000339ctk_mouse_init(void)
adamdunkels1103ef92003-04-02 09:17:18 +0000340{
adamdunkels1103ef92003-04-02 09:17:18 +0000341
adamdunkels1103ef92003-04-02 09:17:18 +0000342}
343/*-----------------------------------------------------------------------------------*/
adamdunkelsf6959692003-04-15 21:19:47 +0000344unsigned short
345ctk_mouse_x(void)
adamdunkels1103ef92003-04-02 09:17:18 +0000346{
adamdunkelsf6959692003-04-15 21:19:47 +0000347 return mouse_x;
adamdunkels1103ef92003-04-02 09:17:18 +0000348}
349/*-----------------------------------------------------------------------------------*/
adamdunkelsf6959692003-04-15 21:19:47 +0000350unsigned short
351ctk_mouse_y(void)
adamdunkels1103ef92003-04-02 09:17:18 +0000352{
adamdunkelsf6959692003-04-15 21:19:47 +0000353 return mouse_y;
adamdunkels1103ef92003-04-02 09:17:18 +0000354}
355/*-----------------------------------------------------------------------------------*/
356unsigned char
adamdunkelsf6959692003-04-15 21:19:47 +0000357ctk_mouse_button(void)
358{
359 return mouse_button;
360}
361/*-----------------------------------------------------------------------------------*/
362void
363ctk_mouse_hide(void)
364{
365}
366/*-----------------------------------------------------------------------------------*/
367void
368ctk_mouse_show(void)
369{
adamdunkels1103ef92003-04-02 09:17:18 +0000370}
371/*-----------------------------------------------------------------------------------*/