Mercurial > hg > xemacs-beta
comparison src/menubar-msw.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | a4f53d9b3154 |
children | 6240c7796c7a |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
128 /* We construct the name in a static buffer. That's fine, beause | 128 /* We construct the name in a static buffer. That's fine, beause |
129 menu items longer than 128 chars are probably programming errors, | 129 menu items longer than 128 chars are probably programming errors, |
130 and better be caught than displayed! */ | 130 and better be caught than displayed! */ |
131 | 131 |
132 static char buf[MAX_MENUITEM_LENGTH+2]; | 132 static char buf[MAX_MENUITEM_LENGTH+2]; |
133 char *ptr; | |
134 unsigned int ll, lr; | 133 unsigned int ll, lr; |
135 | 134 |
136 /* Left flush part of the string */ | 135 /* Left flush part of the string */ |
137 ll = gui_item_display_flush_left (pgui_item, buf, MAX_MENUITEM_LENGTH); | 136 ll = gui_item_display_flush_left (pgui_item, buf, MAX_MENUITEM_LENGTH); |
138 | |
139 /* Escape '&' as '&&' */ | |
140 ptr = buf; | |
141 while ((ptr=memchr (ptr, '&', ll-(ptr-buf))) != NULL) | |
142 { | |
143 if (ll+2 >= MAX_MENUITEM_LENGTH) | |
144 signal_simple_error ("Menu item produces too long displayable string", | |
145 pgui_item->name); | |
146 memmove (ptr+1, ptr, (ll-(ptr-buf))+1); | |
147 ll++; | |
148 ptr+=2; | |
149 } | |
150 | |
151 /* Replace XEmacs accelerator '%_' with Windows accelerator '&' */ | |
152 ptr = buf; | |
153 while ((ptr=memchr (ptr, '%', ll-(ptr-buf))) != NULL) | |
154 { | |
155 if (*(ptr+1) == '_') | |
156 { | |
157 *ptr = '&'; | |
158 memmove (ptr+1, ptr+2, ll-(ptr-buf+2)); | |
159 ll--; | |
160 } | |
161 ptr++; | |
162 } | |
163 | 137 |
164 /* Right flush part */ | 138 /* Right flush part */ |
165 assert (MAX_MENUITEM_LENGTH > ll + 1); | 139 assert (MAX_MENUITEM_LENGTH > ll + 1); |
166 lr = gui_item_display_flush_right (pgui_item, buf + ll + 1, | 140 lr = gui_item_display_flush_right (pgui_item, buf + ll + 1, |
167 MAX_MENUITEM_LENGTH - ll - 1); | 141 MAX_MENUITEM_LENGTH - ll - 1); |
275 { | 249 { |
276 /* Submenu */ | 250 /* Submenu */ |
277 HMENU submenu; | 251 HMENU submenu; |
278 struct gui_item gui_item; | 252 struct gui_item gui_item; |
279 struct gcpro gcpro1; | 253 struct gcpro gcpro1; |
280 struct gcpro ngcpro1; | |
281 | 254 |
282 gui_item_init (&gui_item); | 255 gui_item_init (&gui_item); |
283 GCPRO_GUI_ITEM (&gui_item); | 256 GCPRO_GUI_ITEM (&gui_item); |
284 NGCPRO1 (path); | |
285 | 257 |
286 menu_parse_submenu_keywords (item, &gui_item); | 258 menu_parse_submenu_keywords (item, &gui_item); |
287 | 259 |
288 if (!STRINGP (gui_item.name)) | 260 if (!STRINGP (gui_item.name)) |
289 signal_simple_error ("Menu name (first element) must be a string", item); | 261 signal_simple_error ("Menu name (first element) must be a string", item); |
290 | 262 |
291 if (!gui_item_included_p (&gui_item, Vmenubar_configuration)) | 263 if (!gui_item_included_p (&gui_item, Vmenubar_configuration)) |
292 { | 264 return; |
293 NUNGCPRO; | |
294 UNGCPRO; | |
295 return; | |
296 } | |
297 | 265 |
298 if (!gui_item_active_p (&gui_item)) | 266 if (!gui_item_active_p (&gui_item)) |
299 item_info.fState = MFS_GRAYED; | 267 item_info.fState = MFS_GRAYED; |
300 /* Temptation is to put 'else' right here. Although, the | 268 /* Temptation is to put 'else' right here. Although, the |
301 displayed item won't have an arrow indicating that it is a | 269 displayed item won't have an arrow indicating that it is a |
323 } | 291 } |
324 | 292 |
325 /* Fputhash GCPRO'es PATH */ | 293 /* Fputhash GCPRO'es PATH */ |
326 Fputhash (hmenu_to_lisp_object (submenu), path, hash_tab); | 294 Fputhash (hmenu_to_lisp_object (submenu), path, hash_tab); |
327 } | 295 } |
328 NUNGCPRO; | |
329 UNGCPRO; /* gui_item */ | 296 UNGCPRO; /* gui_item */ |
330 } | 297 } |
331 else if (VECTORP (item)) | 298 else if (VECTORP (item)) |
332 { | 299 { |
333 /* An ordinary item */ | 300 /* An ordinary item */ |
339 GCPRO_GUI_ITEM (&gui_item); | 306 GCPRO_GUI_ITEM (&gui_item); |
340 | 307 |
341 gui_parse_item_keywords (item, &gui_item); | 308 gui_parse_item_keywords (item, &gui_item); |
342 | 309 |
343 if (!gui_item_included_p (&gui_item, Vmenubar_configuration)) | 310 if (!gui_item_included_p (&gui_item, Vmenubar_configuration)) |
344 { | 311 return; |
345 UNGCPRO; | |
346 return; | |
347 } | |
348 | 312 |
349 if (!gui_item_active_p (&gui_item)) | 313 if (!gui_item_active_p (&gui_item)) |
350 item_info.fState = MFS_GRAYED; | 314 item_info.fState = MFS_GRAYED; |
351 | 315 |
352 style = (NILP (gui_item.selected) || NILP (Feval (gui_item.selected)) | 316 style = (NILP (gui_item.selected) || NILP (Feval (gui_item.selected)) |
401 Lisp_Object item_desc; | 365 Lisp_Object item_desc; |
402 int deep_p, flush_right; | 366 int deep_p, flush_right; |
403 struct gcpro gcpro1; | 367 struct gcpro gcpro1; |
404 unsigned long checksum; | 368 unsigned long checksum; |
405 struct gui_item gui_item; | 369 struct gui_item gui_item; |
406 struct gcpro ngcpro1; | |
407 | 370 |
408 gui_item_init (&gui_item); | 371 gui_item_init (&gui_item); |
409 GCPRO_GUI_ITEM (&gui_item); | 372 GCPRO_GUI_ITEM (&gui_item); |
410 NGCPRO1 (desc); | |
411 | 373 |
412 /* We are sometimes called with the menubar unchanged, and with changed | 374 /* We are sometimes called with the menubar unchanged, and with changed |
413 right flush. We have to update the menubar in ths case, | 375 right flush. We have to update the menubar in ths case, |
414 so account for the compliance setting in the hash value */ | 376 so account for the compliance setting in the hash value */ |
415 checksum = REPLACE_ME_WITH_GLOBAL_VARIABLE_WHICH_CONTROLS_RIHGT_FLUSH; | 377 checksum = REPLACE_ME_WITH_GLOBAL_VARIABLE_WHICH_CONTROLS_RIHGT_FLUSH; |
468 0, XSTRING_DATA(gui_item.name)); | 430 0, XSTRING_DATA(gui_item.name)); |
469 InsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); | 431 InsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); |
470 SetMenuDefaultItem (menu, 0, MF_BYPOSITION); | 432 SetMenuDefaultItem (menu, 0, MF_BYPOSITION); |
471 } | 433 } |
472 } | 434 } |
473 NUNGCPRO; | |
474 UNGCPRO; /* gui_item */ | 435 UNGCPRO; /* gui_item */ |
475 return checksum; | 436 return checksum; |
476 } | 437 } |
477 | 438 |
478 static void | 439 static void |
494 HMENU menubar = GetMenu (FRAME_MSWINDOWS_HANDLE (f)); | 455 HMENU menubar = GetMenu (FRAME_MSWINDOWS_HANDLE (f)); |
495 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); | 456 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); |
496 Lisp_Object desc = (!NILP (w->menubar_visible_p) | 457 Lisp_Object desc = (!NILP (w->menubar_visible_p) |
497 ? symbol_value_in_buffer (Qcurrent_menubar, w->buffer) | 458 ? symbol_value_in_buffer (Qcurrent_menubar, w->buffer) |
498 : Qnil); | 459 : Qnil); |
499 struct gcpro gcpro1; | |
500 | |
501 GCPRO1 (desc); /* it's safest to do this, just in case some filter | |
502 or something changes the value of current-menubar */ | |
503 | 460 |
504 top_level_menu = menubar; | 461 top_level_menu = menubar; |
505 | 462 |
506 if (NILP (desc) && menubar != NULL) | 463 if (NILP (desc) && menubar != NULL) |
507 { | 464 { |
508 /* Menubar has gone */ | 465 /* Menubar has gone */ |
509 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil; | 466 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil; |
510 SetMenu (FRAME_MSWINDOWS_HANDLE (f), NULL); | 467 SetMenu (FRAME_MSWINDOWS_HANDLE (f), NULL); |
511 DestroyMenu (menubar); | 468 DestroyMenu (menubar); |
512 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); | 469 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); |
513 UNGCPRO; | |
514 return; | 470 return; |
515 } | 471 } |
516 | 472 |
517 if (!NILP (desc) && menubar == NULL) | 473 if (!NILP (desc) && menubar == NULL) |
518 { | 474 { |
522 } | 478 } |
523 | 479 |
524 if (NILP (desc)) | 480 if (NILP (desc)) |
525 { | 481 { |
526 /* We did not have the bar and are not going to */ | 482 /* We did not have the bar and are not going to */ |
527 UNGCPRO; | |
528 return; | 483 return; |
529 } | 484 } |
530 | 485 |
531 /* Now we bail out if the menubar has not changed */ | 486 /* Now we bail out if the menubar has not changed */ |
532 if (FRAME_MSWINDOWS_MENU_CHECKSUM(f) == checksum_menu (desc)) | 487 if (FRAME_MSWINDOWS_MENU_CHECKSUM(f) == checksum_menu (desc)) |
533 { | 488 return; |
534 UNGCPRO; | |
535 return; | |
536 } | |
537 | 489 |
538 populate: | 490 populate: |
539 /* Come with empty hash table */ | 491 /* Come with empty hash table */ |
540 if (NILP (FRAME_MSWINDOWS_MENU_HASHTABLE(f))) | 492 if (NILP (FRAME_MSWINDOWS_MENU_HASHTABLE(f))) |
541 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Fmake_hashtable (make_int (50), Qequal); | 493 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Fmake_hashtable (make_int (50), Qequal); |
548 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1); | 500 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1); |
549 SetMenu (FRAME_MSWINDOWS_HANDLE (f), menubar); | 501 SetMenu (FRAME_MSWINDOWS_HANDLE (f), menubar); |
550 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); | 502 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); |
551 | 503 |
552 FRAME_MSWINDOWS_MENU_CHECKSUM(f) = checksum_menu (desc); | 504 FRAME_MSWINDOWS_MENU_CHECKSUM(f) = checksum_menu (desc); |
553 | |
554 UNGCPRO; | |
555 } | 505 } |
556 | 506 |
557 static void | 507 static void |
558 prune_menubar (struct frame *f) | 508 prune_menubar (struct frame *f) |
559 { | 509 { |
560 HMENU menubar = GetMenu (FRAME_MSWINDOWS_HANDLE (f)); | 510 HMENU menubar = GetMenu (FRAME_MSWINDOWS_HANDLE (f)); |
561 Lisp_Object desc = current_frame_menubar (f); | 511 Lisp_Object desc = current_frame_menubar (f); |
562 struct gcpro gcpro1; | |
563 | |
564 if (menubar == NULL) | 512 if (menubar == NULL) |
565 return; | 513 return; |
566 | 514 |
567 /* #### If a filter function has set desc to Qnil, this abort() | 515 /* #### If a filter function has set desc to Qnil, this abort() |
568 triggers. To resolve, we must prevent filters explicitely from | 516 triggers. To resolve, we must prevent filters explicitely from |
570 Is copy-tree on the whole menu too expensive? */ | 518 Is copy-tree on the whole menu too expensive? */ |
571 if (NILP(desc)) | 519 if (NILP(desc)) |
572 /* abort(); */ | 520 /* abort(); */ |
573 return; | 521 return; |
574 | 522 |
575 GCPRO1 (desc); /* just to be safe -- see above */ | |
576 /* We do the trick by removing all items and re-populating top level */ | 523 /* We do the trick by removing all items and re-populating top level */ |
577 empty_menu (menubar, 0); | 524 empty_menu (menubar, 0); |
578 | 525 |
579 assert (HASHTABLEP (FRAME_MSWINDOWS_MENU_HASHTABLE(f))); | 526 assert (HASHTABLEP (FRAME_MSWINDOWS_MENU_HASHTABLE(f))); |
580 Fclrhash (FRAME_MSWINDOWS_MENU_HASHTABLE(f)); | 527 Fclrhash (FRAME_MSWINDOWS_MENU_HASHTABLE(f)); |
581 | 528 |
582 Fputhash (hmenu_to_lisp_object (menubar), Qnil, | 529 Fputhash (hmenu_to_lisp_object (menubar), Qnil, |
583 FRAME_MSWINDOWS_MENU_HASHTABLE(f)); | 530 FRAME_MSWINDOWS_MENU_HASHTABLE(f)); |
584 populate_menu (menubar, Qnil, desc, | 531 populate_menu (menubar, Qnil, desc, |
585 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1); | 532 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1); |
586 UNGCPRO; | |
587 } | 533 } |
588 | 534 |
589 /* | 535 /* |
590 * This is called when cleanup is possible. It is better not to | 536 * This is called when cleanup is possible. It is better not to |
591 * clean things up at all than do it too earaly! | 537 * clean things up at all than do it too earaly! |
762 struct frame *f = selected_frame (); | 708 struct frame *f = selected_frame (); |
763 struct Lisp_Event *eev = NULL; | 709 struct Lisp_Event *eev = NULL; |
764 HMENU menu; | 710 HMENU menu; |
765 POINT pt; | 711 POINT pt; |
766 int ok; | 712 int ok; |
767 struct gcpro gcpro1; | |
768 | |
769 GCPRO1 (menu_desc); /* to be safe -- see above */ | |
770 | 713 |
771 if (!NILP (event)) | 714 if (!NILP (event)) |
772 { | 715 { |
773 CHECK_LIVE_EVENT (event); | 716 CHECK_LIVE_EVENT (event); |
774 eev = XEVENT (event); | 717 eev = XEVENT (event); |
825 if (!ok) { | 768 if (!ok) { |
826 menu_cleanup (f); | 769 menu_cleanup (f); |
827 signal_simple_error ("Cannot track popup menu while in menu", | 770 signal_simple_error ("Cannot track popup menu while in menu", |
828 menu_desc); | 771 menu_desc); |
829 } | 772 } |
830 UNGCPRO; | |
831 } | 773 } |
832 | 774 |
833 | 775 |
834 /*------------------------------------------------------------------------*/ | 776 /*------------------------------------------------------------------------*/ |
835 /* Initialization */ | 777 /* Initialization */ |