1 /*
2 $Id: gtkgetlin.c,v 1.7 2004/04/10 15:41:21 j_ali Exp $
3 */
4 /*
5 GTK+ NetHack Copyright (c) Issei Numata 1999-2000
6 Copyright (c) Slash'EM Development Team 2000-2004
7 GTK+ NetHack may be freely redistributed. See license for details.
8 */
9
10 #include <sys/types.h>
11 #include <signal.h>
12 #include <gtk/gtk.h>
13 #include <gdk/gdkkeysyms.h>
14 #include "winGTK.h"
15
16 static GtkWidget *window;
17 static int cancelled;
18
19 static gint
getlin_destroy(GtkWidget * widget,gpointer data)20 getlin_destroy(GtkWidget *widget, gpointer data)
21 {
22 window = NULL;
23 cancelled = 1;
24 gtk_main_quit();
25 return FALSE;
26 }
27
28 static gint
entry_key_press(GtkWidget * widget,GdkEventKey * event,gpointer data)29 entry_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
30 {
31 if (event->keyval == GDK_Return)
32 gtk_main_quit();
33
34 if (event->keyval == GDK_Escape) {
35 cancelled = 1;
36 gtk_main_quit();
37 }
38
39 return FALSE;
40 }
41
42 static gint
entry_ok(GtkWidget * widget,GdkEventButton * event,gpointer data)43 entry_ok(GtkWidget *widget, GdkEventButton *event, gpointer data)
44 {
45 gtk_main_quit();
46
47 return FALSE;
48 }
49
50 static gint
entry_cancel(GtkWidget * widget,GdkEventButton * event,gpointer data)51 entry_cancel(GtkWidget *widget, GdkEventButton *event, gpointer data)
52 {
53 cancelled = 1;
54 gtk_main_quit();
55
56 return FALSE;
57 }
58
59 char *
GTK_getline(const char * query,boolean cancelable)60 GTK_getline(const char *query, boolean cancelable)
61 {
62 char *s, *ret;
63 GtkWidget *frame;
64 GtkWidget *vbox;
65 GtkWidget *hbox;
66 GtkWidget *entry;
67 GtkWidget *ok;
68 GtkWidget *cancel;
69 gulong h;
70
71 cancelled = 0;
72
73 window = nh_gtk_window_dialog(TRUE);
74 nh_position_popup_dialog(GTK_WIDGET(window));
75
76 frame = nh_gtk_new_and_add(gtk_frame_new(query), window, "");
77 gtk_container_border_width(GTK_CONTAINER(frame), NH_PAD);
78
79 vbox = nh_gtk_new_and_add(gtk_vbox_new(FALSE, 0), frame, "");
80
81 entry = nh_gtk_new_and_pack(gtk_entry_new(), vbox, "",
82 FALSE, FALSE, NH_PAD);
83
84 #if GTK_CHECK_VERSION(2,0,0)
85 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
86 #endif
87
88 nh_gtk_focus_set_master(GTK_WINDOW(window),
89 GTK_SIGNAL_FUNC(entry_key_press), 0, TRUE);
90
91 hbox = nh_gtk_new_and_pack(gtk_hbox_new(FALSE, 0), vbox, "",
92 FALSE, FALSE, NH_PAD);
93
94 if (cancelable) {
95 cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
96 gtk_widget_show(cancel);
97 gtk_box_pack_end(GTK_BOX(hbox), cancel, FALSE, FALSE, NH_PAD);
98
99 gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
100 GTK_SIGNAL_FUNC(entry_cancel), NULL);
101 }
102
103 ok = gtk_button_new_from_stock(GTK_STOCK_OK);
104 gtk_widget_show(ok);
105 gtk_box_pack_end(GTK_BOX(hbox), ok, FALSE, FALSE, NH_PAD);
106
107 GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
108 gtk_widget_grab_default(ok);
109
110 gtk_signal_connect(GTK_OBJECT(ok), "clicked",
111 GTK_SIGNAL_FUNC(entry_ok), NULL);
112
113 h = gtk_signal_connect(GTK_OBJECT(window), "destroy",
114 GTK_SIGNAL_FUNC(getlin_destroy), NULL);
115
116 gtk_widget_grab_focus(entry);
117 gtk_grab_add(window);
118 gtk_widget_show_all(window);
119 gtk_widget_realize(window);
120 gdk_window_set_decorations(window->window,
121 GDK_DECOR_BORDER | GDK_DECOR_TITLE);
122
123 gtk_main();
124
125 if (!cancelled) {
126 s = (char *)gtk_entry_get_text(GTK_ENTRY(entry));
127 ret = (char *)alloc(strlen(s) + 1);
128 Strcpy(ret, s);
129 } else {
130 ret = (char *)alloc(1);
131 *ret = '\0';
132 }
133
134 if (window) {
135 gtk_signal_disconnect(GTK_OBJECT(window), h);
136 gtk_widget_unmap(window);
137 gtk_widget_destroy(window);
138 }
139
140 return ret;
141 }
142
143 char *
GTK_ext_getlin(const char * query)144 GTK_ext_getlin(const char *query)
145 {
146 return GTK_getline(query, TRUE);
147 }
148