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 */