comparison src/menubar-msw.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents a307f9a2021d
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Implements an elisp-programmable menubar -- Win32 1 /* Implements an elisp-programmable menubar -- Win32
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) 1997 Kirill M. Katsnelson <kkm@kis.ru>. 4 Copyright (C) 1997 Kirill M. Katsnelson <kkm@kis.ru>.
5 Copyright (C) 2000 Ben Wing. 5 Copyright (C) 2000, 2001 Ben Wing.
6 6
7 This file is part of XEmacs. 7 This file is part of XEmacs.
8 8
9 XEmacs is free software; you can redistribute it and/or modify it 9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the 10 under the terms of the GNU General Public License as published by the
20 along with XEmacs; see the file COPYING. If not, write to 20 along with XEmacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */ 22 Boston, MA 02111-1307, USA. */
23 23
24 /* Synched up with: Not in FSF. */ 24 /* Synched up with: Not in FSF. */
25
26 /* This function mostly Mule-ized (except perhaps some Unicode splitting).
27 5-2000. */
25 28
26 /* Author: 29 /* Author:
27 Initially written by kkm 12/24/97, 30 Initially written by kkm 12/24/97,
28 peeking into and copying stuff from menubar-x.c 31 peeking into and copying stuff from menubar-x.c
29 */ 32 */
94 97
95 /* #### */ 98 /* #### */
96 #define REPLACE_ME_WITH_GLOBAL_VARIABLE_WHICH_CONTROLS_RIGHT_FLUSH 0 99 #define REPLACE_ME_WITH_GLOBAL_VARIABLE_WHICH_CONTROLS_RIGHT_FLUSH 0
97 100
98 #define EMPTY_ITEM_ID ((UINT)LISP_TO_VOID (Qunbound)) 101 #define EMPTY_ITEM_ID ((UINT)LISP_TO_VOID (Qunbound))
99 #define EMPTY_ITEM_NAME "(empty)" 102 #define EMPTY_ITEM_NAME "(empty)" /* WARNING: uses of this need XETEXT */
100 103
101 /* Current menu (bar or popup) descriptor. gcpro'ed */ 104 /* Current menu (bar or popup) descriptor. gcpro'ed */
102 static Lisp_Object current_menudesc; 105 static Lisp_Object current_menudesc;
103 106
104 /* Current menubar or popup hash table. gcpro'ed */ 107 /* Current menubar or popup hash table. gcpro'ed */
115 #define MENU_ITEM_ID_MAX 0xFFFF 118 #define MENU_ITEM_ID_MAX 0xFFFF
116 #define MENU_ITEM_ID_BITS(x) (((x) & 0x7FFF) | 0x8000) 119 #define MENU_ITEM_ID_BITS(x) (((x) & 0x7FFF) | 0x8000)
117 static HMENU top_level_menu; 120 static HMENU top_level_menu;
118 121
119 /* 122 /*
120 * Translate (in place) X accelerator syntax to win32 accelerator syntax. 123 * Translate X accelerator syntax to win32 accelerator syntax.
121 * Return new length.
122 * len = number of bytes (not including zero terminator).
123 * maxlen = size of buffer.
124 * accel = (Emchar*) to receive the accelerator character 124 * accel = (Emchar*) to receive the accelerator character
125 * or NULL to suppress accelerators in the menu or dialog item. 125 * or NULL to suppress accelerators in the menu or dialog item.
126 * 126 *
127 * %% is replaced with % 127 * %% is replaced with %
128 * if accel is NULL: 128 * if accel is NULL:
130 * if accel is non-NULL: 130 * if accel is non-NULL:
131 * %_ is replaced with &. 131 * %_ is replaced with &.
132 * The accelerator character is passed back in *accel. 132 * The accelerator character is passed back in *accel.
133 * (If there is no accelerator, it will be added on the first character.) 133 * (If there is no accelerator, it will be added on the first character.)
134 * 134 *
135 * We assume and maintain zero-termination. To be absolutely sure
136 * of not hitting an error, maxlen should be >= 2*len + 3.
137 */ 135 */
138 Bytecount 136
139 mswindows_translate_menu_or_dialog_item (Intbyte *item, Bytecount len, 137 Lisp_Object
140 Bytecount maxlen, Emchar *accel, 138 mswindows_translate_menu_or_dialog_item (Lisp_Object item, Emchar *accel)
141 Lisp_Object error_name) 139 {
142 { 140 Bytecount len = XSTRING_LENGTH (item);
143 Intbyte *ptr; 141 Intbyte *it = (Intbyte *) alloca (2 * len + 42), *ptr = it;
144 142
143 memcpy (ptr, XSTRING_DATA (item), len + 1);
145 if (accel) 144 if (accel)
146 *accel = '\0'; 145 *accel = '\0';
147 146
148 /* Escape '&' as '&&' */ 147 /* Escape '&' as '&&' */
149 ptr = item; 148
150 while ((ptr = (Intbyte *) memchr (ptr, '&', len - (ptr - item))) != NULL) 149 while ((ptr = (Intbyte *) memchr (ptr, '&', len - (ptr - it))) != NULL)
151 { 150 {
152 if (len + 2 > maxlen) 151 memmove (ptr + 1, ptr, (len - (ptr - it)) + 1);
153 invalid_argument ("Menu item produces too long displayable string",
154 error_name);
155 memmove (ptr + 1, ptr, (len - (ptr - item)) + 1);
156 len++; 152 len++;
157 ptr += 2; 153 ptr += 2;
158 } 154 }
159 155
160 /* Replace XEmacs accelerator '%_' with Windows accelerator '&' 156 /* Replace XEmacs accelerator '%_' with Windows accelerator '&'
161 and `%%' with `%'. */ 157 and `%%' with `%'. */
162 ptr = item; 158 ptr = it;
163 while ((ptr = (Intbyte *) memchr (ptr, '%', len - (ptr - item))) != NULL) 159 while ((ptr = (Intbyte *) memchr (ptr, '%', len - (ptr - it))) != NULL)
164 { 160 {
165 if (*(ptr + 1) == '_') 161 if (*(ptr + 1) == '_')
166 { 162 {
167 if (accel) 163 if (accel)
168 { 164 {
169 *ptr = '&'; 165 *ptr = '&';
170 if (!*accel) 166 if (!*accel)
171 /* #### urk ! We need a reference translation table for 167 *accel = DOWNCASE (0, charptr_emchar (ptr + 2));
172 case changes that aren't buffer-specific. */ 168 memmove (ptr + 1, ptr + 2, len - (ptr - it + 2) + 1);
173 *accel = DOWNCASE (current_buffer, charptr_emchar (ptr + 2));
174 memmove (ptr + 1, ptr + 2, len - (ptr - item + 2) + 1);
175 len--; 169 len--;
176 } 170 }
177 else /* Skip accelerator */ 171 else /* Skip accelerator */
178 { 172 {
179 memmove (ptr, ptr + 2, len - (ptr - item + 2) + 1); 173 memmove (ptr, ptr + 2, len - (ptr - it + 2) + 1);
180 len-=2; 174 len -= 2;
181 } 175 }
182 } 176 }
183 else if (*(ptr + 1) == '%') 177 else if (*(ptr + 1) == '%')
184 { 178 {
185 memmove (ptr + 1, ptr + 2, len - (ptr - item + 2) + 1); 179 memmove (ptr + 1, ptr + 2, len - (ptr - it + 2) + 1);
186 len--; 180 len--;
187 ptr++; 181 ptr++;
188 } 182 }
189 else /* % on its own - shouldn't happen */ 183 else /* % on its own - shouldn't happen */
190 ptr++; 184 ptr++;
191 } 185 }
192 186
193 if (accel && !*accel) 187 if (accel && !*accel)
194 { 188 {
195 /* Force a default accelerator */ 189 /* Force a default accelerator */
196 if (len + 2 > maxlen) 190 ptr = it;
197 invalid_argument ("Menu item produces too long displayable string",
198 error_name);
199 ptr = item;
200 memmove (ptr + 1, ptr, len + 1); 191 memmove (ptr + 1, ptr, len + 1);
201 /* #### urk ! We need a reference translation table for 192 *accel = DOWNCASE (0, charptr_emchar (ptr + 1));
202 case changes that aren't buffer-specific. */
203 *accel = DOWNCASE (current_buffer, charptr_emchar (ptr + 1));
204 *ptr = '&'; 193 *ptr = '&';
205 194
206 len++; 195 len++;
207 } 196 }
208 197
209 return len; 198 return make_string (it, len);
210 } 199 }
211 200
212 /* 201 /*
213 * This returns Windows-style menu item string: 202 * This returns Windows-style menu item string:
214 * "Left Flush\tRight Flush" 203 * "Left Flush\tRight Flush"
215 */ 204 */
216 205
217 /* #### This is junk. Need correct handling of sizes. Use a Intbyte_dynarr, 206 static Lisp_Object
218 not a static buffer. */
219 static char*
220 displayable_menu_item (Lisp_Object gui_item, int bar_p, Emchar *accel) 207 displayable_menu_item (Lisp_Object gui_item, int bar_p, Emchar *accel)
221 { 208 {
222 Bytecount ll; 209 Lisp_Object left, right = Qnil;
223
224 /* We construct the name in a static buffer. That's fine, because
225 menu items longer than 128 chars are probably programming errors,
226 and better be caught than displayed! */
227
228 static char buf[MAX_MENUITEM_LENGTH+2];
229 210
230 /* Left flush part of the string */ 211 /* Left flush part of the string */
231 ll = gui_item_display_flush_left (gui_item, buf, MAX_MENUITEM_LENGTH); 212 left = gui_item_display_flush_left (gui_item);
232 213
233 ll = mswindows_translate_menu_or_dialog_item ((Intbyte *) buf, ll, 214 left = mswindows_translate_menu_or_dialog_item (left, accel);
234 MAX_MENUITEM_LENGTH, accel,
235 XGUI_ITEM (gui_item)->name);
236 215
237 /* Right flush part, unless we're at the top-level where it's not allowed */ 216 /* Right flush part, unless we're at the top-level where it's not allowed */
238 if (!bar_p) 217 if (!bar_p)
239 { 218 right = gui_item_display_flush_right (gui_item);
240 Bytecount lr; 219
241 220 if (!NILP (right))
242 assert (MAX_MENUITEM_LENGTH > ll + 1); 221 return concat3 (left, build_string ("\t"), right);
243 lr = gui_item_display_flush_right (gui_item, buf + ll + 1, 222 else
244 MAX_MENUITEM_LENGTH - ll - 1); 223 return left;
245 if (lr)
246 buf [ll] = '\t';
247 }
248
249 return buf;
250 } 224 }
251 225
252 /* 226 /*
253 * hmenu_to_lisp_object() returns an opaque ptr given menu handle. 227 * hmenu_to_lisp_object() returns an opaque ptr given menu handle.
254 */ 228 */
284 static void 258 static void
285 empty_menu (HMENU menu, int add_empty_p) 259 empty_menu (HMENU menu, int add_empty_p)
286 { 260 {
287 while (DeleteMenu (menu, 0, MF_BYPOSITION)); 261 while (DeleteMenu (menu, 0, MF_BYPOSITION));
288 if (add_empty_p) 262 if (add_empty_p)
289 AppendMenu (menu, MF_STRING | MF_GRAYED, EMPTY_ITEM_ID, EMPTY_ITEM_NAME); 263 qxeAppendMenu (menu, MF_STRING | MF_GRAYED, EMPTY_ITEM_ID,
264 XETEXT (EMPTY_ITEM_NAME));
290 } 265 }
291 266
292 /* 267 /*
293 * The idea of checksumming is that we must hash minimal object 268 * The idea of checksumming is that we must hash minimal object
294 * which is necessarily changes when the item changes. For separator 269 * which is necessarily changes when the item changes. For separator
310 return internal_hash (item, 0) + 13; 285 return internal_hash (item, 0) + 13;
311 } 286 }
312 else if (CONSP (item)) 287 else if (CONSP (item))
313 { 288 {
314 /* Submenu - hash by its string name + 0 */ 289 /* Submenu - hash by its string name + 0 */
315 return internal_hash (XCAR(item), 0); 290 return internal_hash (XCAR (item), 0);
316 } 291 }
317 else if (VECTORP (item)) 292 else if (VECTORP (item))
318 { 293 {
319 /* An ordinary item - hash its name and callback form. */ 294 /* An ordinary item - hash its name and callback form. */
320 return HASH2 (internal_hash (XVECTOR_DATA(item)[0], 0), 295 return HASH2 (internal_hash (XVECTOR_DATA(item)[0], 0),
329 populate_menu_add_item (HMENU menu, Lisp_Object path, 304 populate_menu_add_item (HMENU menu, Lisp_Object path,
330 Lisp_Object hash_tab, Lisp_Object item, 305 Lisp_Object hash_tab, Lisp_Object item,
331 Lisp_Object *accel_list, 306 Lisp_Object *accel_list,
332 int flush_right, int bar_p) 307 int flush_right, int bar_p)
333 { 308 {
334 MENUITEMINFO item_info; 309 MENUITEMINFOW item_info;
335 UINT oldflags = MF_BYPOSITION;
336 UINT olduidnewitem = 0;
337 LPCTSTR oldlpnewitem = 0;
338 310
339 item_info.cbSize = sizeof (item_info); 311 item_info.cbSize = sizeof (item_info);
340 item_info.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID; 312 item_info.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
341 item_info.fState = 0; 313 item_info.fState = 0;
342 item_info.wID = 0; 314 item_info.wID = 0;
344 316
345 if (STRINGP (item)) 317 if (STRINGP (item))
346 { 318 {
347 /* Separator or unselectable text */ 319 /* Separator or unselectable text */
348 if (separator_string_p (XSTRING_DATA (item))) 320 if (separator_string_p (XSTRING_DATA (item)))
349 { 321 item_info.fType = MFT_SEPARATOR;
350 item_info.fType = MFT_SEPARATOR;
351 oldflags |= MF_SEPARATOR;
352 }
353 else 322 else
354 { 323 {
324 Extbyte *itemext;
325
355 item_info.fType = MFT_STRING; 326 item_info.fType = MFT_STRING;
356 item_info.fState = MFS_DISABLED; 327 item_info.fState = MFS_DISABLED;
357 /* !!#### mule-bogosity, fixed in my mule ws */ 328 LISP_STRING_TO_TSTR (item, itemext);
358 item_info.dwTypeData = (Extbyte *) XSTRING_DATA (item); 329 item_info.dwTypeData = (XELPTSTR) itemext;
359 oldflags |= MF_STRING | MF_DISABLED;
360 oldlpnewitem = item_info.dwTypeData;
361 } 330 }
362 } 331 }
363 else if (CONSP (item)) 332 else if (CONSP (item))
364 { 333 {
365 /* Submenu */ 334 /* Submenu */
366 HMENU submenu; 335 HMENU submenu;
367 Lisp_Object gui_item = allocate_gui_item (); 336 Lisp_Object gui_item = allocate_gui_item ();
368 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item); 337 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item);
369 struct gcpro gcpro1, gcpro2, gcpro3; 338 struct gcpro gcpro1, gcpro2, gcpro3;
370 Emchar accel; 339 Emchar accel;
340 Extbyte *itemext;
371 341
372 GCPRO3 (gui_item, path, *accel_list); 342 GCPRO3 (gui_item, path, *accel_list);
373 343
374 menu_parse_submenu_keywords (item, gui_item); 344 menu_parse_submenu_keywords (item, gui_item);
375 345
382 UNGCPRO; 352 UNGCPRO;
383 goto done; 353 goto done;
384 } 354 }
385 355
386 if (!gui_item_active_p (gui_item)) 356 if (!gui_item_active_p (gui_item))
387 { 357 item_info.fState = MFS_GRAYED;
388 item_info.fState = MFS_GRAYED;
389 oldflags |= MF_GRAYED;
390 }
391 /* Temptation is to put 'else' right here. Although, the 358 /* Temptation is to put 'else' right here. Although, the
392 displayed item won't have an arrow indicating that it is a 359 displayed item won't have an arrow indicating that it is a
393 popup. So we go ahead a little bit more and create a popup */ 360 popup. So we go ahead a little bit more and create a popup */
394 submenu = create_empty_popup_menu (); 361 submenu = create_empty_popup_menu ();
395 362
396 item_info.fMask |= MIIM_SUBMENU; 363 item_info.fMask |= MIIM_SUBMENU;
397 item_info.dwTypeData = displayable_menu_item (gui_item, bar_p, &accel); 364 LISP_STRING_TO_TSTR (displayable_menu_item (gui_item, bar_p, &accel),
365 itemext);
366 item_info.dwTypeData = (XELPTSTR) itemext;
398 item_info.hSubMenu = submenu; 367 item_info.hSubMenu = submenu;
399 olduidnewitem = (UINT) submenu;
400 oldlpnewitem = item_info.dwTypeData;
401 oldflags |= MF_POPUP;
402 368
403 if (accel && bar_p) 369 if (accel && bar_p)
404 *accel_list = Fcons (make_char (accel), *accel_list); 370 *accel_list = Fcons (make_char (accel), *accel_list);
405 371
406 if (!(item_info.fState & MFS_GRAYED)) 372 if (!(item_info.fState & MFS_GRAYED))
427 Lisp_Object style, id; 393 Lisp_Object style, id;
428 Lisp_Object gui_item = gui_parse_item_keywords (item); 394 Lisp_Object gui_item = gui_parse_item_keywords (item);
429 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item); 395 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item);
430 struct gcpro gcpro1, gcpro2; 396 struct gcpro gcpro1, gcpro2;
431 Emchar accel; 397 Emchar accel;
398 Extbyte *itemext;
432 399
433 GCPRO2 (gui_item, *accel_list); 400 GCPRO2 (gui_item, *accel_list);
434 401
435 if (!gui_item_included_p (gui_item, Vmenubar_configuration)) 402 if (!gui_item_included_p (gui_item, Vmenubar_configuration))
436 { 403 {
440 407
441 if (!STRINGP (pgui_item->name)) 408 if (!STRINGP (pgui_item->name))
442 pgui_item->name = Feval (pgui_item->name); 409 pgui_item->name = Feval (pgui_item->name);
443 410
444 if (!gui_item_active_p (gui_item)) 411 if (!gui_item_active_p (gui_item))
445 { 412 item_info.fState = MFS_GRAYED;
446 item_info.fState = MFS_GRAYED;
447 oldflags = MF_GRAYED;
448 }
449 413
450 style = (NILP (pgui_item->selected) || NILP (Feval (pgui_item->selected)) 414 style = (NILP (pgui_item->selected) || NILP (Feval (pgui_item->selected))
451 ? Qnil : pgui_item->style); 415 ? Qnil : pgui_item->style);
452 416
453 if (EQ (style, Qradio)) 417 if (EQ (style, Qradio))
454 { 418 {
455 item_info.fType |= MFT_RADIOCHECK; 419 item_info.fType |= MFT_RADIOCHECK;
456 item_info.fState |= MFS_CHECKED; 420 item_info.fState |= MFS_CHECKED;
457 oldflags |= MF_CHECKED; /* Can't support radio-button checkmarks
458 under 3.51 */
459 } 421 }
460 else if (EQ (style, Qtoggle)) 422 else if (EQ (style, Qtoggle))
461 { 423 item_info.fState |= MFS_CHECKED;
462 item_info.fState |= MFS_CHECKED;
463 oldflags |= MF_CHECKED;
464 }
465 424
466 id = allocate_menu_item_id (path, pgui_item->name, 425 id = allocate_menu_item_id (path, pgui_item->name,
467 pgui_item->suffix); 426 pgui_item->suffix);
468 Fputhash (id, pgui_item->callback, hash_tab); 427 Fputhash (id, pgui_item->callback, hash_tab);
469 428
470 item_info.wID = (UINT) XINT (id); 429 item_info.wID = (UINT) XINT (id);
471 item_info.fType |= MFT_STRING; 430 item_info.fType |= MFT_STRING;
472 item_info.dwTypeData = displayable_menu_item (gui_item, bar_p, &accel); 431 LISP_STRING_TO_TSTR (displayable_menu_item (gui_item, bar_p, &accel),
473 olduidnewitem = item_info.wID; 432 itemext);
474 oldflags |= MF_STRING; 433 item_info.dwTypeData = (XELPTSTR) itemext;
475 oldlpnewitem = item_info.dwTypeData;
476 434
477 if (accel && bar_p) 435 if (accel && bar_p)
478 *accel_list = Fcons (make_char (accel), *accel_list); 436 *accel_list = Fcons (make_char (accel), *accel_list);
479 437
480 UNGCPRO; 438 UNGCPRO;
481 } 439 }
482 else 440 else
483 sferror ("Malformed menu item descriptor", item); 441 sferror ("Malformed menu item descriptor", item);
484 442
485 if (flush_right) 443 if (flush_right)
486 item_info.fType |= MFT_RIGHTJUSTIFY; /* can't support in 3.51 */ 444 item_info.fType |= MFT_RIGHTJUSTIFY;
487 445
488 if (xInsertMenuItemA) 446 qxeInsertMenuItem (menu, UINT_MAX, TRUE, &item_info);
489 xInsertMenuItemA (menu, UINT_MAX, TRUE, &item_info);
490 else
491 InsertMenu (menu, UINT_MAX, oldflags, olduidnewitem, oldlpnewitem);
492 447
493 done:; 448 done:;
494 } 449 }
495 450
496 /* 451 /*
571 /* Add the header to the popup, if told so. The same as in X - an 526 /* Add the header to the popup, if told so. The same as in X - an
572 insensitive item, and a separator (Seems to me, there were 527 insensitive item, and a separator (Seems to me, there were
573 two separators in X... In Windows this looks ugly, anyways.) */ 528 two separators in X... In Windows this looks ugly, anyways.) */
574 if (!bar_p && !deep_p && popup_menu_titles && !NILP (pgui_item->name)) 529 if (!bar_p && !deep_p && popup_menu_titles && !NILP (pgui_item->name))
575 { 530 {
576 CHECK_STRING (pgui_item->name); 531 Extbyte *nameext;
577 InsertMenu (menu, 0, MF_BYPOSITION | MF_STRING | MF_DISABLED, 532
578 0, displayable_menu_item (gui_item, bar_p, NULL)); 533 LISP_STRING_TO_TSTR (displayable_menu_item (gui_item, bar_p, NULL),
579 InsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); 534 nameext);
580 if (xSetMenuDefaultItem) /* not in NT 3.5x */ 535 qxeInsertMenu (menu, 0, MF_BYPOSITION | MF_STRING | MF_DISABLED,
581 xSetMenuDefaultItem (menu, 0, MF_BYPOSITION); 536 0, nameext);
537 qxeInsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
538 SetMenuDefaultItem (menu, 0, MF_BYPOSITION);
582 } 539 }
583 } 540 }
584 541
585 if (bar_p) 542 if (bar_p)
586 Fputhash (Qt, accel_list, hash_tab); 543 Fputhash (Qt, accel_list, hash_tab);
719 { 676 {
720 Lisp_Object hash = FRAME_MSWINDOWS_MENU_HASH_TABLE (f); 677 Lisp_Object hash = FRAME_MSWINDOWS_MENU_HASH_TABLE (f);
721 678
722 if (NILP (hash)) 679 if (NILP (hash))
723 return 0; 680 return 0;
724 /* !!#### not Mule-ized */ 681 return !NILP (memq_no_quit
725 return !NILP (memq_no_quit (make_char (tolower (ch)), 682 (make_char
726 Fgethash (Qt, hash, Qnil))); 683 (DOWNCASE (WINDOW_XBUFFER (FRAME_SELECTED_XWINDOW (f)), ch)),
684 Fgethash (Qt, hash, Qnil)));
727 } 685 }
728 686
729 687
730 /*------------------------------------------------------------------------*/ 688 /*------------------------------------------------------------------------*/
731 /* Message handlers */ 689 /* Message handlers */
819 get_gui_callback (data, &fn, &arg); 777 get_gui_callback (data, &fn, &arg);
820 XSETFRAME (frame, f); 778 XSETFRAME (frame, f);
821 /* this used to call mswindows_enqueue_misc_user_event but that 779 /* this used to call mswindows_enqueue_misc_user_event but that
822 breaks customize because the misc_event gets eval'ed in some 780 breaks customize because the misc_event gets eval'ed in some
823 circumstances. Don't change it back unless you can fix the 781 circumstances. Don't change it back unless you can fix the
824 customize problem also.*/ 782 customize problem also. */
825 mswindows_enqueue_misc_user_event (frame, fn, arg); 783 mswindows_enqueue_misc_user_event (frame, fn, arg);
826 784
827 UNGCPRO; /* data */ 785 UNGCPRO; /* data */
828 return Qt; 786 return Qt;
829 } 787 }
970 menu_cleanup (f); 928 menu_cleanup (f);
971 invalid_operation ("Cannot track popup menu while in menu", 929 invalid_operation ("Cannot track popup menu while in menu",
972 menu_desc); 930 menu_desc);
973 } 931 }
974 UNGCPRO; 932 UNGCPRO;
975
976 return Qnil;
977 } 933 }
978 934
979 935
980 /*------------------------------------------------------------------------*/ 936 /*------------------------------------------------------------------------*/
981 /* Initialization */ 937 /* Initialization */