comparison src/dialog-x.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 080151679be2
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
1 /* Implements elisp-programmable dialog boxes -- X interface. 1 /* Implements elisp-programmable dialog boxes -- X interface.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. 2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. 3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
4 Copyright (C) 2000 Ben Wing.
4 5
5 This file is part of XEmacs. 6 This file is part of XEmacs.
6 7
7 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 9 under the terms of the GNU General Public License as published by the
18 along with XEmacs; see the file COPYING. If not, write to 19 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 21 Boston, MA 02111-1307, USA. */
21 22
22 /* Synched up with: Not in FSF. */ 23 /* Synched up with: Not in FSF. */
24
25 /* This file Mule-ized by Ben Wing, 7-8-00. */
23 26
24 #include <config.h> 27 #include <config.h>
25 #include "lisp.h" 28 #include "lisp.h"
26 29
27 #include "console-x.h" 30 #include "console-x.h"
38 41
39 42
40 static void 43 static void
41 maybe_run_dbox_text_callback (LWLIB_ID id) 44 maybe_run_dbox_text_callback (LWLIB_ID id)
42 { 45 {
43 /* !!#### This function has not been Mule-ized */
44 widget_value *wv; 46 widget_value *wv;
45 int got_some; 47 int got_some;
46 wv = xmalloc_widget_value (); 48 wv = xmalloc_widget_value ();
47 wv->name = xstrdup ("value"); 49 wv->name = xstrdup ("value");
48 got_some = lw_get_some_values (id, wv); 50 got_some = lw_get_some_values (id, wv);
49 if (got_some) 51 if (got_some)
50 { 52 {
51 Lisp_Object text_field_callback; 53 Lisp_Object text_field_callback;
52 char *text_field_value = wv->value; 54 Extbyte *text_field_value = wv->value;
53 VOID_TO_LISP (text_field_callback, wv->call_data); 55 VOID_TO_LISP (text_field_callback, wv->call_data);
56 text_field_callback = XCAR (XCDR (text_field_callback));
54 if (text_field_value) 57 if (text_field_value)
55 { 58 {
56 void *tmp = LISP_TO_VOID (list2 (text_field_callback, 59 void *tmp =
57 build_string (text_field_value))); 60 LISP_TO_VOID (cons3 (Qnil,
61 list2 (text_field_callback,
62 build_ext_string (text_field_value,
63 Qlwlib_encoding)),
64 Qnil));
58 popup_selection_callback (0, id, (XtPointer) tmp); 65 popup_selection_callback (0, id, (XtPointer) tmp);
59 } 66 }
60 } 67 }
61 /* This code tried to optimize, newing/freeing. This is generally 68 /* This code tried to optimize, newing/freeing. This is generally
62 unsafe so we will alwats strdup and always use 69 unsafe so we will always strdup and always use
63 free_widget_value_tree. */ 70 free_widget_value_tree. */
64 free_widget_value_tree (wv); 71 free_widget_value_tree (wv);
65 } 72 }
66 73
67 static void 74 static void
86 assert (popup_up_p != 0); 93 assert (popup_up_p != 0);
87 ungcpro_popup_callbacks (id); 94 ungcpro_popup_callbacks (id);
88 popup_up_p--; 95 popup_up_p--;
89 maybe_run_dbox_text_callback (id); 96 maybe_run_dbox_text_callback (id);
90 popup_selection_callback (widget, id, client_data); 97 popup_selection_callback (widget, id, client_data);
98 /* #### need to error-protect! will do so when i merge in
99 my working ws */
100 va_run_hook_with_args (Qdelete_dialog_box_hook, 1, make_int (id));
91 lw_destroy_all_widgets (id); 101 lw_destroy_all_widgets (id);
92 102
93 /* The Motif dialog box sets the keyboard focus to itself. When it 103 /* The Motif dialog box sets the keyboard focus to itself. When it
94 goes away we have to take care of getting the focus back 104 goes away we have to take care of getting the focus back
95 ourselves. */ 105 ourselves. */
100 if (f) 110 if (f)
101 #endif 111 #endif
102 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f), FRAME_X_TEXT_WIDGET (f)); 112 lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f), FRAME_X_TEXT_WIDGET (f));
103 } 113 }
104 114
105 static CONST char * CONST button_names [] = { 115 static const Extbyte * const button_names [] = {
106 "button1", "button2", "button3", "button4", "button5", 116 "button1", "button2", "button3", "button4", "button5",
107 "button6", "button7", "button8", "button9", "button10" }; 117 "button6", "button7", "button8", "button9", "button10" };
108 118
109 /* can't have static frame locals because of some broken compilers */
110 static char tmp_dbox_name [255];
111
112 static widget_value * 119 static widget_value *
113 dbox_descriptor_to_widget_value (Lisp_Object desc) 120 dbox_descriptor_to_widget_value (Lisp_Object keys)
114 { 121 {
115 /* !!#### This function has not been Mule-ized */
116 /* This function can GC */ 122 /* This function can GC */
117 char *name;
118 int lbuttons = 0, rbuttons = 0; 123 int lbuttons = 0, rbuttons = 0;
119 int partition_seen = 0; 124 int partition_seen = 0;
120 int text_field_p = 0; 125 int text_field_p = 0;
121 int allow_text_p = 1; 126 int allow_text_p = 1;
122 widget_value *prev = 0, *kids = 0; 127 widget_value *prev = 0, *kids = 0;
123 int n = 0; 128 int n = 0;
124 int count = specpdl_depth (); 129 int count = specpdl_depth ();
125 Lisp_Object wv_closure, gui_item; 130 Lisp_Object wv_closure, gui_item;
126 131 Lisp_Object question = Qnil, title = Qnil, buttons = Qnil;
127 CHECK_CONS (desc); 132
128 CHECK_STRING (XCAR (desc)); 133 {
129 name = (char *) XSTRING_DATA (LISP_GETTEXT (XCAR (desc))); 134 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
130 desc = XCDR (desc); 135 {
131 if (!CONSP (desc)) 136 if (EQ (key, Q_question))
132 error ("dialog boxes must have some buttons"); 137 {
138 CHECK_STRING (value);
139 question = value;
140 }
141 else if (EQ (key, Q_title))
142 {
143 CHECK_STRING (value);
144 title = value;
145 }
146 else if (EQ (key, Q_buttons))
147 {
148 CHECK_LIST (value);
149 buttons = value;
150 }
151 else
152 syntax_error ("Unrecognized question-dialog keyword", key);
153 }
154 }
155
156 if (NILP (question))
157 syntax_error ("Dialog descriptor provides no question", keys);
133 158
134 /* Inhibit GC during this conversion. The reasons for this are 159 /* Inhibit GC during this conversion. The reasons for this are
135 the same as in menu_item_descriptor_to_widget_value(); see 160 the same as in menu_item_descriptor_to_widget_value(); see
136 the large comment above that function. */ 161 the large comment above that function. */
137 162
145 tree on Lisp error. */ 170 tree on Lisp error. */
146 171
147 wv_closure = make_opaque_ptr (kids); 172 wv_closure = make_opaque_ptr (kids);
148 record_unwind_protect (widget_value_unwind, wv_closure); 173 record_unwind_protect (widget_value_unwind, wv_closure);
149 prev->name = xstrdup ("message"); 174 prev->name = xstrdup ("message");
150 prev->value = xstrdup (name); 175 LISP_STRING_TO_EXTERNAL_MALLOC (question, prev->value, Qlwlib_encoding);
151 prev->enabled = 1; 176 prev->enabled = 1;
152 177
153 for (; !NILP (desc); desc = Fcdr (desc)) 178 {
154 { 179 EXTERNAL_LIST_LOOP_2 (button, buttons)
155 Lisp_Object button = XCAR (desc); 180 {
156 widget_value *wv; 181 widget_value *wv;
157 182
158 if (NILP (button)) 183 if (NILP (button))
159 { 184 {
160 if (partition_seen) 185 if (partition_seen)
161 error ("more than one partition (nil) seen in dbox spec"); 186 syntax_error ("More than one partition (nil) seen in dbox spec",
162 partition_seen = 1; 187 keys);
163 continue; 188 partition_seen = 1;
164 } 189 continue;
165 CHECK_VECTOR (button); 190 }
166 wv = xmalloc_widget_value (); 191 CHECK_VECTOR (button);
167 192 wv = xmalloc_widget_value ();
168 gui_item = gui_parse_item_keywords (button); 193
169 if (!button_item_to_widget_value (gui_item, wv, allow_text_p, 1)) 194 gui_item = gui_parse_item_keywords (button);
170 { 195 if (!button_item_to_widget_value (Qdialog,
171 free_widget_value_tree (wv); 196 gui_item, wv, allow_text_p, 1, 0, 1))
172 continue; 197 {
173 } 198 free_widget_value_tree (wv);
174 199 continue;
175 if (wv->type == TEXT_TYPE) 200 }
176 { 201
177 text_field_p = 1; 202 if (wv->type == TEXT_TYPE)
178 allow_text_p = 0; /* only allow one */ 203 {
179 } 204 text_field_p = 1;
180 else /* it's a button */ 205 allow_text_p = 0; /* only allow one */
181 { 206 }
182 allow_text_p = 0; /* only allow text field at the front */ 207 else /* it's a button */
183 if (wv->value) xfree (wv->value); 208 {
184 wv->value = wv->name; /* what a mess... */ 209 allow_text_p = 0; /* only allow text field at the front */
185 wv->name = xstrdup (button_names [n]); 210 if (wv->value)
186 211 xfree (wv->value);
187 if (partition_seen) 212 wv->value = wv->name; /* what a mess... */
188 rbuttons++; 213 wv->name = xstrdup (button_names [n]);
189 else 214
190 lbuttons++; 215 if (partition_seen)
191 n++; 216 rbuttons++;
192 217 else
193 if (lbuttons > 9 || rbuttons > 9) 218 lbuttons++;
194 error ("too many buttons (9)"); /* #### this leaks */ 219 n++;
195 } 220
196 221 if (lbuttons > 9 || rbuttons > 9)
197 prev->next = wv; 222 syntax_error ("Too many buttons (9)",
198 prev = wv; 223 keys); /* #### this leaks */
199 } 224 }
225
226 prev->next = wv;
227 prev = wv;
228 }
229 }
200 230
201 if (n == 0) 231 if (n == 0)
202 error ("dialog boxes must have some buttons"); 232 syntax_error ("Dialog boxes must have some buttons", keys);
233
203 { 234 {
204 char type = (text_field_p ? 'P' : 'Q'); 235 Extbyte type = (text_field_p ? 'P' : 'Q');
236 static Extbyte tmp_dbox_name [255];
237
205 widget_value *dbox; 238 widget_value *dbox;
206 sprintf (tmp_dbox_name, "%c%dBR%d", type, lbuttons + rbuttons, rbuttons); 239 sprintf (tmp_dbox_name, "%c%dBR%d", type, lbuttons + rbuttons, rbuttons);
207 dbox = xmalloc_widget_value (); 240 dbox = xmalloc_widget_value ();
208 dbox->name = xstrdup (tmp_dbox_name); 241 dbox->name = xstrdup (tmp_dbox_name);
209 dbox->contents = kids; 242 dbox->contents = kids;
213 unbind_to (count, Qnil); 246 unbind_to (count, Qnil);
214 return dbox; 247 return dbox;
215 } 248 }
216 } 249 }
217 250
218 static void 251 static Lisp_Object
219 x_popup_dialog_box (struct frame* f, Lisp_Object dbox_desc) 252 x_make_dialog_box_internal (struct frame* f, Lisp_Object type,
253 Lisp_Object keys)
220 { 254 {
221 int dbox_id; 255 int dbox_id;
222 widget_value *data; 256 widget_value *data;
223 Widget parent, dbox; 257 Widget parent, dbox;
224 258
225 data = dbox_descriptor_to_widget_value (dbox_desc); 259 if (!EQ (type, Qquestion))
260 signal_type_error (Qunimplemented, "Dialog box type", type);
261
262 data = dbox_descriptor_to_widget_value (keys);
226 263
227 parent = FRAME_X_SHELL_WIDGET (f); 264 parent = FRAME_X_SHELL_WIDGET (f);
228 265
229 dbox_id = new_lwlib_id (); 266 dbox_id = new_lwlib_id ();
230 dbox = lw_create_widget (data->name, "dialog", dbox_id, data, parent, 1, 0, 267 dbox = lw_create_widget (data->name, "dialog", dbox_id, data, parent, 1, 0,
250 if (zmacs_regions) 287 if (zmacs_regions)
251 zmacs_region_stays = 1; 288 zmacs_region_stays = 1;
252 289
253 popup_up_p++; 290 popup_up_p++;
254 lw_pop_up_all_widgets (dbox_id); 291 lw_pop_up_all_widgets (dbox_id);
292
293 /* #### this could (theoretically) cause problems if we are up for
294 a REALLY REALLY long time -- too big to fit into lisp integer. */
295 return make_int (dbox_id);
255 } 296 }
256 297
257 void 298 void
258 syms_of_dialog_x (void) 299 syms_of_dialog_x (void)
259 { 300 {
260 } 301 }
261 302
262 void 303 void
263 console_type_create_dialog_x (void) 304 console_type_create_dialog_x (void)
264 { 305 {
265 CONSOLE_HAS_METHOD (x, popup_dialog_box); 306 CONSOLE_HAS_METHOD (x, make_dialog_box_internal);
266 } 307 }
267 308
268 void 309 void
269 vars_of_dialog_x (void) 310 vars_of_dialog_x (void)
270 { 311 {