comparison src/xmenu.c @ 1082:d24afc1bef38

(xmenu_show): If no panes, just return. (Fx_popup_menu): Treat coords relative to spec'd window. (single_keymap_panes): New function; contains guts of keymap_panes. If a command binding for submenu has a prompt string starting with @, make a separate pane for it at this level. (keymap_panes): New function. (Fx_popup_menu): Accept keymap or list of keymaps as MENU argument. Accept mouse button event as POSITION argument.
author Richard M. Stallman <rms@gnu.org>
date Sat, 05 Sep 1992 00:08:07 +0000
parents 3493118bc79f
children 3640e799d5fc
comparison
equal deleted inserted replaced
1081:4e7d09b779eb 1082:d24afc1bef38
82 } 82 }
83 #endif 83 #endif
84 84
85 DEFUN ("x-popup-menu",Fx_popup_menu, Sx_popup_menu, 1, 2, 0, 85 DEFUN ("x-popup-menu",Fx_popup_menu, Sx_popup_menu, 1, 2, 0,
86 "Pop up a deck-of-cards menu and return user's selection.\n\ 86 "Pop up a deck-of-cards menu and return user's selection.\n\
87 ARG is a position specification: a list ((XOFFSET YOFFSET) WINDOW)\n\ 87 POSITION is a position specification. This is either a mouse button event\n\
88 or a list ((XOFFSET YOFFSET) WINDOW)\n\
88 where XOFFSET and YOFFSET are positions in characters from the top left\n\ 89 where XOFFSET and YOFFSET are positions in characters from the top left\n\
89 corner of WINDOW's frame. A mouse-event list will serve for this.\n\ 90 corner of WINDOW's frame. A mouse-event list will serve for this.\n\
90 This controls the position of the center of the first line\n\ 91 This controls the position of the center of the first line\n\
91 in the first pane of the menu, not the top left of the menu as a whole.\n\ 92 in the first pane of the menu, not the top left of the menu as a whole.\n\
92 \n\ 93 \n\
93 MENU is a specifier for a menu. It is a list of the form\n\ 94 MENU is a specifier for a menu. For the simplest case, MENU is a keymap.\n\
94 \(TITLE PANE1 PANE2...), and each pane is a list of form\n\ 95 The menu items come from key bindings that have a menu string as well as\n\
96 a definition; actually, the \"definition\" in such a key binding looks like\n\
97 \(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\
98 the keymap as a top-level element.\n\n\
99 You can also use a list of keymaps as MENU.\n\
100 Then each keymap makes a separate pane.\n\n\
101 Alternatively, you can specify a menu of multiple panes\n\
102 with a list of the form\n\
103 \(TITLE PANE1 PANE2...), where each pane is a list of form\n\
95 \(TITLE (LINE ITEM)...). Each line should be a string, and item should\n\ 104 \(TITLE (LINE ITEM)...). Each line should be a string, and item should\n\
96 be the return value for that line (i.e. if it is selected.") 105 be the return value for that line (i.e. if it is selected.")
97 (arg, menu) 106 (position, menu)
98 Lisp_Object arg, menu; 107 Lisp_Object position, menu;
99 { 108 {
100 int number_of_panes; 109 int number_of_panes;
101 Lisp_Object XMenu_return; 110 Lisp_Object XMenu_return, keymap, tem;
102 int XMenu_xpos, XMenu_ypos; 111 int XMenu_xpos, XMenu_ypos;
103 char **menus; 112 char **menus;
104 char ***names; 113 char ***names;
105 Lisp_Object **obj_list; 114 Lisp_Object **obj_list;
106 int *items; 115 int *items;
109 Lisp_Object ltitle, selection; 118 Lisp_Object ltitle, selection;
110 int i, j; 119 int i, j;
111 FRAME_PTR f; 120 FRAME_PTR f;
112 Lisp_Object x, y, window; 121 Lisp_Object x, y, window;
113 122
114 window = Fcar (Fcdr (arg)); 123 /* Decode the first argument: find the window and the coordinates. */
115 x = Fcar (Fcar (arg)); 124 tem = Fcar (position);
116 y = Fcar (Fcdr (Fcar (arg))); 125 if (XTYPE (tem) == Lisp_Cons)
126 {
127 window = Fcar (Fcdr (position));
128 x = Fcar (tem);
129 y = Fcar (Fcdr (tem));
130 }
131 else
132 {
133 tem = Fcdr (position);
134 window = Fcar (tem);
135 tem = Fcar (Fcdr (Fcdr (tem)));
136 x = Fcar (tem);
137 y = Fcdr (tem);
138 }
117 CHECK_WINDOW (window, 0); 139 CHECK_WINDOW (window, 0);
118 CHECK_NUMBER (x, 0); 140 CHECK_NUMBER (x, 0);
119 CHECK_NUMBER (y, 0); 141 CHECK_NUMBER (y, 0);
142
120 f = XFRAME (WINDOW_FRAME (XWINDOW (window))); 143 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
121 144
122 XMenu_xpos = FONT_WIDTH (f->display.x->font) * XINT (x); 145 XMenu_xpos
123 XMenu_ypos = FONT_HEIGHT (f->display.x->font) * XINT (y); 146 = FONT_WIDTH (f->display.x->font) * (XINT (x) + XWINDOW (window)->left);
147 XMenu_ypos
148 = FONT_HEIGHT (f->display.x->font) * (XINT (y) + XWINDOW (window)->top);
124 XMenu_xpos += f->display.x->left_pos; 149 XMenu_xpos += f->display.x->left_pos;
125 XMenu_ypos += f->display.x->top_pos; 150 XMenu_ypos += f->display.x->top_pos;
126 151
127 ltitle = Fcar (menu); 152 keymap = Fkeymapp (menu);
128 CHECK_STRING (ltitle, 1); 153 tem = Qnil;
129 title = (char *) XSTRING (ltitle)->data; 154 if (XTYPE (menu) == Lisp_Cons)
130 number_of_panes=list_of_panes (&obj_list, &menus, &names, &items, Fcdr (menu)); 155 tem = Fkeymapp (Fcar (menu));
156 if (!NILP (keymap))
157 {
158 /* We were given a keymap. Extract menu info from the keymap. */
159 Lisp_Object prompt;
160 keymap = get_keymap (menu);
161
162 /* Search for a string appearing directly as an element of the keymap.
163 That string is the title of the menu. */
164 prompt = map_prompt (keymap);
165 if (!NILP (prompt))
166 title = (char *) XSTRING (prompt)->data;
167
168 /* Extract the detailed info to make one pane. */
169 number_of_panes = keymap_panes (&obj_list, &menus, &names, &items,
170 &menu, 1);
171 /* The menu title seems to be ignored,
172 so put it in the pane title. */
173 if (menus[0] == 0)
174 menus[0] = title;
175 }
176 else if (!NILP (tem))
177 {
178 /* We were given a list of keymaps. */
179 Lisp_Object prompt;
180 int nmaps = XFASTINT (Flength (menu));
181 Lisp_Object *maps
182 = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
183 int i;
184 title = 0;
185
186 /* The first keymap that has a prompt string
187 supplies the menu title. */
188 for (tem = menu, i = 0; XTYPE (tem) == Lisp_Cons; tem = Fcdr (tem))
189 {
190 maps[i++] = keymap = get_keymap (Fcar (tem));
191
192 prompt = map_prompt (keymap);
193 if (title == 0 && !NILP (prompt))
194 title = (char *) XSTRING (prompt)->data;
195 }
196
197 /* Extract the detailed info to make one pane. */
198 number_of_panes = keymap_panes (&obj_list, &menus, &names, &items,
199 maps, nmaps);
200 /* The menu title seems to be ignored,
201 so put it in the pane title. */
202 if (menus[0] == 0)
203 menus[0] = title;
204 }
205 else
206 {
207 /* We were given an old-fashioned menu. */
208 ltitle = Fcar (menu);
209 CHECK_STRING (ltitle, 1);
210 title = (char *) XSTRING (ltitle)->data;
211 number_of_panes = list_of_panes (&obj_list, &menus, &names, &items,
212 Fcdr (menu));
213 }
131 #ifdef XDEBUG 214 #ifdef XDEBUG
132 fprintf (stderr, "Panes= %d\n", number_of_panes); 215 fprintf (stderr, "Panes = %d\n", number_of_panes);
133 for (i=0; i < number_of_panes; i++) 216 for (i = 0; i < number_of_panes; i++)
134 { 217 {
135 fprintf (stderr, "Pane %d lines %d title %s\n", i, items[i], menus[i]); 218 fprintf (stderr, "Pane %d has lines %d title %s\n",
136 for (j=0; j < items[i]; j++) 219 i, items[i], menus[i]);
137 { 220 for (j = 0; j < items[i]; j++)
138 fprintf (stderr, " Item %d %s\n", j, names[i][j]); 221 fprintf (stderr, " Item %d %s\n", j, names[i][j]);
139 }
140 } 222 }
141 #endif 223 #endif
142 BLOCK_INPUT; 224 BLOCK_INPUT;
143 selection = xmenu_show (ROOT_WINDOW, XMenu_xpos, XMenu_ypos, names, menus, 225 selection = xmenu_show (ROOT_WINDOW, XMenu_xpos, XMenu_ypos, names, menus,
144 items, number_of_panes, obj_list, title, &error_name); 226 items, number_of_panes, obj_list, title,
227 &error_name);
145 UNBLOCK_INPUT; 228 UNBLOCK_INPUT;
146 /** fprintf (stderr, "selection = %x\n", selection); **/ 229 /* fprintf (stderr, "selection = %x\n", selection); */
147 if (selection != NUL) 230 if (selection != NUL)
148 { /* selected something */ 231 { /* selected something */
149 XMenu_return = selection; 232 XMenu_return = selection;
150 } 233 }
151 else 234 else
152 { /* nothing selected */ 235 { /* nothing selected */
153 XMenu_return = Qnil; 236 XMenu_return = Qnil;
154 } 237 }
155 /* now free up the strings */ 238 /* now free up the strings */
156 for (i=0; i < number_of_panes; i++) 239 for (i = 0; i < number_of_panes; i++)
157 { 240 {
158 free (names[i]); 241 free (names[i]);
159 free (obj_list[i]); 242 free (obj_list[i]);
160 } 243 }
161 free (menus); 244 free (menus);
162 free (obj_list); 245 free (obj_list);
163 free (names); 246 free (names);
164 free (items); 247 free (items);
165 /* free (title); */ 248 /* free (title); */
166 if (error_name) error (error_name); 249 if (error_name) error (error_name);
167 return XMenu_return; 250 return XMenu_return;
168 } 251 }
169 252
170 struct indices { 253 struct indices {
191 Lisp_Object entry; 274 Lisp_Object entry;
192 /* struct indices *datap, *datap_save; */ 275 /* struct indices *datap, *datap_save; */
193 char *datap; 276 char *datap;
194 int ulx, uly, width, height; 277 int ulx, uly, width, height;
195 int dispwidth, dispheight; 278 int dispwidth, dispheight;
196 279
280 if (pane_cnt == 0)
281 return 0;
282
197 *error = (char *) 0; /* Initialize error pointer to null */ 283 *error = (char *) 0; /* Initialize error pointer to null */
198 GXMenu = XMenuCreate (XDISPLAY parent, "emacs"); 284 GXMenu = XMenuCreate (XDISPLAY parent, "emacs");
199 if (GXMenu == NUL) 285 if (GXMenu == NUL)
200 { 286 {
201 *error = "Can't create menu"; 287 *error = "Can't create menu";
202 return (0); 288 return (0);
203 } 289 }
204 290
205 for (panes=0, lines=0; panes < pane_cnt; lines += line_cnt[panes], panes++) 291 for (panes = 0, lines = 0; panes < pane_cnt;
292 lines += line_cnt[panes], panes++)
206 ; 293 ;
207 /* datap = (struct indices *) xmalloc (lines * sizeof (struct indices)); */ 294 /* datap = (struct indices *) xmalloc (lines * sizeof (struct indices)); */
208 /*datap = (char *) xmalloc (lines * sizeof (char)); 295 /* datap = (char *) xmalloc (lines * sizeof (char));
209 datap_save = datap;*/ 296 datap_save = datap;*/
210 297
211 for (panes = 0, sofar=0;panes < pane_cnt;sofar +=line_cnt[panes], panes++) 298 for (panes = 0, sofar = 0; panes < pane_cnt;
299 sofar += line_cnt[panes], panes++)
212 { 300 {
213 /* create all the necessary panes */ 301 /* create all the necessary panes */
214 lpane = XMenuAddPane (XDISPLAY GXMenu, pane_list[panes], TRUE); 302 lpane = XMenuAddPane (XDISPLAY GXMenu, pane_list[panes], TRUE);
215 if (lpane == XM_FAILURE) 303 if (lpane == XM_FAILURE)
216 { 304 {
217 XMenuDestroy (XDISPLAY GXMenu); 305 XMenuDestroy (XDISPLAY GXMenu);
218 *error = "Can't create pane"; 306 *error = "Can't create pane";
219 return (0); 307 return (0);
220 } 308 }
221 for (selidx = 0; selidx < line_cnt[panes] ; selidx++) 309 for (selidx = 0; selidx < line_cnt[panes]; selidx++)
222 { 310 {
223 /* add the selection stuff to the menus */ 311 /* add the selection stuff to the menus */
224 /* datap[selidx+sofar].pane = panes; 312 /* datap[selidx+sofar].pane = panes;
225 datap[selidx+sofar].line = selidx; */ 313 datap[selidx+sofar].line = selidx; */
226 if (XMenuAddSelection (XDISPLAY GXMenu, lpane, 0, 314 if (XMenuAddSelection (XDISPLAY GXMenu, lpane, 0,
270 fprintf (stderr, "pane= %d line = %d\n", panes, selidx); 358 fprintf (stderr, "pane= %d line = %d\n", panes, selidx);
271 #endif 359 #endif
272 entry = item_list[panes][selidx]; 360 entry = item_list[panes][selidx];
273 break; 361 break;
274 case XM_FAILURE: 362 case XM_FAILURE:
275 /*free (datap_save); */ 363 /* free (datap_save); */
276 XMenuDestroy (XDISPLAY GXMenu); 364 XMenuDestroy (XDISPLAY GXMenu);
277 *error = "Can't activate menu"; 365 *error = "Can't activate menu";
278 /* error ("Can't activate menu"); */ 366 /* error ("Can't activate menu"); */
279 case XM_IA_SELECT: 367 case XM_IA_SELECT:
280 case XM_NO_SELECT: 368 case XM_NO_SELECT:
281 entry = Qnil; 369 entry = Qnil;
282 break; 370 break;
283 } 371 }
284 XMenuDestroy (XDISPLAY GXMenu); 372 XMenuDestroy (XDISPLAY GXMenu);
285 /*free (datap_save);*/ 373 /* free (datap_save);*/
286 return (entry); 374 return (entry);
287 } 375 }
288 376
289 syms_of_xmenu () 377 syms_of_xmenu ()
290 { 378 {
291 defsubr (&Sx_popup_menu); 379 defsubr (&Sx_popup_menu);
292 } 380 }
293 381
382 /* Construct the vectors that describe a menu
383 and store them in *VECTOR, *PANES, *NAMES and *ITEMS.
384 Each of those four values is a vector indexed by pane number.
385 Return the number of panes.
386
387 KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */
388
389 int
390 keymap_panes (vector, panes, names, items, keymaps, nmaps)
391 Lisp_Object ***vector; /* RETURN all menu objects */
392 char ***panes; /* RETURN pane names */
393 char ****names; /* RETURN all line names */
394 int **items; /* RETURN number of items per pane */
395 Lisp_Object *keymaps;
396 int nmaps;
397 {
398 /* Number of panes we have made. */
399 int p = 0;
400 /* Number of panes we have space for. */
401 int npanes_allocated = nmaps;
402 int mapno;
403
404 if (npanes_allocated < 4)
405 npanes_allocated = 4;
406
407 /* Make space for an estimated number of panes. */
408 *vector = (Lisp_Object **) xmalloc (npanes_allocated * sizeof (Lisp_Object *));
409 *panes = (char **) xmalloc (npanes_allocated * sizeof (char *));
410 *items = (int *) xmalloc (npanes_allocated * sizeof (int));
411 *names = (char ***) xmalloc (npanes_allocated * sizeof (char **));
412
413 /* Loop over the given keymaps, making a pane for each map.
414 But don't make a pane that is empty--ignore that map instead.
415 P is the number of panes we have made so far. */
416 for (mapno = 0; mapno < nmaps; mapno++)
417 single_keymap_panes (keymaps[mapno], panes, vector, names, items,
418 &p, &npanes_allocated, "");
419
420 /* Return the number of panes. */
421 return p;
422 }
423
424 /* This is a recursive subroutine of the previous function.
425 It handles one keymap, KEYMAP.
426 The other arguments are passed along
427 or point to local variables of the previous function. */
428
429 single_keymap_panes (keymap, panes, vector, names, items,
430 p_ptr, npanes_allocated_ptr, pane_name)
431 Lisp_Object keymap;
432 Lisp_Object ***vector; /* RETURN all menu objects */
433 char ***panes; /* RETURN pane names */
434 char ****names; /* RETURN all line names */
435 int **items; /* RETURN number of items per pane */
436 int *p_ptr;
437 int *npanes_allocated_ptr;
438 char *pane_name;
439 {
440 int i;
441 Lisp_Object pending_maps;
442 Lisp_Object tail, item, item1, item2, table;
443
444 pending_maps = Qnil;
445
446 /* Make sure we have room for another pane. */
447 if (*p_ptr == *npanes_allocated_ptr)
448 {
449 *npanes_allocated_ptr *= 2;
450
451 *vector
452 = (Lisp_Object **) xrealloc (*vector,
453 *npanes_allocated_ptr * sizeof (Lisp_Object *));
454 *panes
455 = (char **) xrealloc (*panes,
456 *npanes_allocated_ptr * sizeof (char *));
457 *items
458 = (int *) xrealloc (*items,
459 *npanes_allocated_ptr * sizeof (int));
460 *names
461 = (char ***) xrealloc (*names,
462 *npanes_allocated_ptr * sizeof (char **));
463 }
464
465 /* When a menu comes from keymaps, don't give names to the panes. */
466 (*panes)[*p_ptr] = pane_name;
467
468 /* Get the length of the list level of the keymap. */
469 i = XFASTINT (Flength (keymap));
470
471 /* If the keymap has a dense table, put it in TABLE,
472 and leave only the list level in KEYMAP.
473 Include the length of the dense table in I. */
474 table = keymap_table (keymap);
475 if (!NILP (table))
476 {
477 i += XFASTINT (Flength (table));
478 keymap = XCONS (XCONS (keymap)->cdr)->cdr;
479 }
480
481 /* Create vectors for the names and values of the items in the pane.
482 I is an upper bound for the number of items. */
483 (*vector)[*p_ptr] = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object));
484 (*names)[*p_ptr] = (char **) xmalloc (i * sizeof (char *));
485
486 /* I is now the index of the next unused slots. */
487 i = 0;
488 for (tail = keymap; XTYPE (tail) == Lisp_Cons; tail = XCONS (tail)->cdr)
489 {
490 /* Look at each key binding, and if it has a menu string,
491 make a menu item from it. */
492 item = XCONS (tail)->car;
493 if (XTYPE (item) == Lisp_Cons)
494 {
495 item1 = XCONS (item)->cdr;
496 if (XTYPE (item1) == Lisp_Cons)
497 {
498 item2 = XCONS (item1)->car;
499 if (XTYPE (item2) == Lisp_String)
500 {
501 Lisp_Object tem;
502 tem = Fkeymapp (Fcdr (item1));
503 if (XSTRING (item2)->data[0] == '@' && !NILP (tem))
504 pending_maps = Fcons (Fcons (Fcdr (item1), item2),
505 pending_maps);
506 else
507 {
508 (*names)[*p_ptr][i] = (char *) XSTRING (item2)->data;
509 /* The menu item "value" is the key bound here. */
510 (*vector)[*p_ptr][i] = XCONS (item)->car;
511 i++;
512 }
513 }
514 }
515 }
516 }
517 /* Record the number of items in the pane. */
518 (*items)[*p_ptr] = i;
519
520 /* If we just made an empty pane, get rid of it. */
521 if (i == 0)
522 {
523 free ((*vector)[*p_ptr]);
524 free ((*names)[*p_ptr]);
525 }
526 /* Otherwise, advance past it. */
527 else
528 (*p_ptr)++;
529
530 /* Process now any submenus which want to be panes at this level. */
531 while (!NILP (pending_maps))
532 {
533 Lisp_Object elt;
534 elt = Fcar (pending_maps);
535 single_keymap_panes (Fcar (elt), panes, vector, names, items,
536 p_ptr, npanes_allocated_ptr,
537 /* Add 1 to discard the @. */
538 (char *) XSTRING (XCONS (elt)->cdr)->data + 1);
539 pending_maps = Fcdr (pending_maps);
540 }
541 }
542
543 /* Construct the vectors that describe a menu
544 and store them in *VECTOR, *PANES, *NAMES and *ITEMS.
545 Each of those four values is a vector indexed by pane number.
546 Return the number of panes.
547
548 MENU is the argument that was given to Fx_popup_menu. */
549
550 int
294 list_of_panes (vector, panes, names, items, menu) 551 list_of_panes (vector, panes, names, items, menu)
295 Lisp_Object ***vector; /* RETURN all menu objects */ 552 Lisp_Object ***vector; /* RETURN all menu objects */
296 char ***panes; /* RETURN pane names */ 553 char ***panes; /* RETURN pane names */
297 char ****names; /* RETURN all line names */ 554 char ****names; /* RETURN all line names */
298 int **items; /* RETURN number of items per pane */ 555 int **items; /* RETURN number of items per pane */
301 Lisp_Object tail, item, item1; 558 Lisp_Object tail, item, item1;
302 int i; 559 int i;
303 560
304 if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument (Qlistp, menu); 561 if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument (Qlistp, menu);
305 562
306 i= XFASTINT (Flength (menu, 1)); 563 i = XFASTINT (Flength (menu));
307 564
308 *vector = (Lisp_Object **) xmalloc (i * sizeof (Lisp_Object *)); 565 *vector = (Lisp_Object **) xmalloc (i * sizeof (Lisp_Object *));
309 *panes = (char **) xmalloc (i * sizeof (char *)); 566 *panes = (char **) xmalloc (i * sizeof (char *));
310 *items = (int *) xmalloc (i * sizeof (int)); 567 *items = (int *) xmalloc (i * sizeof (int));
311 *names = (char ***) xmalloc (i * sizeof (char **)); 568 *names = (char ***) xmalloc (i * sizeof (char **));
312 569
313 for (i=0, tail = menu; !NILP (tail); tail = Fcdr (tail), i++) 570 for (i = 0, tail = menu; !NILP (tail); tail = Fcdr (tail), i++)
314 { 571 {
315 item = Fcdr (Fcar (tail)); 572 item = Fcdr (Fcar (tail));
316 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item); 573 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
317 #ifdef XDEBUG 574 #ifdef XDEBUG
318 fprintf (stderr, "list_of_panes check tail, i=%d\n", i); 575 fprintf (stderr, "list_of_panes check tail, i=%d\n", i);
319 #endif 576 #endif
320 item1 = Fcar (Fcar (tail)); 577 item1 = Fcar (Fcar (tail));
321 CHECK_STRING (item1, 1); 578 CHECK_STRING (item1, 1);
322 #ifdef XDEBUG 579 #ifdef XDEBUG
323 fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i, 580 fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i,
324 XSTRING (item1)->data); 581 XSTRING (item1)->data);
325 #endif 582 #endif
326 (*panes)[i] = (char *) XSTRING (item1)->data; 583 (*panes)[i] = (char *) XSTRING (item1)->data;
327 (*items)[i] = list_of_items ((*vector)+i, (*names)+i, item); 584 (*items)[i] = list_of_items ((*vector)+i, (*names)+i, item);
328 /* (*panes)[i] = (char *) xmalloc ((XSTRING (item1)->size)+1); 585 /* (*panes)[i] = (char *) xmalloc ((XSTRING (item1)->size)+1);
329 bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING (item1)->size + 1) 586 bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING (item1)->size + 1)
330 ; */ 587 ; */
331 } 588 }
332 return i; 589 return i;
333 } 590 }
334 591
335 592 /* Construct the lists of values and names for a single pane, from the
593 alist PANE. Put them in *VECTOR and *NAMES.
594 Return the number of items. */
595
596 int
336 list_of_items (vector, names, pane) /* get list from emacs and put to vector */ 597 list_of_items (vector, names, pane) /* get list from emacs and put to vector */
337 Lisp_Object **vector; /* RETURN menu "objects" */ 598 Lisp_Object **vector; /* RETURN menu "objects" */
338 char ***names; /* RETURN line names */ 599 char ***names; /* RETURN line names */
339 Lisp_Object pane; 600 Lisp_Object pane;
340 { 601 {
341 Lisp_Object tail, item, item1; 602 Lisp_Object tail, item, item1;
342 int i; 603 int i;
343 604
344 if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument (Qlistp, pane); 605 if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument (Qlistp, pane);
345 606
346 i= XFASTINT (Flength (pane, 1)); 607 i = XFASTINT (Flength (pane, 1));
347 608
348 *vector = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object)); 609 *vector = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object));
349 *names = (char **) xmalloc (i * sizeof (char *)); 610 *names = (char **) xmalloc (i * sizeof (char *));
350 611
351 for (i=0, tail = pane; !NILP (tail); tail = Fcdr (tail), i++) 612 for (i = 0, tail = pane; !NILP (tail); tail = Fcdr (tail), i++)
352 { 613 {
353 item = Fcar (tail); 614 item = Fcar (tail);
354 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item); 615 if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
355 #ifdef XDEBUG 616 #ifdef XDEBUG
356 fprintf (stderr, "list_of_items check tail, i=%d\n", i); 617 fprintf (stderr, "list_of_items check tail, i=%d\n", i);
357 #endif 618 #endif
358 (*vector)[i] = Fcdr (item); 619 (*vector)[i] = Fcdr (item);
359 item1 = Fcar (item); 620 item1 = Fcar (item);
360 CHECK_STRING (item1, 1); 621 CHECK_STRING (item1, 1);
361 #ifdef XDEBUG 622 #ifdef XDEBUG
362 fprintf (stderr, "list_of_items check item, i=%d%s\n", i, 623 fprintf (stderr, "list_of_items check item, i=%d%s\n", i,
363 XSTRING (item1)->data); 624 XSTRING (item1)->data);
364 #endif 625 #endif
365 (*names)[i] = (char *) XSTRING (item1)->data; 626 (*names)[i] = (char *) XSTRING (item1)->data;
366 } 627 }
367 return i; 628 return i;
368 } 629 }