comparison src/xmenu.c @ 2160:0639c52f017c

(xmenu_show): New arg enable_list. (keymap_panes): New arg enables (single_keymap_panes): New arg enables. Fill in its contents. (list_of_panes, list_of_items): New arg enables. Fill in contents. (Fx_popup_menu): Pass enable and enable_list args. (single_keymap_panes): Set enable flag to -1 if cmd definition is nil.
author Richard M. Stallman <rms@gnu.org>
date Fri, 12 Mar 1993 22:37:07 +0000
parents 42ceb87b43a1
children 12480fa04422
comparison
equal deleted inserted replaced
2159:6a082f5ce7e6 2160:0639c52f017c
111 int number_of_panes; 111 int number_of_panes;
112 Lisp_Object XMenu_return, keymap, tem; 112 Lisp_Object XMenu_return, keymap, tem;
113 int XMenu_xpos, XMenu_ypos; 113 int XMenu_xpos, XMenu_ypos;
114 char **menus; 114 char **menus;
115 char ***names; 115 char ***names;
116 int **enables;
116 Lisp_Object **obj_list; 117 Lisp_Object **obj_list;
117 int *items; 118 int *items;
118 char *title; 119 char *title;
119 char *error_name; 120 char *error_name;
120 Lisp_Object ltitle, selection; 121 Lisp_Object ltitle, selection;
178 prompt = map_prompt (keymap); 179 prompt = map_prompt (keymap);
179 if (!NILP (prompt)) 180 if (!NILP (prompt))
180 title = (char *) XSTRING (prompt)->data; 181 title = (char *) XSTRING (prompt)->data;
181 182
182 /* Extract the detailed info to make one pane. */ 183 /* Extract the detailed info to make one pane. */
183 number_of_panes = keymap_panes (&obj_list, &menus, &names, &items, 184 number_of_panes = keymap_panes (&obj_list, &menus, &names, &enables,
184 &menu, 1); 185 &items, &menu, 1);
185 /* The menu title seems to be ignored, 186 /* The menu title seems to be ignored,
186 so put it in the pane title. */ 187 so put it in the pane title. */
187 if (menus[0] == 0) 188 if (menus[0] == 0)
188 menus[0] = title; 189 menus[0] = title;
189 } 190 }
207 if (title == 0 && !NILP (prompt)) 208 if (title == 0 && !NILP (prompt))
208 title = (char *) XSTRING (prompt)->data; 209 title = (char *) XSTRING (prompt)->data;
209 } 210 }
210 211
211 /* Extract the detailed info to make one pane. */ 212 /* Extract the detailed info to make one pane. */
212 number_of_panes = keymap_panes (&obj_list, &menus, &names, &items, 213 number_of_panes = keymap_panes (&obj_list, &menus, &names, &enables,
213 maps, nmaps); 214 &items, maps, nmaps);
214 /* The menu title seems to be ignored, 215 /* The menu title seems to be ignored,
215 so put it in the pane title. */ 216 so put it in the pane title. */
216 if (menus[0] == 0) 217 if (menus[0] == 0)
217 menus[0] = title; 218 menus[0] = title;
218 } 219 }
220 { 221 {
221 /* We were given an old-fashioned menu. */ 222 /* We were given an old-fashioned menu. */
222 ltitle = Fcar (menu); 223 ltitle = Fcar (menu);
223 CHECK_STRING (ltitle, 1); 224 CHECK_STRING (ltitle, 1);
224 title = (char *) XSTRING (ltitle)->data; 225 title = (char *) XSTRING (ltitle)->data;
225 number_of_panes = list_of_panes (&obj_list, &menus, &names, &items, 226 number_of_panes = list_of_panes (&obj_list, &menus, &names, &enables,
226 Fcdr (menu)); 227 &items, Fcdr (menu));
227 } 228 }
228 #ifdef XDEBUG 229 #ifdef XDEBUG
229 fprintf (stderr, "Panes = %d\n", number_of_panes); 230 fprintf (stderr, "Panes = %d\n", number_of_panes);
230 for (i = 0; i < number_of_panes; i++) 231 for (i = 0; i < number_of_panes; i++)
231 { 232 {
255 XMenu_xpos, XMenu_ypos, &root_x, &root_y, 256 XMenu_xpos, XMenu_ypos, &root_x, &root_y,
256 &dummy_window)) 257 &dummy_window))
257 /* But XGetGeometry said root was the root window of f's screen! */ 258 /* But XGetGeometry said root was the root window of f's screen! */
258 abort (); 259 abort ();
259 260
260 selection = xmenu_show (root, XMenu_xpos, XMenu_ypos, names, menus, 261 selection = xmenu_show (root, XMenu_xpos, XMenu_ypos, names, enables,
261 items, number_of_panes, obj_list, title, 262 menus, items, number_of_panes, obj_list, title,
262 &error_name); 263 &error_name);
263 } 264 }
264 UNBLOCK_INPUT; 265 UNBLOCK_INPUT;
265 /* fprintf (stderr, "selection = %x\n", selection); */ 266 /* fprintf (stderr, "selection = %x\n", selection); */
266 if (selection != NUL) 267 if (selection != NUL)
273 } 274 }
274 /* now free up the strings */ 275 /* now free up the strings */
275 for (i = 0; i < number_of_panes; i++) 276 for (i = 0; i < number_of_panes; i++)
276 { 277 {
277 free (names[i]); 278 free (names[i]);
279 free (enables[i]);
278 free (obj_list[i]); 280 free (obj_list[i]);
279 } 281 }
280 free (menus); 282 free (menus);
281 free (obj_list); 283 free (obj_list);
282 free (names); 284 free (names);
285 free (enables);
283 free (items); 286 free (items);
284 /* free (title); */ 287 /* free (title); */
285 if (error_name) error (error_name); 288 if (error_name) error (error_name);
286 return XMenu_return; 289 return XMenu_return;
287 } 290 }
290 int pane; 293 int pane;
291 int line; 294 int line;
292 }; 295 };
293 296
294 Lisp_Object 297 Lisp_Object
295 xmenu_show (parent, startx, starty, line_list, pane_list, line_cnt, 298 xmenu_show (parent, startx, starty, line_list, enable_list, pane_list,
296 pane_cnt, item_list, title, error) 299 line_cnt, pane_cnt, item_list, title, error)
297 Window parent; 300 Window parent;
298 int startx, starty; /* upper left corner position BROKEN */ 301 int startx, starty; /* upper left corner position BROKEN */
299 char **line_list[]; /* list of strings for items */ 302 char **line_list[]; /* list of strings for items */
303 int *enable_list[]; /* list of strings for items */
300 char *pane_list[]; /* list of pane titles */ 304 char *pane_list[]; /* list of pane titles */
301 char *title; 305 char *title;
302 int pane_cnt; /* total number of panes */ 306 int pane_cnt; /* total number of panes */
303 Lisp_Object *item_list[]; /* All items */ 307 Lisp_Object *item_list[]; /* All items */
304 int line_cnt[]; /* Lines in each pane */ 308 int line_cnt[]; /* Lines in each pane */
346 { 350 {
347 /* add the selection stuff to the menus */ 351 /* add the selection stuff to the menus */
348 /* datap[selidx+sofar].pane = panes; 352 /* datap[selidx+sofar].pane = panes;
349 datap[selidx+sofar].line = selidx; */ 353 datap[selidx+sofar].line = selidx; */
350 if (XMenuAddSelection (XDISPLAY GXMenu, lpane, 0, 354 if (XMenuAddSelection (XDISPLAY GXMenu, lpane, 0,
351 line_list[panes][selidx], TRUE) 355 line_list[panes][selidx],
356 enable_list[panes][selidx])
352 == XM_FAILURE) 357 == XM_FAILURE)
353 { 358 {
354 XMenuDestroy (XDISPLAY GXMenu); 359 XMenuDestroy (XDISPLAY GXMenu);
355 /* free (datap); */ 360 /* free (datap); */
356 *error = "Can't add selection to menu"; 361 *error = "Can't add selection to menu";
417 staticpro (&Qmenu_enable); 422 staticpro (&Qmenu_enable);
418 defsubr (&Sx_popup_menu); 423 defsubr (&Sx_popup_menu);
419 } 424 }
420 425
421 /* Construct the vectors that describe a menu 426 /* Construct the vectors that describe a menu
422 and store them in *VECTOR, *PANES, *NAMES and *ITEMS. 427 and store them in *VECTOR, *PANES, *NAMES, *ENABLES and *ITEMS.
423 Each of those four values is a vector indexed by pane number. 428 Each of those four values is a vector indexed by pane number.
424 Return the number of panes. 429 Return the number of panes.
425 430
426 KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */ 431 KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */
427 432
428 int 433 int
429 keymap_panes (vector, panes, names, items, keymaps, nmaps) 434 keymap_panes (vector, panes, names, enables, items, keymaps, nmaps)
430 Lisp_Object ***vector; /* RETURN all menu objects */ 435 Lisp_Object ***vector; /* RETURN all menu objects */
431 char ***panes; /* RETURN pane names */ 436 char ***panes; /* RETURN pane names */
432 char ****names; /* RETURN all line names */ 437 char ****names; /* RETURN all line names */
438 int ***enables; /* RETURN enable-flags of lines */
433 int **items; /* RETURN number of items per pane */ 439 int **items; /* RETURN number of items per pane */
434 Lisp_Object *keymaps; 440 Lisp_Object *keymaps;
435 int nmaps; 441 int nmaps;
436 { 442 {
437 /* Number of panes we have made. */ 443 /* Number of panes we have made. */
446 /* Make space for an estimated number of panes. */ 452 /* Make space for an estimated number of panes. */
447 *vector = (Lisp_Object **) xmalloc (npanes_allocated * sizeof (Lisp_Object *)); 453 *vector = (Lisp_Object **) xmalloc (npanes_allocated * sizeof (Lisp_Object *));
448 *panes = (char **) xmalloc (npanes_allocated * sizeof (char *)); 454 *panes = (char **) xmalloc (npanes_allocated * sizeof (char *));
449 *items = (int *) xmalloc (npanes_allocated * sizeof (int)); 455 *items = (int *) xmalloc (npanes_allocated * sizeof (int));
450 *names = (char ***) xmalloc (npanes_allocated * sizeof (char **)); 456 *names = (char ***) xmalloc (npanes_allocated * sizeof (char **));
457 *enables = (int **) xmalloc (npanes_allocated * sizeof (int *));
451 458
452 /* Loop over the given keymaps, making a pane for each map. 459 /* Loop over the given keymaps, making a pane for each map.
453 But don't make a pane that is empty--ignore that map instead. 460 But don't make a pane that is empty--ignore that map instead.
454 P is the number of panes we have made so far. */ 461 P is the number of panes we have made so far. */
455 for (mapno = 0; mapno < nmaps; mapno++) 462 for (mapno = 0; mapno < nmaps; mapno++)
456 single_keymap_panes (keymaps[mapno], panes, vector, names, items, 463 single_keymap_panes (keymaps[mapno], panes, vector, names, enables, items,
457 &p, &npanes_allocated, ""); 464 &p, &npanes_allocated, "");
458 465
459 /* Return the number of panes. */ 466 /* Return the number of panes. */
460 return p; 467 return p;
461 } 468 }
463 /* This is a recursive subroutine of the previous function. 470 /* This is a recursive subroutine of the previous function.
464 It handles one keymap, KEYMAP. 471 It handles one keymap, KEYMAP.
465 The other arguments are passed along 472 The other arguments are passed along
466 or point to local variables of the previous function. */ 473 or point to local variables of the previous function. */
467 474
468 single_keymap_panes (keymap, panes, vector, names, items, 475 single_keymap_panes (keymap, panes, vector, names, enables, items,
469 p_ptr, npanes_allocated_ptr, pane_name) 476 p_ptr, npanes_allocated_ptr, pane_name)
470 Lisp_Object keymap; 477 Lisp_Object keymap;
471 Lisp_Object ***vector; /* RETURN all menu objects */ 478 Lisp_Object ***vector; /* RETURN all menu objects */
472 char ***panes; /* RETURN pane names */ 479 char ***panes; /* RETURN pane names */
473 char ****names; /* RETURN all line names */ 480 char ****names; /* RETURN all line names */
481 int ***enables; /* RETURN enable flags of lines */
474 int **items; /* RETURN number of items per pane */ 482 int **items; /* RETURN number of items per pane */
475 int *p_ptr; 483 int *p_ptr;
476 int *npanes_allocated_ptr; 484 int *npanes_allocated_ptr;
477 char *pane_name; 485 char *pane_name;
478 { 486 {
497 = (int *) xrealloc (*items, 505 = (int *) xrealloc (*items,
498 *npanes_allocated_ptr * sizeof (int)); 506 *npanes_allocated_ptr * sizeof (int));
499 *names 507 *names
500 = (char ***) xrealloc (*names, 508 = (char ***) xrealloc (*names,
501 *npanes_allocated_ptr * sizeof (char **)); 509 *npanes_allocated_ptr * sizeof (char **));
510 *enables
511 = (int **) xrealloc (*enables,
512 *npanes_allocated_ptr * sizeof (int *));
502 } 513 }
503 514
504 /* When a menu comes from keymaps, don't give names to the panes. */ 515 /* When a menu comes from keymaps, don't give names to the panes. */
505 (*panes)[*p_ptr] = pane_name; 516 (*panes)[*p_ptr] = pane_name;
506 517
514 525
515 /* Create vectors for the names and values of the items in the pane. 526 /* Create vectors for the names and values of the items in the pane.
516 I is an upper bound for the number of items. */ 527 I is an upper bound for the number of items. */
517 (*vector)[*p_ptr] = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object)); 528 (*vector)[*p_ptr] = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object));
518 (*names)[*p_ptr] = (char **) xmalloc (i * sizeof (char *)); 529 (*names)[*p_ptr] = (char **) xmalloc (i * sizeof (char *));
530 (*enables)[*p_ptr] = (int *) xmalloc (i * sizeof (int));
519 531
520 /* I is now the index of the next unused slots. */ 532 /* I is now the index of the next unused slots. */
521 i = 0; 533 i = 0;
522 for (tail = keymap; XTYPE (tail) == Lisp_Cons; tail = XCONS (tail)->cdr) 534 for (tail = keymap; XTYPE (tail) == Lisp_Cons; tail = XCONS (tail)->cdr)
523 { 535 {
547 } 559 }
548 tem = Fkeymapp (def); 560 tem = Fkeymapp (def);
549 if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) 561 if (XSTRING (item2)->data[0] == '@' && !NILP (tem))
550 pending_maps = Fcons (Fcons (def, item2), 562 pending_maps = Fcons (Fcons (def, item2),
551 pending_maps); 563 pending_maps);
552 else if (!NILP (enabled)) 564 else
553 { 565 {
554 (*names)[*p_ptr][i] = (char *) XSTRING (item2)->data; 566 (*names)[*p_ptr][i] = (char *) XSTRING (item2)->data;
555 /* The menu item "value" is the key bound here. */ 567 /* The menu item "value" is the key bound here. */
556 (*vector)[*p_ptr][i] = XCONS (item)->car; 568 (*vector)[*p_ptr][i] = XCONS (item)->car;
569 (*enables)[*p_ptr][i]
570 = (!NILP (enabled) ? 1
571 : NILP (def) ? -1 : 0);
557 i++; 572 i++;
558 } 573 }
559 } 574 }
560 } 575 }
561 } 576 }
591 606
592 tem = Fkeymapp (def); 607 tem = Fkeymapp (def);
593 if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) 608 if (XSTRING (item2)->data[0] == '@' && !NILP (tem))
594 pending_maps = Fcons (Fcons (def, item2), 609 pending_maps = Fcons (Fcons (def, item2),
595 pending_maps); 610 pending_maps);
596 else if (!NILP (enabled)) 611 else
597 { 612 {
598 (*names)[*p_ptr][i] = (char *) XSTRING (item2)->data; 613 (*names)[*p_ptr][i] = (char *) XSTRING (item2)->data;
599 /* The menu item "value" is the key bound here. */ 614 /* The menu item "value" is the key bound here. */
600 (*vector)[*p_ptr][i] = character; 615 (*vector)[*p_ptr][i] = character;
616 (*enables)[*p_ptr][i]
617 = (!NILP (enabled) ? 1
618 : NILP (def) ? -1 : 0);
601 i++; 619 i++;
602 } 620 }
603 } 621 }
604 } 622 }
605 } 623 }
611 /* If we just made an empty pane, get rid of it. */ 629 /* If we just made an empty pane, get rid of it. */
612 if (i == 0) 630 if (i == 0)
613 { 631 {
614 free ((*vector)[*p_ptr]); 632 free ((*vector)[*p_ptr]);
615 free ((*names)[*p_ptr]); 633 free ((*names)[*p_ptr]);
634 free ((*enables)[*p_ptr]);
616 } 635 }
617 /* Otherwise, advance past it. */ 636 /* Otherwise, advance past it. */
618 else 637 else
619 (*p_ptr)++; 638 (*p_ptr)++;
620 639
621 /* Process now any submenus which want to be panes at this level. */ 640 /* Process now any submenus which want to be panes at this level. */
622 while (!NILP (pending_maps)) 641 while (!NILP (pending_maps))
623 { 642 {
624 Lisp_Object elt; 643 Lisp_Object elt;
625 elt = Fcar (pending_maps); 644 elt = Fcar (pending_maps);
626 single_keymap_panes (Fcar (elt), panes, vector, names, items, 645 single_keymap_panes (Fcar (elt), panes, vector, names, enables, items,
627 p_ptr, npanes_allocated_ptr, 646 p_ptr, npanes_allocated_ptr,
628 /* Add 1 to discard the @. */ 647 /* Add 1 to discard the @. */
629 (char *) XSTRING (XCONS (elt)->cdr)->data + 1); 648 (char *) XSTRING (XCONS (elt)->cdr)->data + 1);
630 pending_maps = Fcdr (pending_maps); 649 pending_maps = Fcdr (pending_maps);
631 } 650 }
632 } 651 }
633 652
634 /* Construct the vectors that describe a menu 653 /* Construct the vectors that describe a menu
635 and store them in *VECTOR, *PANES, *NAMES and *ITEMS. 654 and store them in *VECTOR, *PANES, *NAMES, *ENABLES and *ITEMS.
636 Each of those four values is a vector indexed by pane number. 655 Each of those four values is a vector indexed by pane number.
637 Return the number of panes. 656 Return the number of panes.
638 657
639 MENU is the argument that was given to Fx_popup_menu. */ 658 MENU is the argument that was given to Fx_popup_menu. */
640 659
641 int 660 int
642 list_of_panes (vector, panes, names, items, menu) 661 list_of_panes (vector, panes, names, enables, items, menu)
643 Lisp_Object ***vector; /* RETURN all menu objects */ 662 Lisp_Object ***vector; /* RETURN all menu objects */
644 char ***panes; /* RETURN pane names */ 663 char ***panes; /* RETURN pane names */
645 char ****names; /* RETURN all line names */ 664 char ****names; /* RETURN all line names */
665 int ***enables; /* RETURN enable flags of lines */
646 int **items; /* RETURN number of items per pane */ 666 int **items; /* RETURN number of items per pane */
647 Lisp_Object menu; 667 Lisp_Object menu;
648 { 668 {
649 Lisp_Object tail, item, item1; 669 Lisp_Object tail, item, item1;
650 int i; 670 int i;
655 675
656 *vector = (Lisp_Object **) xmalloc (i * sizeof (Lisp_Object *)); 676 *vector = (Lisp_Object **) xmalloc (i * sizeof (Lisp_Object *));
657 *panes = (char **) xmalloc (i * sizeof (char *)); 677 *panes = (char **) xmalloc (i * sizeof (char *));
658 *items = (int *) xmalloc (i * sizeof (int)); 678 *items = (int *) xmalloc (i * sizeof (int));
659 *names = (char ***) xmalloc (i * sizeof (char **)); 679 *names = (char ***) xmalloc (i * sizeof (char **));
680 *enables = (int **) xmalloc (i * sizeof (int *));
660 681
661 for (i = 0, tail = menu; !NILP (tail); tail = Fcdr (tail), i++) 682 for (i = 0, tail = menu; !NILP (tail); tail = Fcdr (tail), i++)
662 { 683 {
663 item = Fcdr (Fcar (tail)); 684 item = Fcdr (Fcar (tail));
664 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item); 685 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
670 #ifdef XDEBUG 691 #ifdef XDEBUG
671 fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i, 692 fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i,
672 XSTRING (item1)->data); 693 XSTRING (item1)->data);
673 #endif 694 #endif
674 (*panes)[i] = (char *) XSTRING (item1)->data; 695 (*panes)[i] = (char *) XSTRING (item1)->data;
675 (*items)[i] = list_of_items ((*vector)+i, (*names)+i, item); 696 (*items)[i] = list_of_items ((*vector)+i, (*names)+i, (*enables)+i, item);
676 /* (*panes)[i] = (char *) xmalloc ((XSTRING (item1)->size)+1); 697 /* (*panes)[i] = (char *) xmalloc ((XSTRING (item1)->size)+1);
677 bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING (item1)->size + 1) 698 bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING (item1)->size + 1)
678 ; */ 699 ; */
679 } 700 }
680 return i; 701 return i;
681 } 702 }
682 703
683 /* Construct the lists of values and names for a single pane, from the 704 /* Construct the lists of values and names for a single pane, from the
684 alist PANE. Put them in *VECTOR and *NAMES. 705 alist PANE. Put them in *VECTOR and *NAMES. Put the enable flags
685 Return the number of items. */ 706 int *ENABLES. Return the number of items. */
686 707
687 int 708 int
688 list_of_items (vector, names, pane) /* get list from emacs and put to vector */ 709 list_of_items (vector, names, enables, pane)
689 Lisp_Object **vector; /* RETURN menu "objects" */ 710 Lisp_Object **vector; /* RETURN menu "objects" */
690 char ***names; /* RETURN line names */ 711 char ***names; /* RETURN line names */
712 int **enables; /* RETURN enable flags of lines */
691 Lisp_Object pane; 713 Lisp_Object pane;
692 { 714 {
693 Lisp_Object tail, item, item1; 715 Lisp_Object tail, item, item1;
694 int i; 716 int i;
695 717
697 719
698 i = XFASTINT (Flength (pane)); 720 i = XFASTINT (Flength (pane));
699 721
700 *vector = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object)); 722 *vector = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object));
701 *names = (char **) xmalloc (i * sizeof (char *)); 723 *names = (char **) xmalloc (i * sizeof (char *));
724 *enables = (int *) xmalloc (i * sizeof (int));
702 725
703 for (i = 0, tail = pane; !NILP (tail); tail = Fcdr (tail), i++) 726 for (i = 0, tail = pane; !NILP (tail); tail = Fcdr (tail), i++)
704 { 727 {
705 item = Fcar (tail); 728 item = Fcar (tail);
706 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item); 729 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
713 #ifdef XDEBUG 736 #ifdef XDEBUG
714 fprintf (stderr, "list_of_items check item, i=%d%s\n", i, 737 fprintf (stderr, "list_of_items check item, i=%d%s\n", i,
715 XSTRING (item1)->data); 738 XSTRING (item1)->data);
716 #endif 739 #endif
717 (*names)[i] = (char *) XSTRING (item1)->data; 740 (*names)[i] = (char *) XSTRING (item1)->data;
741 (*enables)[i] = 1;
718 } 742 }
719 return i; 743 return i;
720 } 744 }