4
* $Id: glame_console.c,v 1.6 2001/09/17 11:47:12 nold Exp $
6
* Copyright (C) 2001 Richard Guenther
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30
#include <libguile/ports.h>
33
#include "glame_console.h"
36
static GtkWidget *console = NULL;
37
static GtkWidget *text = NULL;
38
static GdkColor fore, back;
39
struct history_entry {
40
struct glame_list_head list;
43
static GLAME_LIST_HEAD(history_list);
44
static int history_cnt = 0;
45
static struct history_entry *history = NULL;
46
static char *history_edited = NULL;
48
static void port_write(SCM port, void *data, size_t size)
50
glame_console_printf("%.*s", (int)size, data);
52
static void port_register()
58
/* Register glame-console port type (output only) */
59
port = scm_make_port_type("glame-console", NULL, port_write);
61
/* Create new port - shamelessly copied from libguile/strports.c */
64
pt = scm_add_to_port_table(s_port);
65
#ifdef SCM_SET_CELL_TYPE /* guile >= 1.4 */
66
SCM_SET_CELL_TYPE(s_port, port|SCM_WRTNG|SCM_OPN);
68
SCM_SETCAR(s_port, port|SCM_WRTNG|SCM_OPN);
70
SCM_SETPTAB_ENTRY(s_port, pt);
74
scm_set_current_output_port(s_port);
75
scm_set_current_error_port(s_port);
78
static gint hide_cb(GtkWidget *window, GdkEventAny *event)
80
gtk_widget_hide(window);
84
static gboolean entry_cb(GtkWidget *entry, GdkEventKey *event)
88
struct history_entry *hentry;
90
if (event->type != GDK_KEY_PRESS)
93
if (event->keyval == GDK_KP_Enter
94
|| event->keyval == GDK_ISO_Enter
95
|| event->keyval == GDK_3270_Enter
96
|| event->keyval == GDK_Return) {
97
/* Catch ENTER - execute command. */
98
cmd = gtk_entry_get_text(GTK_ENTRY(entry));
102
/* add cmd to history and adjust current history pointer */
103
hentry = ALLOC(struct history_entry);
104
GLAME_INIT_LIST_HEAD(&hentry->list);
105
hentry->cmd = strdup(cmd);
106
glame_list_add(&hentry->list, &history_list);
107
if (++history_cnt > 128) {
108
hentry = glame_list_gettail(&history_list,
109
struct history_entry, list);
110
glame_list_del(&hentry->list);
115
if (history_edited) {
116
free(history_edited);
117
history_edited = NULL;
120
glame_console_printf("GLAME> %s\n", cmd);
121
s_res = glame_gh_safe_eval_str(cmd);
122
if (!SCM_UNBNDP(s_res)
124
&& !SCM_EQ_P(s_res, SCM_UNSPECIFIED)
126
&& !(SCM_UNSPECIFIED==s_res)
132
gtk_entry_set_text(GTK_ENTRY(entry), "");
135
} else if (event->keyval == GDK_Up
136
|| event->keyval == GDK_Down) {
137
/* Catch history - remember edited text */
138
cmd = gtk_entry_get_text(GTK_ENTRY(entry));
139
if (!history || strcmp(cmd, history->cmd) != 0) {
141
free(history_edited);
142
history_edited = strdup(cmd);
145
if (!history && event->keyval == GDK_Up)
146
hentry = glame_list_gethead(&history_list,
147
struct history_entry, list);
148
else if (history && event->keyval == GDK_Up)
149
hentry = glame_list_getnext(&history_list, history,
150
struct history_entry, list);
151
else if (history && event->keyval == GDK_Down)
152
hentry = glame_list_getprev(&history_list, history,
153
struct history_entry, list);
154
if (hentry || event->keyval == GDK_Down)
157
gtk_entry_set_text(GTK_ENTRY(entry), history->cmd);
158
else if (event->keyval == GDK_Down)
159
gtk_entry_set_text(GTK_ENTRY(entry), history_edited);
160
gtk_signal_emit_stop_by_name(GTK_OBJECT(entry),
163
} else if (event->keyval == GDK_Tab) {
166
gtk_signal_emit_stop_by_name(GTK_OBJECT(entry),
174
int glame_console_init()
176
GtkWidget *scroll, *label, *entry, *vbox, *hbox;
177
GdkColormap *colormap;
182
console = gtk_window_new(GTK_WINDOW_TOPLEVEL);
183
gtk_window_set_title(GTK_WINDOW(console), "GLAME "VERSION" console");
184
gtk_window_set_default_size(GTK_WINDOW(console), 400, 200);
185
vbox = gtk_vbox_new(FALSE, 10);
186
scroll = gtk_scrolled_window_new(NULL, NULL);
187
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
188
GTK_POLICY_AUTOMATIC,
190
text = gtk_text_new(NULL, NULL);
191
gtk_text_set_editable(GTK_TEXT(text), FALSE);
192
hbox = gtk_hbox_new(FALSE, 10);
193
label = gtk_label_new("GLAME>");
194
entry = gtk_entry_new();
196
gtk_signal_connect(GTK_OBJECT(entry), "key_press_event",
197
(GtkSignalFunc)entry_cb, NULL);
198
gtk_signal_connect(GTK_OBJECT(console), "delete_event",
199
(GtkSignalFunc)hide_cb, NULL);
200
gtk_signal_connect(GTK_OBJECT(console), "destroy_event",
201
(GtkSignalFunc)hide_cb, NULL);
203
gtk_container_add(GTK_CONTAINER(scroll), text);
204
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
205
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 5);
206
gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 5);
207
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
208
gtk_container_add(GTK_CONTAINER(console), vbox);
209
gtk_widget_show(label);
210
gtk_widget_show(entry);
211
gtk_widget_show(hbox);
212
gtk_widget_show(vbox);
213
gtk_widget_show(text);
214
gtk_widget_show(scroll);
216
colormap = gdk_colormap_get_system();
217
gdk_color_white(colormap, &back);
218
gdk_color_black(colormap, &fore);
225
void glame_console_hide()
228
gtk_widget_hide(console);
231
void glame_console_show()
234
gtk_widget_show(console);
237
int glame_console_printf(const char *format, ...)
246
va_start(va, format);
247
res = vsnprintf(buf, 1023, format, va);
251
gtk_text_insert(GTK_TEXT(text), NULL, &fore, &back,